普惠 DeepSeek-V4:Kthena + 昇腾 3 分钟搭建 PD 分离推理

举报
云容器大未来 发表于 2026/04/29 09:42:11 2026/04/29
【摘要】 本文将详细介绍如何通过Kthena控制器,在昇腾NPU上部署DeepSeek-V4-Flash模型,完成P/D分离的实践。我们会深入解析P/D分离的技术原理、Kthena的编排能力,以及ModelRoute如何实现P/D实例的自动发现与KV传输协作。

一、背景介绍

在大模型推理部署中,Prefill-Decode(P/D)分离是一种被广泛采用的性能优化架构。随着大语言模型参数量不断增长,推理过程中的计算资源消耗和延迟问题日益突出。传统的一体化推理架构难以同时优化首token延迟(TTFT)和整体吞吐率(TPOT),而P/D分离通过将推理过程拆分为两个独立阶段,让每个阶段使用最适合其计算特性的并行策略,实现了显著的性能提升。

kthena小图.png

本文将详细介绍如何通过Kthena控制器,在昇腾NPU上部署DeepSeek-V4-Flash模型,完成P/D分离的实践。我们会深入解析P/D分离的技术原理、Kthena的编排能力,以及ModelRoute如何实现P/D实例的自动发现与KV传输协作。


二、P/D分离技术原理

2.1 大模型推理的两阶段解析

大语言模型的推理过程是一个自回归生成过程,本质上分为两个截然不同的阶段:

Prefill阶段(首token生成)

Prefill阶段负责处理用户输入的prompt,将完整的输入序列通过模型前向传播,生成第一个输出token。这个阶段具有以下特征:

  • 计算密集型:需要处理整个输入序列,每个token都需要与所有输入token进行注意力计算
  • 并行度高:输入序列的所有位置可以并行计算,适合较大的张量并行(TP)规模
  • 内存访问模式KV Cache首次生成,需要写入到高速缓存中
  • 延迟敏感:用户等待首token的时间直接影响体验

在我们的配置中,Prefill阶段采用DP(数据并行)=2、TP(张量并行)=8的配置,利用更大的张量并行度来加速矩阵运算:

--data-parallel-size 2 \
--tensor-parallel-size 8 \
--max-num-batched-tokens 8192 \
--max-num-seqs 4 \

Decode阶段(增量生成)

Decode阶段是自回归生成过程,每次只处理一个新生成的token,并将其加入序列进行下一轮推理。这个阶段的特点与Prefill截然不同:

  • Memory-Bound型:每次只计算一个token,但需要读取完整的KV Cache
  • 并行度需求低:单个token的计算量有限,过大的张量并行反而增加通信开销
  • 吞吐率敏感:需要最大化单位时间内生成的token数量
  • KV传输频繁:每个Decode实例都需要访问所有Prefill实例生成的KV Cache

Decode阶段采用DP(数据并行)=8、TP(张量并行)=2的配置,通过更大的数据并行来提升整体吞吐:

--data-parallel-size 8 \
--tensor-parallel-size 2 \
--max-num-batched-tokens 144 \
--max-num-seqs 48 \

2.2 为什么P/D分离能提升性能

传统的单体架构面临"一刀切"的困境:为了同时满足Prefill和Decode的需求,必须在并行策略上做出妥协,导致两个阶段都无法达到最优。而P/D分离的核心价值在于解耦

维度
单体架构
P/D分离
张量并行
折中值(如TP=4)
Prefill用TP=8,Decode用TP=2
数据并行
固定值
各角色独立扩展
资源配置
统一规格
按需分配
扩缩容
整体调整
独立扩缩容

以DeepSeek V4为例:

  • Prefill优化:更大的TP size(8)加速注意力计算,更大的批处理量(8192 tokens)提升吞吐
  • Decode优化:更大的DP size(8)支持更多并发序列,更小的TP size(2)减少通信开销

2.3 KV Cache传输机制

P/D分离后,Prefill和Decode之间需要高效传输KV Cache,这是P/D分离架构中最关键的技术挑战之一。

在我们的部署中,使用Mooncake Connector V1实现KV传输:

--kv-transfer-config\
'{"kv_connector": "MooncakeConnectorV1",
  "kv_role": "kv_producer",     # Prefill为producer
  "kv_port": "9000",
  "engine_id": "$MOONCAKE_ENGINE_ID",
  ...
}'

Mooncake KV传输原理

  1. Producer端(Prefill):生成的KV Cache通过Mooncake引擎传输到Decode节点
  2. Consumer端(Decode):从Mooncake引擎拉取KV Cache用于注意力计算
  3. Engine ID:每个P/D实例组有唯一的engine ID(${GROUP_NAME}_${ROLE_ID}),确保数据传输到正确的目标
# Prefill配置
"kv_role":"kv_producer"
# Decode配置
"kv_role":"kv_consumer"

Mooncake具备昇腾NPU优化的高性能通信库,能够实现节点间KV Cache的低延迟传输,是P/D分离能够实际落地的关键技术。

三、为什么P/D分离需要适配的Router

3.1 路由在P/D分离架构中的核心作用

在P/D分离架构中,请求的路由不再是简单地分发到某个后端实例,而是需要智能地协调Prefill和Decode两个阶段,这与传统微服务路由有本质区别。

传统微服务路由

Client Request → Router → Backend Instance (处理完整请求)

P/D分离路由

Client Request → Router → Prefill Instance (生成首token)
                         ↕ (KV传输)
                       Decode Instance (完成剩余生成)

3.2 路由需要解决的挑战

挑战一:请求生命周期管理

一个完整的请求在P/D架构中需要经过多个阶段:

  1. 请求首先路由到Prefill处理
  2. Prefill生成首token后,需要将请求转交给Decode
  3. Decode可能需要多轮生成,每轮都涉及KV传输
  4. 最终结果需要汇总返回给用户

这要求Router必须理解P/D的请求流程,而不仅仅是做简单的负载均衡。

挑战二:P/D实例发现与匹配

  • Prefill和Decode实例数量可能不同(1P2D、2P1D等)
  • 请求需要在正确的Prefill和Decode实例之间传递
  • 需要跟踪每个请求当前由哪个实例处理

挑战三:KV传输的协调

KV Cache的传输需要满足以下条件:

  • Prefill生成的KV必须传输到处理该请求的Decode实例
  • Mooncake的engine_id需要正确配置以匹配P/D实例
  • 传输超时和错误处理

挑战四:流量分配策略

不同场景下可能需要不同的P/D配比:

  • 计算密集型场景:增加Prefill副本
  • IO密集型场景:增加Decode副本
  • Router需要支持动态调整流量分配

3.3 ModelRoute的适配设计

Kthena的ModelRoute正是为解决上述挑战而设计的适配层。它不仅负责基本的请求路由,还需要理解P/D分离的语义,协调Prefill和Decode的协作。

四、ModelRoute配置详解

4.1 整体配置结构

apiVersion:networking.serving.volcano.sh/v1alpha1
kind:ModelRoute
metadata:
name:deepseek-v4
namespace:default
spec:
modelName:"deepseek_v4"
rules:
-name:"default"
    targetModels:
    -modelServerName:"deepseekv4-pd"
---
apiVersion:networking.serving.volcano.sh/v1alpha1
kind:ModelServer
metadata:
name:deepseekv4-pd
namespace:default
spec:
inferenceEngine:vLLM
model:"deepseek_v4"
workloadPort:
    port:7100
    protocol:http
workloadSelector:                                   # 工作负载选择器
    matchLabels:
      modelserving.volcano.sh/name:deepseekv4-pd     # 这是最基本的标签匹配,用于识别属于该服务的所有Pod。
    pdGroup:                                          # P/D分组配置
      groupKey:"modelserving.volcano.sh/group-name"# 指定用于分组的标签key
      prefillLabels:                                  # 标记哪些Pod是Prefill角色
        modelserving.volcano.sh/role:prefill
      decodeLabels:                                   # 标记哪些Pod是Decode角色
        modelserving.volcano.sh/role:decode
trafficPolicy:
    timeout:"300s"
    retry:
      attempts:3
      retryInterval:"150ms"
kvConnector:
    type:mooncake

其中P/D分组配置(pdGroup)是实现P/D识别的关键配置

  • groupKey:指定用于分组的标签key,具有相同groupKey值的Pod属于同一个P/D实例组。这解决了一个关键问题:当我们部署多个P/D实例组时(如2×(1P1D)),Router需要知道哪些Prefill和Decode属于同一个组。
  • prefillLabels:标记哪些Pod是Prefill角色。
  • decodeLabels:标记哪些Pod是Decode角色。

4.2 实例发现的实现机制

Kthena控制器通过以下步骤实现P/D实例的自动发现:

步骤1:标签注入

在deepseek-serv.yaml中定义的ModelServing资源会被Kthena控制器处理,自动为每个Pod注入标签:

metadata:
  labels:
    modelserving.volcano.sh/name:deepseekv4-pd
    modelserving.volcano.sh/group-name:<group-id>  # 自动生成
    modelserving.volcano.sh/role:prefill/decode    # 根据role名称
    modelserving.volcano.sh/role-id:<role-id>      # 自动生成

步骤2:标签查询

ModelRoute的pdGroup配置会被控制器用于查询匹配的Pod:

1. 查询所有 labels[modelserving.volcano.sh/name] = deepseekv4-pd 的Pod
2. 按 labels[modelserving.volcano.sh/group-name] 分组
3. 在每个组内,识别prefillLabels和decodeLabels匹配的Pod

步骤3:动态维护

当发生扩缩容时:

  • 新Pod创建后自动获得标签
  • Router实时感知Pod变化
  • 无需手动更新配置

4.3 KV传输的协调

ModelRoute通过以下配置协调KV传输:

kvConnector:
  type:mooncake

Mooncake Connector的工作流程

1️⃣ Prefill启动时

    • 从环境变量获取GROUP_NAMEROLE_ID
    • 构建engine_id = ${GROUP_NAME}_${ROLE_ID}
    • 启动Mooncake Server,监听KV请求

2️⃣ Decode启动时

    • 使用相同的GROUP_NAME但不同的ROLE_ID
    • 配置为kv_consumer角色
    • 通过engine_id连接到对应Prefill的Mooncake Server
3️⃣ 请求处理时
    • Prefill处理用户输入,生成KV Cache
    • KV Cache通过Mooncake传输到对应Decode实例
    • Decode使用接收到的KV继续生成

4.4 流量策略配置

trafficPolicy:
  timeout:"300s"
  retry:
    attempts:3
    retryInterval:"150ms"

这些配置确保了请求在P/D之间的可靠传递:

  • timeout:整个生成过程可能需要较长时间,设置5分钟超时
  • retry:如果请求在Prefill或Decode环节失败,自动重试

五、Kthena编排的核心优势

5.1 声明式编排简化运维

传统方式下,部署P/D分离架构需要:

  • 手动创建和管理多组Deployment/Service
  • 手动配置Service之间的发现机制
  • 手动管理标签选择器和Endpoints

使用Kthena的ModelServing,仅需声明式配置:

apiVersion:workload.serving.volcano.sh/v1alpha1
kind:ModelServing
metadata:
name:deepseekv4-pd
spec:
replicas:1
template:
    roles:
    -name:prefill
      replicas:1
    -name:decode
      replicas:1

控制器会自动完成:

  • 创建和管理Prefill/Decode的Pod
  • 注入必要的标签(group-name、role、role-id)
  • 设置健康检查
  • 配置资源限制

5.2 灵活的P/D比例调整

单实例1P1D

roles:
-name:prefill
  replicas:1
-name:decode
  replicas:1

调整为2P1D(提升Prefill吞吐)

roles:
-name:prefill
  replicas:2    # 从1改为2
-name:decode
  replicas:1

调整为1P2D(提升Decode吞吐)

roles:
-name:prefill
  replicas:1
-name:decode
  replicas:2    # 从1改为2

部署2组独立的1P1D实例(横向扩展)

spec:
  replicas:2    # 整体副本数设为2,每组自动生成1P1D

我们测试了以下几种灵活的P/D比例配置

部署模式
Prefill replicas
Decode replicas
说明
1P1D
1
1
基础配置
2P1D
2
1
提升Prefill吞吐,适合输入长度较大的场景
1P2D
1
2
提升Decode吞吐,适合输出长度较大的场景
2×(1P1D)
2组P/D实例
2组P/D实例
横向扩展,整体吞吐翻倍

所有这些调整都只需修改yaml配置并执行:

kubectl apply -f deepseek-serv.yaml

Kthena控制器会自动处理Pod的创建、销毁和负载均衡。

5.3 自动服务发现

在传统的P/D部署中,需要手动配置服务发现:

  • Prefill服务需要知道所有Decode实例的地址
  • Decode服务需要知道所有Prefill实例的地址
  • 扩缩容时需要手动更新配置

Kthena通过pdGroup和标签机制实现了自动服务发现:

  • 新增的Prefill或Decode实例自动被Router识别
  • 使用相同的group-key的实例自动组成P/D组
  • 无需手动配置实例地址

六、部署实践

6.1 模型准备

为了加速部署和启动过程,我们将DeepSeek-V4-Flash模型权重预先下载到所有计算节点的 /models/DeepSeek-V4-Flash-w8a8-mtp 目录下。该目录应包含完整的模型权重文件、配置文件以及chat_template.jinja模板文件。

从ModelScope下载模型权重

# 安装ModelScope
pip install modelscope

# 下载DeepSeek V4 Flash模型
modelscope download --model Eco-Tech/DeepSeek-V4-Flash-w8a8-mtp --local_dir /models/DeepSeek-V4-Flash-w8a8-mtp

如果使用git-lfs进行大文件管理,也可以:

# 安装git-lfs
git lfs install

# 克隆模型仓库
GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Eco-Tech/DeepSeek-V4-Flash-w8a8-mtp.git /models/DeepSeek-V4-Flash-w8a8-mtp

# 进入目录并下载LFS大文件
cd /models/DeepSeek-V4-Flash-w8a8-mtp
git lfs pull

注意事项

  • 确保所有计算节点的模型目录路径一致(/models/DeepSeek-V4-Flash-w8a8-mtp
  • 可以在共享存储(如NFS)上预先下载模型,然后挂载到各个节点
  • 模型下载完成后,建议验证文件完整性:
    ls -la /models/DeepSeek-V4-Flash-w8a8-mtp/
    # 应包含 config.json, model.safetensors, chat_template.jinja 等文件
    

6.2 完整部署流程

Step 1: 创建ConfigMap(包含启动脚本)

kubectl apply -f config.yaml

config.yaml定义了Prefill和Decode的启动脚本,包含:

  • 环境变量配置
  • vLLM启动参数
  • Mooncake KV连接配置

Step 2: 部署ModelServing

kubectl apply -f deepseek-serv.yaml

创建完整的P/D分离实例,包括:

  • Prefill实例(1副本)
  • Decode实例(1副本)
  • 自动注入的标签和配置

Step 3: 配置路由

kubectl apply -f modelRoute.yaml

创建ModelRoute和ModelServer两个对象:

  • ModelRoute:定义路由规则
  • ModelServer:定义后端服务

6.2 验证部署

# 查看ModelServing状态
kubectl get modelserving deepseekv4-pd

# 查看所有相关Pod
kubectl get pods -l modelserving.volcano.sh/name=deepseekv4-pd

# 查看Pod详情(确认标签)
kubectl get pods -l modelserving.volcano.sh/name=deepseekv4-pd -o wide

# 检查Pod日志
kubectl logs -l modelserving.volcano.sh/role=prefill
kubectl logs -l modelserving.volcano.sh/role=decode

6.3 扩缩容操作

扩缩容Prefill

# 编辑配置
kubectl edit modelserving deepseekv4-pd
# 将 prefill.replicas 从 1 改为 2

# 或者使用patch
kubectl patch modelserving deepseekv4-pd --type='json' \
  -p='[{"op": "replace", "path": "/spec/template/roles/0/replicas", "value": 2}]'

扩缩容Decode

kubectl patch modelserving deepseekv4-pd --type='json' \
  -p='[{"op": "replace", "path": "/spec/template/roles/1/replicas", "value": 2}]'

七、总结

通过本次实践,我们验证了 Kthena 在昇腾 NPU 环境下部署 DeepSeek-V4-Flash 模型 P/D 分离(Prefill/Decode Disaggregation) 架构的完整可行性。

主要成果

  • 成功实现P/D分离部署,Prefill和Decode独立运行
  • 通过Mooncake KV传输实现P/D协作
  • 支持灵活的P/D比例调整(1P1D、2P1D、1P2D等)
  • 支持多实例横向扩展

Kthena的核心价值

  1. 简易性:声明式配置替代复杂的手动编排,控制器自动处理Pod管理和标签注入
  2. 灵活性:通过replicas字段即可独立调整P/D比例,无需修改其他配置
  3. 自动发现:pdGroup机制实现P/D实例的自动识别和配对
  4. KV协调:与Mooncake深度集成,确保KV传输的正确路由

综上所述,P/D 分离是提升大模型分布式推理效能的核心技术路径,而 Kthena 的适配 Router 设计与编排逻辑,为这一复杂架构在生产环境中的标准化部署提供了确定性的方案,确保了大模型服务在昇腾算力底座上的高效稳定运行。


相关部署模板参考Kthena项目地址:https://github.com/volcano-sh/kthena/tree/main/examples/models/deepseek-v4-flash

Kthena GitHub地址:https://github.com/volcano-sh/kthena  

更多信息,欢迎访问 Kthena 官网: https://kthena.volcano.sh/

欢迎Star,Fork,来 Kthena 社区一起玩转LLM推理!




容器模仿.png

关注魔方公众号,获取更多前沿资讯

添加社区小助手k8s2222,进入技术交流群


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。