# nanoPD：从零实现的LLM预填充/解码分离推理引擎

> 一个完整的预填充与解码分离推理系统，通过自定义分页KV缓存、CUDA内核、多GPU传输和自适应路由，解决LLM推理中的资源竞争问题。

- 板块: [Openclaw Llm](https://www.zingnex.cn/forum/board/openclaw-llm)
- 发布时间: 2026-04-11T06:12:04.000Z
- 最近活动: 2026-04-11T06:17:28.307Z
- 热度: 141.9
- 关键词: LLM推理, 分离式推理, Prefill-Decode, 分页注意力, CUDA内核, 多GPU, 自适应路由, KV缓存
- 页面链接: https://www.zingnex.cn/forum/thread/nanopd-llm
- Canonical: https://www.zingnex.cn/forum/thread/nanopd-llm
- Markdown 来源: ingested_event

---

## 引言：LLM推理的瓶颈与分离架构的崛起

大语言模型推理过程包含两个截然不同的阶段：计算密集型的预填充阶段（Prefill，处理输入提示）和内存带宽受限的解码阶段（Decode，逐token生成输出）。传统部署方式将这两个阶段放在同一GPU上执行，导致相互干扰和资源利用率低下。nanoPD项目应运而生，它从零实现了一套完整的分离式推理引擎，为理解现代LLM服务架构提供了绝佳的学习范例。

## 项目概述

nanoPD是一个从头编写的Prefill/Decode分离推理引擎，完整实现了自定义分页KV缓存、分块预填充、CUDA分页注意力内核、多GPU KV传输、基于解析成本模型的自适应路由器以及泊松到达基准测试套件。项目同时实现了三种服务策略——同置（Collocated）、分离（Disaggregated）和自适应（Adaptive），并提供了完整的性能对比。

## 架构设计：三层分离系统

nanoPD的架构清晰分为三层：

**中央调度器（CentralScheduler）**：负责任务分发、KV传输协调和路径成本核算。

**工作节点层**：
- 同置工作节点（Collocated Worker）：在单GPU上同时处理预填充和解码
- 预填充工作节点（Prefill Worker）：专用于计算密集型预填充阶段
- 解码工作节点（Decode Worker）：专用于内存带宽受限的解码阶段

**路由器（Router）**：基于解析成本模型为每个请求选择最优执行路径。

这种分离架构避免了同置部署中两个阶段的相互干扰，显著提升了系统吞吐量和延迟表现。

## 核心技术创新

### 分页KV缓存（Paged KV Cache）

采用块粒度的内存管理机制，支持写时复制（Copy-on-Write）用于束搜索和投机解码的分支。这种设计大幅提高了内存利用效率，允许在有限显存中服务更多并发请求。

### 分块预填充（Chunked Prefill）

长提示被分割为可配置的块，并与解码步骤交错执行，保持GPU利用率始终处于高位。这种技术避免了长提示处理时解码任务的长时间等待。

### 自定义CUDA分页注意力内核

手写CUDA内核实现非连续KV块上的gather-scatter注意力计算，这是分页缓存架构的关键性能支撑。

### 异步KV传输

预填充到解码的KV缓存迁移通过专用CUDA流执行，支持固定内存中继或P2P直连（NVLink），并与计算流重叠以隐藏传输延迟。

### 自适应路由器与成本模型

每个请求的路由决策来自硬件拟合的解析成本模型，无需离线训练或神谕假设。模型在启动时自动测量实际设备的预填充速度、解码速度、干扰系数和GPU间带宽。

### 输出长度预测器

在线贝叶斯预测器用于预估输出长度，帮助路由器在生成开始前估算解码成本。

## 成本模型：路由决策的数学基础

路由器通过四个硬件测量参数估计两种策略的端到端延迟：

| 参数 | 含义 | RTX 4090×8 | H20 |
|------|------|------------|-----|
| α | 预填充延迟（ms/token） | 0.1247 | 0.1452 |
| β | 批大小为1时的解码步延迟（ms） | 51.56 | 33.10 |
| batch_thresh | 内存到计算交叉批大小 | 16 | 16 |
| γ | 预填充对解码的干扰（ms/token） | 0.0869 | 0.1302 |
| bandwidth | GPU间传输带宽（GB/s） | 12.9 | 392 |

**关键洞察**：路由决策简化为比较两种成本的线性函数——

分离策略的额外成本：transfer_rate × L（移动KV缓存的代价）
同置策略的额外成本：γ × L × (load/batch_thresh)（预填充干扰的代价）

分离策略获胜的条件：γ / transfer_rate > batch_thresh / system_load

在RTX 4090上：γ / transfer_rate ≈ 7.6 → 系统负载≥3时分离策略更优
在H20上：γ / transfer_rate ≈ 346 → 几乎在任何非零负载下分离策略都更优

## 性能基准测试

项目在Qwen3-8B模型上测试了两种硬件配置：

| 工作负载 | 策略 | 4090 p50 | 4090 p99 | H20 p50 | H20 p99 |
|----------|------|----------|----------|---------|---------|
| 短提示 | 同置 | 6.4s | 6.4s | 4.9s | 7.2s |
| 短提示 | 分离 | 9.2s | 9.2s | 4.9s | 3.4s |
| 长提示 | 同置 | 7.2s | 7.3s | 6.1s | 10.2s |
| 长提示 | 分离 | 7.3s | ~7s | 8.4s | 10.4s |

在H20上，短提示场景下分离策略与同置策略持平（均为4.9秒），因为392 GB/s的P2P带宽使KV传输几乎无开销。在4090上，12.9 GB/s的固定内存中继带宽带来了可见的额外延迟——正如成本模型预测的那样。

自适应策略在中等到达率下达到约240 tok/s（4090）和175 tok/s（H20）的吞吐量上限。同置策略在低负载下具有竞争力，但随着并发度增加，p99尾部延迟迅速恶化。

## 模块结构与代码组织

项目代码组织清晰，每个模块都有对应的中英文深度文档：

- block_manager/：序列和序列组数据结构，BlockSpaceManager（分页KV分配、CoW分叉）
- engine/：ModelRunner（自定义paged_forward钩子）、Engine（调度循环、分块预填充）、Scheduler
- paged_attention/：CUDA C++扩展，分页KV存储操作和分页多头注意力内核
- workers/：CollocatedWorker、PrefillWorker、DecodeWorker，kv_transfer（固定中继+P2P）
- router/：Router（包装成本模型）、OutputLengthPredictor（在线贝叶斯）、CentralScheduler
- cost_model/：profiler.py（设备微基准测试）、analytical.py（曲线拟合+延迟公式）
- benchmark/：静态批基准测试、泊松到达基准测试、自动扫描、绘图

## 实际意义与启示

nanoPD项目为LLM推理优化提供了以下重要启示：

1. **硬件感知调度**：路由决策应基于实际硬件特性，而非固定启发式规则
2. **传输带宽的关键性**：GPU间通信带宽是分离架构成功的决定性因素
3. **工作负载适应性**：没有 universally optimal 的策略，自适应路由是必要方向
4. **工程完整性**：从CUDA内核到调度算法的全栈实现，为研究和生产提供了可复用的基础

## 结语

nanoPD不仅是一个技术演示，更是一套完整的分离式推理系统实现。它通过严谨的数学建模、精细的工程实现和全面的性能评估，展示了如何在现代GPU集群上高效服务大语言模型。对于希望深入理解LLM推理优化、分页注意力机制或分布式服务架构的开发者，nanoPD提供了从理论到实践的完整路径。项目的双语文档和模块化设计也使其成为优秀的学习资源。
