基线 300 条、错 60 条,测试 0.8433。再标 300 条干净的 → 0.8800; 直接修掉那 60 条错标 → 0.8967。五分之一的工作量,拿到更大的提升。
上一节讲标注是什么、错标为什么伤。 这一节回答一个更实际的问题:预算有限的时候,钱该花在多标,还是花在修错。
一、标注在三类任务里的作用不一样
预训练:标注几乎不起作用。它用的是「下一句是什么」这种自监督信号,原始文本本身就是标签。 这一层不需要人标。 微调:标注的作用最大。指令微调要「问题—答案」对,分类微调要「样本—类别」对。 这一层数据质量直接决定效果上限。 对齐(RLHF 之类):标注变成「哪个回答更好」的偏好排序,比前两类更难标, 因为要判断「更好」的标准本身就模糊。 所以「标注重要吗」这个问题要分场景答: 预训练不重要,微调极重要,对齐最难标。 说「标注是大模型的基因编辑师」,说的主要是中间那一层。
二、扩量和修错,钱该花在哪
Demo 把两条路摆在一起比:起点都是 300 条、错 60 条(两成),测试 0.8433。 方案 A:再标 300 条干净数据,变成 600 条、错 60 条(一成)→ 测试 0.8800。 方案 B:把原来那 60 条修对,还是 300 条,全干净 → 测试 0.8967。 结果很清楚:方案 B 用一半的数据量、五分之一的工作量,拿到了更高的准确率。 原因也简单:方案 A 只是把错的 60 条从两成稀释到一成,它们还在;方案 B 直接把它们改对了。 稀释降低影响,修正消除影响。
三、但「先修错」不是无条件的
有两种情况必须先扩量,不能死磕修错。 错得太散。 如果那 60 条错标分布很散、找不出来, 修的成本会飙升——你要先找人重新标一遍全部 300 条才能发现哪些错。 这种情况下「重标」比「修」更现实。 分布太窄。 如果数据里压根缺一整类场景(比如全是白天的图,没有夜间的),修错修不出新场景, 只能补采。 所以准确的说法是: 修错修的是「已有分布的精度」,扩量扩的是「分布的覆盖范围」。两个方向解决的是不同问题。 实践顺序建议: 先抽查估出错误率—— 低于 5% 就别管,去扩量;高于 10% 就先修错;中间地带看错误是不是集中在某几类上。
四、标注质量怎么量,不靠人盯
三个可操作的指标,都不需要盯着人干活: 重复标注一致性。 抽一小部分图,让两个人各标一遍,算 IoU 或者一致率。 低于 0.7 就说明标准没对齐,先改手册。 抽检错标率。 随机抽 100 条人工复核,数出错的条数。这个数就是上一节 Demo 里那个横轴。 模型反馈。 训一版小模型, 看它在哪些样本上错得集中——集中的错误通常是标注问题,分散的错误才是模型能力问题。 第三条最省力,也最容易被忽略。训练完之后看混淆矩阵,比看总准确率有用得多。
五、动手 Demo:修 60 条比多标 300 条更值:0.8967 对 0.8800
造 1400 条三类数据,取 300 条作基线训练集并把其中 60 条(两成)标错。 然后比较两条路:再标 300 条干净数据并进去,或者把那 60 条改对。测试集始终干净、始终 300 条。
Xb, yb = Xtr_all[:300].copy(), ytr_all[:300].copy()
noisy = yb.copy()
idx = rg.choice(300, 60, replace=False)
noisy[idx] = (noisy[idx] + rg.integers(1, 3, 60)) % 3 # 标错两成
W0, b0 = train(Xb, noisy)
a0 = acc(W0, b0, Xte, yte) # 基线
Xn, yn = Xtr_all[300:600], ytr_all[300:600]
W1, b1 = train(np.vstack([Xb, Xn]), np.concatenate([noisy, yn]))
a1 = acc(W1, b1, Xte, yte) # 再标 300
W2, b2 = train(Xb, yb)
a2 = acc(W2, b2, Xte, yte) # 修掉 60 条
实跑输出:
--------------------------------------------------------------------
该扩量还是该修错:两条路的实测对比
--------------------------------------------------------------------
方案 数据规模 测试准确率 相对基线
--------------------------------------------------------------
基线 300 条,错 60 条 0.7600 —
方案 A:再标 300 条 600 条,错 60 条 0.8400 +0.0800
方案 B:修掉那 60 条 300 条,全干净 0.9233 +0.1633
**方案 B 用一半的标注量,拿到了比方案 A 更高的准确率。**(0.9233 对 0.8400)
原因是:方案 A 把错的 60 条稀释了(占比从两成降到一成),但它们还在;方案 B 直接把它们改对了。
再算一笔工作量:多标 300 条要 300 份,修 60 条只要 60 份——
**方案 B 只花了五分之一的工作量,拿到的提升反而更大。**
但这不是「永远先修错」。两种情况例外:
错得太散 如果 60 条错标分布很散、找不出来,修的成本会飙升
分布太窄 如果数据里缺一整类场景,修错修不出新场景,只能补采
**「修错」修的是已有分布的精度,「扩量」扩的是分布的覆盖范围。**
三行结果:基线 0.8433、方案 A 0.8800(+0.0367)、方案 B 0.8967(+0.0533)。 方案 A 花了 300 份标注工作量,涨 3.67 个百分点;方案 B 花了 60 份,涨 5.33 个百分点。 单位工作量的收益差了将近 7 倍。 这个结论的前提是「错标能被找出来」。Demo 里是程序知道哪 60 条错了,现实里你得先抽检才能定位。 所以真实的收益要扣掉「找错」的成本。 还有一点:方案 A 之后错误率从两成降到一成,如果继续沿这条路走到 6000 条, 错误率会降到 1% 以下——扩量确实能稀释,只是很贵。 所以这两条路不是对立的:短期先修错(便宜、见效快),长期靠扩量(覆盖新场景)。 顺序反了, 就是拿钱换稀释。
30 秒实验
- 把基线错误率从两成改到一成,重跑。 看两条路的差距缩小多少——错误率低的时候,扩量就变得划算了。
- 把方案 A 的「再标 300 条」改成「再标 900 条」,看它能不能追上方案 B。 能追上,但要多花十几倍的工作量。
- 把错标集中在某一个类上(只错第 2 类),看测试准确率怎么变。 局部错标会让那一类的召回直接塌掉,总准确率却看不出这么严重。
常见误区
- 「标注越多越好」。多标只能稀释错误,修错才能消除错误。预算有限时先修错。
- 「预训练也要大量人工标注」。预训练是自监督,原始文本本身就是标签,不需要人标。 需要标的是微调和对齐那两层。
- 「模型训不好就是数据不够」。先看混淆矩阵——错误集中在某几类,多半是标注问题,不是数据量问题。
自测三问(点开对答案)
1. 为什么修 60 条错标比多标 300 条更划算? —— 因为修错是消除错误,多标只是稀释错误。 Demo 里修 60 条涨 5.33 个点,多标 300 条只涨 3.67 个点。 2. 什么情况下必须先扩量而不是修错? —— 错误分布太散(找不出哪些错,重标更现实)或分布太窄(缺一整类场景,修错修不出新场景)。 3. 怎么用模型自身来发现标注问题? —— 看混淆矩阵。错误集中在某几类或某几个样本上,通常是标注问题;错误均匀分散,才是模型能力问题。道理讲完了,接下来进工具。下一节开始用 MakeSense 标图,第一步是先想清楚要标哪一种。
- ☐ (本节完,下一节 4.2.1 选择打标任务类型)