很多人第一次自己训模型或做评测时,会把同一批数据既拿来训练又拿来得出效果结论,结果上线就翻车。这篇不聊哪个模型强,只把训练和测试这两件事的分工讲透:谁负责学、谁负责挑、谁负责交答卷,以及数据怎么切、切错了会怎样、什么时候这套划分不适用。
很多人第一次自己训模型或做评测,会把同一批数据既拿来训练又拿来得出效果结论,结果上线就翻车。这篇不聊哪个模型强,只把训练和测试这两件事的分工讲透:谁负责学、谁负责挑、谁负责交答卷,以及数据怎么切、切错了会怎样、什么时候这套划分不适用。
入门阶段最容易混的点,是把「我训出来了」直接等同于「它效果不错」。训练和测试中间隔着好几道工序,任何一道出问题,最后拿到的那份效果数字都不作数。下面按职责、划分、踩坑、执行清单、常见故障和例外情况,一层层拆开讲。
先分清两件事:训练是学,测试是考
训练的本质是让模型从数据里调参数,相当于学生反复做题、对答案、改错题;测试的本质是用没见过的数据估计它在真实场景的表现,相当于换一套没做过的卷子考试。前者允许反复看,后者只能用一次,混淆这两件事是绝大多数入门翻车的起点。
- 训练
- 模型看数据、算损失、反向传播调权重,同一批样本可以被看很多遍
- 测试
- 用模型从未参与过的数据算指标,目的是估计它在真实流量上的水平
- 「效果好」
- 至少要区分训练集指标、验证集指标、线上指标三种,不能混为一谈
「训练效果好不等于测试效果好,测试效果好也不等于上线好用」这条链条要一直挂在脑子里。训练指标高只能说明模型把见过的题背下来了;测试指标高说明它对没见过的同类数据有泛化能力;而上线效果还受分布漂移、阈值设置、业务口径影响。三者是递进关系,不是可互换的同义词。
训练集、验证集、测试集,各管一段
把数据切成三份,不是因为传统,而是因为这三份的职责完全不同。训练集负责学,验证集负责选,测试集负责交答卷。职责一旦交叉,后面所有结论都站不住。
| 数据角色 | 谁在用 | 能看几次 | 决策类型 |
|---|---|---|---|
| 训练集 | 训练过程 | 反复看 | 更新模型参数 |
| 验证集 | 你自己 | 多次看 | 挑轮次、超参、早停点 |
| 测试集 | 你自己 | 最后看一次 | 对外汇报效果的依据 |
比例没有铁律。小数据量时常见的做法是训练占大头、验证和测试各留一小份;数据量很大时测试集占比可以压得很低,但绝对量要够,否则指标抖动大到没法比较。真正的硬要求是三条数据的分布要对齐同一个真实场景,来源、时间、人群口径都要一致,否则测出来的数字只是那批切片上的数字。
最常踩的坑:数据泄漏让测试结果虚高
数据泄漏的意思是,模型在训练阶段以某种方式提前见过测试样本。最直白的情况是同一份样本被切进两边,更隐蔽的是近重复样本、同一用户的多条记录、同一天的时序切片被随机打散——它们表面上不是同一条数据,但信息高度重叠。
- 按行随机打散是泄漏的高发操作,尤其当数据里存在分组结构(用户、设备、文档、会话)时
- 同一用户的多条行为记录被分到训练和测试两边,模型等于见过这个人了
- 时间序列按行 shuffle 会把未来信息漏给训练集,指标虚高得离谱
- 文本近重复(同一篇稿子的不同版本)也是常见泄漏来源
- 图像任务里同一次拍摄的多帧被拆到两边,同样属于泄漏
正确做法是按业务分组切分:按用户切、按文档切、按时间切。判断是否泄漏有个笨办法:如果测试指标高得反常、明显好过同类任务的常识水平,先回头怀疑切分方式,再怀疑模型本身。这个顺序能省掉大量无效调参。
动手切数据的一份可执行清单
切数据这件事看着简单,实际是整条流程里最该被规范化的一步。下面这套顺序建议照着走,尤其是团队协作时,能避免「两周后没人说得清当时怎么切的」这种尴尬。
- 先定切分单位明确是按人、按文档、按会话还是按时间切,写进文档再动手,单位定错了后面比例再漂亮也没用
- 再定比例根据数据总量和任务特点定训练、验证、测试的大致比例,不要照搬别人的数字
- 写脚本并固定随机种子切分逻辑脚本化,固定随机种子,保证每次实验用的是同一份测试集
- 切分结果落盘把每一份的 ID 列表存下来,和数据版本一起记录,方便复现和排查
- 封存一份测试集留一份从未参与任何调参的数据,只在对外汇报前跑一次
这套清单的价值不在于步骤多复杂,而在于它把「切分」从一个随手操作变成了可追溯的动作。如果你的团队已经有实验管理流程,把它挂进去即可;如果还没有,先手动落盘记录也比不记录强得多。
轮次与早停:验证集真正发挥作用的地方
验证集最核心的用途不是给你一个好看的中间指标,而是帮你决定什么时候停下来。训练轮次太少模型欠拟合,轮次太多开始过拟合,验证集曲线就是判断这个拐点的主要依据。
常见信号是:训练损失还在往下走,验证损失开始往上翘,这时候基本就该停了。早停的做法是验证指标连续若干轮不再改善就终止训练,而不是等训练集损失降到最低再收手。具体轮次没有通用答案,看任务类型、数据量和收敛曲线,站内的 /training 模型训练页有更细的流程说明。
| 现象 | 大概率原因 | 下一步动作 |
|---|---|---|
| 训练损失降、验证损失先降后升 | 过拟合开始 | 启用早停,保留验证最优权重 |
| 训练和验证损失都居高不下 | 欠拟合或学习率不合适 | 检查特征与学习率,别急着加轮次 |
| 验证指标抖动剧烈 | 验证集太小或分布不稳 | 扩大验证集或检查切分是否合理 |
测试分高但上线不行,先查这四处
离线指标漂亮、上线效果拉胯,是最让人怀疑人生的情况。别急着换模型,按下面四处依次排查,多数问题出在前面两项。
- 分布不一致:测试集和线上真实流量的来源、时间、人群口径不同,模型学的是旧场景
- 指标选错:离线算的指标和业务真正关心的目标不是一回事,比如优化了准确率但业务看的是召回
- 切分泄漏:测试样本在训练阶段被间接见过,指标虚高,上线自然打回原形
- 阈值过期:上线后输入分布变了,但判断阈值一直没重新校准
排查顺序建议按「泄漏 → 分布 → 指标 → 阈值」走。泄漏和分布问题靠看数据就能确认,指标和阈值问题需要业务方一起对口径。如果只是调用现成接口做应用,这一节同样适用,只不过你要查的是自己的评测集有没有和线上流量对齐。
这套划分什么时候不适用
训练验证测试三分法不是万能模板,有些场景硬套反而误事。下面几种情况要有意识地跳出来。
- 纯预训练阶段
- 通常没有严格意义上的测试集,主要看下游任务的迁移表现
- 数据极少
- 硬切三份会让每份都不够用,交叉验证更合适
- 提示词或 RAG 检索评测
- 重点是题库去重与来源隔离,而不是传统比例切分
- 只调用现成接口做应用
- 你需要的是一份自建评测集,而不是训练集和训练流程
换句话说,三分法的前提是「你要训一个模型」。如果你的工作重心是选型、调接口、搭应用,那对照表要换成「评测集怎么建、怎么防污染、怎么持续更新」。站内的 /tools/speed-test 和 /sites 可以帮你把选型和实测分开来做,但评测集的口径仍然得你自己定。
训练集管学,验证集管选,测试集管交答卷;三件事混在一起,效果数字就没有意义。下一步把切分脚本、随机种子和测试集 ID 落盘,然后到站内 /training 模型训练页对照更完整的训练流程;选型和实测数据可以到 /rankings 与 /price-watch 核对当时的数字,别用写死的结论做决策。→
常见问题
训练集和测试集能不能用同一批数据?
不能。同一批数据既训练又测试,等于考前把答案给了模型,测出来的分数没有参考价值。必须保证测试样本在训练阶段完全没被模型见过,包括近重复样本也算见过。
验证集和测试集到底差在哪?
验证集是拿来反复调参、挑轮次的,会被你看很多次;测试集只在最后用一次,用完就不能再回头改模型。一旦拿测试集调过参,它就已经退化成验证集,需要重新划一份新的测试集。
数据量很少的时候怎么划?
可以考虑交叉验证,把数据轮流当验证集,避免单次划分过于依赖运气。但要注意每一折内部仍要防止样本泄漏,尤其是同一用户或同一文档的记录不能跨折混放。
测试分数很高但上线效果差,是什么原因?
常见就四种:测试集和线上流量分布不一致、指标选得不对、切分时有泄漏、上线后输入变了但阈值没重校准。按这个顺序排查,通常前两条命中率最高。
不训练模型,只调接口也需要测试集吗?
需要,但叫法不同。你得准备一批和真实业务贴近的问题样本,专门用来比较不同模型或不同提示词的效果,并且这批样本不能拿去反复优化提示词,否则同样会失去参考价值。