vLLM 中 Kimi K3 的性能优化:吞吐量提升至 2.8 倍
Kimi K3 Performance Optimizations in vLLM: The Road to 2.8× Throughput
vLLM 团队公布 Kimi K3 在 vLLM 上的服务优化结果,从 v0.27.1 到 0913 main 在 8K/1K 负载、TP8、8 个 DSpark 投机 token 下延迟降低 56%–60%、吞吐提升 2.2–2.8 倍、TTFT 降低 72%–85%。
vLLM 团队拆解 Kimi K3 服务优化的四类改动,并给出可复现的启动与压测命令,便于对照自身部署瓶颈。
Day-0 支持让 Kimi K3 在 vLLM 中运行。高效服务还需要对整个技术栈进行另一轮优化。KDA 循环状态、LatentMoE、MXFP4 专家内核、推测解码以及 TP/PP 各自暴露出不同的瓶颈;调度器限制和小张量拷贝可能与大型 GEMM 同样重要。
本文先给出端到端结果,然后审视四项代表性改动:自适应推测令牌预算、内部 KDA 前缀检查点、零拷贝混合 KDA 批次,以及延迟 MXFP4 最终化。还涵盖:ReplaySSM、预填充/解码分离与缓存卸载,以及解码上下文并行。更广泛的工作记录在 Kimi K3 性能优化 #50587 中。
性能
使用 8K/1K 工作负载、TP8、八个令牌 DSpark 推测进行测量。并发数为 1、4 和 16。对比从 v0.27.1 到提交 82a85dc1 (0913),在 B300 节点(CUDA 13.3)上测试。
启动服务器:
vllm serve moonshotai/Kimi-K3 \
--trust-remote-code \
--tensor-parallel-size 8 \
--load-format fastsafetensors \
--gpu-memory-utilization 0.9 \
--reasoning-parser kimi_k3 \
--enable-auto-tool-choice \
--tool-call-parser kimi_k3 \
--host 0.0.0.0 \
--port 30000 \
--max-model-len auto \
--no-enable-prefix-caching \
--speculative-config '{"model":"RedHatAI/Kimi-K3-speculator.dspark","method":"dspark","num_speculative_tokens":8,"draft_sample_method":"probabilistic","rejection_sample_method":"standard"}'注意:两次运行中前缀缓存均被禁用,因为 v0.27.1 存在一个已知的 Kimi K3 前缀缓存问题,该问题后来已修复。
运行基准测试:
guidellm run \
--backend '{"kind":"openai_http","target":"http://127.0.0.1:30000","model":"moonshotai/Kimi-K3","request_format":"/v1/chat/completions","timeout":100000,"extras":{"body":{"reasoning_effort":"max","temperature":1.0,"top_p":0.95}}}' \
--tokenizer '{"kind":"huggingface_auto","model":"moonshotai/Kimi-K3","load_kwargs":{"trust_remote_code":true}}' \
--data 'kind=synthetic_text,prompt_tokens=8000,output_tokens=1000' \
--profile 'kind=concurrent,warmup=0.1,cooldown=0.1' \
--override profile.streams '1,4,16' \
--constraint 'kind=max_duration,seconds=150' \
--constraint 'kind=max_errors,count=10' \
--seed 'kind=static,value=42' \
--metrics 'kind=generative,sample_size=20' \
--output 'kind=json,path=guidellm-results/output_vllm_kimik3_8k1k.json'| 并发数 | 0.27.1 平均延迟 (s) | 0913 main 平均延迟 (s) | 0.27.1 吞吐量 (tok/s) | 0913 main 吞吐量 (tok/s) | 0.27.1 平均 TTFT (ms) | 0913 main 平均 TTFT (ms) |
|---|---|---|---|---|---|---|
| 1 | 12.37 | 5.30 (−57.2%) | 83.3 | 183.3 (+120.0%) | 2262.9 | 376.3 (−83.4%) |
| 4 | 23.67 | 10.50 (−55.6%) | 166.7 | 416.7 (+150.0%) | 2314.9 | 640.5 (−72.3%) |
| 16 | 55.90 | 22.17 (−60.3%) | 258.3 | 725.0 (+180.6%) | 7601.1 | 1121.0 (−85.3%) |
端到端优化示例
自适应调度预算
低请求数导致大量 max_num_batched_tokens 未被使用。PR #51725:自适应调度令牌预算。PR #51726:高内存 GPU 层级的默认限制从 8,192 提高到 16,384。在报告的 8K/1K 工作负载上:TTFT 降低 55%–65%,吞吐量提升高达 41.5%。
让我们考虑 max_num_seqs=1024、max_num_batched_tokens=8192 和 K=8:
| 实际请求数 | 旧逻辑调度的令牌数 | 现在 |
|---|---|---|
| 1 | 1024 (8192 - 1024 * (8-1)) | 8185 (8192 - 7) |
| 32 | 1024 | 7968 |
| 128 | 1024 | 7296 |
| 1024 | 1024 | 1024 |
该 PR 通过使用自适应策略,在请求数较少时使调度的令牌数大幅增加,因此一个请求不会被拆分到多次前向调用中。
内部 KDA 前缀检查点
Mamba 风格的前缀缓存将预填充拆分在最后一个可缓存块边界处,有时会为短后缀增加一次全模型前向。PR #52789:在一次预填充过程中导出检查点,TTFT 降低 9%–25%。PR #53614:部分前缀命中和推测解码,包括 EAGLE 重放边界对齐。
对于 8K 输入:
该 PR 帮助我们避免第二次全模型前向经过注意力、MoE、路由和 TP 集合通信。
零拷贝混合 KDA 批次
混合推测和非推测批次每层使用六次 index_select 和两次 index_copy_ 操作。PR #56159:连续零拷贝切片和直接输出写入。在并发数 4 和 16 时吞吐量提升 5.2%–7.7%;批次大小为 1 时持平。
延迟 MXFP4 最终化
PR #53152:在 latent-tail kernel 内完成 MXFP4 top-k finalization;减少一次 launch 和一次中间张量的写入/读取。端到端延迟降低约 5%。PR #53327:修复初始化顺序,在权重加载前启用 deferred 路径。
这减少了一次 kernel launch,并避免了写入和重新读取 finalization 后的中间张量。
ReplaySSM:重建 KDA 状态而非存储它
投机解码会在每个 draft 位置写入一个 KDA 循环状态,以便被拒绝的 token 可以回滚。对于 T 个 draft 位置,这意味着每步额外 T 次状态写入。ReplaySSM 改为缓冲最近的 SSM 输入,并在提交时重建被接受的状态。回滚只需移动一个缓冲区指针。
PR #51855:在 Model Runner V2 上为 Kimi K3 实现 ReplaySSM。一个 Triton kernel 在 align 模式下提交被接受的状态以及下一个 prefix-cache 边界。在相同的 46.48 GiB 缓存预算下,TP8 下有效容量提升 10.97%,且无精度损失。
Prefill/decode 分离与混合状态卸载
PD 分离和缓存卸载必须同时传输 MLA KV 和 KDA 状态。MLA KV 在 TP rank 间复制;KDA 状态按 head 和维度分片。Mamba align block table 也可能是稀疏且可变的。纯 attention 的传输假设并不适用。
PR #51358:Mooncake 存储调度器选定的边界状态,并将其固定,直到所有 rank 上的异步写入完成。PR #50344:只有能够恢复 KDA 状态的 connector 才能服务每组不同的 prefix 命中。
Decode 上下文并行
TP 会在每个 rank 上复制 MLA latent KV,因此增加 TP rank 并不会增加 KV-cache 容量。Decode 上下文并行 沿序列维度对其分片,适用于长共享前缀的 agentic 工作负载。
PR #50484:为 Kimi K3 的融合 MLA 路径实现 DCP。对称内存 A2A 处理 output/LSE 归约;NVLS multicast 收集 query;multimem 收集分块上下文的 KV。Query 分片直接写入消费者的最终缓冲区。在 4×GB200 上,query 交换延迟降低 10.4%–29.9%。

在 120k token 的工作负载上(114k 共享前缀、6k 后缀、400 输出 token),KV-cache 容量从 1.93M token 提升到 19.75M token。并发度为 1 时 TPOT p50 从 13.8 ms 降至 10.5 ms,并发度为 2 时从 16.2 ms 降至 11.8 ms。GSM8K:DCP8 为 96.97%,TP8 为 96.21%;零请求错误。
超越这些示例
更广泛的工作涵盖内存布局、序列与流水线并行、KDA prefill 与循环状态、MLA、MoE 和 GEMM。它对大型投影和共享专家进行了分片,减少了集合通信和数据移动,并优化了小批量 GPU 路径。完整的 PR 列表记录在 issue #50587 中。
选定的社区 PR 拓展了这项工作:Robert Shaw 和 Summer Yang 添加了 DeepEPv2 with DeepGEMM MXFP4 以及上文所述的 DCP 支持,而 Thien Tran 开发了 序列并行 GEMM 路径。Nick Hill 和 Xiaolong Xu 在 PR #51540 和 PR #52458 中优化了 KDA prefill。完整的贡献者名单列于下方。
致谢
Benjamin Chislett、Bolin Sun、Dao Le、Duncan Moss、Harris Nover、Julian Huang、Ming、Nick Hill、Rebecca Lee、Robert Shaw、Summer Yang、Thien Tran、Tyler Michael Smith、Xiaolong Xu 和 Yifan Qiao 为 Kimi K3 提交的 PR。感谢审阅者、CI 维护者、基准测试负责人和硬件团队。我们还要感谢 Novita AI 团队为本文所述部分优化工作赞助算力。
来源:vLLM Blog · vllm.ai