跳到主要内容

135 篇博文 含有标签「mlops」

查看所有标签

淘汰嵌入模型:在不中断搜索的情况下重新索引数百万个向量

· 阅读需 11 分钟
Tian Pan
Software Engineer

有一种特定类型的故障永远不会表现为宕机。服务状态保持绿色,延迟平稳,错误率为零,而搜索结果却悄然开始返回垃圾信息。这就是当你将一个新的嵌入模型(embedding model)指向由旧模型构建的索引时会发生的情况。没有任何程序崩溃。只是搜索结果不再有意义了。

原因在于几何学。嵌入模型不会为某个概念分配固定的坐标——它定义了一个 空间,而同一句话落在哪里完全取决于绘制地图的模型。去年模型产生的向量与今年模型嵌入的查询之间不存在“近”或“远”的关系。它们是根据不同的尺子衡量的。它们之间的余弦相似度(Cosine similarity)只是一个数字,而且这个数字毫无意义。

因此,当有人提交一个标题为“升级到新嵌入模型”的工单时,他们提交的并不是一个配置更改。他们提交的是一个披着单行代码差异(diff)外衣的完整数据迁移。如果你把它当作普通的库版本升级来处理,你就是在发布一个无声的故障。

腐烂的黄金数据集:为什么你的评估集会与产品脱节

· 阅读需 10 分钟
Tian Pan
Software Engineer

最危险的 eval set 是那些依然能通过测试的。变红的 regression suite 会引起关注:有人会打开失败的案例进行争论、修复 Bug 或更新预期。绿色的 suite 则会赢得信任。而这种信任恰恰是失效的 eval set 不配拥有的,因为得分保持绿色并非因为你的系统足够好,而是因为测试已经不再反映用户的真实行为。

这是 AI 评估中一种隐蔽的失败模式。你构建了一个 golden dataset —— 几百个精心标记的案例,代表了产品的工作任务。它能在一整个季度里发挥作用。每次部署都会运行它,每个分数都是绿色,每个人都睡得很香。与此同时,产品发布了三个新功能,企业级流量从查询量的 10% 攀升至 45%,用户开始以 18 个月前团队中没人写过的方式来表达请求。eval set 对此一无所知。它继续根据一个已经不存在的分布对模型进行评分。

试点炼狱:廉价的 90% 正是你的 AI POC 无法转正的原因

· 阅读需 10 分钟
Tian Pan
Software Engineer

演示在一周内惊艳了执行团队。十八个月后,它依然只是个演示。模型仍在沙盒中回答问题,幻灯片依然被循环用于新的路演,每个季度都有人问为什么还没上线。没有人能给出一个好的答案,因为真相往往令人不安:让所有人印象深刻的部分是廉价的部分,而没有人为昂贵的部分做过规划。

这就是“试点炼狱”(pilot purgatory),而它现在已成为默认的结局。MIT 的 NANDA 计划发现,大约 95% 的企业生成式 AI 试点项目未能对损益表产生可衡量的影响。IDC 和 Lenovo 统计了另一项指标——即那些字面上从未上线的 POC——将这一比例定为 88%:企业每启动 33 个概念验证,只有 4 个能进入生产阶段。放弃大部分 AI 计划的公司比例从 2024 年的 17% 飙升至 2025 年的 42%。这些故事的主角并非模型能力不足,而是没有人为其预留预算的“毕业差距”。

令人不安的事实是,一个可以运行的演示仅代表了在生产环境中运行该系统所需工作的 10%,但正是这 10% 看起来像完成了 100%。所有让 AI 系统能 安全运行 的要素——评估(evals)、护栏(guardrails)、可观测性、成本控制、安全审查、值班(on-call)以及拥有预算的负责人——在演示中是不可见的,但在生产环境中却是不可逾越的底线。

为权重签名:模型是供应链忽略的可执行文件

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的 CI 流水线固若金汤。容器镜像在部署前经过签名和验证。每个 npm 和 PyPI 依赖项都根据带有固定哈希值的锁文件进行解析。提交需要签名标签。然后,在你模型服务启动脚本的某个地方,有一行代码从模型中心或 S3 存储桶下载数 GB 的二进制大对象(blob)并将其加载到内存中——没有签名检查,没有哈希验证,也没有生产者的记录。这个对你产品实际功能起决定性作用的唯一制品,偏偏是你的供应链工具从未听说过的那个。

这并非虚构的漏洞。安全研究人员已经从公共中心撤下了数百个恶意模型——这些模型在你加载它们的瞬间就会执行攻击者代码,它们是专为绕过中心运行的扫描器而精心设计的。弥补这一漏洞的工具现已存在:安全序列化格式、行业签名规范、以及拒绝未签名权重的准入控制器。大多数团队只是还没意识到,“模型文件”与“来自互联网且未经审计的二进制文件”在本质上是同一类东西。

你的微调模型是一个你需要维护的分支

· 阅读需 12 分钟
Tian Pan
Software Engineer

微调项目的预算会议总是估错了重点。团队估算的是数据流水线、训练运行和评估轮次——一项有着明确终点的一次性投资。随后模型发布,准确率图表节节攀升,然后大家就转向下一个项目了。六个月后,一封邮件寄达:你的适配器(adapter)所绑定的基础模型有了退役日期。你的系统本身没有任何变化,但它的根基全变了。

这是没人算进成本的部分:微调不是一个你已经完成的产品。它是别人代码库的一个分叉(fork),而每一次基础模型的发布都是一次你并未计划的上游变基(rebase)。任何曾在快速更迭的开源项目中维护私有补丁(patches)的人都清楚个中滋味——分叉的创建成本很低,但维护成本极高。

护栏也是模型:那个没人放进仪表盘的隐藏依赖

· 阅读需 13 分钟
Tian Pan
Software Engineer

这是一个正在演变成一种典型的故障复盘(postmortem)模式。主模型整晚运行良好。延迟平稳,Token 吞吐量正常,服务商状态页显示正常。然而,整整 40 分钟内,每一个用户请求都失败了——因为位于模型前端的安全分类器(safety classifier)超时了,中间件将该超时封装为一个通用异常,而异常处理程序返回了拒绝响应。你的模型并没有宕机。是你的“门禁”宕机了,而这扇门被一名从未将其视为决策选项的工程师配置成了“故障即关闭”(fail closed)。

令人不安的事实是,大多数团队在生产环境中运行着第二个机器学习系统,却不愿承认。内容审核分类器、越狱检测器、PII 清洗器、主题过滤器——每一个都是模型,拥有各自的延迟分布、错误率、在漂移中悄然腐烂的训练数据假设,以及各自的故障模式。但因为它被称为“护栏”,它就被当作配置文件来对待:设置一次,从不监控,在仪表盘上缺席,也不在值班手册中。你绝不会在没有 SLO 的情况下发布主模型。但大多数团队发布护栏时,甚至连健康检查都没有。

金丝雀群组:按 ID 哈希的分流如何将核心用户聚集到同一实验组

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个发布团队在百分比旗标(percentage flag)的保护下发布了一个新模型。分桶计算公式为 hash(user_id) % 100,金丝雀(canary)测试覆盖 0–4 桶。在两周内,人均参与度的提升显著且稳定,于是团队将比例提升到 20%,随后是 50%,最后推向全球。在 50% 到全量发布的某个阶段,这种提升突然消失了。事后复盘(post-mortem)发现问题出在金丝雀人群(canary cohort)。实验变量并没有真正改变指标。金丝雀组的样本是一个特殊的群体。

团队以为自己是在对用户进行采样,实际上它是在对 ID 进行采样。

团队上线了新提示词模板,评估框架却还在测昨天的旧版本

· 阅读需 10 分钟
Tian Pan
Software Engineer

事件时间线清晰可见。9:02,你的平台团队将 prompt-template@v38 推送到了配置服务。11:14,你的仪表板显示一切正常。16:51,支持团队有人标记了升级件数的激增。17:03,你打开了评估套件,发现回归分数为 0.34,于是进行了回滚。复盘报告称:“在 8 小时内捕获,除了 0.04% 看到该问题的客户外,未造成进一步损害。”工程领导层对响应速度表示赞赏。

但这是错的。回归在 0 小时内就被捕获了。17:03 运行的评估套件与 09:03 运行的是同一个。它一直指向的是 v37。评估框架在进程启动时从配置服务加载了模板,将渲染后的 Prompt 以 Python 对象的形式缓存到了模块级作用域中,并且从未重新读取源文件。你的线上流量在上午 9 点切换到了 v38。而你的评估直到 17:03 有人重启了 Worker 池来“重新运行回归”时才发生变化。在长达 8 小时的时间里,客户交互是基于从未经过评估打分的 Prompt 进行的,而评估系统却一直在给生产环境中根本没人在用的 Prompt 打分。

离职工程师带走的微调产物

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个微调(fine-tune)不仅是一个文件。它是训练集上流水线的闭包(closure),如果一个团队在交付文件时没有提供这种闭包,那么他们就构建了一个生产依赖,其源代码其实只存在于某个人的脑子里。当那个人带着两周的离职通知和一份整洁的交接文档离开的那天,你某个收入相关特性的巴士系数(bus factor)就降到了零,而且没人会察觉,因为权重依然在注册表中,注册表标签依然稳定,模型也依然在处理流量。清算会在以后出现,比如在一次常规的基座模型迁移中,原本应该只需要一个 sprint 的工作却耗费了一个季度。

在我观察到陷入此困境的团队中,这种模式是一致的。一名 ML 工程师花了六个月时间迭代一个微调模型——包括数据策展(data curation)、超参数搜索、以及根据感觉在留存集上评估的行为补丁(behavioral patches)。最终的适配器(adapter)权重被推送到模型注册表并打上标签。而产出这些权重的训练流水线,只是该工程师笔记本电脑里的一个 Notebook,里面充斥着硬编码路径和浮动依赖,这些依赖指向的是每个单元格最后一次执行当天的最新版本。团队理所当然地接受了交接,因为权重有效、评估分数不错,且注册表标签很稳定。18 个月后,该工程师离职了。又过了 6 个月,一次基座模型迁移需要针对更新后的基座重新生成适配器。此时 Notebook 运行后生成的权重分数降低了 3 分,并且在最困难的客户细分领域出现了明显的性能退化,团队花了 4 个月时间尝试复现原始产物,但最终以失败告终。

那个平台团队搭建却无人更新的模型注册表

· 阅读需 13 分钟
Tian Pan
Software Engineer

我认识的一个平台团队花了两个季度构建了一个模型注册中心(model registry)。它拥有组织架构要求的一切:从 devstaging 再到 prod 的晋升工作流、CODEOWNERS 风格的审批矩阵、血缘追踪、评估分数门禁、包含 30 天窗口期的弃用政策,以及一个展示每个模型版本在哪个服务中运行的 Backstage 磁贴。他们发布了上线公告,举办了技术分享会,并在合规活页夹中增加了相关条目。

六个月后,公司流量最高的智能体(agent)运行在一个模型卡片上,其“所有者”字段仍指向一个已经离职的人,评估分数来自团队早已弃用的基准测试,而“批准人”姓名是平台技术主管——他从未用过那个智能体,从未读过其评估集,并在周四晚上 11:43 点击了批准,因为生产者在私信(DM)中对他说,明天就要发布了。

注册中心没有坏。晋升门禁触发了。审计日志是完整的。发布公告承诺的一切都是真的。然而,该组织对生产环境模型的实际监管,反而比 18 个月前更少了。当时同样的决策是由一名 ML 工程师在将模型 URI 粘贴进配置文件之前,手动阅读评估输出后做出的。

RAG 阈值固定在了绝对分值上,而 Embedding 升级却悄然改变了分布

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个 RAG 流水线在发布时设置了 0.4 的重排序器(reranker)分数阈值。任何低于该分数的片段都会从提示词(prompt)中被剔除。半年后,一次常规的索引重建将嵌入模型(embedding model)更换为同系列的一个更新版本——变更日志称这是一次透明的升级。两天后,回答的相关性下降了 6%。团队将责任归咎于 LLM,进行了模型对比测试(bake-off),却发现没有任何候选模型能挽回损失,结果花了一个季度去追踪一个根本不存在于他们所对比模型中的回归问题。

回归问题就出在门控(gate)环节。重排序器——未做变动,相同的模型版本(checkpoint),相同的权重——现在正在对一组不同的候选集进行评分。新的嵌入模型将不同的数据块(chunks)拉入前 50 名,重排序器根据自身的校准对它们给出了更低的分数,而 0.4 的门控剔除的候选者比前一周增加了 37%。0.4 这个数字没变,但 0.4 所代表的含义变了。

那个通过后门污染了你评估集的点赞按钮

· 阅读需 12 分钟
Tian Pan
Software Engineer

“点赞”按钮是你所能埋点的最廉价信号。它也是最危险的信号之一,因为没有任何迹象表明它正在重塑你的评估集本应代表的分布。这个按钮作为正向信号被收集——策展流水线将其解读为高质量——而六个月后,评估集就被一群不包含最可能流失的客户的用户所选择的案例占据了。

这种失败很少表现为回归。它表现为一种偏离:每周评估趋势向好,企业级用户的 NPS 下滑,而团队只有在一个流失的账户指出了其团队一直遇到错误回答的具体问题类型时,才会诊断出这种差距。评估集中根本没有这种类型的案例。你正在优化的信号是真实的。它只是测量了错误的分布。