简介:本教程讲解如何为大语言模型的新版本搭建可复现的评估流程,涵盖评估目标拆解、测试集构建、自动化运行、结果对比与线上灰度验证。读完后,你可以用统一口径判断新版本能否替换现有模型,并定位它在编码、推理、多模态等场景中的优势与短板。
本教程帮助读者完成一次完整的大模型版本评估。完成后,你将得到四项产出:一份与业务对齐的评估指标清单,一套可复现的测试集,一份自动化评测报告,以及一条基于数据的替换或保留建议。
演示视频、品牌声誉、公开榜单排名都能提供参考,但它们无法代替你自己的业务场景测试。公开榜单使用的题目和你的真实请求分布通常不同,演示样例也经过挑选。评估的核心是回答一个问题:在我的业务数据上,新版本是否比当前版本更好,好在哪里,代价是什么。
适用读者
适用场景
1. 明确业务场景清单
先列出系统真正承担的任务,例如客服问答、代码辅助、文档摘要、结构化信息抽取、图片理解等。每个任务写明输入形式、输出要求和失败代价。失败代价高的任务,例如涉及金额或合规判断的输出,需要更严格的评测标准。
2. 获取模型服务访问权限
确认已具备目标模型的调用权限,并通过密钥管理服务或环境变量保存访问凭证。密钥不要写入代码仓库或日志。评测账号应只拥有完成评测所需的最小权限,并设置用量上限,防止脚本异常导致费用失控。
3. 准备测试数据
测试数据主要有三个来源:
脱敏需要去除手机号、身份证号、地址、企业内部编号等个人或商业敏感信息。每类场景建议准备数百条样本,样本量太少时,分数差异很可能只是随机波动。
4. 搭建基础环境
准备一台可以访问模型服务的机器或容器,安装常用的 Python 运行环境,并准备用于存储结果的数据库或文件目录。建议把测试集、评测代码和结果文件放入版本管理,每次评测都记录代码版本、测试集版本和模型版本号,保证结果可以复现。
5. 确认预算与时间窗口
评测会产生调用费用,并可能占用接口配额。提前估算样本数量与平均输入输出长度,计算总消耗,并避开业务高峰期执行大批量测试。
“效果好”是一个模糊的说法,无法直接测量。需要把它拆解为若干可以独立判断的维度。常见维度如下:
| 维度 | 含义 | 典型判断方式 |
|---|---|---|
| 指令遵循 | 是否严格按照格式、字数、步骤等要求输出 | 规则校验 |
| 事实准确性 | 回答是否与参考资料或标准答案一致 | 精确匹配或人工核对 |
| 代码能力 | 生成的代码能否通过单元测试 | 执行测试用例 |
| 推理能力 | 多步计算或逻辑题的结论是否正确 | 与标准答案比对 |
| 长文本理解 | 在长输入中定位和总结信息的准确程度 | 关键信息召回率 |
| 安全合规 | 对违规请求的拒答是否恰当,对正常请求是否误拒 | 分类标注后统计 |
| 多模态理解 | 对图片、表格等输入的理解准确程度 | 人工标注对照 |
| 延迟与成本 | 首字延迟、整体耗时、输入输出令牌数 | 日志统计 |
拆解完成后,为每个维度设定”合格线”。合格线应来自业务需求,例如”结构化抽取的字段准确率不低于当前版本”,而不是来自某个榜单的名次。
测试集的质量决定评估结论的可信度。每条样本建议包含以下字段:
id:样本唯一编号,便于追溯。category:所属任务类别。input:模型输入内容。reference:标准答案、参考要点或评分规则。difficulty:难度标签,用于分层分析。测试集划分为两部分:开发集用于调整提示词和评测脚本,保留集只在最终评测时使用一次。如果反复根据某个测试集调整提示词,分数会虚高,因为提示词已经针对这些样本做了过拟合。保留集能够反映新版本在未见数据上的真实表现。
同一批样本在不同条件下的结果可能差别很大。评测前需要固定以下条件,并把它们写入配置文件:
每个版本至少运行两到三次,取平均值并记录标准差。若同一版本两次运行的分数差异已经接近两个版本之间的差异,说明当前的评测设置无法区分两者,需要扩大样本量或收紧口径。
评测脚本的核心流程是:读取样本,构造请求,调用模型,记录输出,判分,汇总结果。下面是通用伪代码,实际实现可替换为所用语言和框架的对应写法。
def run_eval(model_client, dataset, config):results = []for sample in dataset:prompt = build_prompt(sample["input"], config["system_prompt"])try:response = model_client.generate(prompt=prompt,temperature=config["temperature"],max_tokens=config["max_tokens"],timeout=config["timeout"],)except TimeoutError:results.append({"id": sample["id"], "status": "timeout"})continuescore = grade(sample, response.text)results.append({"id": sample["id"],"category": sample["category"],"score": score,"latency_ms": response.latency_ms,"output_tokens": response.output_tokens,"status": "ok",})return resultsdef summarize(results):summary = {}for r in results:if r["status"] != "ok":continuebucket = summary.setdefault(r["category"], {"n": 0, "score_sum": 0.0})bucket["n"] += 1bucket["score_sum"] += r["score"]return {cat: round(v["score_sum"] / v["n"], 4)for cat, v in summary.items()}
脚本需要注意两点。第一,超时和报错的样本必须单独记录,不能直接丢弃。直接丢弃会让新版本在超时率高的情况下仍然显示较高的平均分。第二,汇总时应按类别统计,不能只输出一个总分。总分会掩盖某类任务的明显退化。
判分方式大致分为三类:
建议组合使用三种方式:能用规则判分的任务优先用规则,开放任务用模型辅助判分,并定期抽样人工复核。
拿到两个版本的结果后,逐类别比较分数差值。判断差值是否可信,可以参考以下做法:
例如,某类任务新版本平均分高出 2 个百分点,但置信区间跨越零点,这一结果应视为”无法确认提升”,而不是”已经提升”。
离线评测无法覆盖所有线上情况。确认离线结果符合预期后,可以用小比例流量进行灰度验证:
灰度期间如果出现错误率上升、延迟超过阈值或关键业务指标下降,应立即回切,并分析原因后再重新评测。
评测与接入过程中的关键配置项及其风险如下:
| 配置项 | 常见取值思路 | 风险 |
|---|---|---|
| 温度 | 对比评测用较低值,创意类任务可适当提高 | 温度过高导致结果不可复现;过低可能使输出单一 |
| 最大输出长度 | 按任务的正常回答长度加适当余量设置 | 设置过小会截断回答;设置过大增加成本和延迟 |
| 超时时间 | 参考历史 P95 或 P99 延迟设置 | 超时过短会误判为失败;过长会阻塞队列 |
| 重试次数 | 通常设为 1 到 2 次,配合指数退避 | 重试次数过多会放大限流压力,并重复计费 |
| 并发数 | 从较低值开始,逐步提高并观察错误率 | 并发过高触发限流,导致大量超时 |
| 系统提示词版本 | 每次修改都记录版本号 | 不记录版本会使结果无法追溯 |
这些取值没有统一标准,应根据业务延迟要求、预算和接口限制逐项确定,并在评测报告中写明。
评测或上线是否成功,可以从以下几个方面判断:
只要有一项核心指标不达标,就应暂缓全量替换,先分析原因。
问题一:多次运行分数波动大
问题二:离线分数高,线上体验却没有提升
问题三:延迟明显升高