DeepSeek-V4-Flash × 昇腾910B PD分离深度分析:模型切分、权重分布与显存占用全揭秘
DeepSeek-V4-Flash × 昇腾910B PD分离深度分析:模型切分、权重分布与显存占用全揭秘
摘要:本文基于华为昇腾Atlas 800I A2(910B 64GB)×8台服务器,使用vLLM-Ascend推理引擎 + Mooncake KV Cache传输框架,对DeepSeek-V4-Flash(284B参数/13B激活/MoE)进行 Prefill-Decode(PD)分离部署的模型切分机制进行全方位深度剖析。不从"怎么部署"讲起,而是从"模型在64张卡上到底是如何被切开的"这一核心问题出发,逐层拆解每张卡上究竟存放了哪些权重参数、每部分占用多少显存、P节点和D节点的显存分配为何截然不同。
目录
- DeepSeek-V4-Flash 模型架构速览
- 硬件拓扑与并行策略总览
- PD分离架构:P和D节点的本质差异
- EP专家并行:模型切分的核心引擎
- 逐层权重切分:每张卡上到底有什么
- 显存占用精确计算:从权重到KV Cache
- Mooncake KV Cache传输:P到D的关键桥梁
- 总结:PD分离为什么这样切
1. DeepSeek-V4-Flash 模型架构速览
1.1 为什么先讲模型架构
理解切分方案,必须先理解被切分的东西长什么样。DeepSeek-V4-Flash 的 MoE 架构决定了它不适合用传统的张量并行(TP)来切——因为278B参数是专家权重,它们天然适合按"专家"这个维度来切分。
1.2 模型核心参数
| 维度 | 数值 | 对切分的影响 |
|---|---|---|
| 总参数量 | 284B | 决定了总权重体积 ~280GB(W8A8) |
| 激活参数量 | ~13B/token | 每token仅激活6/256路由专家 |
| 层数 | 43层 | 全部为MoE层,切分粒度是"层×专家" |
| 隐藏维度(d_model) | 4096 | 决定每层矩阵的形状 |
| FFN中间维度(d_ff) | 2048 | SwiGLU,决定每个专家的参数量 |
| 注意力机制 | MLA(64 Q heads / 1 KV latent) | KV Cache仅~44KB/token |
| MoE专家数 | 256路由 + 1共享/层 | 这是切分的核心维度 |
| 每token激活专家 | Top-6路由 + 1共享 | 决定单次推理的通信量 |
| 残差连接 | mHC(hc_mult=4) | 替代传统残差 |
| 量化方案 | W8A8(int8权重 + int8激活) | 1参数 ≈ 1字节 |
1.3 一个MoE层的内部结构
在深入切分之前,先看一层Transformer里究竟有哪些权重参数。DeepSeek-V4-Flash 的每一层包含以下模块:
第N层 Transformer Block 完整结构:
│
├── [1] mHC 入口投影(4×4096 → 4096) ← hc_mult=4 副本加权融合
│
├── [2] MLA 自注意力(Multi-head Latent Attention)
│ ├── Q投影:wq_a(4096×1024) → q_norm → wq_b(1024×64×512)
│ ├── KV投影:wkv_a(4096×512) → kv_norm → wkv_b(512×512)
│ └── O投影:wo_a(4096×8×512) → wo_b(8×512×4096)
│
├── [3] RMSNorm ×2(pre-attn + pre-ffn) ← 极小参数量
│
├── [4] Router Gate(4096 → 256) ← 决定token分配给哪些专家
│
├── [5] Shared Expert FFN(始终激活)
│ └── gate_proj(4096×2048) + up_proj(4096×2048) + down_proj(2048×4096)
│
└── [6] Routed Expert FFN ×256(按需激活top-6)
每个专家: gate_proj(4096×2048) + up_proj(4096×2048) + down_proj(2048×4096)
关键的参数分配规律:上面6类模块中,[1][2][3][4][5] 合起来约 5.9GB/43层,它们在每张卡上都需要完整副本。真正的"大户"[6] 占了约278GB,它才是被EP切分的对象。
1.4 每层的参数量精确计算
MLA 注意力参数(每层):
| 矩阵 | 形状 | 参数量 | 说明 |
|---|---|---|---|
| wq_a | 4096 × 1024 | 4,194,304 | Q低秩投影A |
| q_norm | 1024 | 1,024 | Q LayerNorm |
| wq_b | 1024 × (64×512) | 33,554,432 | Q低秩投影B, 64头 |
| wkv_a | 4096 × 512 | 2,097,152 | KV压缩投影 |
| kv_norm | 512 | 512 | KV LayerNorm |
| wkv_b | 512 × 512 | 262,144 | KV解压缩 |
| wo_a | 4096 × (8×512) | 16,777,216 | O投影A, 8组 |
| wo_b | (8×512) × 4096 | 16,777,216 | O投影B |
| MLA合计 | 73,664,000 | ~0.074 GB/层 |
MoE 专家参数(每层、每个专家):
SwiGLU FFN 包含3个矩阵:
gate_proj: 4096 × 2048 = 8,388,608
up_proj: 4096 × 2048 = 8,388,608
down_proj: 2048 × 4096 = 8,388,608
─────────────────────────────────
每个专家: 25,165,824 params ≈ 25.17M
全43层合计(W8A8量化后,1参数≈1字节):
| 类别 | 参数量 | W8A8权重体积 | 是否可切分 |
|---|---|---|---|
| 路由专家×256×43层 | 277.0B | 277.0 GB | ✅ EP切分 |
| 共享专家×1×43层 | 1.08B | 1.08 GB | ❌ 完整副本 |
| MLA 注意力×43层 | 3.17B | 3.17 GB | ❌ 完整副本 |
| Embedding + LM Head | 1.06B | 1.06 GB | ❌ 完整副本 |
| Router Gates + Norms + mHC | ~0.2B | ~0.2 GB | ❌ 完整副本 |
| 总计 | ~283.5B | ~283.5 GB | — |
表中可以切分的权重仅277GB(专家),不可切分的约5.9GB。这个5.9GB决定了每张卡有一个不可压缩的"固定开销"——无论EP组多大,每卡都得装这5.9GB。
2. 硬件拓扑与并行策略总览
2.1 集群配置
集群总规模: 8台 Atlas 800I A2 (910B 64GB) × 8卡 = 64卡
┌──────────────────────┐ ┌──────────────────────┐
│ P 节点组(4台) │ │ D 节点组(4台) │
│ 每台8卡 = 32卡 │ │ 每台8卡 = 32卡 │
│ │ │ │
│ dp-size = 8 │ │ dp-size = 32 │
│ tp-size = 1 │ │ tp-size = 1 │
│ │ │ │
│ 4个独立EP组(每组8卡) │ │ 1个EP组(32卡) │
│ 每卡32个路由专家 │ │ 每卡8个路由专家 │
└──────────────────────┘ └──────────────────────┘
2.2 并行策略对比
这张表是理解后续所有显存计算的基础:
| 维度 | P节点(Prefill) | D节点(Decode) | 为什么不同? |
|---|---|---|---|
| 总卡数 | 32 | 32 | — |
| dp-size | 8 | 32 | P需要多个prefill实例并行 |
| tp-size | 1 | 1 | 不使用张量并行 |
| EP组数 | 4组(32÷8) | 1组(32÷32) | P每个EP组是独立服务 |
| 每EP组卡数 | 8 | 32 | — |
| 每卡专家数 | 32个 | 8个 | 256÷8=32, 256÷32=8 |
| 每卡权重 | ~40.5 GB | ~14.6 GB | 差了2.78倍 |
| 可用KV空间 | ~17 GB | ~43 GB | D节点KV空间是P的2.5倍 |
2.3 为什么P用dp=8而D用dp=32
这是整篇分析的核心设计决策。背后的权衡非常精妙:
P节点(dp=8):用显存"买"算力并行度
- dp-size=8 意味着每个EP组只有8张卡,形成4个独立的Prefill实例
- 4个实例可以并行接收和处理来自不同用户的prefill请求
- 代价是每卡要放32个专家(256÷8=32),权重大(~40.5GB)
- 但prefill是计算密集型,KV Cache只是瞬态的(算完就传给D),不需要很大KV空间
- 所以P节点"有余量"承受更高权重
D节点(dp=32):用算力并行度"换"显存
- dp-size=32 意味着所有32张D卡组成一个EP组,仅1个服务实例
- 代价是prefill并发能力差(就1个实例)
- 但decode是访存密集型,瓶颈在KV Cache的读写而非计算
- 每卡仅8个专家(256÷32=8),权重小(~14.6GB)
- 释放出~43GB给KV Cache,支撑30个并发序列的超长上下文解码
一句话总结:P节点用显存换计算并行度(多EP副本),D节点用计算并行度换KV Cache空间(大EP组减专家)。
3. PD分离架构:P和D节点的本质差异
3.1 为什么要PD分离
传统混部模式下,同一张卡既要处理prefill(计算密集、大batch)又要处理decode(访存密集、小batch),两阶段的资源需求矛盾不可调和:
- Prefill阶段:需要一次处理全部输入token(可能数千个),计算量大,需要高算力
- Decode阶段:逐token自回归生成,每次只算1个token,但需要频繁读写KV Cache,是纯访存密集型
PD分离将两个阶段分配到不同节点,让P节点专注计算、D节点专注KV Cache管理。
3.2 请求生命周期
Client Request
│
▼
Proxy(路由层)
│
▼
┌─────────┐ Mooncake ┌─────────┐
│ P 节点 │ ════════════▶ │ D 节点 │
│ Prefill │ KV Cache传输 │ Decode │
└─────────┘ └─────────┘
│ │
│ ① 接收prompt │ ③ 接收KV Cache
│ ② 并行处理全部输入token │ ④ 逐token自回归生成
│ ②' 生成完整KV Cache │ ⑤ 流式返回结果
│ │
3.3 P和D节点的根本差异
理解下面这个对比,才能理解为什么同样一张64GB的卡,P和D的显存分配思路完全不同:
| P节点(Prefill) | D节点(Decode) | |
|---|---|---|
| 本质特征 | 计算密集型 | 访存密集型 |
| 单次处理token数 | 数千(大批量) | 1(逐token) |
| KV Cache角色 | 临时产物,立即传输 | 长期驻留,频繁读写 |
| KV Cache生命周期 | Prefill期间暂存,完成后推送 | 整个decoding过程持续占用 |
| 需要大KV空间? | 不需要(瞬态) | 非常需要(长驻) |
| 需要并行度? | 需要(多prefill实例) | 不太需要(纯访存,多实例反而浪费) |
| 权重大小影响 | 可容忍较高权重 | 必须是低权重(更多空间给KV) |
| DP选择逻辑 | dp较小 → 多EP实例 | dp较大 → 少专家/卡 → 多KV空间 |
4. EP专家并行:模型切分的核心引擎
4.1 什么是EP(Expert Parallelism)
EP(专家并行)是DeepSeek-V4-Flash切分的核心策略。它的基本原理非常简单:
- 将256个路由专家均匀分配给EP组内的每张卡
- 每张卡持有部分专家的权重参数
- 非专家权重(Attention、Embedding、共享专家等)在每张卡上保留完整副本
- 当一个token需要计算时,先在本卡算完Attention和共享专家,然后通过AllToAll通信把hidden state发到持有目标专家的卡上计算
4.2 EP切分的数学描述
设EP组有N张卡,256个专家编号为0~255:
Card 0: 持有 Expert[0, 1, 2, ..., 256/N - 1]
Card 1: 持有 Expert[256/N, 256/N+1, ..., 2×256/N - 1]
...
Card k: 持有 Expert[k×256/N, ..., (k+1)×256/N - 1]
在本部署中:
- P节点(dp=8):N=8,每卡持有 256/8 = 32个专家
- D节点(dp=32):N=32,每卡持有 256/32 = 8个专家
4.3 单Token推理时的EP完整流程
以P节点(8卡EP组)为例,一个token经过一层MoE Layer的完整流程:
┌─────────────────────────────────────────────────────────────┐
│ 第N层 EP推理流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Step 1: 每张卡独立计算(无通信) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ • mHC入口融合(4副本→1) │ │
│ │ • MLA Attention(Q/K/V/O) │ │
│ │ • RMSNorm │ │
│ │ • Shared Expert FFN(gate→up→down) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Step 2: Router Gate 评分(无通信) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 输入: hidden_state [4096] │ │
│ │ Router: 4096 → 256 → Softmax │ │
│ │ 选出 Top-6 专家的索引和权重 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Step 3: AllToAll 分发(有通信) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 根据Top-6专家所在的卡,将hidden_state拆分发送: │ │
│ │ │ │
│ │ Card 0 上的Token → Expert 10(Card 1) + Expert 45(Card 1)│
│ │ + Expert 100(Card 3) + Expert 200(Card 6)│
│ │ + Expert 230(Card 7) + Expert 250(Card 7)│
│ │ │ │
│ │ → Card 0 发送6份数据到 Card 1,1,3,6,7,7 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Step 4: 目标卡计算Expert FFN(独立并行) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Card 1 计算 Expert 10 和 Expert 45 的 FFN │ │
│ │ Card 3 计算 Expert 100 的 FFN │ │
│ │ Card 6 计算 Expert 200 的 FFN │ │
│ │ Card 7 计算 Expert 230 和 Expert 250 的 FFN │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Step 5: AllToAll 聚合(有通信) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 各卡将专家输出 × Router评分权重后发回原卡 │ │
│ │ Card 0 收到6份专家输出,加权求和 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Step 6: mHC出口融合(无通信) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 将专家聚合输出 + 入口hidden state 通过mHC融合为4副本 │ │
│ │ 进入下一层 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
4.4 P和D的EP差异可视化
P节点 EP组 = 8卡 D节点 EP组 = 32卡
┌────────────────────────────┐ ┌──────────────────────────────────────┐
│ Card 0: Expert 0 ~ 31 │ │ Card 0: Expert 0 ~ 7 │
│ Card 1: Expert 32 ~ 63 │ │ Card 1: Expert 8 ~ 15 │
│ Card 2: Expert 64 ~ 95 │ │ Card 2: Expert 16 ~ 23 │
│ Card 3: Expert 96 ~ 127 │ │ Card 3: Expert 24 ~ 31 │
│ Card 4: Expert 128 ~ 159 │ │ Card 4: Expert 32 ~ 39 │
│ Card 5: Expert 160 ~ 191 │ │ ... │
│ Card 6: Expert 192 ~ 223 │ │ Card 30: Expert 240 ~ 247 │
│ Card 7: Expert 224 ~ 255 │ │ Card 31: Expert 248 ~ 255 │
│ │ │ │
│ 每卡专家: 32个 │ │ 每卡专家: 8个 │
│ 这批权重: ~34.7 GB │ │ 这批权重: ~8.7 GB │
│ │ │ │
│ 4个独立的这样的EP组 │ │ 只有这1个EP组 │
└────────────────────────────┘ └──────────────────────────────────────┘
4.5 为什么不用TP(张量并行)
TP(Tensor Parallelism)将单个矩阵按列或行切分到多张卡上,每张卡进行一次部分计算后AllReduce。但在这个场景下TP被刻意避免了(tp=1):
| 对比维度 | TP(假设tp=2) | EP(本方案) |
|---|---|---|
| 切分对象 | 每个矩阵(Attention/FFN/专家) | 仅专家维度 |
| 非专家权重复制 | 每卡一半(~3GB) | 每卡完整(~5.9GB) |
| 通信频率 | 每层多次AllReduce | 每层2次AllToAll(仅MoE) |
| 通信数据量 | 小但频繁 | 较大但仅MoE层 |
| 单机可行? | 可以(但tf=2减半作用有限) | 需要足够多卡均分256个专家 |
| 适配MoE? | 一般(每次都同步) | 天然契合 |
对于256个专家的MoE模型,EP比TP自然得多——专家本来就是独立模块,天然适合按专家维度切分。
5. 逐层权重切分:每张卡上到底有什么
这是本文最核心的一节。我们逐层、逐模块地分析:每一张910B卡(64GB)上,到底存放了哪些权重参数。
5.1 权重分类总览
在EP切分策略下,DeepSeek-V4-Flash的权重被分为两大类:
DeepSeek-V4-Flash 权重(W8A8, ~283.5GB)
│
┌───────────────────┴───────────────────┐
│ │
┌───────▼──────────┐ ┌─────────────▼──────────────┐
│ 【I类:可切分】 │ │ 【II类:不可切分】 │
│ EP均分到每张卡 │ │ 每张卡完整复制 │
│ │ │ │
│ 路由专家×256 │ │ Token Embedding │
│ ×43层 │ │ LM Head │
│ ≈ 277.0 GB │ │ MLA Attention ×43层 │
│ │ │ Shared Expert ×43层 │
│ │ │ Router Gates ×43层 │
│ │ │ RMSNorm ×86个 │
│ │ │ mHC 超连接参数 │
│ │ │ ≈ 5.9 GB │
└───────────────────┘ └─────────────────────────────┘
5.2 II类权重(不可切分)的详细拆解
这部分约5.9GB,每张卡都有完全相同的副本。无论P节点还是D节点,无论EP组多大,这部分都是固定的"入场费"。
5.2.1 Token Embedding(嵌入层)
形状: vocab_size × d_model = 129,280 × 4096
参数量: 129,280 × 4096 = 529,530,880 ≈ 529.5M
W8A8体积: 529.5M × 1字节 = 0.53 GB
存放位置: 每张卡都有完整副本
作用: 将token ID映射为4096维向量
DeepSeek-V4的vocab_size为129,280,这是其自定义Tokenizer的大小。
5.2.2 LM Head(输出投影层)
形状: d_model × vocab_size = 4096 × 129,280
参数量: 4096 × 129,280 = 529,530,880 ≈ 529.5M
W8A8体积: 0.53 GB
存放位置: 每张卡都有完整副本
注: 通常与Token Embedding共享权重(weight tying),实际可能不额外占用
5.2.3 MLA Attention × 43层
这是最复杂的部分。MLA(Multi-head Latent Attention)通过低秩分解大幅压缩了注意力参数和KV Cache。
Q投影(每层):
wq_a: 4096 × 1024 = 4,194,304 params
q_norm: 1024 = 1,024 params
wq_b: 1024 × (64×512) = 33,554,432 params
└─ 64 head × 512 dim = 32,768 (Q的每个head维度)
小计 Q: 37,749,760 params
KV压缩投影(每层):
wkv_a: 4096 × 512 = 2,097,152 params
kv_norm: 512 = 512 params
wkv_b: 512 × 512 = 262,144 params
小计 KV: 2,359,808 params
O投影(每层):
wo_a: 4096 × (8×512) = 16,777,216 params
└─ 8组 × 512维 = 4096 (输出压缩到4096)
wo_b: (8×512) × 4096 = 16,777,216 params
小计 O: 33,554,432 params
MLA单层合计:37.75M + 2.36M + 33.55M ≈ 73.66M params = 0.0737 GB
MLA 43层合计:43 × 0.0737 = 3.17 GB
5.2.4 Shared Expert FFN × 43层
每层有1个始终激活的共享专家:
gate_proj: 4096 × 2048 = 8,388,608
up_proj: 4096 × 2048 = 8,388,608
down_proj: 2048 × 4096 = 8,388,608
─────────────────────────────────
单层: 25,165,824 params = 0.0252 GB
43层: 43 × 0.0252 = 1.08 GB
5.2.5 Router Gate × 43层
每层: 4096 → 256 = 1,048,576 params = 0.001 GB
43层: 43 × 0.001 = 0.045 GB
Router Gate用于为256个路由专家打分并选出Top-6。
5.2.6 RMSNorm、mHC等其他参数
RMSNorm × 86 (43层×2个): 86 × 4096 = 352,256 params
mHC 参数 (hc_mult=4): ~100万params量级
其他: bias, scale 等
────────────────────────────
合计: ~0.05 GB
5.2.7 II类权重总汇总
| 子项 | 参数量 | W8A8体积 |
|---|---|---|
| Token Embedding | 529.5M | 0.53 GB |
| LM Head | 529.5M | 0.53 GB* |
| MLA Attention ×43 | 3,170M | 3.17 GB |
| Shared Expert ×43 | 1,082M | 1.08 GB |
| Router Gates ×43 | 45M | 0.05 GB |
| RMSNorm + mHC + 其他 | ~10M | ~0.01 GB |
| II类合计 | ~5,900M | ~5.9 GB |
*LM Head通常与Embedding共享,实际可能不重复计。但保守起见,本文单独统计。
5.3 I类权重(可切分)的EP均分计算
5.3.1 单个路由专家的参数量
SwiGLU FFN 三层矩阵:
gate_proj: 4096 × 2048 = 8,388,608
up_proj: 4096 × 2048 = 8,388,608
down_proj: 2048 × 4096 = 8,388,608
─────────────────────────────────
单个专家: 25,165,824 params ≈ 25.17M
W8A8体积: ~0.0252 GB
5.3.2 全部路由专家总权重
256专家 × 43层 × 25.17M = 277,071,310,848 params ≈ 277.07B
W8A8体积: 277.07 GB
5.3.3 P节点每卡的I类权重
EP组 = 8卡
每卡分摊: 277.07 GB ÷ 8 = 34.63 GB
具体分配(以Card k为例):
Card k 持有 Expert [k×32, k×32+1, ..., k×32+31] × 43层
即每层持有32个专家的完整FFN权重
Card 0: Expert 0 ~ 31 (34.63 GB)
Card 1: Expert 32 ~ 63 (34.63 GB)
Card 2: Expert 64 ~ 95 (34.63 GB)
...
Card 7: Expert 224 ~ 255 (34.63 GB)
5.3.4 D节点每卡的I类权重
EP组 = 32卡
每卡分摊: 277.07 GB ÷ 32 = 8.66 GB
具体分配(以Card k为例):
Card k 持有 Expert [k×8, k×8+1, ..., k×8+7] × 43层
即每层仅持有8个专家的完整FFN权重
Card 0: Expert 0 ~ 7 (8.66 GB)
Card 1: Expert 8 ~ 15 (8.66 GB)
Card 2: Expert 16 ~ 23 (8.66 GB)
...
Card 31: Expert 248 ~ 255 (8.66 GB)
5.4 最终每卡权重全景图
P节点每卡 (dp=8, 32专家/卡)
┌──────────────────────────────────────────────────────────┐
│ P节点每卡权重分布 (W8A8) │
├──────────────────────────────────────────────────────────┤
│ │
│ ██████████████████████████████████████████ 34.63 GB │
│ │ I类:EP切分的路由专家权重 │ │
│ │ Expert[i×32 ~ i×32+31] × 43层 │ │
│ │ 每个专家: gate + up + down │ │
│ ██████████████████████████████████████████ │
│ │
│ ██████ 5.90 GB │
│ │ II类:完整复制的非专家权重 │ │
│ │ │ │
│ │ ├── Token Embedding 0.53 GB │ │
│ │ ├── LM Head 0.53 GB │ │
│ │ ├── MLA Attention ×43 3.17 GB │ │
│ │ ├── Shared Expert ×43 1.08 GB │ │
│ │ ├── Router Gates ×43 0.05 GB │ │
│ │ └── Norms + mHC 0.01 GB │ │
│ ██████ │ │
│ │
│ ═══════════════════════════════════════ │
│ 总权重: 34.63 + 5.90 = 40.53 GB │
│ 64GB可用(gpu-mem-util=0.9): 57.6 GB │
│ 剩余给KV Cache + 激活 + 框架: 17.07 GB │
│ ═══════════════════════════════════════ │
└──────────────────────────────────────────────────────────┘
D节点每卡 (dp=32, 8专家/卡)
┌──────────────────────────────────────────────────────────┐
│ D节点每卡权重分布 (W8A8) │
├──────────────────────────────────────────────────────────┤
│ │
│ ██████████ 8.66 GB │
│ │ I类:EP切分的路由专家权重 │ │
│ │ Expert[i×8 ~ i×8+7] × 43层 │ │
│ ██████████ │
│ │
│ ██████ 5.90 GB(与P节点完全相同) │
│ │ II类:完整复制的非专家权重 │ │
│ ██████ │
│ │
│ ═══════════════════════════════════════ │
│ 总权重: 8.66 + 5.90 = 14.56 GB │
│ 64GB可用: 57.6 GB │
│ 剩余给KV Cache + 激活 + 框架: 43.04 GB │
│ ═══════════════════════════════════════ │
└──────────────────────────────────────────────────────────┘
5.5 P vs D 权重对比总结
| 权重类别 | P节点每卡 | D节点每卡 | P/D比值 | 切分方式 |
|---|---|---|---|---|
| 路由专家(I类) | 34.63 GB | 8.66 GB | 4:1 | EP按组均分 |
| Token Embedding | 0.53 GB | 0.53 GB | 1:1 | 完整复制 |
| LM Head | 0.53 GB | 0.53 GB | 1:1 | 完整复制 |
| MLA Attention ×43 | 3.17 GB | 3.17 GB | 1:1 | 完整复制 |
| Shared Expert ×43 | 1.08 GB | 1.08 GB | 1:1 | 完整复制 |
| Router Gate ×43 | 0.05 GB | 0.05 GB | 1:1 | 完整复制 |
| Norms + mHC | <0.02 GB | <0.02 GB | 1:1 | 完整复制 |
| 总权重 | 40.5 GB | 14.6 GB | 2.78:1 | — |
关键洞察:P/D节点的II类权重完全相同(都是5.9GB),唯一的区别来自I类(路由专家)的EP切分差异。P节点每卡32专家、D节点每卡8专家,造成权重差4倍,但加上固定的5.9GB后,总权重差约2.78倍。
6. 显存占用精确计算:从权重到KV Cache
6.1 KV Cache 大小的物理基础
与传统MHA不同,DeepSeek-V4-Flash的MLA和CSA/HCA将KV Cache压缩到了极致。
MLA KV压缩原理:
传统MHA的KV Cache = 2 × num_kv_heads × head_dim × num_layers,动辄数百KB/token。MLA将Key和Value压缩为一个512维潜在向量:
每层KV潜在向量: 512维 × 2字节(FP16) = 1 KB
加上可选的RoPE decoupled部分: ~512维 × 2字节 = 1 KB
──────────────────────────────────────────
每层: ~2 KB/token
43层: 43 × 2 KB = 86 KB/token (保守上界)
实际KV Cache(考虑CSA/HCA压缩):
DeepSeek 技术报告指出,在1M上下文下,V4-Flash的KV Cache仅为V3.2的7%。CSA(Compressed Sparse Attention)对长上下文进行分组稀疏采样,HCA(Heavily Compressed Attention)对远距离token进行重度压缩。实际有效KV远小于86KB/token。
保守估计: ~44 KB/token(取官方数据的中位估算)
乐观估计: ~22 KB/token(在长上下文场景下CSA/HCA充分压缩)
6.2 P节点显存预算分析
┌────────────────────────────────────────────────────────────┐
│ P节点每卡显存预算 (64GB × 0.9 = 57.6GB可用) │
├────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────┐ 40.5 GB │
│ │ 模型权重 │ │
│ │ ├── I类(EP路由专家 32个×43层) 34.63 GB │ │
│ │ └── II类(非专家完整复制) 5.90 GB │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ 0.2 GB │
│ │ Prefill 临时KV Cache │ │
│ │ max-num-batched-tokens = 4096 │ │
│ │ 4096 × 44KB ≈ 180 MB ≈ 0.2 GB │ │
│ │ ⚡ Prefill完成后立即推送给D,不长期占用 │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ 2.0 GB │
│ │ 激活值 / 中间张量 │ │
│ │ 大批量prefill(multi-token)的中间激活 │ │
│ │ hc_mult=4的mHC副本也额外消耗激活内存 │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ 1.5 GB │
│ │ 框架开销 (vLLM + CANN + Mooncake) │ │
│ │ 包含: runtime、通信buffer、MTP draft head │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ═══════════════════════════════════════════ │
│ 已占用: 40.5 + 0.2 + 2.0 + 1.5 = 44.2 GB │
│ 剩余: 57.6 - 44.2 = 13.4 GB 宽裕 │
│ ═══════════════════════════════════════════ │
│ │
└────────────────────────────────────────────────────────────┘
P节点为什么KV Cache不需要很大?
P节点的KV Cache是"瞬态"的——prefill计算完一个batch的所有token后,生成的KV Cache立即通过Mooncake推送给D节点,P节点随即释放KV空间。因此P节点的KV需求仅取决于单批次的最大token数(4096),而非所有并发请求的累积。
P节点KV Cache峰值 = max-num-batched-tokens × 每token KV大小
= 4096 × 44KB = 180MB ≈ 0.2GB
而D节点KV Cache = max-num-seqs × max-model-len × 每token KV大小
= 30 × 135000 × 44KB = 最大值可达数百GB
这就是为什么P节点"敢"放40.5GB的权重——它不需要为KV Cache预留太多空间。
6.3 D节点显存预算分析
┌────────────────────────────────────────────────────────────┐
│ D节点每卡显存预算 (64GB × 0.9 = 57.6GB可用) │
├────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────┐ 14.6 GB │
│ │ 模型权重 │ │
│ │ ├── I类(EP路由专家 8个×43层) 8.66 GB │ │
│ │ └── II类(非专家完整复制) 5.90 GB │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ ⬜ 可变 │
│ │ Decode KV Cache(长驻) │ │
│ │ │ │
│ │ 场景A: 30 seqs × 16K context │ 21.1 GB │
│ │ 30 × 16384 × 44KB = 21.1 GB │ │
│ │ │ │
│ │ 场景B: 30 seqs × 32K context │ 42.2 GB │
│ │ 30 × 32768 × 44KB = 42.2 GB │ │
│ │ │ │
│ │ 场景C: 30 seqs × 64K context │ 84.5 GB │
│ │ 超出单卡64GB, 需降低并发 │ │
│ │ │ │
│ │ 场景D: 15 seqs × 64K context │ 42.2 GB │
│ │ 减半并发后依然可行 │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ 2.0 GB │
│ │ 激活值 / 中间张量 │ │
│ │ 逐token decode, 激活远小于prefill │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ 2.0 GB │
│ │ 框架开销 (vLLM + CANN + Mooncake + MTP) │ │
│ │ D节点多了graph cache + recompute_scheduler │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ═══════════════════════════════════════════ │
│ 场景A: 14.6 + 21.1 + 2.0 + 2.0 = 39.7 GB 宽裕 │
│ 场景B: 14.6 + 42.2 + 2.0 + 2.0 = 60.8 GB 接近上限 │
│ 场景D: 14.6 + 42.2 + 2.0 + 2.0 = 60.8 GB 接近上限 │
│ ═══════════════════════════════════════════ │
│ │
└────────────────────────────────────────────────────────────┘
6.4 P vs D 显存占用对比表
| 显存组成 | P节点每卡 | D节点每卡 | P/D比 | 说明 |
|---|---|---|---|---|
| I类权重(路由专家) | 34.63 GB | 8.66 GB | 4.00× | EP组大小决定 |
| II类权重(非专家复制) | 5.90 GB | 5.90 GB | 1.00× | 完全相同 |
| 权重小计 | 40.53 GB | 14.56 GB | 2.78× | — |
| KV Cache | ~0.2 GB | 21~42 GB | 0.005× | P瞬态/D长驻 |
| 激活值 | ~2.0 GB | ~2.0 GB | 1.00× | — |
| 框架开销 | ~1.5 GB | ~2.0 GB | 0.75× | D多了graph等 |
| 总计(典型) | ~44.2 GB | ~39.7 GB | 1.11× | 场景A |
| 总计(长上下文) | ~44.2 GB | ~60.8 GB | 0.73× | 场景B |
| 64GB利用率 | 69% | 62%~95% | — | 场景A~B |
6.5 显存分配的深层逻辑
这张图揭示了PD分离最精妙的设计:
P节点 (dp=8): D节点 (dp=32):
┌──────────────────────┐ ┌──────────────────────┐
│ ████████████ 权重 63%│ │ ███ 权重 23% │
│ ░░ KV 0.3% │ │ ██████████ KV 66% │
│ ▒▒ 激活 3% │ │ ▒▒ 激活 3% │
│ ▓▓ 框架 2% │ │ ▓▓ 框架 3% │
│ □□ 剩余 21% │ │ □□ 剩余 5% │
└──────────────────────┘ └──────────────────────┘
P: 权重占比大 → 计算力优先(多prefill实例并行)
D: KV占比大 → 并发优先(多序列长上下文解码)
核心逻辑链:
- D节点dp-size=32 → 每卡仅8专家 → 权重仅14.6GB → 释放43GB给KV Cache
- KV Cache空间大 → 可支撑30个序列 × 32K长上下文
- P节点dp-size=8 → 4个独立prefill实例 → 高prefill吞吐
- P的KV Cache瞬态(~0.2GB)→ 权重可以大(~40.5GB)→ 更多prefill副本
7. Mooncake KV Cache传输:P到D的关键桥梁
7.1 传输在PD分离中的地位
前面的分析建立了一个前提:P节点计算完KV Cache后,要把它传给D节点。没有高效传输,PD分离就没有意义。
MooncakeHybridConnector 是vLLM-Ascend中实现PD分离KV传输的组件。它的核心能力:
- P节点作为
kv_producer,D节点作为kv_consumer - 优先使用 NPU Direct RDMA(零拷贝、~20GB/s有效带宽)
- 降级使用 TCP fallback
7.2 传输数据量估算
典型请求的KV传输量:
每token KV: ~44 KB(MLA压缩+CSA/HCA压缩后)
输入 8000 tokens: 8000 × 44KB = 352 MB
RoCE 200Gbps 网络,有效带宽 ~18 GB/s:
传输延迟: 352 MB ÷ 18 GB/s ≈ 20 ms
128K超长上下文prompt:
传输量: 128K × 44KB = 5.6 GB
传输延迟: ~310 ms
KV传输延迟直接影响TTFT(Time To First Token),是PD分离架构最关键的延迟指标。这也是为什么KV压缩(MLA+CSA/HCA)在PD分离中如此重要——它不仅节省显存,还减少传输量。
7.3 recompute_scheduler 兜底
当D节点KV Cache满载时(场景C),recompute_scheduler 将请求回退到P节点重新计算:
正常: Request → P(prefill) → Mooncake → D(decode) → Response
D满载: Request → P(prefill) → Mooncake → D(KV满)
│
回退到P ────────┘
│
P重新prefill + 直接在P上decode
(退化为混部模式)
8. 总结:PD分离为什么这样切
8.1 一张图理解整个切分逻辑
DeepSeek-V4-Flash W8A8 (~283.5 GB 权重)
│
│ 切分策略: EP(专家并行) + tp=1
│
├── I类可切分 (277GB) II类不可切分 (5.9GB)
│ ┌──────────────┐ ┌─────────────┐
│ │ 路由专家 ×256 │ │ Embedding │
│ │ gate+up+down │ │ MLA Attn │
│ │ ×43层 │ │ Shared Exp │
│ └──────┬───────┘ │ Router Gate │
│ │ │ Norms+mHC │
│ EP按组均分 └──────┬──────┘
│ │ │
│ ┌──────┴──────────┐ 每卡完整复制(无通信)
│ │ │
│ P: N=8 D: N=32
│ 每卡32专家 每卡8专家
│ 34.63 GB/卡 8.66 GB/卡
│
├─ 每卡权重 ──────────────────────
│ P: 34.63 + 5.9 = 40.5 GB
│ D: 8.66 + 5.9 = 14.6 GB
│
└─ 每卡显存分配 ────────────────────
P: 权重40.5 + KV 0.2 + 激活2.0 + 框架1.5 = 44.2 GB (69%)
D: 权重14.6 + KV 21~42 + 激活2.0 + 框架2.0 = 39.7~60.8 GB (62%~95%)
8.2 五个核心结论
1. EP是DeepSeek-V4-Flash切分的唯一正确姿势
256个专家天然适合按专家维度切分。tensor parallelism(TP=1被刻意避免)在这个场景下既增加了通信开销,又不能解决MoE专家分布不均的问题。
2. 每张卡有两类权重:EP切分的专家(I类)+ 完整复制的非专家(II类)
- I类(277GB)按EP组大小均分:P节点每卡34.63GB / D节点每卡8.66GB
- II类(5.9GB)每卡完整副本:Embedding + MLA Attention + Shared Expert + Router + Norms
3. P/D权重比2.78:1,但KV空间比1:2.5
这完美体现了PD分离的设计哲学——P用显存换计算并行度,D用计算并行度换KV Cache空间。
4. MLA+CSA/HCA的KV压缩是PD分离可行的物理前提
如果DeepSeek-V4-Flash使用传统MHA(每token需数百KB的KV),D节点就算是dp=32也远远不够。正是MLA将KV压缩到~44KB/token + CSA/HCA进一步压缩,才让D节点能承载30并发×32K上下文。
5. 64GB显存对V4-Flash是刚好够用的"甜蜜点"
- P节点:权重40.5GB + 开销~3.7GB = 44.2GB,占69%,余量13.4GB
- D节点(16K上下文):权重14.6GB + KV 21GB + 开销~4GB = 39.7GB,占62%,余量17.9GB
- D节点(32K上下文):60.8GB,占95%,接近极限,需要精细调参
8.3 dp-size选择决策树
选择DP-size的关键约束:
│
├── P节点 dp-size
│ ├── 太小(dp=4): 64专家/卡 → ~75GB权重 → 超出64GB
│ ├── dp=8: 32专家/卡 → ~40.5GB → 刚好
│ └── 太大(dp=16): 16专家/卡 → ~23GB → 但仅2个P实例,prefill吞吐下降
│
└── D节点 dp-size
├── 太小(dp=16): 16专家/卡 → ~23GB权重 → ~32GB KV空间 → 不够
├── dp=32: 8专家/卡 → ~14.6GB → ~43GB KV空间
└── 太大(dp=64): 需要64卡D节点,实际不可行
参考资源:
免责声明:本文中的显存计算基于公开的模型架构参数和vLLM-Ascend官方文档的并行策略计算得出,实际值可能因驱动版本、CANN版本、vLLM版本及具体配置有所差异。所有数值均为理论推导,实际部署以
npu-smi info输出为准。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐
所有评论(0)