跳到正文
vLLM Blog· vLLM Team and Inferact·· 2026-07-27精选AI 评分83

vLLM 上线 Kimi K3 day-0 支持

Kimi K3 Is Here: Efficient Day-0 Support on vLLM

AI 导读

vLLM 宣布对月之暗面 Kimi K3 提供 day-0 支持,权重公开当天即可用 vLLM 部署。Kimi K3 是 2.8 万亿参数的 MoE 模型,每 token 激活 896 个专家中的 16 个,基于 Kimi Delta Attention 与 Attention Residuals,支持 1M token 上下文和原生视觉。

推荐理由

vLLM 官方给出 Kimi K3 的 day-0 部署配方与性能数字,可据此判断这套混合架构的落地成本。

正文 · AI 翻译

我们非常激动地宣布,vLLM 为 Kimi K3 提供了高效的 day-0 支持,这是有史以来发布的最强大的开放权重模型之一。

上周,我们预览了针对 Kimi K3 的生产级集成工作;今天,Moonshot AI 的权重已公开,支持也已上线。

Kimi K3 day-0 support on vLLM
vLLM 上的 Kimi K3 day-0 支持

Kimi K3 是一个 2.8 万亿参数的混合专家(MoE)模型(每个 token 激活 896 个专家中的 16 个),基于 Kimi Delta Attention(KDA)和 Attention Residuals(AttnRes)构建,具有 1M token 的上下文窗口和原生视觉能力。对我们来说,Kimi K3 带来的最令人兴奋的挑战是让 KDA、MXFP4 MoE、KV 缓存管理、prefill/decode 分离、投机解码和长上下文部署方案在一个可运行的推理引擎中协同工作。

预览文章解释了内核和缓存架构,特别是针对循环状态的前缀缓存这一挑战。本篇发布文章是实用指南:vLLM 如何适配 Kimi K3 的架构、数字背后的内核工作,以及 day 0 已就绪的内容。

快速开始

# See the linked recipes for the exact Docker command.
vllm serve moonshotai/Kimi-K3 \
  --tensor-parallel-size 8 \
  --trust-remote-code \
  --load-format fastsafetensors \
  --enable-prefix-caching \
  --enable-auto-tool-choice \
  --tool-call-parser kimi_k3 \
  --reasoning-parser kimi_k3

运行 Kimi K3 最简单的方式是使用上述命令,搭配 8 块 NVIDIA B300 GPU 或 8 块 AMD MI355X GPU。

Inferact 还为 Kimi K3 训练并开源了一个 DSpark 推测器。通过在 serve 命令中添加以下选项来启用它:

--speculative-config '{"model":"Inferact/Kimi-K3-DSpark","method":"dspark","num_speculative_tokens":7,"attention_backend":"FLASHINFER_MLA","draft_sample_method":"probabilistic","rejection_sample_method":"block"}'

如需更多细节,包括适用于各种平台的 Docker 镜像和部署策略,请参阅详细的 recipes。由于依赖关系复杂,目前只能使用 Docker 镜像。这些 Docker 镜像依赖若干预发布依赖项,包括 FlashInfer。

TL;DR

  • 2.8 万亿参数的多模态 MoE:Kimi K3 每个 token 激活 896 个专家中的 16 个,支持高达 1M token 的上下文窗口,并基于 Kimi Delta Attention、Attention Residuals、LatentMoE 和原生 MXFP4(4 位)权重构建。
  • 每用户最高 370 tok/s:在 16 块 NVIDIA GB300 NVL72 GPU 上,vLLM 在不使用投机解码时以 118 tok/s 服务 Kimi K3,使用 DSpark 时达到 370 tok/s(提升 3.14 倍),这得益于针对 Kimi K3 架构的大量优化。
  • 广泛的生产功能支持:vLLM 支持投机解码、prefill/decode 分离、基于 Mooncake 的智能体 KV 缓存、工具调用、推理输出和结构化输出,并在发布时支持 NVIDIA(Hopper 和 Blackwell)和 AMD(MI355X)。
  • 开源 DSpark 支持:vLLM 支持针对 Kimi K3 的最先进的块扩散投机解码算法,该算法使用 vLLM 和 TorchSpec 训练,并由 Inferact 开源。
  • 混合前缀缓存:服务 Kimi K3 的循环与全注意力设计需要重新设计基于循环 KDA 状态的混合前缀缓存。这一改动现在惠及所有混合线性模型。

Kimi K3 的架构,以及 vLLM 如何服务它

Kimi K3 architecture innovations
Kimi K3 架构创新

Kimi K3 架构创新,来自原始发布博客文章。

Kimi K3 的架构在几个方面偏离了标准 Transformer,每一处都改变了推理引擎必须做的事情。预览文章深入介绍了内部细节;这里我们回顾新增内容,并重点介绍 vLLM 如何适配以服务它。

Kimi Delta Attention:混合循环 + 全注意力堆栈

新特性:Kimi K3 的大部分层都是 KDA,这是一种线性注意力机制,它维护固定大小的循环状态,而不是不断增长的 KV 缓存,并与周期性的全注意力层交错,以保留精确的全局召回。这正是让 100 万 token 上下文变得可负担的原因。

vLLM 如何服务它:单个混合 KV 缓存管理器在同一个调度器下并排持有两种内存:用于全注意力层的分页 KV 块,以及用于 KDA 层的紧凑循环状态块。专用的 KDA 注意力后端在预填充阶段运行 FlashKDA,在解码阶段运行融合 CUDA 内核(或在运行投机解码时使用 Flash-Linear-Attention/Triton 路径)。

最难的部分是跨 Kimi K3 混合缓存的前缀缓存:全注意力层存储逐 token 的 KV,而 KDA 层在每个 token 上更新循环状态和卷积状态,但无法承担在每个可能的前缀边界保留快照的开销。vLLM 将大型物理 KDA 状态块与细粒度前缀匹配解耦,在这些块内注册状态快照,并在扩展前复制它们,以便长共享提示可以同时复用 KDA 状态和分页 KV。这套混合缓存机制是 vLLM 核心中的新功能,如今惠及所有类似 Kimi K3 的混合模型。

Kimi K3's hybrid KDA and full-attention cache
Kimi K3 的混合 KDA 与全注意力缓存

Kimi K3 将 Kimi Delta Attention 层与周期性的全注意力层交错;vLLM 的混合缓存将循环状态与分页 KV 一起管理。

注意力残差:跨深度的残差贡献学习式混合

新特性:对于每个 token,Block AttnRes 用深度方向的注意力取代普通的残差累积:每个 Transformer 子层使用一个学习到的伪查询,对来自前面层块的 RMS 归一化残差状态进行加权,然后接收相应的加权组合作为其输入。

vLLM 如何服务它:vLLM 使用优化的 Triton 和 CUDA 内核,在单个融合操作中计算深度方向的注意力 logits、softmax 和隐藏状态聚合。在支持的情况下,残差更新和输出 RMSNorm 被折叠进同一个内核,从而减少预填充和解码中的中间内存流量和内核启动开销。

Stable LatentMoE:896 选 16 稀疏度下的分位数平衡潜在空间专家

新特性。由 NVIDIA 提出的 LatentMoE 将分派的 token 激活投影到更窄的潜在维度以进行路由专家计算,然后将组合后的专家输出投影回模型宽度——减少专家权重带宽和 all-to-all 通信,从而在相近的推理成本下使用更多专家。Kimi K3 的 Stable LatentMoE 将此设计扩展到 896 个专家、每个 token 激活 16 个,并使用 Quantile Balancing 从路由分数分位数推导专家分配,而非启发式平衡更新。

vLLM 如何服务它:专家通过专家并行进行分片。vLLM 提供两种针对不同拓扑调优的 MoE 后端:用于张量并行(TP > 1)的 TRT-LLM-Gen,以及用于解耦/专家并行(DEP)的 MegaMoE。它还支持可选的专家并行负载均衡(EPLB),以确保每个 rank 具有相似的计算量。权重在 MoE 路径上以 MXFP4 原生执行。

聊天模板:一个渲染程序,而非 Jinja 模板

新特性:Kimi K3 的聊天模板必须使用精确的控制标记来编码系统、用户和助手消息、多模态内容、工具定义以及工具结果。与常见的在分词前将请求渲染为文本的 Jinja 聊天模板 方法不同,Kimi K3 使用 Python 程序直接构建提示词标记序列。其输出同样包含推理、答案文本和工具调用的不同区域,这些区域必须被解析为 API 响应。

vLLM 如何提供服务:vLLM 在其 Python 和 Rust 前端中实现了输入渲染器和流式输出解析器,在将用户提供和工具提供的文本视为普通内容的同时,保留控制标记边界。对于工具调用和结构化输出,vLLM 将 Kimi K3 的格式与 XGrammar 集成,以便在解码过程中约束结构化区域,并将其作为独立的推理、内容和工具调用字段返回。

为生产环境打造

要良好地服务一个 2.8T 的混合 MoE 模型,意味着对每个用户都要快,对大量并发会话要高效,并且对智能体要可扩展。vLLM 确保 Kimi K3 在这三方面都准备就绪。

超低延迟:使用 DSpark 的推测解码

要在像 Kimi K3 这样的 2.8T 参数模型上实现超低延迟且不损失精度,推测解码是自然的选择。这就是为什么 vLLM 从第 0 天起就支持 DSpark——一种最先进的推测解码算法——也是为什么我们为 Kimi K3 训练并发布了 DSpark 推测器。草稿模型使用 TorchSpec 在 vLLM 中训练,以实现推测器推理与训练之间的完全数值一致性。

DSpark 使用块扩散主干,基于 Kimi K3 丰富的中间状态,在一次并行传递中生成多个推测标记,因此草稿成本随着块加深而保持平稳。低秩马尔可夫头提供块内依赖关系,置信头预测每个草稿被接受的可能性。我们将草稿设计为原生 MLA,镜像 Kimi K3 自身的注意力机制,因此草稿和目标共享相似的 KV 布局,以最大程度兼容高级 KV 管理和 P/D 分离设置。

Kimi K3 DSpark positional acceptance rates
Kimi K3 DSpark 位置接受率

Kimi K3 DSpark 在不同数据集上的位置接受率。

借助 DSpark,我们在单用户请求上实现了 3.14 倍的加速,从 118 tok/s 提升到 370 tok/s,使用 SPEED Bench 测量。我们还对不同任务的接受率和加速比进行了基准测试,结果如上所示。对于编码和其他低熵任务,我们每步获得约 4.73 个接受的标记。对于创意写作等高熵任务,我们每步获得约 2.61 个接受的标记。

在 vLLM 中,基于置信度的 DSpark 调度是一项持续进行的工作。一旦启用,它会使用 DSpark 模型中包含的置信头来预测每个草稿标记被接受的可能性,优先处理强候选并修剪弱候选,从而避免将验证花费在不会存活的标记上。

截至本次发布,草稿模型 和推理支持均已开源。请参阅下方的部署指南以启用它。

DSpark draft-and-verify flow for Kimi K3
Kimi K3 的 DSpark 草稿-验证流程

轻量级 DSpark 草稿提出候选标记,Kimi K3 在一次并行传递中验证,加速单流解码。

TEP 预填充的序列并行

Sequence parallelism for TEP prefill
TEP 预填充的序列并行

序列并行将 token 的所有权分片到各个 rank 上;注意力残差按分片应用,一次 all-gather 在下一层的 QKV 投影之前重建完整批次。

在 prefill 阶段,我们将注意力张量并行与 MoE 专家并行(TEP)相结合。与纯 TP 相比,TEP 减少了通信开销,并将完整的专家保留在每个 rank 上,从而获得更高效的专家 GEMM 形状。

然而,朴素的 TEP 实现每层执行两次 all-reduce——一次在注意力输出投影之后,一次在 MoE 之后——因此每个 rank 都会物化完整批次,并对全部内容冗余地应用注意力残差。为解决这一问题,我们实现了序列并行:将 o_proj 之后的 all-reduce 替换为 reduce-scatter,使每个 rank 拥有一个 token 分片,注意力残差按分片应用,MoE 的 all-to-all 执行 dispatch 和 combine,并在下一层的 QKV 投影之前通过一次 all-gather 恢复完整批次。

这一设计提供了两个关键优势:

  • 降低通信开销:reduce-scatter + all-to-all dispatch + all-to-all combine + all-gather 在理论上比两次 all-reduce 更廉价。然而在实践中,NCCL 的 reduce-scatter 和 all-gather 并未针对 prefill 的消息大小进行优化,无法带来加速。因此我们实现了自定义的 reduce-scatter 和 all-gather kernel,比 NCCL 快 1.7×–4.5×,尤其是在中小消息大小下。
  • 分片注意力残差:注意力残差在整个层中始终保持跨 rank 分片,因此每个 rank 只计算并维护其 token 分片,而非整个批次。这对 Kimi K3 尤为重要,因为 AttnRes 将残差流转变为持久的跨层状态,并带有自身的计算和内存开销。

序列并行会在适当情况下默认启用:当使用 TP 配合 MegaMoE kernel 时,或组合 TP + DP + EP 时。无需额外标志。

大规模服务:prefill/decode 分离

对于高吞吐场景,vLLM 以跨节点的专家并行和数据并行来服务 Kimi K3,并采用 prefill/decode(PD)分离,将 prefill 密集型和 decode 密集型工作运行在独立的副本上,使各自针对自身的瓶颈进行规模配置。我们验证过的拓扑之一将 TEP8 prefill 路由到 DEP16 decode,并使用 NIXL 作为 KV 传输引擎。

PD 分离对混合模型而言极为严苛:循环 KDA 状态、全注意力分页 KV 以及块表都必须正确到达。NIXL 连接器将共享的 KV-cache 页视为两个逻辑视图:token 级 MLA cache 和请求级 KDA 状态,包括卷积和循环状态。在握手期间,它交换 MLA/KDA 元数据,然后为每次传输构建单独的传输描述符。

在异构 TP 下,vLLM 的混合分配器对 prefill 和 decode 使用不同的块大小。为支持这种情况,vLLM 的 NIXL 连接器跟踪逻辑到物理的块映射,并将任何未传输的尾部区域置零,防止先前请求的陈旧数据通过填充或布局间隙泄漏。

Prefill/decode disaggregation flow
Prefill/decode 分离流程

协调部分块缓存命中与 KV cache 卸载

如 Kimi K3 预览 中所述,vLLM 支持细粒度的前缀命中,命中点可能落在物理缓存块内部。这给 KV 卸载带来了一个微妙的挑战:vLLM 可能先找到一个带有部分尾部的本地 GPU 命中,随后又在 Mooncake 等外部存储中发现更长的前缀。对于整块命中,远程复用可以干净地延伸到本地前缀之外。然而,部分尾部可能与远程结果重叠。

因此,vLLM 调度器会比较两个层级中精确的可复用 token 长度,并选择更长的前缀。如果远程命中胜出,它会释放为较短的本地尾部预留的块,并将所有缓存组协调到新的前缀长度。

重要的是,我们完全通过现有的 KV Connector API 构建了这一机制,这些 API 已经提供了所有必需的语义。这使得 MooncakeStoreConnector、SimpleCPUOffloadConnector 及其他连接器能够支持多层级部分前缀复用,而无需针对特定模型的集成路径。

该设计记录在 RFC 中,并在 PR #45939、PR #46384 和 PR #49502 中实现。

Agentic 服务:更智能的缓存保留策略

Kimi K3 的线性注意力层只需要恒定大小的 KDA 状态,使其在长上下文长度下具有内存效率。单层的 KDA 状态大致相当于几千个 token 的 MLA 缓存。尽管很大,但该状态不像传统 KV 缓存那样随序列长度增长。这一区别对于跨越数十万到一百万个 token 的 agentic 工作负载而言意义重大。

同样的设计使前缀缓存变得复杂。KDA 状态在解码过程中原地更新,因此 vLLM 必须在下一个前向传播覆盖它之前,在选定的前缀边界处复制该状态。在每个 token 位置进行缓存将代价高昂:每个 KDA 检查点都比单个 token 的 MLA 缓存大得多,并且会迅速耗尽即使是分布式缓存池。

为了提高缓存空间效率,同时保留有用的前缀,vLLM 支持两种互补的保留策略。

基于间隔的保留

缓存每个 KDA 状态是浪费的,但缓存过于稀疏又会迫使下一个请求重新计算大量后缀。基于间隔的保留通过将选定位置视为检查点来平衡这些成本——例如,每 32K 个 token 一个。

提示边界是更好的检查点。在 agentic 工作负载中,下一轮通常以重放上一轮的提示开始,因此该提示末尾的状态特别有可能被复用。vLLM 会自动检测并保留这些边界。

用户可以通过 VLLM_PREFIX_CACHE_RETENTION_INTERVAL 控制周期性检查点。将其设置为 0 会禁用周期性检查点,仅保留提示末尾状态,这非常适合以多轮对话为主的工作负载。更大的间隔会以一些重新计算换取更低的缓存使用量。

基于间隔的保留在 PR #43447 中为 DeepSeek V4 和混合滑动窗口注意力模型引入,并在 PR #45845 中增加了对 Kimi K3 和混合线性注意力模型的 day-0 支持。

Interval-based KDA cache retention
基于间隔的 KDA 缓存保留

基于间隔的缓存保留。MLA 为每个块缓存 KV,而 KDA 状态仅在检查点保留:提示末尾(绿色)始终保留,固定间隔检查点(橙色)可配置。

Marconi 风格的选择性保留

Prompt-end retention 对对话状态效果很好,但有价值的共享前缀也可能出现在其他地方。系统提示词、仓库快照或工具规范可能在许多请求中复用,却不与 prompt 边界对齐。

Marconi 式保留(MLSys '25)用一条简单规则处理这些情况:第二次命中时缓存。第一次观察提供了前缀存在的证据;第二次表明它确实被共享。只有到那时,vLLM 才会为其 KDA 状态花费缓存容量。

这把保留变成了需求驱动的决策。一次性前缀不会挤占缓存,而反复出现的前缀会自动提升——无需用户预测其工作负载的哪些部分会变热。

选择性保留在 PR #37898 中引入,day-0 Kimi K3 支持在 PR #47782 中添加。

Selective KDA cache retention
选择性 KDA 缓存保留

选择性缓存保留。请求 1 仅在其自身 prompt 末尾、共享前缀之后保留一个 KDA 状态,因此请求 2 获得 KV 命中但 KDA 未命中。这第二次出现证明该前缀是共享的,于是在前缀边界处缓存一个状态,请求 3 便可复用它。

这些策略共同覆盖了可预测和涌现的复用:区间保留为结构上重要的边界设置检查点,而 Marconi 式保留则学习哪些其他前缀值得保留。

性能优化

服务像 Kimi K3 这样的大模型因其规模而带来自身挑战。整个模型几乎无法装入单台 NVIDIA DGX B300,在该代硬件上服务至少需要 16 块 NVIDIA B200/GB200 GPU。服务必须在交互性与系统总吞吐量之间权衡:张量并行有利于交互性,但总体吞吐量低,因为有效 KV 缓存大小受限;而大规模专家并行可能因网络带宽瓶颈限制单用户输出 token 速度。这里我们重点介绍在两种情况下都能提升性能的优化,以便用户选择适合其工作负载的方案。其中许多优化已在我们预览博客中介绍过。

注意力残差

Kimi K3 使用 Block AttnRes,最多关注八个缓存的块表示加上当前块内残差。对于每个 token,vLLM 从 RMS 归一化的来源计算 logits,在这些深度方向的候选上应用 softmax,并聚合它们的表示。其实现类似 FlashAttention 的在线 softmax 策略,但作用于模型深度而非序列位置,且最多有九个来源。vLLM 在单个融合内核中执行这种混合,在输入端纳入残差更新,并可选择对输出应用 RMSNorm。一个可移植的 Triton 实现覆盖通用路径,而专用 CUDA 内核加速受支持的 Blackwell 配置。

KDA 解码

Fused KDA decode kernel
融合 KDA 解码内核

融合 KDA 解码内核将因果卷积、循环更新和 RMSNorm 合并为单次启动,而非一连串独立内核。

KDA 层涉及许多操作:输入投影、因果一维卷积、QK 归一化、门控计算、KDA 循环更新以及输出门控 RMSNorm。在支持的配置上,vLLM 将投影后的解码路径——从因果卷积到门控 RMSNorm——融合为单个专用 CUDA 内核。该内核原地更新卷积和循环状态,并直接写出归一化输出,从而避免了中间张量、重复的状态读写,以及 Kimi K3 众多 KDA 层中逐操作的启动开销。可移植的 Triton 回退路径覆盖了不支持的配置。

KDA 预填充

KDA 预填充成为我们最喜欢的开源开发实践案例之一。Moonshot AI 首先发布了 FlashKDA,这是一个高性能的 CUTLASS KDA 实现。我们迅速将其集成到 vLLM 中,并处理了那些不那么光鲜的生产细节:更广泛的 GPU 覆盖、元数据类型、张量布局以及可靠的 vendoring。Shikhar Mishra 随后针对 H100 优化了这些内核,并发布了 Flash-Flash-KDA,在保持数值正确性的同时改进了数据移动。不到一天,我们就在 GB300 NVL72 上验证了这些改进,优化了循环流水线和同步,并将其合并到我们的 FlashKDA 集成中。结果不是单向的交接,而是一个持续循环:一个开放内核由服务社区扩展,由独立贡献者改进,并迅速投入生产。

KDA 元数据构建器

Nsight Systems traces before and after KDA metadata preparation optimization
KDA 元数据准备优化前后的 Nsight Systems 跟踪

在 Kimi K3 DSpark 启动过程中,KDA 元数据准备成为显著的开销来源。Kimi K3 最初复用了通用的 GDN 元数据构建器,该构建器准备了 K3 并不消费的 FLA 元数据,并使用一系列小型即时 PyTorch 操作来组装和暂存 GPU 元数据。我们引入了专用的 Kimi K3 KDA 元数据构建器,裁剪了未使用的路径,并用融合的 Triton 内核替换了那些操作序列,将每个序列缩减为单次启动。在批大小为 1 时,这将元数据准备延迟降低了 96%,从 870 μs 降至 34 μs,并将端到端 DSpark 延迟改善了 6%。

低延迟 BF16 GEMM

在低批大小、延迟敏感的场景中,我们用自己实现的 skinnyGEMM 替换了通用 BF16 GEMM——它用于多个线性投影层。通用 cuBLAS 内核在此处无法达到最佳性能,因为它们针对更通用的形状进行了优化。在该内核中,我们绕过了共享内存数据暂存,将激活值和权重直接加载到寄存器中,并使用 CUDA Core FMA 指令执行计算。这避免了为实现最大吞吐量而使用的繁重 TMA 和 Tensor Core 设置阶段。我们的微基准测试显示,内核级加速在 8% 到 100% 之间,在小批量场景下端到端延迟降低约 10%。

低延迟 MoE 尾部融合

LatentMoE tail-fusion optimization
LatentMoE 尾部融合优化

LatentMoE 尾部优化将两次 all-reduce、RMSNorm、潜在上投影和逐元素加法替换为三个内核,以减少计算并更好地重叠通信与计算。

vLLM 采用一种新颖策略来降低超低延迟服务中 latent-MoE 的尾部延迟。在 LatentMoE 的末尾,来自路由专家的降维激活必须先经过 RMSNorm 归一化并上投影,然后才能加到共享专家的输出上。在常规 TP 情况下,这需要对路由专家和共享专家做两次 all-reduce——或者通过拼接做一次 all-reduce——并复制上投影。

为避免复制线性投影带来的冗余计算,vLLM 改为对共享专家执行 reduce-scatter,并在路由专家上保留 all-reduce,因为它们的激活需要归一化。随后,复制后的路由专家激活以列并行方式与上投影进行矩阵乘法,并按元素加到已经分片的共享专家输出上。最后,使用 broadcast 将结果 all-gather 到每个 rank 上。我们观察到这一步延迟降低约 20%,端到端加速约 7%–8%。

质量与性能基准

准确性与正确性评估

vLLM 对准确性的重视不亚于速度。我们通过一个已服务的 OpenAI 兼容端点对 Kimi K3 进行了端到端验证,精确配置见 recipes,它干净地通过了准确性评估。在最高推理努力级别下,vLLM 上的 Kimi K3 在 GSM8K 上得分 0.976,在 GPQA-Diamond 上得分 0.939,在 OCRBench 上得分 0.889,在 MMMU Pro Vision 上得分 0.818。

评估时有一个值得注意的坑:Kimi K3 在回答前会思考很多。低分往往是因为答案被截断,而不是答错,所以请提高推理努力、将 max_tokens 设置得足够宽裕,并在调试其他任何东西之前先检查生成是否被截断。

服务性能

Kimi K3 single-user decode throughput
Kimi K3 单用户解码吞吐量

Kimi K3 在 batch size 1 下的解码吞吐量,在 GB300 NVL72 GPU 上以 TP8 和 TP16 配置测量。

发布时,vLLM 在 batch size 1 下于 TP8 上达到每用户 111 tok/s,于 TP16 上达到每用户 118 tok/s。DSpark 投机解码将交互性提升约 3 倍,在 TP8 上达到每用户 331 tok/s,在 TP16 上达到每用户 370 tok/s。

Kimi K3 GB300 NVL72 pareto curve
Kimi K3 GB300 NVL72 帕累托曲线

我们还展示了在 GB300 NVL72 上服务 Kimi K3 的初步帕累托前沿性能结果,覆盖从 2K+ TPGS 的高吞吐服务到 100+ TPS/用户的低延迟服务等一系列场景。

复现我们的基准测试

以下是使用 DSpark 在 TP8 下复现上述解码吞吐量数字的完整 recipes:

export NCCL_DMABUF_ENABLE=0
export VLLM_ALLREDUCE_USE_FLASHINFER=1
export VLLM_USE_RUST_FRONTEND=1
export VLLM_ENGINE_READY_TIMEOUT_S=3600
export HEAD_ADDR=127.0.0.1  # Change if vllm-bench runs on another host.
 
vllm serve moonshotai/Kimi-K3 \
  --enable-prefix-caching \
  --tensor-parallel-size 8 \
  --nnodes 2 \
  --node-rank 0 \
  --moe-backend auto \
  --trust-remote-code \
  --load-format fastsafetensors \
  --max-num-seqs 512 \
  --gpu-memory-utilization 0.9 \
  --max-model-len auto \
  --max-cudagraph-capture-size 256 \
  --kv-cache-dtype fp8 \
  --attention-config '{"mla_prefill_backend":"FLASHINFER","use_prefill_query_quantization":true}' \
  --speculative-config '{"model":"Inferact/Kimi-K3-DSpark","method":"dspark","num_speculative_tokens":7,"attention_backend":"FLASHINFER_MLA","draft_sample_method":"probabilistic","rejection_sample_method":"block"}'
 
# Batch size = 1, 8K/1K random (no speculative decoding)
vllm-bench \
  --backend openai \
  --base-url "http://${HEAD_ADDR}:8000" \
  --model moonshotai/Kimi-K3 \
  --dataset-name random \
  --random-input-len 8192 \
  --random-output-len 1024 \
  --random-range-ratio 0.8 \
  --prompt-token-ids \
  --ignore-eos \
  --sweep-max-concurrency 1 \
  --sweep-num-prompts-factor 10 \
  --seed 42 \
  --percentile-metrics "ttft,tpot,itl,e2el" \
  --metric-percentiles "50,90,99" \
  --save-result
 
# Batch size = 1, SPEED Bench (speculative decoding)
vllm-bench \
  --backend openai \
  --base-url "http://${HEAD_ADDR}:8000" \
  --model moonshotai/Kimi-K3 \
  --dataset-name speed-bench \
  --speed-bench-config throughput_16k \
  --speed-bench-max-input-len 10240 \
  --speed-bench-category low_entropy \
  --output-len 1536 \
  --num-prompts 10 \
  --no-oversample \
  --max-concurrency 1 \
  --temperature 1.0 \
  --top-p 0.95 \
  --save-result \
  --save-detailed

完整 recipes,包括多节点、专家并行和视觉配置,见 Kimi K3 recipes。

重要部署提示

  1. 前缀缓存:--enable-prefix-caching 会开启前缀缓存。前缀缓存在 vLLM 中通常默认启用,但目前对 Kimi K3 默认禁用,因为混合缓存设计仍在演进中。请显式传入该标志。
  2. 工具调用:在依赖它之前,请先在你自己的流量上验证。我们偶尔看到 K3 发出一种其自身解析器不期望的工具调用格式,导致 tool_calls 结果为空,而在同一设置下的干净探测却能完美解析。这取决于提示词和运行,并非普遍性失败,但生产级 agent 应针对你的 schema 进行验证,在 tool_calls 返回为空时重试或回退,并考虑使用严格或结构化工具调用,在生成过程中约束输出语法。
  3. All-to-all 后端:--all2all-backend 决定 MoE 后端在专家并行期间如何通信。NVIDIA NVLink 使用 flashinfer_nvlink_one_sided,RDMA 使用 deepep_v2。
  4. MoE 后端:vLLM 针对不同场景提供了多种 MoE 后端。对于任何 DEP 环境,我们推荐使用 deep_gemm_mega_moe。
  5. Rust 前端:设置 VLLM_USE_RUST_FRONTEND=1 以启用 Rust 前端,该前端完全支持此模型。
  6. ViT 并行:--mm-encoder-tp-mode=data 默认启用。K3 的视觉编码器具有 head_size=12,在 TP=8 下无法均匀分片。由于 K3 的视觉编码器参数少于 1B,而主干网络约有 2T,我们默认启用 ViT DP,以避免编码器带来的 all-reduce 开销。

Kimi K3 vLLM 常见问题解答

服务 Kimi K3 需要多少块 GPU?

至少需要一个 8× B300(或 GB300 NVL72)节点;也支持 16× B200。大多数生产部署采用多节点,配合专家并行和数据并行,通过 RDMA 或 NVLink 连接。

如何启用 DSpark 投机解码?

添加:

--speculative-config '{"model":"Inferact/Kimi-K3-DSpark","method":"dspark","num_speculative_tokens":7,"attention_backend":"FLASHINFER_MLA","draft_sample_method":"probabilistic","rejection_sample_method":"block"}'

在推理和编码工作负载上,它大致可将单流解码速度提升至三倍。

应该使用哪种 MoE 和 all-to-all 后端?

对于解耦或专家并行(DEP)部署,使用 deep_gemm_mega_moe;对于 TP > 1,使用 flashinfer_trtllm。根据你的互连选择 all-to-all 后端:NVLink 使用 flashinfer_nvlink_one_sided,RDMA 使用 deepep_v2。

Kimi K3 是否支持前缀缓存,默认开启吗?

它支持对全注意力 KV 和循环 KDA 状态进行前缀缓存,但默认未启用,因此需传入 --enable-prefix-caching。

vLLM 是否支持在 AMD GPU 上运行 Kimi K3?

支持。ROCm 支持随发布一同提供,更广泛的调优已在路线图中。

这与 Kimi K3 预览文章有何不同?

预览是架构与内核的深度解析,包括 KDA 前缀缓存和内核是如何构建的。本文是实用发布指南,包含相关产物:vLLM 如何适配 Kimi K3、配方、标志、性能,以及 Kimi K3 已为生产环境做好了哪些准备。

路线图与未来工作

  • Kimi K3 的 RL 支持:vLLM rollout 支持已添加。我们将与 RL 生态项目紧密合作,支持 Kimi K3 的端到端 RL 训练。
  • 持续性能改进:在 day 0 之后继续提升性能。
  • 解码上下文并行(DCP):我们的原型显示出良好的加速效果,我们将很快向上游提交支持。早期实验表明,在选定工作负载下,吞吐量比 TP8 高出 40%。
  • 专家并行负载均衡(EPLB):改进 EPLB 性能。
  • 基于置信度的调度:使用 DSpark 中的置信度头来修剪需要验证的草稿 token 数量。
  • 更广泛的 AMD ROCm 调优。

快速链接

致谢

感谢 Moonshot AI 创建 K3、在发布前分享架构并共同设计 KDA 感知缓存;感谢 Inferact 团队完成端到端 vLLM 集成与部署验证;感谢 NVIDIA 提供融合 KDA 解码、KDA 预填充和 Attention Residual 内核以及 MXFP4 MoE 协作;感谢 AMD 完成 ROCm 适配;感谢我们的推理合作伙伴,包括 Alibaba Cloud、Baseten、DigitalOcean 和 Modal;感谢 Shikhar 的 Flash-Flash-KDA;以及感谢 vLLM 社区。为 Kimi K3 构建的缓存基础设施现在属于每一个具有类似架构的混合模型。我们迫不及待想看到你们用它来服务什么。

来源:vLLM Blog · vllm.ai