东方智慧AI 算力
AI算力 · 昇腾部署课件 D4

昇腾部署第 D4 课:PD 分离与混部——为什么把 Prefill 和 Decode 拆开

2026-10-05

编制:观澜|日期:2026-10-05|级别:T2 标准级 层级:D 层 · L3 服务(D 层第 4 课,前接 D3《MindIE Motor》) 素材来源:昇腾官方 MindIE 3.1.0 文档(《PD 分离说明》《PD 分离架构说明》《HIXL 单边通信库》《服务部署方式说明》) 数据纪律:阶段定义、优势、架构要素、部署形态逐字出自官方文档;标注「归纳」的是便于记忆的整理,非官方口径。


第一段 · 章前定位

D3 提到过 PD 分离与 PD 混部,并给了一张对照表 ——

部署模式 Engine 容器 跨角色 KV 传输
PD 分离 Prefill 和 Decode 容器 需要
PD 混部 union 容器 不需要

当时留了一个问题没答:

为什么要把 Prefill 和 Decode 拆开? 拆开为什么要付出"KV 传输"这个代价?

这一课回答它。而答案的关键,是这两个阶段的"性格"完全不同。

为什么这一课值得单独讲:

  1. 它是 L3 服务层最核心的架构概念之一 —— 官方在 MindIE Motor 里反复提到它("增强 PD 分离服务的能力")。
  2. 它决定了很多部署选择的走向:资源怎么配、网络怎么搭、KV 存储要不要上。
  3. C 层已经给它铺过路了 —— C3 讲过"图模式 / 单算子模式",那是单个请求怎么算; PD 分离是"多个请求怎么排队算" —— 从微观走到了宏观。

第二段 · 学习目标

学完这一课,你应该能回答:

  1. Prefill 和 Decode 各在做什么(官方定义)
  2. 这两个阶段的"性格差别"是什么——为什么说一个计算密集、一个访存密集
  3. PD 分离在解决什么问题("不分离"会怎样)
  4. 官方给出的三条优势分别是什么
  5. PD 分离是个集群架构——它需要哪三个必要元素
  6. 分离的代价:KV Cache 传输为什么绕不过去

第三段 · 两个阶段:官方定义(本课的基础)

官方原文(《PD 分离说明》):

Prefill 阶段:对输入 prompt 执行一次完整前向传播,生成初始隐藏状态(Hidden States), 计算密集型;每个新输入序列都需执行一次 Prefill。

Decode 阶段:基于 Prefill 结果逐步生成后续 token,每步仅计算最新 token 的激活与 attention, 单步计算量较小,但需反复执行直至生成结束,访存密集型(以 KV Cache 等内存访问为主)。

把这两段话拆成对照表(归纳)

Prefill Decode
干什么 处理输入 prompt,一次完整前向 逐 token 往后生成
产出 初始隐藏状态 后续 token
特性(官方用词) 计算密集型 访存密集型
执行次数 每个新输入序列执行一次 反复执行直到生成结束
每次的"量" 一次很大(整个 prompt) 单步计算量较小,但次数多
内存访问 —— 以 KV Cache 等内存访问为主

⭐ 用一句话记住两者的差别(归纳)

Prefill 是"一次性把题读懂",Decode 是"一个字一个字往外写"。

  • 读题:输入很长,要一次算完 → 吃算力(计算密集)
  • 写字:每次只写一个字,但要写很多字,且每次都要回看前面 → 吃内存带宽(访存密集)

"回看前面"这件事就是 KV Cache(官方原文:Decode 阶段"以 KV Cache 等内存访问为主")—— Decode 的每一步都要访问它。

⭐ 记住这一组词就够了: Prefill = 计算密集;Decode = 访存密集。 这一课的其余部分,都是从这一句话推出来的。


第四段 【如果我来做】一条真实的执行路径:先判断"值不值得拆"

这一节是本课的核心。 前三段讲的是"两个阶段分别是什么";这一节讲的是:如果现在把"PD 分离"这件事交给我,我从哪里开始、按什么顺序做、每一步凭什么判断。

4.0 我会按这个顺序做(八步)

① 先摸底 —— 先判断"值不值得拆":不装任何东西,先把 Prefill 计算密集 / Decode 访存密集(第三段)这两个事实对上你的负载和硬件,再决定要不要拆。 ② 定方案(做哪一种):单机 PD 分离 / 多机 PD 分离 / PD 混部三选一,别默认上全套。 ③ 确认集群三要素齐了:调度器 Coordinator + Prefill 实例 + Decode 实例,缺一不可(第六段)。 ④ 规划 KV Cache 传输路径:拆开就有代价 —— Prefill 算出的 KV Cache 必须搬到 Decode,这条路要先想清楚(第七段)。 ⑤ 动手起服务,每步立刻验:建命名空间 → 拉起集群 → kubectl get pods 看状态,一步一验,不攒着一起验。 ⑥ 联调:发一个真实请求:看 P 算完 D 是否接着生成;接不上,就是"搬的环节"出了问题。 ⑦ 出证据:留下 Pod 状态、global_ranktable.json、流式响应,给别人能复现。 ⑧ 诚实:官方没给性能数字的地方,明写"这里要自己查"。

为什么把①放最前:① 是这几步里唯一"不可返工"的判断 —— 负载本来就小、机器也不多时,拆开反而更慢(多出来的那趟 KV 传输白搭)。所以先查事实,再决定拆不拆。下面 4.1 先把"为什么'不拆'会有问题"说清,4.2 给出要敲的命令和会看到的结果。


4.1 第①步 · 值不值得拆:为什么"不拆"会有问题

官方的说法(原文):

PD 分离……将大语言模型推理的预填充(Prefill)与解码(Decode)两个阶段拆分到不同实例上运行, 适用于对时延和吞吐要求较高的场景。通过 PD 分离可提高 NPU 利用率, 减轻 Prefill 与 Decode 分时复用带来的相互干扰,在相同时延下提升整体吞吐。

官方在另一处(PD 分离架构说明)又说了一遍:

该架构将推理的 2 个阶段(Prefill 和 Decode)分别部署到不同的实例上进行计算, 从而减少 Prefill 和 Decode 之间互相干扰,提升推理性能。

"分时复用"与"互相干扰"是什么意思(归纳):

混部(union)时,Prefill 和 Decode 在同一个实例上"轮着用"同一批卡。 问题在于两者的性格相反(第三段的结论):

需要什么 混在一起会怎样
Prefill 大量算力 它一上来就占满算力,把 Decode 挤住
Decode 大量内存带宽 它要持续占用带宽,也被 Prefill 打断

归纳:一个吃算力、一个吃带宽 —— 混在一起时,两边的强项都用不满,还要互相等。 这就是官方说的"分时复用带来的相互干扰"。

类比(归纳,帮理解): 一家餐厅,厨师(算力)和服务员(带宽)是两拨人。 混部 = 同一个人又当厨师又当服务员 —— 炒菜时没人端菜,端菜时没人炒菜。 分离 = 分成两个岗,各干各的,同时进行。

一个直接的后果:吞吐(官方原文):

吞吐能力提升:Prefill 处理新请求的同时,Decode 可持续处理已有请求的解码, 整体处理能力更高。

归纳:分离之后,"读新题"和"写旧文"可以同时发生 —— 这是吞吐提升最直观的来源。

这一步怎么落到我的判断上:把上面的"性格差别"对回自己的场景 —— 并发高、对时延敏感、机器和网络都够,就值得拆;只是想把服务先跑通、机器只有一台,就别拆(更细的选型见第五段)。


4.2 第⑤⑥步 · 起服务与联调(命令 + 结果)

以下命令逐字出自官方 MindIE 3.1.0《PD分离服务部署 · 使用 kubectl 部署单机 PD 分离服务示例》(原文路径:zh/mindie/310/mindiellm/llmdev/mindie_motor_cpp/user_guide/service_deployment/pd_separation_service_deployment.md)。 它们都要在部署脚本目录 examples/kubernetes_deploy_scripts 下执行(官方明说:不在该目录下会报错)。

命令 kubectl create namespace mindie

含义:给 PD 分离集群建一个 K8s 命名空间(官方示例默认名 mindie) 拆解:kubectl(K8s 命令行工具)+ create namespace(创建命名空间)+ mindie(名字,可换成你自己的,后面命令跟着换) 用法:首次部署必建;也可写成 kubectl create namespace <你的名称> 期望:回显 namespace/mindie created 不过会怎样:报 Error from server (AlreadyExists) → 该命名空间已建过,直接进下一步;报连接类错误 → kubectl 没配好 kubeconfig,或你不在 K8s 管理节点上(官方要求由集群管理员在管理节点执行)

命令 bash deploy.sh 800i_a2

含义:一键拉起单机 PD 分离集群(Controller / Coordinator / Server 三组件由这一个脚本下发) 拆解:bash(执行脚本)+ deploy.sh(部署入口脚本)+ 800i_a2(机型参数) 用法:官方给三种写法 —— bash deploy.sh(默认)/bash deploy.sh 800i_a2(Atlas 800I A2 推理服务器)/bash deploy.sh 800i_a3(Atlas 800I A3 超节点服务器);跑前先 export MINDIE_USER_HOME_PATH={镜像的安装路径} 指向镜像里 MindIE 的安装父目录 期望:脚本自动下发业务配置、自动生成 global_ranktable、自动把 Pod 调度到计算节点 不过会怎样:路径类报错 → 先核 MINDIE_USER_HOME_PATH;配置字段非法 → 官方建议先用 MindStudio 预检工具校验配置文件再看部署脚本

命令 kubectl get pods -n mindie

含义:查看 PD 集群里所有 Pod 的状态 拆解:get pods(列出 Pod)+ -n mindie(限定命名空间 mindie) 用法:直接执行;想持续观察加 -w 期望:Controller、Coordinator、Server 都启动在"以 mindie-server 开头的 Pod"里;READY 1/1、STATUS Running 不过会怎样:出现 Pending / ErrImagePull / CrashLoopBackOff → 记下现象回第八段排查;⚠️ Running 只代表容器被调度起来了,不代表业务程序启动成功 —— 还要看日志(下一条)

命令 bash log.sh

含义:一键查询这个部署脚本拉起的所有 Pod 的标准输出日志 拆解:bash log.sh(脚本示例自带的日志查询脚本) 用法:只看某一个 Pod 用 kubectl logs mindie-server-7b795f8df9-vl9hv -n mindie(把 Pod 名换成 kubectl get pods 里看到的实际名字) 期望:日志里输出生成了 global_ranktable.json(含 server_group_list、server_list 等) 不过会怎样:日志里没有 ranktable、或报通信错误 → 多半是参数面互联没通(官方要求服务器 NPU 卡对应的端口处在同一个 VLAN、可通过 RoCE 互通),或 P 节点与 D 节点的 NPU 卡数不一致

命令 bash generate_stream.sh

含义:用 curl 向推理入口发一个流式请求,验端到端能不能出 token 拆解:generate_stream.sh(脚本示例自带的流式响应示例;chat.sh 是简单对话版) 用法:先把脚本里的 IP 改成"集群管理节点宿主机 IP";Coordinator 走 HTTPS 就配证书,走 HTTP 就把脚本里的 HTTPS 改成 HTTP 并删掉证书相关配置 期望:逐 token 流式返回生成结果(官方:部署成功后节点开放 31015 端口作为推理业务接口) 不过会怎样:连不上 → 先查 31015 端口和脚本里的 IP 填对没;能连但迟迟不出结果 → 卡在"搬的环节"(KV Cache 没从 P 传到 D)或 P/D 有一侧其实没起来(回第八段)

命令 bash delete.sh mindie ./

含义:一键卸载已部署的 PD 集群(改配置重部署前要先卸载) 拆解:bash delete.sh + mindie(命名空间,按实际替换)+ ./(路径参数) 用法:必须在该脚本所在的 examples/kubernetes_deploy_scripts 目录下执行 期望:相关 Pod 被删除、集群停止 不过会怎样:报错、服务停不掉 → 十有八九是没在脚本目录下执行(官方明说:否则无法停止服务并报错)


第五段 · 官方给出的三条优势(原文,逐条)

官方《PD 分离说明》的"主要优势"一节,原文如下:

① 资源利用更优

Prefill 为计算密集型、Decode 为访存密集型,特性不同, 分离部署可更充分利用 NPU 的计算与带宽资源。

② 吞吐能力提升

Prefill 处理新请求的同时,Decode 可持续处理已有请求的解码,整体处理能力更高。

③ 时延更可控

两阶段分离可减少排队与等待,尤其在高并发场景下有助于降低时延。

三条优势的内在逻辑(归纳)

① 资源利用更优   ← 因为两者一个吃算力、一个吃带宽,分开才能各自用满
        ↓
② 吞吐提升       ← 因为可以同时进行(读新题 & 写旧文)
        ↓
③ 时延更可控     ← 因为不再互相排队等

三条优势不是并列的三个好处,而是同一件事的三个侧面。

⚠️ 一个必须说清的边界

官方的三条优势,前提都是"对时延和吞吐要求较高的场景"(原文如此)。

归纳:PD 分离不是"总是更好"(归纳):

场景 更合适
高并发、追求吞吐、对时延敏感 PD 分离(官方原文:适用于对时延和吞吐要求较高的场景)
需要独立规划 P/D 资源 PD 分离(官方《服务部署方式说明》:"适用于需要独立规划 P/D 资源、追求更高吞吐的场景")
小规模、先跑通、没有多余的机器 PD 混部(更简单:一个 union 容器,不需要跨角色 KV 传输)

这与 B4/C1 的思路一致:先按最简单的跑通,再按需要上复杂度。


第六段 · PD 分离是个集群架构:三个必要元素

官方原文(《PD 分离架构说明》):

PD 分离是集群化架构,集群中,存在三种必要的元素,如下所示: - 调度器(Coordinator) - Prefill 实例(P) - Decode 实例(D)

对照 D3 的五个子组件(归纳)

D3 讲过 Motor 的五个子组件 —— 现在看它们在 PD 分离里各站什么位置:

PD 分离的必要元素 对应 D3 的哪个组件 干什么
调度器 Coordinator Coordinator(D3) 接收请求,调度到 P 或 D 实例
Prefill 实例(P) Server 侧(EngineServer + 引擎) 跑 Prefill
Decode 实例(D) Server 侧(EngineServer + 引擎) 跑 Decode

⭐ 这就是 D3 那句"Coordinator 是数据流枢纽"的实际含义 —— 它是 P 和 D 之间的那个调度中枢。

官方给的参考部署方案(原文)

官方在《PD 分离说明》里说明了本仓库采用的方案:

本仓库采用多机 PD 分离部署方案:通过 K8s Service 为 Coordinator 暴露推理入口, 使用多个 Deployment 分别部署 Controller(单 Pod)、 Coordinator(单 Pod)以及 Server(P 实例与 D 实例各若干 Pod)。 Controller 负责集群与实例管理,Coordinator 接收用户请求并调度至 P/D 实例, 由 P 实例与 D 实例协同完成一次完整推理。

归纳这个方案的形状(归纳):

                    [ K8s Service ]      ← 对外暴露推理入口
                          │
                          ▼
                   Coordinator(单 Pod)   ← 调度中枢
                     │            │
        ┌────────────┘            └────────────┐
        ▼                                      ▼
  Server: P 实例(若干 Pod)        Server: D 实例(若干 Pod)
        └────────── 协同完成一次完整推理 ──────────┘
                    ▲
        Controller(单 Pod)← 集群与实例管理

注意两件事(归纳):

  1. P 和 D 都是"若干 Pod" —— 可以水平扩展(这也回应了官方说的"需要独立规划 P/D 资源")
  2. Controller 和 Coordinator 都是"单 Pod" —— 控制面是单点(这也解释了为什么官方单独强调 RAS 能力)

第七段 · 分离的代价:KV Cache 传输

D3 留的钩子在这里解 —— 为什么 PD 分离"需要跨角色 KV 传输"。

官方原文(《LLM DataDist》/《HIXL 单边通信库》)

大模型推理 PD 分离式框架中,Prefill 阶段生成的 KV Cache 需要传输到 Decode, 然后 Decode 阶段进行增量迭代推理。 LLM-DataDist 作为大模型分布式集群和数据管理组件, 通过简易的 API 开放给用户……

推理一下"为什么必须传"(归纳)

把第三段的结论连起来:

Prefill 在 P 实例上算完      →  产生了 KV Cache(第三段:Decode 要"回看前面")
Decode 在 D 实例上继续生成    →  它需要"回看前面"的那些内容
但两者在不同实例上           →  所以 KV Cache 必须搬过去

⭐ 一句话:

拆开是有代价的 —— 原来在同一个实例里"直接就能看到"的东西,现在要跨网络搬。

这也解释了 D3 那张对照表里的两列: - PD 分离:跨角色 KV 传输 需要 - PD 混部:不需要(因为压根没拆开)

由此引出的两类组件(归纳)

官方文档里与这件事相关的名字:

名字 官方定位 在哪一层
KV Cache Store D3 提到"按需拉起 KV Cache Store" Motor 侧的部署概念
LLM-DataDist "大模型分布式集群和数据管理组件" CANN 侧(CANN 的更多组件里)
HIXL 单边通信库 CANN 的通信库之一(B1/A3 的 ops 包里提到过 HIXL) L1(CANN)

⭐ 注意这里的层次跨度: PD 分离这件事,从 L3(Motor 的部署)一直穿到 L1(HIXL 通信库)。 这就是为什么"部署"这门手艺难 —— 一个架构决策会牵动好几层。

回想 A3 讲的 HDK 四件套、B1 讲的 NNAL: HIXL 单边通信库正是 ops 包里包含的库之一 —— 它在 P 和 D 之间搬数据这件事上派上用场。

规划 KV Cache 传输路径时,我会先问三个问题(归纳)

把八步里的第 ④ 步落到实处:

  1. 搬的是什么、从哪搬到哪 —— Prefill 实例上生成的 KV Cache,要搬到 Decode 实例(官方原文)。
  2. 用什么搬 —— 官方相关的名字有两个层次:Motor 侧的 KV Cache Store(D3 提到"按需拉起")、 CANN 侧的 LLM-DataDist / HIXL 单边通信库(本课只给定位,用法以各自官方文档为准)。
  3. 这条路的物理条件够不够 —— 官方对多机 PD 分离明确要求 NPU 网口互联(带宽 200Gbps), 且集群必须具备参数面互联(NPU 卡对应端口处在同一个 VLAN,可以通过 RoCE 互通)。 这条不满足,"搬"一定出问题 —— 也正是 4.2 里日志报通信错时要先查的地方。

⚠️ 一句话:KV Cache 的传输路径,是 PD 分离里唯一"因为拆开才多出来"的东西; 它规划不好,前面省下的时间会在这里还回去。


第八段 · 出问题怎么查

先做"选型判断":该分离还是该混部

按官方的适用条件照镜子(归纳):

你的情况 建议
高并发、要吞吐、时延敏感 PD 分离
需要独立规划 P/D 的资源 PD 分离
机器够、网络好 PD 分离
先跑通 / 机器少 / 不想引入 KV 传输 PD 混部(一个 union 容器)

分离场景的排查方向(归纳)

现象 先查什么
P 或 D 有一边起不来 各实例的 Pod / 容器状态;NodeManager 管这个(D3)
请求进不来 Coordinator(统一入口)+ K8s Service(官方方案里由它暴露入口)
P 算完了但 D 不接着生成 KV Cache 传输那条路(跨角色传输 / KV Cache Store)
部分卡在等 资源规划:P 和 D 的资源配比是否合理
想让 P/D 各自扩容 官方方案里 P/D 是若干 Pod,可水平扩展
混部改分离后性能反而差 分离有代价:多了 KV 传输;小规模时不一定划算

⭐ 一个最省时间的判断法

PD 分离出的问题,先分清是"算的环节"还是"搬的环节"。

类型 表现(归纳) 方向
算的环节 某一侧实例没起来 / 起了但报错 实例本身(回到 D2/D3)
搬的环节 两边都活着,但卡在中间;或结果接不上 KV 传输 / KV Cache Store / HIXL

"算的不行"和"传的不行"是两种病 —— 分离架构把这两种病分开了, 所以排查时也要先把它们分开。

常见报错清单(按现象查)

⚠️ 数据纪律提示:官方在本课涉及的部署文档里没有单独收录"报错原文清单", 下表全是由官方给出的限制与约束推出的按现象排查的方向,不含编造的报错文本。 真正的报错原文,请用官方故障案例库按实际报错的特征词检索(入口见附录 A)。

现象 先归到哪一类 先查什么
kubectl get pods 里 P 或 D 实例起不来 算的环节 各实例的 Pod / 容器状态(Pod 生命周期归 NodeManager 管,见 D3)
Pod 一直是 Pending 算的环节 计算节点资源够不够、nodeSelector 选中的节点对不对、卡有没有被占
Pod 是 ErrImagePull / ImagePullBackOff 算的环节 镜像名(官方:mindie_server.yaml / mindie_ms_coordinator.yaml / mindie_ms_controller.yaml 里的 image)能不能拉到
Pod Running 但业务没起来 算的环节 看日志:bash log.sh 或 kubectl logs <pod> -n mindie
日志里没有 global_ranktable.json / 报通信错 算的环节 参数面互联(NPU 网口同 VLAN、RoCE 互通);P、D 卡数是否一致
请求进不来 算的环节 Coordinator(统一入口)+ K8s Service(官方方案里由它暴露入口)
能连上但一直不出结果 搬的环节 KV Cache 传输那条路(跨角色传输 / KV Cache Store / HIXL,见第七段)
P 算完了但 D 不接着生成 搬的环节 同上:KV Cache 有没有从 P 传到 D
部分卡在等 算的环节 资源规划:P 和 D 的资源配比是否合理(官方 default_p_rate / default_d_rate)
HTTPS 开了之后服务被 K8s 反复重启 算的环节 官方提示:启用 TLS 时要在 controller_init.yaml、coordinator_init.yaml 里删掉三项健康探针,否则可能被频繁重启
部署脚本跑不起来 / 卸载失败 算的环节 必须在 examples/kubernetes_deploy_scripts 目录下执行(官方明说否则报错)
用的模型/特性不支持 算的环节 官方限制:单机仅 Atlas 800I A2/A3;LLaMA3-8B / Qwen2.5-7B / Qwen3-8B 支持;不与 Prefix Cache、稀疏量化、KV Cache int8 量化同时用

第九段 · 小结与下一课

三句话带走

  1. Prefill 是计算密集型(一次性读懂整个 prompt),Decode 是访存密集型(一个字一个字往外写,每步都要回看 KV Cache)。 性格相反,所以混在一起会互相干扰。
  2. PD 分离的官方三条优势:资源利用更优(算力与带宽各自用满)、 吞吐能力提升(读新题与写旧文可同时进行)、时延更可控(减少排队等待)—— 三者是同一件事的三个侧面。
  3. PD 分离是集群架构,三种必要元素:调度器(Coordinator)、Prefill 实例、Decode 实例; 代价是 Prefill 生成的 KV Cache 必须传到 Decode —— 这件事从 L3 一路穿到 L1 的通信库。

本课在体系里的位置

─── L0 硬件与环境(A 层,已完成)─── A0 / A1 / A2 / A3
─── L1 基础软件(B 层,已完成)─── B1 / B2 / B3 / B4 / B5
─── L2 框架(C 层,已完成)─── C1 / C2 / C3
─── L3 服务(D 层)───
D1 L3 服务层:推理服务是怎么跑起来的        ✅
D2 vLLM Ascend:把推理服务真正跑起来        ✅
D3 MindIE Motor:五个子组件与集群的骨架      ✅
D4 PD 分离与混部:为什么把 P 和 D 拆开        ★ 本课
D5(拟)服务的起停、端口与调优
─── 排障(E 层)─── E1

本课留下的"钩子"

钩子 在哪一课填
服务怎么扩缩容、限流、主备倒换 D5
虚推健康检查、KV Cache 亲和调度、KV 池化(官方 Motor 运维章节提到) D5 / 后续
HIXL / LLM-DataDist 的完整用法 CANN 通信库文档
量化(msModelSlim)属于 L4 应用层 D 层之后

课后自测(3 题)

  1. Prefill 和 Decode 各是"什么密集"?为什么?这一条为什么能推出后面的所有结论?
  2. 用"餐厅"之外的一个类比,说明"分时复用带来的相互干扰"是什么。
  3. PD 分离之后为什么必须传 KV Cache?这个代价在什么情况下可能不划算?

附录 A · 本课引用的官方出处

内容 出处
PD 分离的定义、「提高 NPU 利用率、减轻分时复用带来的相互干扰、在相同时延下提升整体吞吐」 官方 MindIE《PD 分离说明》
zh/mindie/310/mindiemotor/motordev/docs/zh/user_guide/features/pd_disaggregation.md
Prefill / Decode 两阶段的官方定义(计算密集型 / 访存密集型 / Hidden States / KV Cache) 同上
多机 PD 分离部署方案(K8s Service、多个 Deployment、Controller 单 Pod、Coordinator 单 Pod、Server 的 P/D 各若干 Pod) 同上
PD 分离的三条主要优势(资源利用更优 / 吞吐能力提升 / 时延更可控) 同上
「PD 分离是集群化架构,存在三种必要的元素:调度器(Coordinator)、Prefill 实例(P)、Decode 实例(D)」 官方《PD 分离架构说明》
zh/mindie/310/mindiellm/llmdev/mindie_llm0044.html
「将推理的 2 个阶段分别部署到不同实例,减少互相干扰,提升推理性能」 同上
「Prefill 阶段生成的 KV Cache 需要传输到 Decode,然后 Decode 阶段进行增量迭代推理」;LLM-DataDist 的定位 官方 CANN《LLM DataDist 开发(Python)· 概述》
zh/CANNCommunityEdition/920beta2/others/llmdatadistdev/docs/zh/user_guides/llm_datadist/llm_datadist_dev/python/introduction.md
HIXL 单边通信库与 PD 分离式框架的关系 官方 CANN《HIXL 单边通信库 · 概述》
zh/CANNCommunityEdition/920beta2/commlib/hixlug/docs/zh/guide/python/introduction.md
PD 分离「适用于需要独立规划 P/D 资源、追求更高吞吐的场景」(业务拓扑) 官方 MindIE《服务部署方式说明》
zh/mindie/310/mindiemotor/motordev/docs/zh/user_guide/deployment/k8s/README.md
官方故障案例库入口 https://www.hiascend.com/document/caselibrary

⚠️ 数据纪律提示: ① 本课未给出任何性能数字(如吞吐提升倍数、时延下降幅度)—— 官方在《PD 分离说明》中未给出量化数据,故不编造; ② 计算密集/访存密集是官方原文用词;更深的硬件原理本课未展开; ③ KV Cache Store / LLM-DataDist / HIXL 的具体用法本课只给定位,用法以各自官方文档为准; ④ 标注「归纳」的内容(餐厅类比、三条优势的逻辑链、两张判断表)非官方口径。


附录 B · 本课出现的名词详解

Prefill(预填充)

  • 官方定义:对输入 prompt 执行一次完整前向传播,生成初始隐藏状态(Hidden States)
  • 特性:计算密集型
  • 频次:每个新输入序列都需执行一次

Decode(解码)

  • 官方定义:基于 Prefill 结果逐步生成后续 token,每步仅计算最新 token 的激活与 attention
  • 特性:单步计算量较小,但需反复执行直至生成结束;访存密集型(以 KV Cache 等内存访问为主)

KV Cache

  • 它是什么(结合官方原文化解):Decode 阶段"要回看前面"所依赖的那份缓存
  • 在 PD 分离中的角色:Prefill 生成它 → 传输给 Decode → Decode 用它做增量迭代推理
  • 为什么它是关键:它既是 Decode 性能的依赖,也是 PD 分离的代价来源

增量迭代推理

  • 官方原文用词:「Decode 阶段进行增量迭代推理」
  • 归纳:每次只新增一个 token,在已有结果上往前推一步(不是每次都重算全部)

分时复用

  • 官方原文用词:「减轻 Prefill 与 Decode 分时复用带来的相互干扰」
  • 归纳:同一份资源被两个阶段轮流占用(混部时的状态)

名词速查表

名词 一句话
Prefill 一次性读懂 prompt,计算密集
Decode 逐 token 生成,访存密集
KV Cache Decode 要回看的缓存;PD 分离要传的就是它
分时复用 两个阶段轮流用同一份资源(混部)
PD 分离 拆成 P 实例 + D 实例,需要跨角色 KV 传输
PD 混部 一个 union 容器,不需要 KV 传输
Coordinator PD 分离的调度器(三种必要元素之一)
P 实例 / D 实例 分别跑 Prefill / Decode
KV Cache Store 官方 Motor 部署里"按需拉起"的组件
LLM-DataDist 大模型分布式集群与数据管理组件(CANN 侧)
HIXL CANN 的单边通信库(ops 包里包含,见 A3/B1)

附:D3 与 D4 的分工

问题 在哪一课
Motor 五个子组件、部署形态、配置文件与端口规划 D3
Prefill/Decode 的本质差别、PD 分离的动机与官方优势、集群三要素、KV 传输的代价 本课(D4)
起停、限流、主备倒换、伸缩、调优 D5
选修 · 昇腾 AI 部署实操 本机读完 0/51
选修 C · 昇腾 AI 部署实操
从零把昇腾 AI 部署学一遍:先看懂分几层,再逐层装起来,最后出问题能自己定位到哪一层。不需要先有卡就能开始。
看完整学习路径(6 站 + 3 门选修) · 进度只存在你这台设备的浏览器里,不用登录
辽ICP备2026019944号-1