跳到正文
北京时间
原文
PyTorch:Blog· Cody Mazza-Anthony, Sr. Staff Machine Learning Engineer, @cmazzaanthony & Andrew McNamara, VP Machine Learning, @drewch·· 13 天前精选AI 评分63

Shopify 如何用 PyTorch 和 vLLM 构建持续学习闭环,服务成本降低 96%

How Shopify built a continual learning loop with PyTorch and vLLM

AI 导读

Shopify 在 PyTorch 官方博客详解其基于 PyTorch 和 vLLM 的持续学习闭环,通过自愈管线把生产失败转为训练信号,用 SFT 加 GRPO 让专用模型质量超越前沿模型,GraphQL agent 服务成本从估算的每年约 2700 万美元降至约 100 万美元,降幅 96%。

推荐理由

原文给出从质量标注、判官校准到 SFT 加 RL 和 gist 压缩的完整闭环方法,可迁移到自建 Agent 的持续学习场景。

正文 · AI 翻译

How Shopify built a continual learning loop with PyTorch & vLLMTL;DR:本案例研究探讨了 Shopify 如何每天将生产环境中的失败压缩进模型权重,超越前沿模型的质量,并通过使用 PyTorch 和 vLLM 构建持续学习循环,将服务成本降低 96%。

前沿模型通常是推出新 AI 产品最快的方式。小团队可以快速将有用的东西呈现给用户,并从真实使用中学习。但随着使用量增长,经济性会发生变化:前沿模型可能太慢、太贵,无法大规模服务每一个请求。

前沿模型是通用的,并非为你的产品量身定制。更重要的是,它们不会自行从生产环境中学习。用户的纠正、被拒绝的输出或反复出现的失败,都不会让下一次响应变得更好。但每一次失败都是关于你产品的来之不易的知识,而持续学习始于捕捉这些知识并将其反馈到系统中。

此外,已部署的前沿模型权重是冻结的。它没有机制来内化生产环境教给它的东西。相反,改进会积累在它周围的离散产物中:提示词编辑、检索示例、路由规则和框架代码。生产知识堆积在文字和代码中,而模型的权重却保持不变。飞轮是我们的答案:一个持续学习循环,将生产经验压缩到模型权重的连续空间中。PyTorch 提供了使这些更新成为可能的训练基础。

Shopify 的 GraphQL agent 是我们在生产环境中运行这一循环最清晰的例子。这个飞轮提供了比前沿模型更高的质量,同时降低了延迟并将成本削减了 96%。

Flywheel Optimization Process从定义质量开始;它成为奖励信号

定义质量是循环中最重要的一步——也是团队最常草率对待的一步。它始于对“好”是什么样子的规范,并成为驱动学习的奖励信号。当你把评估或规范搞错时,下游的一切都会优化错误的行为。

质量始于评分标准,而该评分标准将你的产品需求转化为几个评分维度:完整性、执行、响应质量和安全性。每个维度都有具体的锚点,说明每个分数意味着什么。把它看作你的产品团队对好与坏的定义。它是下游一切的质量契约,也是标注者用来将对话转化为真实标签的依据。至关重要的是,这些真实标签应包含随机抽样的流量,而不仅仅是精心挑选的示例。黄金集测试的是你已经知道要寻找的案例;随机样本揭示的是生产环境中好与坏实际的样子。

一旦你对评分标准满意,让你最好的两位标注者/产品专家对 25 个随机样本进行盲标,并记录他们之间的标注者一致性。我们使用 Cohen's kappa,它衡量的是超出随机水平的一致性。如果它非常低(大约 0.2),说明评分标准含糊不清:再次开会并迭代。如果评分标准让几位每天都做这个产品的产品专家感到困惑,那么它也会让 LLM 感到困惑。

这种一致性是评判者的上限:即使是专家标注者也不会 100% 一致,因为有些对话确实模棱两可。目标不是“完美”的评判者,而是与人类匹配程度大致相当于人类彼此匹配程度的评判者。

当你收集标注时,要力求细节。一个分数加一句话不足以让校准算法从中学习。你需要每个分数背后的原因,而那种推理是金子。

Judges校准你的评判器

评分标准只是起点。它是评判器的第一个提示词,但它还没有从你的真实基准中学到任何东西。校准会把这个评分标准变成一个可以运行在无限生产数据点上的评判器。

我们非常喜欢用 DSPy 来做这件事,并且用基于反思的优化器如 GEPA 和 Agentic Context Engineering 来进行校准 [1,2]。GEPA 通过反思自然语言的失败轨迹来演化提示词,并保留一个候选的帕累托前沿,而不是贪婪地选择单一赢家。ACE 通过小的增量编辑来整理出一本结构化的操作手册。

评判器是你的离线指标,是你在发布前用来优化的对象。但它只是一个代理,所以你需要确认它反映了真实流量上的表现,并且与你的在线指标一致。用之前的 A/B 测试对它进行回测:它能否恢复已知的参与度、留存率或你的产品旨在驱动的行为上的胜负方向?

然后运行有针对性的退化测试,可以在离线进行,也可以在精心控制的一小部分流量上进行。故意让某个行为变差,并确认相应的标准会做出反应。例如,如果系统不再试图实现用户的目标,那么目标实现分数就应该专门下降。

让每个评判器保持小而聚焦,而不是把你产品的所有行为都塞进一个里面。聚焦的评判器让这些测试更容易解读,也让由此产生的指标更容易被信任。你随时可以添加更多。

用自动研究改进前沿基线

现在我们有了一个可靠的评判器,就可以用它来改进我们最初发布的、由前沿模型驱动的产品——那个为了快速触达用户而构建的基线。在这个阶段,我们在不触碰权重的情况下,把那个系统推到极限。每一项改进都落在提示词、工具定义和运行框架上。

但改进这个基线系统与构建评判器是不同的问题。它已经是一个生产应用,拥有动态组装的提示词、自定义控制循环,以及散布在庞大代码库中的定制编排。没有任何单一提示词决定它的行为,所以提示词调优只能触及系统的一小部分。优化目标是整个运行框架:它的提示词、工具定义和编排代码。

所以我们把它当作一个自动研究问题,秉承Karpathy 最近项目的精神:一个智能体提出对提示词、工具定义或运行框架的修改;用评判器评估它;如果分数提高就保留该修改;否则丢弃。

我们把整个东西配置在一个可读的 markdown 文件里:从哪里获取数据、智能体可以编辑哪些目录、以评判器作为指标、使用哪个优化器,以及提出-评估-保留或丢弃的循环。

program.md从离散产物到连续参数更新

一旦运行框架的改进趋于平稳,我们就开始在参数空间中进行优化,通过挖掘匿名化的生产流量来寻找困难负样本:即评判器正确给出低分、并暴露出模型最薄弱之处的对话。

在数百万形形色色的商家中,真实流量持续产生源源不断的困难案例:上下文不完整、请求含糊不清、业务特有的工作流、工具故障,以及表达同一意图的多种方式。在传统工作流中,每一次失败都会变成一份 bug 报告或一个 Slack 讨论串。而在飞轮中,这些失败会自动进入一条自愈流水线,由一组前沿推理模型将其转化为训练信号,再通过强化学习回填到模型的权重中。

Failed convo flow一组前沿推理模型对每次失败进行评判。一个仲裁者将这些评判合并为一条单一的修复指令,并在用户回合之前注入,这种技术有时被称为“提示注入”(hinting)。我们从该点重放对话,评判者再次打分。如果修复通过,重放轨迹就成为强化学习的一条轨迹,评判者的分数作为其奖励。如果仍然失败,我们将其标记为需要人工标注。这正是 Toloka 发挥作用的地方:其专家标注员会修正我们的评判模型无法修复的对话,并按照用于校准评判者的同一套评分标准对其进行打分。

训练分两个阶段进行。首先,我们通过监督微调将修复后的轨迹蒸馏到一个较小的模型中。我们在完整轨迹上进行训练——包括产生这些轨迹的推理过程——而不仅仅是它们的最终答案(参见 Toloka 面向智能体工作流的微调)。这种思维链蒸馏让较小的模型能够继承仅凭答案无法学到的行为 [3]。

其次,我们应用 GRPO,使用校准后的评判者作为奖励信号。对于每个提示,模型采样一组回复,评判者为其打分,GRPO 则强化表现最佳的回复。监督微调教会模型模仿成功的轨迹;GRPO 则直接针对我们对质量的定义对其进行优化。

自愈流水线每天运行,不断向训练语料库中添加新的轨迹。按照同样的节奏,我们对累积的数据进行全参数微调,然后重复 GRPO。在新旧轨迹上同时训练可以限制跨周期的漂移和灾难性遗忘 [4]。随着飞轮转动,质量不断提升,最终超越由前沿模型驱动的基线。

我们使用 PyTorch 通过张量并行、上下文并行和数据并行将训练分布到多个 GPU 上,使全参数微调在大规模下变得切实可行。

压缩提示以实现更快的服务

更好的模型仍然需要运行,而智能体的系统提示又长又静态。注意力随序列长度扩展,因此每个生成的 token 都要关注整个前缀。长提示是对延迟和服务成本的固定税负,每次请求都要支付。

要点压缩(Gist compression)消除了其中大部分税负。我们以两种方式运行同一个模型:一个使用完整系统提示的教师模型,以及一个使用一短串学习到的要点 token 的学生模型。我们构建了一个自定义的 PyTorch 训练器,在保持模型权重冻结的同时,通过匹配教师的输出分布来学习要点 token 的嵌入。结果是用少量 token 以极短的长度复现了提示的行为,且在评判者上没有测得质量损失 [5,6]。

system prompt飞轮实战:GraphQL 智能体

Merchant Sidekick convo要看清整个循环如何运作,最直观的地方就是我们的 GraphQL agent,它在生产环境中每分钟最多处理 2,000 个请求。它通过针对 Shopify 的 Admin GraphQL API 编写并运行查询,来回答商家关于其店铺的问题:商家可能会问哪些产品即将缺货,agent 会找出正确的查询、对店铺运行该查询,并把结果转化为通俗易懂的回答。

GraphQL distillation它的运作方式如下:

它让模型变得更好。自愈流水线把低分的生产对话转化为成功的轨迹,为模型提供源源不断的、源自真实商家需求的经验教训。SFT 和 RL 共同作用,使这个专用模型超越了前沿模型的性能。

它让模型的部署成本大幅降低。我们通过 vLLM 来部署模型,这是一个基于 PyTorch 构建的推理引擎。vLLM 通过连续批处理保持高吞吐量,非常适合我们这种工具调用繁重的工作负载。按照平均 token 成本估算,用前沿模型承载这些流量每年很容易花费约 2,700 万美元。而微调后的模型成本可能只是其一小部分,接近 100 万美元:部署成本降低了 96%。这正是那种在 Shopify 规模下运行起来令人痛苦的功能,与那种我们可以放心地为每个商家一直开启的功能之间的差别。

它让模型变得更快,而且负载越高差距越大。Gisting 将 agent 冗长、静态的系统提示词从大约 6,000 个 token 压缩到约 1,500 个学习到的 gist token。在每分钟 350 个请求的负载测试中,首 token 时间下降了约 19%,端到端延迟下降了约 38%。

它释放了硬件资源。同样的压缩提升了吞吐量:在相同的 GPU 上,每秒请求数增加约 16%,每秒输出 token 数增加约 12%,这意味着承载相同流量所需的 GPU 大约减少 14%。

超越 harness:不断累积的持续学习

前沿模型能帮你启动项目,而最初的改进存在于它们周围的离散产物中:提示词、上下文、工具定义和控制流。这些改动强化了 harness,但模型本身并未改变。

持续学习则更进一步,把这些经验教训转化为模型连续参数空间中的更新。每个循环都从一个能力更强的模型开始,而不仅仅是一个更精巧的 harness。这就是一个小模型如何变得比前沿基线更快、更便宜、更擅长你的任务。持久的优势在于那个不断把生产经验转化为更好权重的循环。

参考文献

  1. Agrawal et al. GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning. arXiv:2507.19457
  2. Zhang et al. Agentic Context Engineering: Evolving Contexts for Self-Improving Language Models. arXiv:2510.04618
  3. Hsieh et al. Distilling Step-by-Step! Outperforming Larger Language Models with Less Training Data and Smaller Model Sizes. arXiv:2305.02301
  4. Shuttleworth et al. LoRA vs Full Fine-tuning: An Illusion of Equivalence. arXiv:2410.21228
  5. Wingate et al. Prompt Compression and Contrastive Conditioning for Controllability and Toxicity Reduction in Language Models. arXiv:2210.03162
  6. Mu et al. Learning to Compress Prompts with Gist Tokens. arXiv:2304.08467

最初发表于 Shopify Engineering Blog。本版本已为 PyTorch 社区改编。

来源:PyTorch:Blog · pytorch.org