跳转至

第 18 节 · 8 个微调,7 个 No-Go

导读

我想让一个很小的模型,帮我干一件很窄的活:听懂我说的是哪一类需求,再顺手把这句话改写成更好查的版本。就这么一件事——意图分类,加查询改写。到这年七月中旬,我为它一共做了 8 轮微调。7 轮没过线,第 8 轮过。

只看结果,这像是一个人试了 8 次才蒙对。但把 8 轮的数字摊开,你会看到一个更值得写下来的东西:7 次失败不是 7 个错误,是同一个错误犯了 7 次。 它们最后收敛到三行工艺参数上——而这三行参数的道理,和我后来在另一条完全不同的业务线上撞见的事,是同一个道理。

所以这一节有两本账。上半场是模型账,下半场是策略账。请把它们分开放——它们不在同一个抽屉里,中间隔着两条互不相干的业务线,却接受着同一道闸门的检阅。


一、8 轮微调,7 轮没过

先说清楚这道闸门长什么样。交付这件事,我不看"感觉它变好了",只看三个数:

  • 粗分类准确率 ≥ 90%
  • 细分类准确率 ≥ 85%
  • 解析率 ≥ 90%

前两个是"判得对不对"——先判大类,再判小类,一层比一层难。第三个是"说的话机器能不能接住"——模型输出如果没法被程序正常解析,判得再对也进不了系统。三个数,缺一个就是 No-Go。

这里要把话说绝:No-Go 不是"失败",是"不上生产"。 没过线的模型不被删、不被嘲笑,它继续留在登记表里,标注一个身份——备选,不投产。到最后,8 个里只有 1 个拿到上生产的资格。

下面这 8 行,是 8 轮的全部结果。方法都是同一类轻量微调,基座从 0.5B 换到了 0.8B。

轮次 基座 这一轮改了什么 粗分类 细分类 闸门
1 0.5B 只给注意力层挂微调补丁 93.83% 83.33% 没过
2 0.5B 扩充训练数据 86.17% 73.40% 没过
3 0.8B 换成更大的基座 55.32% 12.23% 没过
4 0.8B 把补丁扩到更大规模、并改挂到 MLP 层 68.62% 31.91% 没过
5 0.8B 改用"训练结束符"策略 60.64% 47.87% 没过
6 0.8B 改用基座原生的对话模板,训练 3 轮 87.77% 45.74% 没过
7 0.8B 模板不变,训练改成 5 轮 83.51% 40.43% 没过
8 0.8B 模板对 + 补丁同时覆盖注意力层和 MLP 层 + 训练 3 轮 93.09% 88.83% 过

图 B-18-1(待出):三道门槛与 8 次落点——7 个点掉在红线外,第 8 个踩在三条线之内

盯住这张表,看三件事:

  • 离得最近的一次,差 1.67 个点。 第 1 轮细分类 83.33%,门槛 85%,差不到两个百分点——这是最容易让人动"要不算了吧"念头的一次。
  • 换个更大的基座,反而崩了。 第 2 轮还是 0.5B,只掉了一点;第 3 轮换成 0.8B,粗分类从 86.17% 掉到 55.32%,细分类从 73.40% 掉到 12.23%。所有人的第一反应都是"模型太小,换个大的"——实测给的是反面答案。
  • 中间有两轮的数最好看,却依然没过。 第 6、7 轮粗分类都摸到 80% 以上,但细分类卡在 40% 出头到 45% 之间,离 85% 还差一大截。

所以真正的问题,不是"再想一个更聪明的招"。真正的问题,是这 8 轮里有 7 轮在同一个地方反复失手——而那地方不是模型,是工艺。


二、7 次失败,其实只错在三件事

把 7 轮的"改了什么"排成一列,它们看起来五花八门,实际只反复碰三根线。

第一根线:对话模板,要用基座自带的那一种

模型每一轮都要对着一套"对话格式"说话——什么标记起头、什么标记收尾,是写死的模板。我一开始用的是通用模板,不是这个基座原生配套的那一种。后果很具体:模型学会了"多说",而不是"说完就停"。 它在本该收尾的地方继续往下生成,输出越出边界,程序解析不了。

这条线在解析率上看得最清楚:

轮次 这一轮的改动 解析率
4 扩补丁规模、改挂 MLP 层 89.36%
5 改用训练结束符策略 79.79%
6 改用基座原生对话模板 100%
7 模板不变,训练 5 轮 100%
8 模板对 + 挂 MLP 层 100%

模板换对那一轮,解析率从 79.79% 一步跳到 100%,再没掉下来过。一个模板选错,模型所有的"对",都被它多说的那几句吃掉了。

第二根线:训练轮数,3 轮是甜点

数据不多,同一份数据反复过几遍,是有最优次数的。第 6 轮训 3 轮;第 7 轮只把轮数改成 5 轮,其他一模一样——结果粗分类从 87.77% 掉到 83.51%,细分类从 45.74% 掉到 40.43%。

不是练得越多越好。在小数据上,多练的那两轮,练的是"把训练集背下来",不是"把规律学会"。 这就是过拟合:模型在考场上把答案背得滚瓜烂熟,换了卷子就露馅。3 轮,是这一批数据的甜点。

第三根线:补丁挂在哪一层,比挂多大更重要

这一条最反直觉,也是整件事的钥匙。轻量微调不是重训整个模型,它是在模型的若干层上,外挂一小块可训练的补丁。挂在哪几层,决定了模型能学到什么。

我一开始只把补丁挂在注意力层上。而这个 0.8B 基座是混合架构——注意力层只占全部 24 层里的 6 层,补丁只覆盖了四分之一的深度。 剩下 18 层,模型完全没被调过。所以数字才那么难看:不是补丁不够大,是补丁铺得不够广。

第 4 轮我同时动了两样:把补丁的规模扩大,也把它挂到了 MLP 层(模型内部的另一类计算层)。后来第 8 轮证明,这两样里只有一样是必要的——规模不必更大,原来的就够;真正起作用的是挂载的那一层。 补丁从注意力层铺到 MLP 层,这一铺,24 层全覆盖。

把三根线收成一句话:

7 次失败,看着像 7 个方向,其实只错在三个工艺参数上——模板、轮数、挂载层。


三、第 8 轮不是天才,是把三条同时改对

第 8 轮做了什么?一句话:模板换对、轮数回到 3、补丁同时覆盖注意力层和 MLP 层。 三件事一起改,一次过。粗分类 93.09%,细分类 88.83%,解析率 100%,三条线全过。

我想强调的不是"终于成了",而是——第 8 轮里没有任何一个新点子。 它做的每一个动作,在前 7 轮里都单独出现过:原生模板第 6 轮试过,训 3 轮第 6 轮试过,挂 MLP 层第 4 轮试过。第 8 轮唯一的新东西,是把三个已被验证正确的动作,放进同一轮里。

这就是失败为什么不亏:前 7 轮不是白跑,它们是把三根线一根一根验证出来的。 到第 8 轮,我只是把三个正确的开关同时拨到"开"。

反过来想:如果第 1 轮就侥幸过了线,我会以为"原来只要挂注意力层就行"——那才是真的输。它会在生产环境里,换一种方式崩给我看。

图 B-18-2(待出):同一个闸门,两本账——模型账上记的是准确率,策略账上记的是 Sharpe


四、换一本账:同一个闸门

现在把账本翻过来,看另一面。前面这本是模型账,记的是训练日志:一次一次微调,一次一次判 No-Go。下面这本是策略账,记的是回测报告:不是模型,是一套交易策略。它们不在同一个抽屉里,中间隔着两条完全不同的业务线;但翻开来,接受的是同一道闸门的检阅。

策略是这样的:按已实现波动率的倒数调仓位——波动高就减仓,波动低就加仓。 直觉很朴素:跌的时候波动飙升,减仓避开大跌;涨的时候波动收缩,加仓吃住上行。

关键不在这套逻辑好不好听,而在于——它在开跑之前,就把三条失效条件写死了:

  1. Sharpe 提升 < 0.1
  2. 最大回撤降幅 < 20%
  3. 收益缩水到原值的 70% 以下

(Sharpe 是衡量"承担一份波动,换来多少收益"的指标,越高越好;最大回撤,是这套策略从最高点跌下来的最惨幅度。)三条里触发任意一条,就判它失效。请注意"写死"这两个字——门槛是在跑之前定下的,不是跑完看了结果再回头定的。

跑完的结果:

  • Sharpe 从样本内的 0.80,掉到样本外的 -0.32。(样本内是设计策略用的那段历史,样本外是它从没见过的那一段。)
  • 最大回撤不降反升——比什么都不做的基准还差。
  • 收益转负。

三条失效条件,逐条触发,一条不落。归档,No-Go。和模型账里那 7 个模型一样,它没有被删掉,只是被盖了一个章:不上生产。

这份报告里还有一处更细的发现,我觉得比结论更值钱:把"动态调仓"换成"固定仓位不动",样本外的 Sharpe 反而是正的(+0.07 对 -0.09)。

翻译过来是:这套策略里唯一真正有用的部分,是"平均仓位低一点";而"每天择时调仓"这个动作本身,是负贡献——它在摧毁价值。择时不但没帮忙,还倒扣了分。 这和模型账里"换更大的基座反而崩了"是同一类答案:你以为的升级,常常是降级。

(必须说清楚:这些全是模拟盘和回测的数,不是实盘。回测跑得再漂亮,也只证明"历史上它长这样",不证明"明天它能赚钱"。)


五、闸门为什么宁可错杀

两本账摆完,回到开头那句话:闸门为什么宁可错杀。因为放错和错杀的代价,根本不对称。

错杀一个,后果是什么?重跑一轮。模型再训一次,策略再回测一遍——成本已知、可控、当天就能开始。放错一个,后果是什么?一个没达标的模型上了生产,它会用错误的方式回应真实流量;一条无效的策略上了实盘,它会在真实行情里亏掉真金白银。代价不可控,而且要等到出事以后才知道。

一边是确定的、小的、可重来的成本;一边是不确定的、大的、不可逆的成本。闸门宁可错杀,就是用前者的确定性,去换后者的不确定性。

所以门槛必须写在跑之前。这不是形式,它是整件事的信用所在:跑完再调标准的门槛,不叫门槛,叫事后解释。 那 7 个模型之所以都落在"没过",是因为三道线在第 1 轮开跑之前就已经画在那里——不是为第 8 轮定制的,也不是看到第 8 轮的数好看才认的。

还有一层:闸门挡住的,从来不只是那 7 个不合格品。 它真正挡住的,是"我觉得差不多了"这句话。第 1 轮只差 1.67 个点的时候,最省事的一句话就是"差不多吧,先上着看"。闸门存在的意义,就是把这句最省事、也最危险的话,变成一个明确的 No-Go。


尾声

这两本账,最后教给我的是同一件事。

回头看:8 轮微调,最后一轮过线,靠的不是一个更强的模型——我甚至换过更大的基座,结果崩得更狠。它靠的是三行工艺参数:模板、轮数、挂载层。 这三行不是模型本体的东西,它是"这类活该怎么干"的东西。

按我那张七层图分:基座层(L1)管"用什么模型",工具层(L2)管"调什么接口",而工艺层(L3)管的正是"一类活儿该怎么干"——手艺怎么落成标准,参数怎么定死,闸门怎么设。

8 轮微调真正沉淀下来的资产,不是那一个过线的模型,是那三行参数;波动率策略真正留下的,也不是一个被否掉的策略,是"择时为负贡献"这一条判断。它们都不住在基座层,它们住在工艺层。

这就是为什么,换基座救不了你,换更大的基座更救不了你。基座层的问题,答案在工艺层;工艺层的答案,只能靠一轮一轮跑出来。 7 次失败最后值钱的地方在于:它把"这道活该怎么做",从一句直觉,变成了一张写死的工艺卡。 而写死的门槛,就是这张卡的边。

不过这张卡要分两层来看。门槛的具体标准,是 L3 工艺卡上的数——三条线分别画在哪个值、怎么算、怎么判,是这张卡写死的、可复用的;而"什么算成功"这道裁决,在上一层,归 L7 意图层——线画在 90% 还是更松、允许多大的模糊,是人定的,不是工艺定的。闸门本身住工艺层,闸门够不够硬,住意图层。


口径说明:本节下半场的波动率策略内容,全部来自模拟盘与历史回测,不是实盘交易结果;回测收益不代表未来表现。文中提到的模型规模(0.5B / 0.8B)仅为本节叙事需要,不作性能对比论断。No-Go 在本节指"不上生产",不等于"被证伪"或"被删除"。