三起近期事件的事后复盘¶
原文链接: English Original
这是一份关于三个间歇性降低 Claude 响应质量的 bug 的技术报告。下文我们将解释发生了什么、为什么修复耗时较长,以及我们正在做出哪些改变。
背景¶
在 8 月到 9 月初期间,三个基础设施 bug 间歇性地降低了 Claude 的响应质量。我们现已解决这些问题,并希望解释发生了什么。
8 月初,一些用户开始报告 Claude 的响应质量下降。这些最初的报告很难与用户反馈中的正常波动区分开来。到 8 月底,这些报告的频率和持续性不断增加,促使我们展开调查,最终发现了三个独立的基础设施 bug。
需要明确声明:我们绝不会因为需求量、时段或服务器负载而降低模型质量。 用户报告的问题完全是由基础设施 bug 造成的。
我们认识到用户期望 Claude 提供一致的质量,我们维护着极高的标准,以确保基础设施更改不影响模型输出。在最近的这些事件中,我们没有达到这个标准。以下的事后复盘解释了出了什么问题、为什么检测和解决的时间比我们预期的更长,以及我们正在做出哪些改变以防止类似事件再次发生。
我们通常不会分享关于基础设施的这一级别的技术细节,但这些问题的范围和复杂性值得进行更全面的解释。
我们如何大规模提供 Claude 服务¶
我们通过我们的第一方 API、Amazon Bedrock 和 Google Cloud 的 Vertex AI 向数百万用户提供 Claude 服务。我们将 Claude 部署在多个硬件平台上,即 AWS Trainium、NVIDIA GPU 和 Google TPU。这种方法提供了为全球用户服务所需的容量和地理分布。
每个硬件平台具有不同的特性,需要特定的优化。尽管存在这些差异,我们对模型实现有严格的等效性标准。我们的目标是无论哪个平台服务用户的请求,用户都应该获得相同质量的响应。这种复杂性意味着任何基础设施更改都需要在所有平台和配置上进行仔细验证。
事件时间线¶
这些 bug 的重叠性质使得诊断特别具有挑战性。第一个 bug 于 8 月 5 日引入,影响了约 0.8% 的发往 Sonnet 4 的请求。另外两个 bug 来自 8 月 25 日和 26 日的部署。
虽然最初的影响有限,但 8 月 29 日的一次负载均衡更改开始增加受影响的流量。这导致更多用户体验到问题,而其他用户继续看到正常性能,产生了令人困惑和矛盾的反馈。
三个重叠的问题¶
以下是造成质量下降的三个 bug 的描述,包括它们发生的时间以及我们如何解决它们:
1. Context window 路由错误¶
8 月 5 日,一些 Sonnet 4 请求被错误路由到为即将推出的 1M token context window 配置的服务器。这个 bug 最初影响了 0.8% 的请求。8 月 29 日,一次常规的负载均衡更改无意中增加了被路由到 1M context 服务器的短 context 请求数量。在 8 月 31 日受影响最严重的那一小时,16% 的 Sonnet 4 请求受到影响。
在此期间发送请求的 Claude Code 用户中,约 30% 至少有一条消息被路由到错误的服务器类型,导致响应质量下降。在 Amazon Bedrock 上,从 8 月 12 日起,错误路由的流量峰值达到所有 Sonnet 4 请求的 0.18%。在 Google Cloud 的 Vertex AI 上,8 月 27 日至 9 月 16 日期间,错误路由影响了不到 0.0004% 的请求。
然而,一些用户受到的影响更为严重,因为我们的路由是"粘性"的。这意味着一旦一个请求由错误的服务器提供服务,后续的跟进请求也可能会由同一个错误的服务器提供服务。
解决方案:我们修复了路由逻辑,确保短 context 和长 context 请求被定向到正确的服务器池。我们于 9 月 4 日部署了修复。到 9 月 16 日完成了向第一方平台和 Google Cloud Vertex AI 的推广,到 9 月 18 日完成了向 AWS Bedrock 的推广。
2. 输出损坏¶
8 月 25 日,我们向 Claude API TPU 服务器部署了一个错误配置,导致 token 生成过程中出现错误。由运行时性能优化引起的一个问题偶尔会给在给定 context 下本应很少产生的 token 分配高概率,例如在响应英文 prompt 时产生泰文或中文字符,或在代码中产生明显的语法错误。一小部分用英语提问的用户可能会在响应中间看到"สวัสดี",例如。
这种损坏影响了 8 月 25-28 日期间发往 Opus 4.1 和 Opus 4 的请求,以及 8 月 25 日至 9 月 2 日期间发往 Sonnet 4 的请求。第三方平台未受此问题影响。
解决方案:我们识别了该问题并于 9 月 2 日回滚了更改。我们在部署过程中添加了针对意外字符输出的检测测试。
3. Approximate Top-k XLA:TPU 编译错误¶
8 月 25 日,我们部署了代码来改进 Claude 在文本生成期间选择 token 的方式。此更改无意中触发了 XLA:TPU 编译器中的一个潜在 bug,已确认该 bug 影响了发往 Claude Haiku 3.5 的请求。
我们还认为这可能影响了 Claude API 上 Sonnet 4 和 Opus 3 的一个子集。第三方平台未受此问题影响。
解决方案:我们首先观察到该 bug 影响 Haiku 3.5,并于 9 月 4 日回滚。后来我们注意到用户报告了与该 bug 兼容的 Opus 3 问题,并于 9 月 12 日回滚。经过广泛调查,我们无法在 Sonnet 4 上复现此 bug,但出于谨慎考虑也决定回滚。
同时,我们 (a) 一直在与 XLA:TPU 团队合作修复编译器 bug,(b) 部署了使用增强精度的精确 top-k 的修复。
深入了解 XLA 编译器 bug¶
为了说明这些问题的复杂性,以下是 XLA 编译器 bug 的表现方式以及为什么它的诊断特别具有挑战性。
当 Claude 生成文本时,它计算每个可能的下一个词的概率,然后从这个概率分布中随机选择一个样本。我们使用"top-p sampling"来避免无意义的输出——只考虑累计概率达到阈值(通常为 0.99 或 0.999)的词。在 TPU 上,我们的模型跨多个芯片运行,概率计算在不同的位置进行。为了对这些概率进行排序,我们需要在芯片之间协调数据,这很复杂。
2024 年 12 月,我们发现我们的 TPU 实现偶尔会在温度为零时丢弃最可能的 token。我们部署了一个临时修复方案来解决这种情况。
根本原因涉及混合精度算术。我们的模型使用 bf16(16 位浮点)计算下一个 token 的概率。然而,向量处理器是 fp32 原生的,因此 TPU 编译器 (XLA) 可以通过将某些操作转换为 fp32(32 位)来优化运行时。此优化过程由 xla_allow_excess_precision 标志保护,该标志默认为 true。
这造成了一个不匹配:本应在最高概率 token 上达成一致的操作在不同的精度级别上运行。精度不匹配意味着它们无法就哪个 token 具有最高概率达成一致。这导致最高概率 token 有时完全从考虑范围中消失。
8 月 26 日,我们部署了采样代码的重写版本,以修复精度问题并改进我们处理达到 top-p 阈值的概率的方式。但在修复这些问题的过程中,我们暴露了一个更棘手的问题。
为什么检测很困难¶
我们的验证过程通常依赖于基准测试以及安全评估和性能指标。工程团队进行抽查,并首先部署到小的"canary"组。
这些问题暴露了我们应该更早识别的关键差距。我们运行的评估根本没有捕捉到用户报告的质量下降,部分原因是 Claude 通常能很好地从孤立的错误中恢复。我们自己的隐私实践也给调查报告带来了挑战。我们的内部隐私和安全控制限制了工程师访问用户与 Claude 交互的方式和时间,特别是当这些交互未作为反馈报告给我们时。这保护了用户隐私,但阻止工程师检查识别或复现 bug 所需的有问题的交互。
每个 bug 在不同平台上以不同的速率产生不同的症状。这产生了一系列令人困惑的报告,不指向任何单一原因。它看起来像是随机的、不一致的质量下降。
更根本的是,我们过于依赖嘈杂的评估。虽然我们意识到了在线报告的增加,但缺乏将它们与我们最近每个更改联系起来的清晰方法。当负面报告在 8 月 29 日激增时,我们没有立即将其与一个原本标准的负载均衡更改联系起来。
我们正在改变什么¶
在继续改进基础设施的同时,我们也在改进评估和防止上述 bug 的方式,涵盖我们提供 Claude 服务的所有平台。以下是我们正在改变的内容:
-
更灵敏的评估:为了帮助发现任何给定问题的根本原因,我们开发了能更可靠地区分正常和异常实现的评估。我们将继续改进这些评估,以更密切地监控模型质量。
-
在更多位置进行质量评估:虽然我们在系统上定期运行评估,但我们将在真正的生产系统上持续运行它们,以捕获诸如 context window 负载均衡错误之类的问题。
-
更快的调试工具:我们将开发基础设施和工具,以在不牺牲用户隐私的情况下更好地调试社区来源的反馈。此外,这里开发的一些专门工具将用于减少未来类似事件(如果发生的话)的修复时间。
评估和监控很重要。但这些事件表明,当 Claude 的响应未达到通常标准时,我们还需要来自用户的持续信号。观察到的具体变化的报告、遇到的意外行为的示例以及不同用例中的模式都帮助我们隔离了问题。
用户继续直接向我们发送反馈仍然特别有帮助。你可以在 Claude Code 中使用 /bug 命令,或者在 Claude 应用中使用"踩"按钮来这样做。开发者和研究人员经常创建新的、有趣的方法来评估模型质量,以补充我们的内部测试。如果你想分享你的方法,请联系 feedback@anthropic.com。
我们对社区的这些贡献表示感谢。
脚注¶
[1] XLA:TPU 是优化编译器,将 XLA 高级优化语言——通常使用 JAX 编写——翻译为 TPU 机器指令。
[2] 我们的模型对于单个芯片来说太大,被分割在数十个或更多芯片上,使我们的排序操作成为分布式排序。TPU(就像 GPU 和 Trainium 一样)也与 CPU 有不同的性能特征,需要使用向量化操作而非串行算法的不同实现技术。
[3] 我们之前一直在使用这种近似操作,因为它产生了显著的性能改进。近似操作通过接受最低概率 token 中潜在的误差来工作,这不应影响质量——除非 bug 导致它丢弃了最高概率 token。
[4] 请注意,现在正确的 top-k 实现可能会导致 top-p 阈值附近 token 的包含出现细微差异,在罕见情况下用户可能受益于重新调整其 top-p 选择。
致谢¶
由 Sam McAllister 撰写,感谢 Stuart Ritchie、Jonathan Gray、Kashyap Murali、Brennan Saeta、Oliver Rausch、Alex Palcuie 以及许多其他人。