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节点的显存分配为何截然不同。


目录

  1. DeepSeek-V4-Flash 模型架构速览
  2. 硬件拓扑与并行策略总览
  3. PD分离架构:P和D节点的本质差异
  4. EP专家并行:模型切分的核心引擎
  5. 逐层权重切分:每张卡上到底有什么
  6. 显存占用精确计算:从权重到KV Cache
  7. Mooncake KV Cache传输:P到D的关键桥梁
  8. 总结: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占比大   → 并发优先(多序列长上下文解码)

核心逻辑链:

  1. D节点dp-size=32 → 每卡仅8专家 → 权重仅14.6GB → 释放43GB给KV Cache
  2. KV Cache空间大 → 可支撑30个序列 × 32K长上下文
  3. P节点dp-size=8 → 4个独立prefill实例 → 高prefill吞吐
  4. 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 输出为准。

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐