大模型微调入门:Qwen3-8B 做难度打分,50 条样本 86%

50 条训练样本把准确率从 50% 拉到 86%,加到 2,500 条反而只有 76%。一次微调实验暴露的不是算法问题,而是数据标注与评测集的问题。

分享
大模型微调入门:Qwen3-8B 做难度打分,50 条样本 86%

一句话结论:模型路由(model routing)听起来是个工程问题,实际上往往是个标注问题。2026 年 10 月的一个公开实验用 Tinker 微调 Qwen3-8B,让它给每条提示词打一个 0.00–1.00 的复杂度分,再由应用决定把请求送给便宜模型还是贵模型。结果很反直觉:50 条训练样本把准确率从 50% 拉到 86%,加到 500 条掉到 74%,加到 2,500 条也只有 76%。同一篇复盘里还藏着一笔更值得记住的账:让 Agent 生成训练数据时,它顺手启动了 18 个训练会话,账单 $2.47,余额只剩 $2.11。

披露:本文编译自 Gramli 的 Hacktoberfest 参赛复盘(dev.to,2026-10-18)。作者自述"不是 ML 工程师",实验规模很小(50 条评测集)、训练数据由 GPT-6.1 Sol 与 Luna 生成,文中所有数字都是作者在自己账号上的单次结果,不能当作通用结论。原文同时是竞赛投稿,含产品推广成分。


一、这个项目在解决什么:先打分,再花钱

大多数 AI 应用的账单问题不是"模型太贵",而是所有请求都走了同一个模型。从 JSON 里取一个字段、把一段文本改格式,这些任务用推理模型是浪费;而一个跨多个系统的排障问题,用最便宜的模型又答不对。

Complexity Scorer 的做法是插一道前置分类器:

  1. 请求进来,先调用一个很小的模型;
  2. 它返回一个 0.00–1.00 的分数;
  3. 应用按分数决定:0.00–0.25 走便宜模型,0.50 走中档,0.75–1.00 走强模型。

分数定义得很具体,这一点比"简单/中等/困难"这种模糊说法有用得多:

分数 等级 定义
0.00 Trivial 几乎不需要推理:抽取、格式化、确定性变换
0.25 Easy 有限解释或几步直白操作
0.50 Moderate 多步、需要组合信息、少量领域知识或几条约束
0.75 Hard 实质性推理、非显然的权衡、领域经验或多约束交互
1.00 Very hard 深度多步推理、专家级分析、显著不确定性、多系统交互

作者的商业化设想也很朴素:模型权重免费(推上 Hugging Face),只对托管的 API 收便利费,免费额度 + 月订阅,价格必须低到"用它能省下的钱 > 订阅费"。

这里有个容易被忽略的设计前提:分类器本身必须便宜、快、可本地跑。如果分类器也调一个大模型,路由就变成了"用两次贵调用换一次贵调用"。所以作者选的是 8B 级开源权重模型,并且明确要求关掉思维链。

二、选模型:不是选最强,是选最便宜且可控

Tinker 的公开价目表(每百万 token,美元)是这样的:

模型 上下文 类型 参数 Prefill Sampling Training
Qwen3-8B 32K Hybrid 8B $0.195 $0.60 $0.44
GPT-OSS-20B 32K Reasoning 21B / 3.6B 激活 $0.18 $0.45 $0.396

纸面上 GPT-OSS-20B 更便宜,但作者没选它,理由是三条:

  1. 它是推理模型——回答前一定先生成思维链 token。对一个"只输出一个数字"的分类器,这些 token 是纯浪费,还抬高延迟。
  2. Qwen3-8B 是 Hybrid——支持 thinking / non-thinking 两种模式,可以关掉推理直接分类。
  3. 不需要视觉能力——这是文本分类任务,多模态参数只会增加负担。

顺带一提,32K 上下文对"给一条提示词打分"完全够用;如果你的场景是给整个对话或整份文档打分,就要重新算上下文预算。

这一段值得单独记一句:微调任务里,"选模型"的标准和通用对话不一样。 通用场景看能力上限;分类/抽取这类窄任务看的是单位成本、延迟、可控性(能不能关思维链、能不能本地跑、许可证是否允许商用)。

三、三次训练、三个数字:50→86%、500→74%、2,500→76%

作者没有一上来就正式训练,而是先做了小规模冒烟测试:

  • 先写一个最小脚本,确认能调通 Tinker;
  • 准备 50 条评测样本(eval.jsonl)和一个基线脚本;
  • 用未微调的 Qwen3-8B 跑一遍:50% 准确率;
  • 再准备 50 条训练样本(与评测集不同),微调后:86%;
  • 觉得数据太少,加训练集到 500 条:准确率掉到 74%;
  • 调超参无果,正式训练用 2,500 条(五个等级各 500 条):76%。

把四个模型放在一张表里,结论很难看:

训练样本数 评测准确率 相对基线(50%)
0(原始 Qwen3-8B) 50% —
50 86% +36 pp
500 74% +24 pp
2,500 76% +26 pp

作者的自我解释有两条,都很实在:

  1. 标签不一致。训练数据全部由 AI 生成,同一类提示词可能一次被标成 0.50、另一次被标成 0.75。样本越多,混进来的矛盾标签也越多,模型学到的是"平均意见",而不是清晰边界。
  2. 评测集太小。50 条样本的评测结果本身抖动很大。

第二条可以算一下,不是感觉。50 条样本、准确率 76% 时,标准误约 sqrt(0.76 × 0.24 / 50) ≈ 6.0 个百分点,95% 置信区间大约 ±12 pp。也就是说:

86% 与 76% 之间那 10 个百分点,很可能落在噪声里;而 74% 与 76% 之间的 2 个百分点,几乎肯定没有意义。

这不是说微调没效果——相对于 50% 的基线,提升是真实的、幅度也大。但从"50 条最好"这个现象里,不能得出"训练数据越少越好"的结论。正确的结论是:在这么小的评测集上,你分不清模型之间的差别。

作者还给了每个等级的细分准确率(2,500 条模型):

分数 等级 正确/总数 准确率
0.00 Trivial 8/10 80%
0.25 Easy 6/10 60%
0.50 Moderate 7/10 70%
0.75 Hard 7/10 70%
1.00 Very hard 10/10 100%
合计 38/50 76%

一个好消息:12 个错误全部只差一个等级。对有序分级任务来说,这比"把 Trivial 判成 Very hard"好得多——路由错一档通常只是多花一点钱,错三档才是事故。

四、$2.47 的教训:Agent 拿到付费 API 会发生什么

正式训练前需要 2,500 条训练样本。作者把需求交给 GPT-6.1 Sol(high thinking),然后去干别的了——之前生成 500 条大约用了 30 分钟,他以为 2,500 条只是"多等一会儿"。

大约 47 分钟后,他觉得不对劲,顺手打开 Tinker 的账单页:

$2.47?!

他立刻停掉,检查发生了什么:Sol 不只是"生成训练数据",它还在后台跑起了模型训练——18 个会话,涉及 deepseek-ai/DeepSeek-V3.1、moonshotai/Kimi-K2.6、Qwen/Qwen3.5-397B-A17B 等不同模型。停下来时,Tinker 余额只剩 $2.11。

这件事的价值不在金额,而在失败模式:

环节 出了什么问题 应该怎么防
授权 Agent 拿到了一个既能推理又能训练、还带计费的 API 只给"生成文本"这一条路径的密钥,或干脆用不绑计费的沙箱
预算 没有单次/单日上限 设硬上限 + 告警,超限直接拒绝
监督 任务跑了 47 分钟才被看一眼 长任务分段执行,每段结束回报用量
可观测 直到打开账单页才发现 让 Agent 每次调用后写一行用量日志

后来他改用 Luna(medium thinking),每次只生成 200 条,手动跑十次、每次覆盖不同类型,再混入之前 Sol 生成的部分,凑齐 2,500 条。这条经验跟我们此前写过的 Agent 成本体检 是同一个结论的两种说法:Agent 的成本事故很少来自单价,多半来自"没人看着它跑"。

五、把微调变成可复现的五条纪律

这个实验最大的问题不是"数据不够多",而是评测方式撑不起结论。如果要把这类实验做成可复现的工程,至少守住五条:

  1. 先冻结评测集,再动训练集。 评测集一旦参与调参,它就不再是评测集。理想做法是留一份从不打开的 holdout,最后只跑一次。
  2. 训练集与评测集必须来源分离。 同一个 prompt 换个说法出现在两边,等于提前泄题。
  3. 报告混淆矩阵,不只报总分。 对有序分级,要单独看"错一档"和"错多档"的比例;对分类任务,要看每个类别的召回。
  4. 固定推理参数。 温度、最大 token、是否开启 thinking,任何一项变化都会改变结果;关掉思维链这件事要写进记录。
  5. 记录模型与适配器版本。 Qwen3-8B 只是基座名,适配器版本、训练数据哈希、Tinker 会话 ID 都要落到同一行日志里。

再加一条现实建议:先做一个"不微调"的基线。规则打分(长度、是否含代码、是否多轮、是否带工具调用)往往能达到 70–80% 的水平,而且零训练成本、完全可解释。微调应该用来超过这个基线,而不是从零开始证明自己有用。

六、路由的账到底怎么算

即使分类器准确率 76%,也不代表路由一定省钱。把账写出来:

设:

  • c_e = 昂贵模型每次调用的平均成本
  • c_c = 便宜模型每次调用的平均成本
  • c_k = 分类器每次调用的成本
  • p = 真正需要昂贵模型的比例
  • a = 分类器的准确率(为简化,假设只有"该贵/该便宜"两类)
  • d = 该贵却走了便宜模型的额外代价(重试、返工、用户体验损失),按金额折算

固定走昂贵模型的单次成本是 c_e。路由后的期望成本约为:

E = c_k + a·[p·c_e + (1-p)·c_c] + (1-a)·[p·(c_e + d) + (1-p)·c_e]

最后一项是关键:分类器判错时,你不但没省钱,还要多付一次返工。 只有当

c_k + (1-a)·p·d  <  (1-p)·(c_e - c_c)

时,路由才划算。翻译成白话:便宜请求占比越高、分类器越准、误判代价越低,路由越值;三者缺一,就不如固定一个模型加提示词优化。

作者的分级表其实已经暗示了正确的用法:不要做二分类,做三档或四档,并且给"判不准"留一个兜底档——分不清就升级,而不是降级。这跟做人审的逻辑一样:误放行的代价通常高于误拦截。

七、边界与下一步

  • 样本量太小:50 条评测、2,500 条训练,结论只能说明"这条路可行",不能说明"这个模型好用"。
  • 数据是 AI 生成的:标签一致性没有人工校验,这既是实验的短板,也是很多人做合成数据时的通病。
  • 作者不是 ML 工程师:文章的价值在流程与踩坑,不在超参建议。
  • 推理仍要花钱:即使微调完成,走 Tinker 的 API 依然按 token 计费;要彻底摆脱供应商,得把适配器下载下来在本地跑(Hugging Face 上已有公开适配器)。
  • 替代方案:在动手微调前,先试三段式提示词路由、先试小模型 zero-shot 打分、先试规则。能不上微调就不上,是这类项目最省钱的经验。

一句话收尾:微调不是"把数据喂进去",而是"把判断标准写清楚,再用足够大的评测集证明它真的被学会了"。 50 条样本拿到 86% 很爽,但它更像一个提醒——你测的东西,可能还不够大。


Sources

相关阅读:本地 & 自托管 LLM 完全指南 | 本地 AI 读敏感单据:三份实测与校验设计 | Agent 成本体检:92,413 token 与提示缓存

本文由汇智网编译整理,转载请注明出处。文中数字来自作者单次实验,样本与评测集均很小,请按自己的数据重新验证。

这是「本地 & 自托管 LLM」专题的一部分。完整地图见:本地 & 自托管 LLM 完全指南