普惠 DeepSeek-V4:Kthena + 昇腾 3 分钟搭建 PD 分离推理
一、背景介绍在大模型推理部署中Prefill-DecodeP/D分离是一种被广泛采用的性能优化架构。随着大语言模型参数量不断增长推理过程中的计算资源消耗和延迟问题日益突出。传统的一体化推理架构难以同时优化首token延迟TTFT和整体吞吐率TPOT而P/D分离通过将推理过程拆分为两个独立阶段让每个阶段使用最适合其计算特性的并行策略实现了显著的性能提升。本文将详细介绍如何通过Kthena控制器在昇腾NPU上部署DeepSeek-V4-Flash模型完成P/D分离的实践。我们会深入解析P/D分离的技术原理、Kthena的编排能力以及ModelRoute如何实现P/D实例的自动发现与KV传输协作。相关部署模板参考Kthena项目地址https://github.com/volcano-sh/kthena/tree/main/examples/models/deepseek-v4-flash二、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 CacheDecode阶段采用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分离张量并行折中值如TP4Prefill用TP8Decode用TP2数据并行固定值各角色独立扩展资源配置统一规格按需分配扩缩容整体调整独立扩缩容以DeepSeek V4为例Prefill优化更大的TP size8加速注意力计算更大的批处理量8192 tokens提升吞吐Decode优化更大的DP size8支持更多并发序列更小的TP size2减少通信开销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传输原理Producer端Prefill生成的KV Cache通过Mooncake引擎传输到Decode节点Consumer端Decode从Mooncake引擎拉取KV Cache用于注意力计算Engine ID每个P/D实例组有唯一的engine ID${GROUP_NAME}_${ROLE_ID}确保数据传输到正确的目标# Prefill配置 kv_role:kv_producer # Decode配置 kv_role:kv_consumerMooncake具备昇腾NPU优化的高性能通信库能够实现节点间KV Cache的低延迟传输是P/D分离能够实际落地的关键技术。三、为什么P/D分离需要适配的Router3.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架构中需要经过多个阶段请求首先路由到Prefill处理Prefill生成首token后需要将请求转交给DecodeDecode可能需要多轮生成每轮都涉及KV传输最终结果需要汇总返回给用户这要求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配置会被控制器用于查询匹配的Pod1. 查询所有 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:mooncakeMooncake Connector的工作流程1️⃣ Prefill启动时从环境变量获取GROUP_NAME和ROLE_ID构建engine_id ${GROUP_NAME}_${ROLE_ID}启动Mooncake Server监听KV请求2️⃣ Decode启动时使用相同的GROUP_NAME但不同的ROLE_ID配置为kv_consumer角色通过engine_id连接到对应Prefill的Mooncake Server3️⃣ 请求处理时Prefill处理用户输入生成KV CacheKV 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比例调整单实例1P1Droles: -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 replicasDecode replicas说明1P1D11基础配置2P1D21提升Prefill吞吐适合输入长度较大的场景1P2D12提升Decode吞吐适合输出长度较大的场景2×(1P1D)2组P/D实例2组P/D实例横向扩展整体吞吐翻倍所有这些调整都只需修改yaml配置并执行kubectl apply -f deepseek-serv.yamlKthena控制器会自动处理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_SMUDGE1 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.yamlconfig.yaml定义了Prefill和Decode的启动脚本包含环境变量配置vLLM启动参数Mooncake KV连接配置Step 2: 部署ModelServingkubectl 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/namedeepseekv4-pd # 查看Pod详情确认标签 kubectl get pods -l modelserving.volcano.sh/namedeepseekv4-pd -o wide # 检查Pod日志 kubectl logs -l modelserving.volcano.sh/roleprefill kubectl logs -l modelserving.volcano.sh/roledecode6.3 扩缩容操作扩缩容Prefill# 编辑配置 kubectl edit modelserving deepseekv4-pd # 将 prefill.replicas 从 1 改为 2 # 或者使用patch kubectl patch modelserving deepseekv4-pd --typejson \ -p[{op: replace, path: /spec/template/roles/0/replicas, value: 2}]扩缩容Decodekubectl patch modelserving deepseekv4-pd --typejson \ -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的核心价值简易性声明式配置替代复杂的手动编排控制器自动处理Pod管理和标签注入灵活性通过replicas字段即可独立调整P/D比例无需修改其他配置自动发现pdGroup机制实现P/D实例的自动识别和配对KV协调与Mooncake深度集成确保KV传输的正确路由综上所述P/D 分离是提升大模型分布式推理效能的核心技术路径而 Kthena 的适配 Router 设计与编排逻辑为这一复杂架构在生产环境中的标准化部署提供了确定性的方案确保了大模型服务在昇腾算力底座上的高效稳定运行。相关部署模板参考Kthena项目地址https://github.com/volcano-sh/kthena/tree/main/examples/models/deepseek-v4-flashKthena GitHub地址https://github.com/volcano-sh/kthena更多信息欢迎访问 Kthena 官网https://kthena.volcano.sh/欢迎Star★Fork来 Kthena 社区一起玩转LLM推理