一、官方部署 Recipe:先看硬件门槛
vLLM 团队这次同时放出 V4-Pro(1.6T)和 V4-Flash(284B)两个型号的部署 Recipe 先
说结论:门槛劝退
V4-Flash 单节点最简部署(B200/B300 各 4 卡):
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
V4-Pro 版本一样的形态,区别只是 --data-parallel-size 8,跑在 8×B200 或 8×B300 上
镜像
deepseekv4-cu130(129也可以),需要 CUDA 13.0;KV cache 直接 FP8,
block-size 256是硬规定,下面会解释为什么;--attention_config.use_fp4_indexer_cache=True是 V4 独有的 FP4 indexer cache 开关;tokenizer / tool call / reasoning parser 全是
deepseek_v4专属新解析器,老的 V3 那套解析器不通用
Recipe 里更狠的是 H200 单节点 PD 解耦部署:4 张 GPU 跑 prefill、4 张跑 decode,中间走 MooncakeConnector + RDMA 传 KV,外面再挂一个 vllm-router 做轮询:
pip install vllm-routervllm-router --policy round_robin \
--vllm-pd-disaggregation \
--prefill http://localhost:8000 \
--decode http://localhost:8001 \
--host 127.0.0.1 \
--port 30000 \
--intra-node-data-parallel-size 4 \
--kv-connector mooncake
Flash 还有三档推理强度,对应技术报告里的 Non-think / Think High / Think Max:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
model = "deepseek-ai/DeepSeek-V4-Flash"
messages = [{"role": "user", "content": "What is 17*19? Return only the final integer."}]# Think Max 档要求 max-model-len >= 393216
resp = client.chat.completions.create(
model=model,
messages=messages,
extra_body={
"chat_template_kwargs": {
"thinking": True,
"reasoning_effort": "max",
},
},
)
官方推荐采样:temperature = 1.0, top_p = 1.0。
Think Max 档要求 --max-model-len >= 393216(384K tokens),低于这个数会被截断
二、注意力机制为什么这么麻烦
长上下文推理的两个老大难:
KV cache 显存爆炸 :标准 MHA / MQA 的 KV 随上下文线性增长,到 1M 直接撑爆。MLA 已经把这个问题压了一档,但 1M 还是顶
注意力计算昂贵 :即便有 DSA(DeepSeek Sparse Attention),1M 上的注意力计算依然是大头
V4 的解法是在 MLA 之上又叠了 4 层结构:
Key 和 Value 共享 :直接 2× 显存节省,但为了保持 RoPE 的相对位置正确性,要在 attention 输出端补一个 inverse RoPE ;
跨 token 压缩 KV (4× 到 128× 节省),分两种:
**
c4a**:压缩比约 1/4,每个压缩 token 是 8 个原始 token 的加权和,stride = 4;**
c128a**:压缩比约 1/128,每个压缩 token 是 128 个原始 token 的加权和,stride = 128;
DSA 稀疏选择 :即使压缩到 1/4,1M 上下文也还有 25 万压缩 token,再用 DSA 选 top-k 参与计算(V4-Flash 在 c4a 上 k=512,c128a 上 k=8192);
保留局部性 :滑动窗口 SWA,window size = 128 跑在未压缩的原始 token 上,让 query 在到达压缩边界之前还能看到本地信息
CSA 的结构是先压缩再稀疏,每 m 个 token 的 KV 被压成一条,再走 DSA 选 top-k:
HCA 的压缩比更激进,m'=128,走稠密注意力:
vLLM 博客给了一段 c4a 处理 13 个 token 的动画,把上面四步的连锁关系展示得很清楚:
c4a 注意力机制动画:展示压缩→稀疏选择→局部窗口的完整流程
最后效果:bf16 KV Cache 在 1M 上下文下每序列 9.62 GiB,比 V3.2 那个 61 层堆叠估算的 83.9 GiB 小 8.7×;indexer 用 fp4、attention 用 fp8 之后再砍一半,比 bf16 估算再 2× 节省
下图是 vLLM 官方对 V3.2 和 V4 每层 KV 状态的直观对比:
V3.2 与 V4 逐层 KV 状态对比,V4 的压缩效果一目了然
❝ 引用 vLLM 博客原文:DeepSeek V4 only has 9.62 GiB KV cache per sequence at 1M context. That is about 8.7x smaller than the 83.9 GiB estimate for a 61-layer DeepSeek V3.2-style stack.
但是省下来的显存不是白省的——这套混合注意力让"KV cache 管理"这件事的复杂度爆炸式增长:
同一个 attention kernel,prefill 用 bf16 KV cache,decode 用部分 token-wise fp8;
模型里同时存在 c4a、c128a、纯 SWA 三种层,KV cache 管理要兼容三种压缩比;
同一个 batch 里多条 sequence,相对于压缩边界的状态可能不同;
模型权重原生就是 fp4 MoE,需要 vLLM 专门处理
vLLM 的优化分两条线:显存管理和内核效率
3.1 显存:把 KV Cache 压紧
(1) 统一逻辑块大小为 256 个原生 token
不同层压缩比不同(c4a 是 1/4、c128a 是 1/128、SWA 是 1/1)。一个朴素思路是按"压缩后 entry 数"凑整,但那样每层 page layout 都不一样,allocator 要分别处理
vLLM 的选择是:把逻辑块在所有压缩层统一钉死在 256 个原生 token 位置。这样 c4a 块物理上装 256/4 = 64 条压缩 entry,c128a 块装 256/128 = 2 条。分配一个块永远意味着预留下一个 256 原生位置,slot mapping、调度器记账、prefix-hit 检测全都不用 branch on compress_ratio
这就是为什么 Recipe 里 --block-size 256 是硬规定
(2) 把压缩器残差状态当成 SWA
每个压缩器层每个请求维护一个滚动残差:c4a 是 8 个 token(带 overlap)的部分状态,c128a 是 128 个 token。直觉是放"每请求侧 buffer"里,但这样会让 prefix caching 要在每个可缓存边界做快照、PD 解耦要新增一条残差传输路径——又给系统多堆一层状态
vLLM 的做法是把压缩器状态注册成 sliding-window KV cache,sliding_window = coff × compress_ratio(c4 是 8、c128 是 128)。一来 prefix caching 直接复用块语义;二来 PD 解耦把残差当 SWA 传,省下来的传输大小不变;三来 CUDA graphs / MTP 跟 SWA 走同一条集成路径
(3) Page size 三桶归一
c4 indexer 块、c128a KV 块、c4a 压缩器状态块还是不一样大。如果每种都自己一个 block pool,跨池碎片化又回来了
vLLM 注意到 page size = block_size × compress_ratio × per_entry_size,三个因子都可控。仔细挑参数之后整个五路缓存栈被压成 3 个 page-size 桶,每个桶一个 block pool:
最大桶 :c4a 主 KV、SWA KV、c4a 压缩器状态、c128a 压缩器状态;
中桶 :c4 indexer KV、c4 indexer 压缩器状态;
最小桶 :c128a 主 KV
加载时一次性 size 好,运行时只是桶查找——零运行时重分区、零按种类记账、零跨缓存碎片
下图展示了 V4 异构 KV Cache 的整体布局,State Cache 和 KV Cache 两级结构如何共存:
异构 KV Cache 两级布局:State Cache 存 SWA 与尾部未压缩 token,KV Cache 按块存 CSA/HCA 压缩结果 3.2 内核:把 GPU 喂饱
显存安排好之后,问题变成"这个模型 decode 路径上有一堆小的、内存受限的内核,启动开销和 HBM 来回都要省"
vLLM 的回答是内核融合 + 多流并发
下图是 c4a decode 路径的完整算子图,彩色轮廓标出了三处融合,蓝色带是 default stream,琥珀色带是 indexer stream:
c4a decode 路径:内核融合(彩色轮廓)与多流分区(蓝色=default stream,琥珀色=indexer stream)
三个融合:
Compressor + RMSNorm + RoPE + cache 写入 :压缩之后 K 立刻走 RMSNorm、RoPE、写入下一层 attention 的 KV cache(主 attention 或者 indexer),全是 elementwise,融成一个 kernel。indexer K cache 和主 attention K cache 仍保留各自的 kernel 以便对每个 head dim 单独调并行策略。 1.4-3× 加速
Inverse RoPE + fp8 quant :主 attention 输出之后过 inverse RoPE,再进
o_lora投影的 fp8 batched matmul。两步融了之后省一次 HBM 来回,算术强度抬上去。 2-3× 加速Fused Q norm + KV RoPE + K insert :主 attention 之前的 query 和未压缩 SWA key 那段 elementwise 工作,做 horizontal fusion,按 warpID 静态分派到 Q head 或 K head,不用跨 warp 通信。 10-20× 加速
多流并发:
主 attention 之前可拆成三件事——indexer 计算、主 attention KV 压缩、SWA token 插入。投影之后这三条几乎独立,所以走多 CUDA stream 并发
c128a 层 没有 indexer,主 KV 压缩跟 SWA token 插入并发;
c4a 层 完整 indexer 流水线在自己的 stream 上跟主 KV 压缩、SWA 插入并发(后两者之间还是串行)
实测低 batch 下端到端延迟降低 5-6%。叠加 CUDA Graph 把 launch 开销也压下去
完整实现是 vLLM 这个 PR:#40760
vLLM 团队也写了下一步要做的优化方向:DeepGEMM MegaMoE 内核、Paged prefill 内核。当前实现主要面向 NVIDIA Hopper 和 Blackwell。
靠着 vLLM 的插件系统,vllm-ascend(华为昇腾)和 vllm-mlu(寒武纪)已经独立支持上 V4
四、总结
回到标题——为什么 V4 本地部署如此困难?
不是 vLLM 不给力,是模型本身把"如何用最少的显存装下 1M 上下文"这件事做到了极致:MLA 之上叠 K/V 共享 + 双层 KV 压缩(c4a + c128a)+ DSA + SWA,再叠 fp4 indexer + fp8 attention cache。每多一层都是一次工程债,所有的债都得 vLLM 这一侧的 KV cache allocator、kernel fusion、多流调度还
最后落到普通用户能感知的就是 Recipe 第一行:起步 4 张 B200/B300,单节点最简部署,pip 装个 vllm-router 还得自己起两个 docker
我的判断:
个人用户、消费级显卡、本地离线跑 V4 这件事,短期内别想了;
真正能吃到 V4 红利的是有 H200/B200 集群、又需要 1M 上下文 + agent 工作流的团队,比如做长文档分析、多轮 agent 任务的 infra 团队;
想理解 V4 推理实现的细节,vLLM 这篇博客 + Recipe + PR 是目前最干净的官方解释,比对着技术报告读更直观
制作不易,如果这篇文章觉得对你有用,可否点个关注。给我个三连击:点赞、转发和在看。若可以再给我加个,谢谢你看我的文章,我们下篇再见!
热门跟贴