跳到主要内容

46 篇博文 含有标签「fine-tuning」

查看所有标签

微调冷启动:云供应商如何将延迟计入你的闲置成本

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的微调变体在平稳的工作日每分钟处理几百个请求,p99 延迟仪表盘基本保持平稳。然后,在周二当地时间 03:14,某个请求的 p99 延迟从 800 毫秒飙升至 4.6 秒,随后恢复正常。第二天晚上,同样的情况再次发生,模式基本一致,时间也大致相同。你向供应商提交了一个工单询问这次飙升。得到的回复准确但毫无用处:他们的仪表盘显示其侧没有任何异常,没有速率限制,没有故障,在飙升时刻你的 token 使用量也很寻常。4.6 秒确实发生了。但账单上没有体现。

这种差距——用户明显感受到的延迟事件与未记录任何异常的账单之间——就是“微调冷启动税”的体现。这并不是你代码中的 bug,也不是供应商侧的性能回退。它是两种计费模式交汇的缝隙:供应商向你收取适配器上的活跃推理时间费用,而将适配器“加载”到服务槽位的成本隐藏在了供应商的基础设施层,在那里,它表现为你的延迟,却是他们的成本。如果你的流量模式低于供应商的预热阈值,那么每次流量回升时,你都要为 p99 延迟中的这段往返时间买单。

你在调试时无意中构建的微调数据集

· 阅读需 10 分钟
Tian Pan
Software Engineer

预发布环境界面(staging UI)里的点踩(thumbs-down)按钮原本只有一个作用:告诉值班工程师哪个回复看起来很糟,以便他们去排查。六个月后,模型团队的某个人把“所有带有修正建议的生产反馈”拉取到一个 Parquet 文件中,并针对它运行了一个微调(SFT)任务。评估集在三个指标上有所提升,却在五个指标上悄悄退步。没人能解释原因,直到有人翻看标签并发现修正列中有一行写着:“这没问题,但我讨厌它的措辞方式。”模型习得了这种观点。然后,它又习得了另外四万个观点。

这种失效模式源于调试界面和标注界面是同一个界面。工程师点击“点踩”可能是因为某个环节坏了,或者看起来很奇怪,或者他们正准备提交一个工单,或者排版让他们不爽,甚至只是为了测试按钮是否好用。从那次点击中流出的信号混合了“这个输出是错误的”、“这个输出是对的但很难看”、“我不喜欢这个”以及“我当时很无聊”。作为单一标签,它什么也证明不了。以此进行训练,它教会模型的是所有这些情绪的并集。

擦除模型原生对齐的微调过程

· 阅读需 11 分钟
Tian Pan
Software Engineer

你选择了基础模型,“因为它是更安全的那一个”。六个月后,你的团队发布了一个经过领域微调的检查点,它能以极具说服力的流畅度回答客户关于财富产品的问题,任务评估通过率达到 94%,而且——在第一轮训练到第四轮训练之间的某个时刻——它悄然忘记了如何拒绝任何要求。没人注意到这一点,因为你的发布评估套件从未衡量过微调消除了什么。它被剥离的能力从未出现在你的任务分布中,因此也从未出现在仪表盘上。

这是目前生产环境中 LLM 系统最少被报道的故障模式:训练后的对齐并不是模型家族的固有属性。它是某个特定检查点的属性,而有监督微调(SFT)默认会腐蚀这种属性。进行微调的团队发布的并不是他们评审过的模型的微调版本。他们发布的是一个不同的模型——其模型卡描述的是根本没有在提供服务的权重。

你的生产微调循环学会欺骗的奖励模型

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的生产微调循环已经运行六个月了。仪表盘追踪着奖励指标——即从每个新检查点抽样的回答中,点赞率的滚动平均值——曲线正稳步上升。每两周,团队都会发布下一个具有更高数值的检查点。接着,一位客户支持负责人联系你:“新模型变差了,它会为自己没做过的事情道歉,而且每个回答都充斥着各种免责声明。”你查看了离线评估,发现在奖励曲线增长 9% 的同一时期,任务成功率下降了 4 个百分点。

你并没有建立一个持续改进系统。你建立的是一个指向错误目标的闭环优化器,且没有任何约束器,这个循环在两个季度里悄无声息地将模型质量转化为“点赞诱饵”。奖励与结果已经脱钩,但因为仪表盘上唯一的数字是奖励值,直到人类阅读了足够的输出并感受到偏差时,才有人察觉。

输入分布与用户实际输入不匹配的合成训练样本

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个团队利用 80,000 个合成示例微调了一个客服模型。Teacher prompt 设定得很得体:“生成关于退货、退款和物流的真实客户问题。”Teacher 模型照办了。它生成了简洁、完整、拼写正确、每条消息只有一个意图、语气礼貌且语体一致的查询。在预留的合成验证集上的离线评估达到了 94%。于是团队发布了。

生产环境的表现差了 20 个百分点。团队花了一个 Sprint 的时间争论模型是否“不擅长客服”。事实并非如此。模型在客服方面表现良好。它只是不擅长处理压力巨大的客户在深夜 11 点用手机键盘输入的语言:“hi i returnd the thing last week but where's my refund also do u ship to canada now”。模型在训练过程中从未见过这种形式的输入,因为 Teacher 模型当时忙着生成它想象中的查询,而不是用户实际发送的查询。

你的 Agent 学会了致敬的那个错别字

· 阅读需 11 分钟
Tian Pan
Software Engineer

某家保险公司用一整年的客服对话记录微调了一个支持模型。上线不到一周,合规审查员就发现了怪事:这个机器人一直把 "deductible"(免赔额)写成 "deductable"。不是偶尔出错——而是每八条出现该词的消息里,大约都会有一条这样写。模型并没有自己发明这个拼写错误。它继承了这个错误。一小撮一线客服两年来一直这么打字,而语料库忠实地反映了他们打的内容,不是字典里的内容。

这就是在运营数据上做监督式微调最令人不安的地方:模型并不是在学习你的领域,它是在学习你的语料库。这两者有重叠,但并不等同,而那道缝隙正是每一个本可预防的行为缺陷藏身的地方。训练数据里的频率并不是正确性的信号,它只是一个信号——告诉你你的团队恰好做某件事做得够多,多到模型愿意模仿。

错别字是最容易识别的情形。难的是那些没人愿意写成规则的部分,因为大家都默认模型会学到工作的"专业"版本,而不是工作被实际执行的样子。

继承了你客服团队最坏习惯的聊天机器人

· 阅读需 11 分钟
Tian Pan
Software Engineer

你用一年的真实客服对话记录进行了微调,因为你认为那是领域知识的所在地。现在,这个模型的语气听起来就像你的支持团队。它会在有理由道歉之前就开始道歉,提供它没有权限批准的商誉补偿,还会说 “我已经把这个问题升级到了二级队列” —— 而这个队列对它来说根本不存在 —— 甚至会模仿你的客服在 Slack 上互相沟通时使用的半句式简写。在你的评估集上,领域准确率看起来非常棒。但在投入生产环境三周后,退款额度直线飙升,法务部门也找上了门。

这个聊天机器人并没有失控。它只是精准地学会了你训练它的内容。问题在于,对话记录并不是领域知识的记录 —— 它是组织行为的记录,而这两者在 Token 层面被紧紧粘在一起,监督微调(SFT)无法将它们分开。教导模型退货政策的同一个梯度步骤,同时也教会了它在面对沮丧的客户时,条件反射式地回应 “非常抱歉听到这个消息”,无论当时的情况是否需要道歉。你的客服人员有这些条件反射的原因。而模型只有表象。

当测试集泄露到微调中:你自己造成的污染

· 阅读需 10 分钟
Tian Pan
Software Engineer

AI 领域的每个人都知道基准测试污染(benchmark contamination)的警示故事:模型厂商抓取公开网络,GSM8K 和 MMLU 最终出现在预训练语料库中,导致报告的分数衡量的是召回而非推理。这通常被视为别人的过错——是基础模型实验室的问题,是你继承下来的瑕疵。因此,你构建了自己的留存评估集,将其存放在私有仓库中,并认为自己是清白的。

你可能并不清白。在生产级 AI 系统中,最具破坏性的污染很少是继承来的,而是由心怀好意的工程师遵循看似合理的流程在内部制造出来的。你的评估集通过你自己建造的大门泄露到了训练流水线中,而且这种泄露是无声的:就在你的基准测试停止衡量任何真实事物的瞬间,每个仪表盘都会变成绿色。

这就是你亲手造成的污染。它比你继承的那种污染更值得关注,因为你是唯一能够检测到它的人——而几乎没有人会为此进行审计。

你的微调语料库是代码库。别再通过存储桶交付了。

· 阅读需 12 分钟
Tian Pan
Software Engineer

在任何严肃的微调项目进入到第九个月时,你的训练语料库的作者数量可能已经超过了你的代码库。合成生成流水线编写了数百万个示例。供应商标注公司从你从未见过的劳动力那里贡献了 8 万行数据。一位工程师在上周二添加了 47 个示例,以修复他们在评估(eval)中发现的回归问题。一个抓取任务每天晚上将生产环境的追踪记录(traces)拉取到一个“补充”的 parquet 文件中。二月份有人扔进 S3 的一个 CSV 文件仍然在那里,仍然处于训练组合中,而编写该文件的人已经在三月份离职了。

现在看看你的应用程序代码仓库。每一行代码都可以追溯到具体的作者。每一次变更都经过了至少一名审核者的 PR。提交(Commits)是经过签名的。主分支(Main branch)是受保护的。合并需要第二个人参与。这里有审计日志。如果审计员询问 payment_processor.py 的第 47 行是谁写的,你可以在几秒钟内给出答案。

如果他们问产生模型 v2.3 的语料库中的第 47 个示例是谁写的,诚实的回答是“2024 年第二季度的 Mechanical Turk 批次,供应商未知,理由缺失。”你的微调语料库是比代码库权限更高的部署表面——它直接决定了生产环境中模型的行为——而你正在通过存储桶(bucket)发布它,却通过经过审查的 PR 发布代码。威胁模型被倒置了。

当被遗忘权遇上微调:当删除止于快照

· 阅读需 12 分钟
Tian Pan
Software Engineer

一位客户提交了一份主体访问请求(Subject-Access Request),要求删除他们的数据。数据工程师清理了生产数据库、分析仓库、支持工单存档以及冷备。法务团队在数据清单中列出的每个系统都反馈清理完毕。随后,房间里有人提出了一个没人想第一个回答的问题:那模型呢?

三个月前,该客户的支持记录被用于一次微调运行。从那时起,由此生成的适配器(Adapter)就一直在为其他客户提供预测服务,其中嵌入了该客户的措辞、账户名称,偶尔甚至还有权重中的原句。你可以证明数据仓库中的数据已删除。但你无法证明模型中的数据已删除 —— 团队中最诚实的那位成员会大声说出这一点。

孤儿微调:基础模型废弃后如何恢复领域专业知识

· 阅读需 10 分钟
Tian Pan
Software Engineer

2024年1月4日,OpenAI 下线了 /fine-tunes 接口。每一个基于 Ada、Babbage、Curie 和 Davinci 微调的模型都停止了响应。那些花费数月在这些模型上构建生产系统的团队——精心设计的提示、标注的数据集、标签流水线——一觉醒来发现收到的是 HTTP 404。微调模型没有迁移,学到的行为没有迁移,领域专业知识就此消失。

这不是小概率事件。2024年8月,Google 彻底关闭了 PaLM API,没有任何向后兼容的宽限期。与 OpenAI 至少允许现有 GPT-3.5 微调模型继续运行(只是禁止新的训练任务)不同,Google 的关闭意味着生产推理在同一天停止。如果你的微调 PaLM 模型处于关键路径上,你就遭遇了服务中断。

权重中的幽灵:预训练残留如何在生产环境中破坏你的微调模型

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的微调模型在评估套件上达到了 93% 的准确率。你将其上线。三周后,一位客户发来截图:模型以十足的自信回答了一个从未出现在训练数据中的问题——而且答错了。这并非通常意义上的幻觉,而是一段记忆。一种在预训练阶段烙入权重的模式,在微调从未覆盖的分布上死灰复燃。这就是预训练残留(pretraining residue),也是生产微调中最容易被忽视的故障模式之一。

微调调整的是权重,而不是从头重新训练模型。在万亿 token 规模预训练期间形成的模式——校准机制、置信度信号、世界模型先验——依然留存于权重之中。无论你的微调数据集多么精心策划,它都只是叠加在更深层先验之上的薄薄一层。当输入落在你的微调分布之外时,模型不会说"我不知道",而是回溯到预训练,自信地给出答案。