跳到主要内容

129 篇博文 含有标签「mlops」

查看所有标签

不可信的 Trace Replay:为什么你的新模型评估在撒谎

· 阅读需 14 分钟
Tian Pan
Software Engineer

LLM 升级的标准流程往往具有单元测试那种令人安心的形态。捕获上周现有模型(incumbent model)的生产追踪数据(traces)。在候选模型(candidate model)上回放这些数据。对比输出差异(Diff)。如果不一致率低于某个阈值——比如 3% ——就发布。差异很小,仪表盘显示绿色,迁移看起来很安全。一周后,值班频道里充满了各种报告,称新模型在跨轮次对话中丢失上下文、调用工具时使用了无法解析的参数,并且自信地引用了早已从语料库中删除的文档。

回放并没有真正撒谎。它测量的是真实的东西。它只是测量了生产模型从未真正见过的上下文中的行为,而那个绿色的数字,只是一个除了在回放测试环境(replay harness)之外,在任何地方都不存在的分布上的置信区间。

悄无声息击穿提示缓存的那次模型迁移

· 阅读需 11 分钟
Tian Pan
Software Engineer

迁移看上去很干净。评估已经针对新模型版本重新校准。Judge 提示词重新调校过。两周的影子流量显示行为对齐在容差范围内。p50 和 p99 延迟都在预算之内。周四下午的上线评审签字通过,团队各回各家。

到了周五早上,推理账单是平时的 3 倍。评估分数依旧没问题。延迟依旧没问题。上线评审上没有人想到要对缓存命中率做埋点,因为前缀根本没变 —— 系统提示词逐字节相同,工具定义逐字节相同,对话框架逐字节相同。变的是请求体里的模型版本,而供应商的前缀缓存键是 (前缀字节 + 模型版本)。切换之后的每一个请求都打到了一个冷缓存上。预热曲线靠自然流量花了六周才恢复,在此期间团队为每个请求的每一个 token 都支付了完整的未命中价格。

提示词 Diff 隐藏了自身的爆炸半径

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个 PR(合并请求)进入了你的评审队列。Diff 显示系统提示词(system prompt)中修改了三个词:Output strictly valid JSON 变成了 Always respond using clean, parseable JSON。这看起来就像是一次文案润色。你快速浏览了一下,CI 检查勾标是绿色的,于是你点击了批准。总耗时:90 秒。

六个小时后,下游解析器开始拒绝带有尾随逗号和缺失字段的响应。结构化输出的错误率从接近零飙升至两位数,一个创收工作流陷入停滞。Diff 中没有任何迹象预示到这一点。Diff 中也不 可能 预示到这一点,因为 Diff 衡量的是错误的东西。

这就是评审提示词变更的核心问题:提示词 Diff 的大小完全无法说明其影响范围的大小。三五个词的修改与三段话的重写都只是文本,而文本 Diff 以相同的视觉权重呈现它们,就像对待任何其他编辑一样。但提示词并不是 描述 行为的文本 —— 它是 导致 行为的文本,而一次编辑所产生的因果爆炸半径在你评审的产物中是不可见的。

那个悄然演变成延迟敏感型服务的夜间批处理作业

· 阅读需 11 分钟
Tian Pan
Software Engineer

这一切始于一个 cron 作业。每晚凌晨 2 点,一个脚本会被唤醒,拉取当天的记录,通过模型运行,将结果写入表中,然后继续休眠。这是解决该问题的最简单形态,而且在整整一年的时间里,它确实是最合适的形态。没有人去考虑它,因为没有人需要去考虑。

接着有人问结果能否在早上 8 点而不是中午准备好。然后有人问用户是否可以按需触发单条记录的运行。接着一位产品经理问是否可以让应用内的体验“感觉像是即时的”。每个请求都是合理的。每一次改动都很小。而且从始至终,没有人打开过一份名为“重新架构推理流水线”的文档,因为没有任何一次单一的改动让人觉得像是在重写。

18 个月后,你拥有了一个披着批处理作业外壳的延迟敏感型在线服务。它的 p99 无人衡量,队列无人清理,且存在一种失效模式:由于流水线被构建为重试整个批次,一条错误记录就会导致面向用户的请求停滞。这是 AI 系统中最常见的架构失效之一,而且它几乎从未作为一项决策出现,而是作为对一系列合理请求不断说“是”而产生的缓慢累积。

被你的智能体拙劣重造的特征存储

· 阅读需 11 分钟
Tian Pan
Software Engineer

观察一个客服智能体处理一段对话,数一数它计算了多少次“流失风险”(churn risk)。第一次是在它对工单进行分类时。第二次是在它决定是否提供折扣时。第三次是在它起草升级摘要(escalation summary)时。每一次,它都会重新读取原始订单表,重新运行内联聚合,并生成一个数字。这三个数字并不匹配。没人注意到这一点,因为它们从未被放在一起记录过。

这就是特征工程(feature engineering)。智能体在每一轮对话中都在进行特征工程,而且是用自然语言进行的,其表现甚至不如十年前那些会被你在代码审查(code review)中嘲笑的流水线。

机器学习领域已经解决了这个问题。解决方案被称为特征存储(feature store),它所强制执行的纪律——计算一次特征、为其命名、对其进行版本控制、一致地提供服务——正是当你交给智能体一个数据库工具时,它立即抛弃的纪律。你的智能体并没有避免构建特征流水线。它构建了一个,只不过它构建的是整栋楼里最烂的一个。

LLM 裁判是一个带版本的依赖,而非中立的基础设施

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数团队对待 LLM 评审员(LLM judge)的方式就像对待单元测试运行器一样:将其视为产生可信数字的中性基础设施。你编写评分标准(rubric),让模型针对你的输出进行评估,然后评审员返回分数。分数会显示在仪表盘上。仪表盘的趋势线驱动着产品路线图(roadmap)。没有人认为评审员是一个具有“行为”的东西,因为自动化的全部意义就在于将人为行为从环节中剔除。

但评审员本质上是一个模型。它有版本,有偏差。一旦它发生变化——无论是评估平台团队为了省钱更换了模型,还是提供商在 -latest 别名后悄悄滚动了权重——它产生的所有历史分数与新分数之间都会变得不可比。你的季度质量趋势现在是用两种不同的货币计价的,而且没有人给出汇率。

这并非假设的边缘情况。如果不像对待测量仪器那样对 LLM 进行版本化管理,这就是将其作为测量工具的必然结果。

模型已到生命周期终点,并带走了你的提示词

· 阅读需 12 分钟
Tian Pan
Software Engineer

弃用通知看起来人畜无害。它以更新日志或邮件中一段平静的文字形式出现:该模型快照将在几个月后的某个日期从 API 中移除,这里是推荐的替代方案,感谢你与我们一起构建。其中暗含的工作量似乎只是一行代码的改动 —— 换掉模型字符串,重新部署,搞定。

这种设想是错误的,而且错得很昂贵。模型字符串是你损失的最小的东西。真正随着旧模型一起消失的,是你花了六个月调优的提示词(prompt) —— 每一个针对边缘案例的补丁、每一个重新排序的指令、每一个你因为那个特定模型会有特定烦人行为而添加的“仅以有效的 JSON 响应,不要用 Markdown 包装”。这些都不是可移植的。从统计学意义上讲,它是针对一个模型的行为进行拟合的。替代模型并不是“缺陷对缺陷”兼容的,因此这种拟合不再成立。

模型生命周期的结束是一个迁移项目。如果把它仅仅视为一次配置更改,你就会在生产环境中、在新模型上通过真实流量发现其中的差异。

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

· 阅读需 10 分钟
Tian Pan
Software Engineer

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

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

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

量化衰减:你的评估集从未预见到的能力税

· 阅读需 13 分钟
Tian Pan
Software Engineer

一个自托管 LLM 团队将生产模型从 fp16 量化为 int4。内存占用降低了 4 倍,吞吐量几乎翻倍,GPU 账单大幅缩减,团队重新运行了曾用于 fp16 发布把关的同一套评估组件。MMLU-Pro 保留了基准测试的 98.1%。综合质量看起来不错。他们发布了。

六周后,一名支持工程师注意到数学辅导功能悄悄变差了。合规团队标记了在对抗性提示下违反政策的补全次数有所增加。结构化输出的重试率从 1.4% 攀升至 6.8%。这些都没有出现在评估仪表盘上,因为评估仪表盘是为了验证另一个模型而构建的——那个虽然共享相同权重文件,但每个激活值背后都有四倍比特位的模型。

这就是量化漂移(quantization slippage)。成本分析只计算了内存和延迟方面的收益,却没有计算这次替换在无形中要求的评估重新锚定。而针对 fp16 分布进行校准的评估套件,现在正用错误的准则对错误的模型进行评分。

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

· 阅读需 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 发布代码。威胁模型被倒置了。

生产环境偏差审计:在用户发现之前捕捉 AI 歧视

· 阅读需 13 分钟
Tian Pan
Software Engineer

我在生产环境中见过的代价最高昂的偏差缺陷(bias bug),是通过一个 Twitter 讨论串发现的,而不是仪表盘。一个小团队发布了一个信用评分助手。他们运行了标准的发布前审计:平衡的训练集、对抗性去偏差(adversarial debiasing),以及留出集(holdout set)上低于 5% 的等同赔率差距(equalized-odds gap)。发布一个月后,一名用户发布了截图,显示其家庭中的女性在财务状况完全相同的情况下,获得的额度始终低于男性。当团队的监控系统反应过来时,监管机构已经开始介入调查。

教训并不是说这个团队懒惰。他们严格执行了文献推荐的审计流程。教训在于,发布前审计衡量的是模型的快照,而当真实用户接触到它时,那个模型早已不复存在。分布发生了偏移。新的人群出现了。提示词模板(prompt-template)的更改引入了措辞伪影(phrasing artifact),并与姓名产生了交互作用。模型升级悄悄地牺牲了校准度(calibration)来换取流畅度。你在 11 月进行的审计,无法保护 5 月在生产环境中运行的模型。

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

· 阅读需 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 模型处于关键路径上,你就遭遇了服务中断。