vLLM 中的 DeepSeek V4:高效长上下文 Attention
DeepSeek V4 in vLLM: Efficient Long-context Attention
vLLM Team 发布 DeepSeek V4 支持,覆盖 DeepSeek-V4-Pro(1.6T)和 Flash(285B),支持 100 万 token 上下文;实现共享 KV、c4a/c128a 压缩、DSA、hybrid KV cache、Kernel Fusion 与 Multi-stream,1M 下 bf16 KV cache 约 9.62 GiB。
vLLM 中的 DeepSeek V4:高效长上下文 Attention | vLLM Blog
菜单
主题
](https://vllm.ai/)[文档](https://docs.vllm.ai/)[Blog](https://vllm.ai/blog)[活动](https://vllm.ai/events)[联系](https://vllm.ai/contact)[社区](https://vllm.ai/#community)搜索⌘J[](https://github.com/vllm-project/vllm "GitHub")
vLLM 中的 DeepSeek V4:高效长上下文 Attention
2026 年 4 月 24 日 17 分钟阅读
vLLM Team
- 在 vLLM 上运行 DeepSeek V4
- DeepSeek-V4-Pro
- DeepSeek-V4-Flash
- DeepSeek V4 的 Attention 机制解释
- vLLM 对 DeepSeek V4 的实现
- 保持 KV Cache 内存紧凑
- (1) 单一逻辑块大小
- (2) 将 compressor state 作为滑动窗口
- (3) 统一 page size
- 保持 GPU 忙碌
- (1) Kernel Fusion
- (2) Multi-stream
- 计划中的工作
- 致谢
- 附录:DeepSeek V4 Attention 机制背后的数学
- 为什么 key 和 value 共享时需要 inverse RoPE
- 实现细节:精确的位置范围和因果性条件
- 实现细节:c4a 和 c128a 中 k 的精确值
- 实现细节:为什么需要短滑动窗口
- 8.7x 节省估算背后的算术
目录
我们很高兴宣布,vLLM 现在支持 DeepSeek V4 系列模型(deepseek-ai/DeepSeek-V4-Pro 和 deepseek-ai/DeepSeek-V4-Flash)。
这些模型具备高效的长上下文 attention 机制,专为涉及最多 一百万 token 的任务设计。新的 attention 设计初读可能显得复杂,但只要系统地拆解,其基本原理是直接的。
本文分为三部分:
- 在 vLLM 上服务 DeepSeek V4 的快速入门指南
- 从第一性原理解释 DeepSeek V4 的新架构设计
- 概述我们在 vLLM 上实现和优化该模型的方法与挑战:hybrid KV cache、kernel fusion,以及 disaggregated serving。
这是我们对该模型支持的初始发布,后续优化正在积极推进。我们希望下面的技术说明能帮助开源社区理解 attention 机制本身,以及我们当前实现决策背后的原因。
在 vLLM 上运行 DeepSeek V4
DeepSeek V4 包含 2 个模型:大型 1.6T 参数模型 DeepSeek-V4-Pro,以及小型 285B 参数模型 DeepSeek-V4-Flash。两个模型都支持最多 100 万 token 的上下文,vLLM 对新 attention 机制的实现也设计为可扩展到这一上下文长度。
DeepSeek-V4-Pro
这里我们重点展示一个单节点部署,面向便捷测试和原型开发进行优化,并包含 FP4 indexer 和 MTP 等若干可选优化。以下命令可在 8xB200 或 8xB300 上运行。
docker run --gpus all \
--ipc=host -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
vllm/vllm-openai:deepseekv4-cu130 deepseek-ai/DeepSeek-V4-Pro \
--trust-remote-code \
--kv-cache-dtype fp8 \
--block-size 256 \
--enable-expert-parallel \
--data-parallel-size 8 \
--compilation-config '{"cudagraph_mode":"FULL_AND_PIECEWISE", "custom_ops":["all"]}' \
--attention_config.use_fp4_indexer_cache=True \
--tokenizer-mode deepseek_v4 \
--tool-call-parser deepseek_v4 \
--enable-auto-tool-choice \
--reasoning-parser deepseek_v4
更多部署策略,包括 disaggregated serving / 更多 GPU 架构,请参考 recipes。
DeepSeek-V4-Flash
这里我们重点展示一个单节点部署,面向便捷测试和原型开发进行优化,并包含 FP4 indexer 和 MTP 等若干可选优化。以下命令可在 4xB200 或 4xB300 上运行。
docker run --gpus all \
--ipc=host -p 8000:8000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
vllm/vllm-openai:deepseekv4-cu130 deepseek-ai/DeepSeek-V4-Flash \
--trust-remote-code \
--kv-cache-dtype fp8 \
--block-size 256 \
--enable-expert-parallel \
--data-parallel-size 4 \
--compilation-config '{"cudagraph_mode":"FULL_AND_PIECEWISE", "custom_ops":["all"]}' \
--attention_config.use_fp4_indexer_cache=True \
--tokenizer-mode deepseek_v4 \
--tool-call-parser deepseek_v4 \
--enable-auto-tool-choice \
--reasoning-parser deepseek_v4
更多部署策略,包括 disaggregated serving / 更多 GPU 架构,请参考 recipes。
DeepSeek V4 的 Attention 机制解释
长上下文推理面临两个主要挑战:
- KV cache 内存增长:KV cache 会随上下文长度线性增长。尽管 DeepSeek 风格模型使用 Multi-head Latent Attention (MLA),相比标准 Multi-head Attention (MHA) 或 Multi-Query Attention (MQA) 显著节省内存,但考虑到 GPU 内存容量有限,扩展到一百万 token 仍然困难。
- Attention 计算成本:在长上下文上计算 attention 代价很高。即使使用 DeepSeek Sparse Attention (DSA) 等既有技术,计算仍然是重要瓶颈。
为了解决这些挑战,DeepSeek 团队设计了一种新的 attention 机制,目标是同时压缩 KV cache 并降低 attention 计算时间。
共享 key 和 value 向量(节省 2x 内存)。为保证正确性,我们对 attention 输出应用 inverse RoPE 操作。
跨多个 token 压缩 KV cache(节省 4x 到 128x 内存)。在 DeepSeek V4 中,有两种做法: *
c4a:将 KV cache 大约压缩到 1/4。一个压缩 token 是 8 个未压缩 token 的加权和,stride 为 4。 *c128a:将 KV cache 大约压缩到 1/128。一个压缩 token 是 128 个未压缩 token 的加权和,stride 为 128。DeepSeek Sparse Attention(有界的 attention 计算成本)。即使用
c4aattention 压缩 KV cache,一百万 token 序列仍有 250k 个压缩 token。为加速 attention 计算,我们可以使用 DeepSeek Sparse Attention (DSA),只 attend 到 top- 个压缩 token。保留局部性:短滑动窗口。DeepSeek V4 使用大小为 128 的滑动窗口处理局部信息,并在未压缩 token 上运行,使 query token 在到达压缩边界之前能够 attend 到局部信息。
为了更好地说明这种新的 attention 机制,下面是 c4a attention 处理 13 个 token 的动画。理解上述细节后,c128a 的情况也应当很容易理解。可以打开交互版本,将鼠标悬停在 token 上查看连接关系。

c4a attention 动画
这种高效 attention 设计带来了显著的 KV cache 节省。使用 bf16 KV cache 时,DeepSeek V4 在 1M 上下文下每个序列只有 9.62 GiB KV cache。相比之下,61 层 DeepSeek V3.2 风格 stack 的估算值为 83.9 GiB,DeepSeek V4 约小 8.7x。在实践中,我们对 indexer cache 使用 fp4,对 attention cache 使用 fp8,相比 bf16 估算值进一步将 KV cache 大小减少约 2x!
DeepSeek V3.2 与 DeepSeek V4 中每层 KV state 对比。
关于算术和数学解释的更多细节,请参见附录。
vLLM 对 DeepSeek V4 的实现
尽管结构上实现了节省,这种 attention 机制仍然具有内在复杂性;要在 vLLM 中高效实现这些节省,是一个包含多个实现挑战的系统问题:
- 与 DeepSeek V3.2 模型类似,attention kernel 在 prefill 阶段使用 bfloat16 KV cache,在 decode 阶段部分 token-wise 使用 fp8。
- 该模型混合使用
c4a和c128aattention,部分 attention 层则仅使用滑动窗口处理局部信息而不进行压缩。异构的 attention 类型让 KV cache 管理复杂得多。 - 在 batch 多个序列时,它们相对于 KV cache 压缩边界可能处于不同状态。
- 模型自带原生 fp4 MoE 权重,这需要在 vLLM 中进行特殊处理。
除 attention 机制本身外,还有若干其他更新,包括 Manifold-Constrained Hyper-Connections 这类架构变化,以及 MoE 模块的一些变化。本文不涵盖这些内容,因为它们属于更简单、也更容易适配的模型改动。
vLLM 从两个方面进行优化来应对这些挑战:内存管理和 kernel 效率。
保持 KV Cache 内存紧凑
vLLM 的 KV cache 内存分配器必须在 GPU 内存中紧密打包多种 KV state,同时仍要与 prefix caching、prefill/decode disaggregation、CUDA graphs 以及 vLLM 服务路径的其他部分协同工作。三个设计选择让这件事变得可控。
(1) 单一逻辑块大小
不同层的压缩比例不同(c4a 为 1/4,c128a 为 1/128,SWA 为 1/1)。一个显而易见的设计是围绕某个整数数量的 压缩后 entry 来设置每层的 block 大小。但这样每层都会有自己的 page layout,allocator 必须分别处理它们。
相反,我们为每个压缩层将逻辑 block 固定为 256 个原生 token 位置。这样,一个 c4a block 在物理上包含 256 / 4 = 64 个压缩 entry,一个 c128a block 包含 256 / 128 = 2 个。分配一个 block 始终意味着为某个请求的上下文保留接下来的 256 个原生位置,不管它属于哪一层。Slot mapping、scheduler accounting 和 prefix-hit detection 都可以使用同一个单位,而不需要基于 compress_ratio 分支处理。
(2) 将 compressor state 作为滑动窗口
每个 compressor 层还会为每个请求维护一个小的滚动 residual:C4 使用 8-token(重叠)的 partial state,C128 使用 128-token 的 partial state。一个自然的初始设计是把这个 residual 保存在每个请求的 side buffer 中。单独来看这可行,但一旦它需要与服务栈的其他部分交互,就会变得别扭。
使用 side buffer 时,prefix caching 需要在每个可缓存边界对滚动 state 做 snapshot,将其与 prefix hash 一起作为 key,并在命中时恢复。Disaggregated prefill 需要第二条传输路径,在把 KV block 从 prefill worker 发送到 decode worker 的同时发送 residual。每个需求单独来看都可管理,但合在一起会形成另一条需要跨特性维护的 state-management 路径。
vLLM 通过把 compressor state 当作 sliding-window KV 来避免这个问题。运行时 invariant 是相同的:每个请求固定大小,随 decode 推进而前移,窗口外 state 要么丢弃,要么通过 caching 处理。因此,我们将 compressor state 注册到 sliding-window KV cache spec 中,设置 sliding_window = coff * compress_ratio(C4 为 8,C128 为 128),并在同一个 hybrid KV cache manager 下将其放入 SWA 风格的 block。
这让多个服务特性可以复用同一抽象:
- Prefix caching 复用普通的 block 语义。cache hit 会落在 KV cache block 边界(上面所说的 256-position 单位),而该边界上的 compressor state 已经是正确的交接点。
- Disaggregated prefill 将 compressor state 视作 SWA state。只传输窗口内的 block,这在保持传输大小节省的同时,不引入单独的 residual 专用传输路径。
- CUDA graphs 和 MTP 遵循与 SWA 相同的集成模式,同时保留 compressor state 专属的 metadata 和实现细节。
(3) 统一 page size
以上两个选择仍然不够。C4 indexer block、c128a KV block 和 c4a compressor-state block 的 page size(每个 block 的字节数)仍然不同。如果每种 cache 都有自己的 block pool,我们就会遇到原本想消除的跨 pool 碎片问题。
好在每种 cache 的 page size 都是 block_size * compress_ratio * per_entry_size 的乘积,而这三个因子都在我们的控制范围内。如果仔细选择,不同 cache 可以收敛到少数几个 page-size bucket,每个 bucket 都可以由一个共享 block pool 支撑。
在我们的实现中,整个五路 cache stack 可放入 三种 page size。每个 pool 在加载时只需确定一次大小,分配时就是一次 bucket lookup。没有运行时重新划分,没有按 cache kind 分开的 accounting,也没有 cache kind 之间的碎片。
- 最大 bucket:
c4amain KV、SWA KV、c4acompressor state、c128acompressor state。 - 中等 bucket: C4 indexer KV、C4 indexer compressor state。
- 最小 bucket:
c128amain KV。
保持 GPU 忙碌
内存布局只是运行时故事的一半;另一半是让 GPU 计算保持饱和。
vLLM 集成了 FlashMLA 和 FlashInfer,它们提供优化后的 attention 和 MoE kernel。但这个模型需要许多小型、主要受内存带宽限制的 kernel。我们需要避免额外 launch 和 HBM 往返,否则会拖慢完整 decode 路径。
c4a decode 路径:带有 kernel fusion(彩色轮廓)和 multi-stream 分区(默认 stream = 蓝色带,indexer stream = 琥珀色带)的 operator graph。
(1) Kernel Fusion
我们部署了三类 fusion 来减少内存往返。在下图中,它们表现为围绕若干 operator 组的彩色轮廓。
- Compressor + RMSNorm + RoPE + cache insertion。 压缩之后,压缩后的 K 会立即经过 RMSNorm、RoPE,并插入到后续 attention 的 KV cache 中,目标可能是 main attention,也可能是 indexer。由于这些阶段几乎完全是 elementwise 操作,我们将它们融合到一个 kernel 中。我们为 indexer K cache 和 main-attention K cache 保留独立 kernel,使并行化策略仍能针对各自的 head dim 调优。总体上,相比未融合 baseline,我们看到约 ~1.4-3x 的加速。
- Inverse RoPE + fp8 quant。 main attention 之后,输出会经过 inverse RoPE,然后进入用于
o_loraprojection 的 fp8 batched matmul。融合这两步可以避免连续的 HBM 往返,并提高算术强度,相比未融合版本带来约 ~2-3x 加速。 - Fused Q norm + KV RoPE + K insert。 main attention 之前,我们需要为压缩路径和滑动窗口路径都进行 KV cache insertion。压缩路径已经由第一类 fusion 覆盖,因此剩下的是 query 和未压缩 SWA key 上的 elementwise 工作。我们用静态
warpIDdispatch 将这些工作横向融合到单个 kernel 中:每个 warp 独立处理一个 Q head 或一个 K head,因此不需要跨 warp 通信。相比朴素的未融合 kernel,这带来了 10-20x 的加速。
我们还复用了 DeepSeek V3.2 工作中的 fusion,包括 Q RoPE + quant + weight multiply,以及 attention 开始处 QK projection 之后 QK norm 的 horizontal fusion。
(2) Multi-stream
main attention 之前的操作高度可并行。它们可分为三部分:indexer computation、main-attention KV compression,以及 sliding-window token insertion。初始 projection 之后,这些分支几乎相互独立,因此我们在多个 CUDA stream 上重叠执行。这里也可以用另一种方式阅读同一张图:蓝色带表示默认 stream,琥珀色带表示 indexer stream。
- 对于没有 indexer 的
c128a层,我们将 main KV compression 与 SWA token insertion 并行运行。 - 对于
c4a层,我们在独立 stream 上运行完整的 indexer pipeline,同时与 main KV compression 和 SWA token insertion 并行(后两者彼此之间仍保持串行)。
通过这些重叠,在低 batch size 下,我们观察到 5-6% 的端到端延迟下降;这说明 decode 路径减少了 GPU 利用不足的时间,是一个有用信号。
此外,和其他模型一样,我们在 decode 路径上使用 CUDA graphs 来降低 launch overhead。
完整实现见 PR。
计划中的工作
我们正在积极推进以下优化,以进一步提升 DeepSeek V4 在 vLLM 上的性能:
- DeepGEMM MegaMoE kernel
- Paged prefill kernel
当前实现主要面向 NVIDIA GPU,包括 Hopper 和 Blackwell 架构。针对这些加速器的部署 recipes 可在我们的 recipe 网站找到。借助 vLLM 可扩展的 plugin system,硬件厂商可以直接为模型添加支持。例如,vllm-ascend 和 vllm-mlu 都独立支持 DeepSeek V4。
致谢
我们感谢 DeepSeek 团队开源 DeepSeek V4,也感谢 DeepSeek 管理团队对 vLLM 的信任与支持!该模型支持得益于 Inferact Inc. 的贡献,这家公司致力于将 vLLM 发展为全球 AI inference engine,并通过让推理更便宜、更快速来加速 AI 进展。
附录:DeepSeek V4 Attention 机制背后的数学
为什么 key 和 value 共享时需要 inverse RoPE
给定位置 的 query token,应用 RoPE 后的 query representation 为 ,其中 是旋转矩阵,其旋转角由位置 参数化。旋转矩阵的一些基本性质包括:
- 是正交矩阵,即
给定一组位于 的 key token,应用 RoPE 后的 key representation 分别为 ,,...,,...。
对于位置 的 value vector,我们通常不对它们应用 RoPE。value representation 只是 ,,...,,...。
attention 输出随后为(为简化起见,省略了一些细节,例如 scaling factor):
attention 输出的一个良好性质是它具有平移不变性。任何依赖位置的因子,即 和 ,都只依赖 query 与 key 之间的相对位置。这意味着如果我们将 query 和 key 同时平移相同距离,attention 输出保持不变。
如果共享 key 和 value vector,attention 输出将变为:
此时输出会通过旋转矩阵 直接携带绝对位置信息。这不是我们想要的。修正方法很简单:对 attention 输出应用 inverse RoPE 操作:
这样,输出只会通过旋转矩阵 携带相对位置信息,并重新具有平移不变性。
类似讨论也可见于 https://kexue.fm/archives/10862。
实现细节:精确的位置范围和因果性条件
处理压缩 KV cache 时需要小心。对于每个压缩 index ,我们先组合一组固定的局部原始 token,然后使用该压缩 token 的 anchor position 应用一次 RoPE,随后将这个压缩 token 存入 KV cache。
对于 c4a,第 个压缩 token 是位置范围 中 token 的加权和,其中 从 0 开始,负 index 被视为值为 0 的 token。应用 RoPE 时,该压缩 token 的位置是 。
对于 c128a,第 个压缩 token 是位置范围 中 token 的加权和,其中 从 0 开始。应用 RoPE 时,该压缩 token 的位置是 。
对于因果性,我们需要确保位置 的 query token 只 attend 到由位置范围 中 token 产生的信息。这意味着对于位置 的 query 和 KV cache 中第 个压缩 token,我们需要确保 (对于 c4a)或 (对于 c128a)。
实现细节:c4a 和 c128a 中 k 的精确值
在 DeepSeek V4 的 c4a attention 中, 的默认值为 512;在 c128a attention 中, 的默认值为 8192。(作为对比,在 DeepSeek V3.2 中, 的默认值为 2048。)
c128a attention 具有更高的压缩比例。在 100 万 token 上下文下,它最多拥有 8k 个压缩 token。8k token 对 attention 计算来说并不算多,因此我们可以直接对 c128a 压缩 token 使用 full attention。在实现上,我们仍可以将 c128a attention 表述为一个 sparse-attention 问题,其 top- 值为 8192。
实现细节:为什么需要短滑动窗口
使用 c128a 时,位置 的 query token 不能 attend 到 KV cache 中任何压缩 token,因为第一个压缩 token 包含来自位置 到 的信息,但由于因果性,query token 不能 attend 到位置 之后的信息。有了短滑动窗口,query token 可以 attend 到位置范围 中的未压缩 token,因此仍能访问局部信息。
8.7x 节省估算背后的算术
对于 1M 上下文的序列:
使用 bf16 KV cache 的 DeepSeek V3.2:
- 每个 token 每层的 MLA cache: 字节。
- 每个 token 每层的 indexer cache: 字节。
- 每个 token 每层的总 cached state: 字节。
- 在 1,048,576 个 token 下:每层 GiB。
- 61 层总计:约 GiB。
61 层、使用 bf16 KV cache 的 DeepSeek V4:
- 每个 shared-KV cached entry 存储 字节。
- 每个
c4aindexer cached entry 存储 字节。 c4a层:shared-KV cache 字节,加上 indexer cache 字节,总计约 MiB。c128a层: MiB。- 30 个
c4a层和 31 个c128a层合计:约 GiB。
上一篇 vLLM 中 FP8 KV-Cache 和 Attention Quantization 的现状下一篇 使用 vLLM 运行基于 NVIDIA Nemotron 3 Nano Omni 的高效多模态 Agentic AI
相关文章
使用 vLLM 运行基于 NVIDIA Nemotron 3 Nano Omni 的高效多模态 Agentic AI 2026 年 4 月 28 日·7 分钟阅读 我们很高兴在 vLLM 上支持新发布的 NVIDIA Nemotron 3 Nano Omni 模型。### 宣布 vLLM 支持 Gemma 4:逐字节看,能力最强的开放模型 2026 年 4 月 2 日·3 分钟阅读 随着 Gemma 4 发布,vLLM 立即支持 Google 最先进的开放模型系列,覆盖多种硬件 backend,并首次在 Google TPU 上提供 Day 0 支持,...### 使用 vLLM 运行高效且准确的 Multi-Agent AI:NVIDIA Nemotron 3 Super 2026 年 3 月 11 日·5 分钟阅读 我们很高兴在 vLLM 上支持新发布的 NVIDIA Nemotron 3 Super 模型。
- 在 vLLM 上运行 DeepSeek V4
- DeepSeek-V4-Pro
- DeepSeek-V4-Flash
- DeepSeek V4 的 Attention 机制解释
- vLLM 对 DeepSeek V4 的实现
- 保持 KV Cache 内存紧凑
- (1) 单一逻辑块大小
- (2) 将 compressor state 作为滑动窗口
- (3) 统一 page size
- 保持 GPU 忙碌
- (1) Kernel Fusion
- (2) Multi-stream
- 计划中的工作
- 致谢
- 附录:DeepSeek V4 Attention 机制背后的数学
- 为什么 key 和 value 共享时需要 inverse RoPE
- 实现细节:精确的位置范围和因果性条件
- 实现细节:c4a 和 c128a 中 k 的精确值
- 实现细节:为什么需要短滑动窗口
- 8.7x 节省估算背后的算术
目录
© 2026 vLLM·保留所有权利。