返回 文章 apply CMS 文章

更小、更快、更安全:Cloudflare 如何大规模运行 Kimi 和 GLM

了解 Cloudflare 如何通过三项关键技术优化大型模型推理,提升吞吐量并降低成本。

KV缓存量化模型压缩推理优化
成长分 / 100 72 综合收获、行动、留存与影响

更小、更快、更安全:Cloudflare 如何大规模运行 Kimi 和 GLM
为什么值得读揭示大规模 AI 推理中的内存瓶颈与解决方案

提供量化 KV 缓存和权重压缩的实测数据与精度对比

关键洞察
  1. FP8 KV 缓存使上下文容量翻倍,吞吐量提升 41%,成本降低 30%
  2. INT4 权重压缩使 GLM 5.2 检查点缩小 40%,解码速度提升 55%
  3. KV 缓存完整性检查开销低于 1%,保障共享缓存安全
转成行动

深入阅读

正文与原文对照

原文保真覆盖:全文原文字符:8099

Workers AI 在靠近用户的 Cloudflare 数据中心的 GPU 上,为一批全球顶尖的开源模型提供推理服务。其中最强大、要求也最高的两个,是 Moonshot 的 Kimi K 系列和 Z.ai 的 GLM。它们都是大型、长上下文的混合专家(mixture-of-experts)模型,用起来非常出色,但受限于内存,要高效地提供服务也非常困难。

我们之前介绍过如何在 Workers AI 上部署大模型,也介绍过把推理的 prefill 和 decode 阶段分离,以便从每块 GPU 中榨取更多性能。本文将介绍我们在此基础上叠加的三项技术,用来让这些模型装进内存并保持高速:量化 KV 缓存、压缩模型权重,以及——因为前两者会让更多请求挤在共享硬件上——保护这些请求共享的缓存。这些优化让我们能以更低的成本服务更多客户,而且模型精度不变。

我们所有的实验和生产流量,都运行在开源推理服务框架 SGLang 上,并以它做基准测试。我们发现 SGLang 提供了市面上最好的性能,并与 SGLang 团队密切合作,把补丁和新功能上游合并,让开源社区也能用上我们的成果。

量化 KV 缓存

模型在生成文本时,会把已经处理过的每个 token 的注意力键(K)和值(V)存放在一种叫作 KV 缓存的结构中。有了这份缓存,模型在延续长对话时,就不必在每生成一个新 token 时重新读取整个上下文。对于长上下文模型,它增长得很快,通常最先占满 GPU 内存的是 KV 缓存,而不是模型权重。

默认情况下,缓存以 16 位精度(BF16)存储。我们改用 8 位浮点(FP8,e4m3)来存储,体积减半。在 Kimi K2.6 上,这使内存中可容纳的上下文从约 686,000 个 token 提升到约 137 万个,翻了一倍。

有必要精确说明收益从何而来,因为它并不是原始速度。量化缓存会给每个 token 增加少量工作,因为 FP8 注意力内核在读取数值时需要进行转换。它真正改变的是我们能同时驻留多少请求。以下测量针对的是 Kimi K2.6 在解耦式 H200 部署上的 decode,并直接对比了注意力内核:

并发请求数 BF16 KV 缓存(tok/s) FP8 KV 缓存(tok/s)
1 137 125
8 731 689
16 1,106 1,028
32 1,558 1,489
64 内存不足 2,192

在任意单一并发水平下,BF16 的单 token 速度都要快几个百分点。但 BF16 在 32 个并发请求时就耗尽了缓存,无法接纳第 33 个请求,而 FP8 可以继续扩展到 64 个,达到每秒 2,192 个 token,比 BF16 的峰值高出约 41%,每个 token 的成本则低约 30%。由于我们把 prefill 和 decode 作为独立的池来运行,可以把这一做法用在收益最大的地方:prefill 受计算限制而非内存限制,所以那里我们让缓存保持 BF16,保留其略高的吞吐量。

如果这一切改变了模型的回答,那就毫无意义,所以我们做了验证。在我们的整套评测中,FP8 缓存与 BF16 缓存没有可察觉的差别:

基准测试 BF16 KV FP8 KV
GSM8K 94.24 94.09
ARC-Easy 89.06 89.14
ARC-Challenge 66.72 67.49
MMLU 89.11 89.04
MMLU-Pro 80.29 79.29
mcxams(内部基准测试) 61 / 63 61 / 63
工具调用有效性 92.2% 92.6%

压缩模型权重

KV 缓存是对 GPU 内存的一项需求,模型权重则是另一项。对于 GLM 5.2,我们把权重从 8 位浮点压缩到 4 位整数(INT4),且精度没有损失。检查点从 705 GB 缩小到 421 GB,约减少 40%;在 8 路张量并行部署中,每块 GPU 的内存占用从约 88 GB 降到 52 GB,这让同样的硬件上可以留出约 118 万个 token 的 KV 缓存空间。

在我们的整套评测中,INT4 权重与 FP8 权重没有可察觉的差别:

基准测试 / 能力 指标 FP8 INT4
GSM8K 精确匹配 94.39% 93.56%
GSM8K Flexible 94.24% 93.48%
ARC-Easy 准确率 86.62% 86.15%
ARC-Easy Acc (norm) 84.51% 85.19%
ARC-Challenge 准确率 64.93% 64.85%
ARC-Challenge Acc (norm) 67.24% 66.64%
MMLU 平均 86.60% 86.54%
MMLU-Pro Exact 80.80% 80.47%
mcxams(内部基准测试) 通过 62 / 63 62 / 63

权重变小会让 decode 阶段更快,原因很明确:生成每个 token 都需要把模型权重从 GPU 内存中流式读出,所以 decode 速度受内存带宽限制。搬运的数据更少,每个 token 就来得更早。这种效果在低并发时最明显,而低并发正是单请求延迟最重要的场景:

并发请求数 GLM FP8(tok/s) GLM INT4(tok/s) INT4 增益
1 60 92 +55%
8 425 513 +21%
16 683 825 +21%
32 994 1,267 +27%
64 1,672 1,933 +16%

Prefill 的表现则不同。它受计算限制,而 INT4 权重在参与乘法之前必须先展开还原,这一额外步骤使 prefill 变慢而不是变快:GLM 的 prefill 在 FP8 下可持续约每秒 10,160 个 token,INT4 下则为 8,660。与 KV 缓存一样,解耦式设计把这变成了一种选择而非折中:decode 用 INT4,因为那里它占优;prefill 用 FP8,因为那里它占优。在我们运行的所有基准测试中,模型精度与 FP8 模型的差距都在 0.8 个点以内,质量上没有可察觉的差别。

保护共享的 KV 缓存

上述两项技术有同样的效果:让多得多的请求可以同时共享一块 GPU 的内存。这种效率正是关键所在,但也意味着数百个请求在读写同一块物理 KV 缓存的各个页面。让这一切变快的机制——分页注意力(paged attention)、连续批处理(continuous batching)、缓存复用——都依赖于把记账工作做得分毫不差,而在我们的请求量级下,即便十亿分之一的差错也会时常出现。

因此,我们构建了 KV 缓存完整性检查,作为一层防御。思路很简单:每个物理缓存页都带有一个标签,页面一旦被重新分配,标签就会改变;服务器会记录每个请求预期使用的页面和标签。在受支持的 decode 操作读取缓存之前,会先检查这些映射。如果有任何不匹配,受影响的请求就会被中止,而不是被允许返回来自错误页面的数据。

决定一项安全检查能否上线的问题是:它的代价是什么。我们在一个中等规模的生产模型上,以两个 prefill、两个 decode 的配置,使用 8,192 个 token 的输入和 1,000 个 token 的输出进行了测量:

并发数 吞吐量变化 p95 延迟变化
1 −0.53% +0.42%
2 −0.38% +0.54%
4 −0.79% +0.63%
8 −0.43% +0.80%

无论是吞吐量还是尾延迟,代价都不到 1%,即使取 95% 置信区间的上界,也仍接近 1%。我们把验证作为一次单独的批量检查来运行,而不是融合进注意力内核,从而保持了很低的计算开销;融合的做法会在 GPU 线程组之间引入竞争条件。它可按部署单独启用,默认路径使用空操作(no-op)的跟踪器,没有可测量的开销,因此不需要它的部署不会付出任何代价。

下一步

高效地服务前沿模型是一个不断移动的目标,这些就是背后持续进行的工作。我们正在把 FP8 KV 缓存推广到更多集群,在 Blackwell(NVIDIA 的 GPU 架构)上验证 NVFP4 权重,并努力让完整性检查能够以可忽略的代价在所有地方常开。这些优化将使我们能够以更低的成本、相同的精度,继续服务更多客户。

如果把最好的开源模型塞进 GPU、再把它们提供给数百万开发者这件事听起来正是你喜欢的挑战,欢迎加入我们。