shishi fe375e1307 docs(pd): 补充运维一键部署完整步骤(干净环境从零到跑通)
- experiments README 新增「运维一键部署」章节:6 步完整流程
  (免密/文件分发/仓库 clone/拉镜像/启动/验证)+ 停止重启 + 文件来源
- docs/KIMI_K3_DEPLOY.md 附录 B 新增 B.2 运维准备,编号顺延 B.3-B.6
- 修复 scp 分发命令(先建父目录)
2026-08-11 11:55:39 +08:00

185 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Kimi-K3 PD 分离部署MoonCake RDMA实验
RTX 6000Dsm_1208 节点 64 卡)上 Kimi-K3 的 **Prefill/Decode 分离部署**KV 传输使用 **MoonCake RDMA**(计算网 mlx5_0~34 链路 RoCE
## 背景与动机
PD 分离部署PD Disaggregation将 prefill预填充计算密集型与 decode逐 token 生成,访存密集型)拆分到不同节点组,是长上下文下提升吞吐/利用率的行业标准做法。本实验聚焦 KV 传输后端的选型验证与稳定部署。
### 为什么不用 NIXL
实测 NIXLUCX 后端)在 RTX 6000D无 GDR/GDAKI**VRAM 单次传输上限约 20MB**24/32/64MB 均报 `Input/output error``NIXL_ERR_REMOTE_DISCONNECT`),且 sglang NIXL 后端不做按字节分块(一次传输整个请求全部 KV连续负载下必断。根因UCX 依赖 GDAKIGPU Direct Async接口当前未启用`NVreg_RegistryDwords="PeerMappingOverride=1;"`)。详见飞书 wiki「Kimi-K3 部署手册」PD 章节。
### 为什么 MoonCake RDMA 可行
- MoonCake 走 **libibverbs 直连**(传统 GDR + dmabuf 注册),不依赖 UCX/GDAKI
- 实测跨节点 GPU 显存传输 **1GB 无压力**,连续 10×64MB 全部成功
- **必须用 0.3.12.post1**(含 dmabuf 注册修复 #2035;镜像自带的 0.3.11.post1 无修复)
### 关键坑(务必遵守)
1. **不能设 `PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True`**
expandable_segments 分配的 GPU 段mooncake RDMA 注册报 `Bad address [14]`GitHub kvcache-ai/Mooncake **#2511**)。移除后 KV 注册 2376 条失败 → 0 失败。
2. **P 组先启动D 组后启动**prefill 需先注册 bootstrap
3. **容器内必须升级 mooncake 到 0.3.12.post1**wheel 在 `/data/flashkda_deploy/wheels/`profile 的 BOOTSTRAP 里已含 pip install
4. NCCL/GLOO 走计算网(`bond1` + `NCCL_IB_HCA=mlx5_0..3`),不要走管理网 bond0。
## 架构
```
┌───────────────────┐
client ──31000──▶ │ router (MiniLB) │ 174.1.60.5
└───────┬───────────┘
┌───────▼───────────┐
P 组 (prefill) │ 174.1.60.1~4 │ TP32×EP324 节点 32 卡
└── prefill 计算 │ 计算完产出 KV │
└───────┬───────────┘
┌───────▼───────────┐
MoonCake RDMA│ mlx5_0~3 (RoCE) │ 4 链路并行
└───────┬───────────┘
┌───────▼───────────┐
D 组 (decode) │ 174.1.60.5~8 │ TP32×EP324 节点 32 卡
└── decode 生成 │ 接收 KV 逐 token │
└───────────────────┘
mc-master (174.1.60.1:50051) MoonCake 元数据服务
```
## 运维一键部署(从干净环境到跑通)
以下是运维同学按顺序执行即可完成整套 PD 部署的完整步骤。**前 4 步是"一次性准备"**(新机器/新环境才需要;已部署过的集群可跳过,直接看第 5 步)。
### 步骤 1准备 8 节点环境(一次性)
前置8 台节点174.1.60.1~8已安装 NVIDIA 驱动 + CUDA + DockerGPU 空闲(`nvidia-smi` 全 0 MiB
```bash
# 在任意一台(建议 .5)确认能免密 ssh 到全部 8 节点
for i in 1 2 3 4 5 6 7 8; do ssh 174.1.60.$i hostname; done
# 若某台需密码,先配免密(把公钥分发过去)
ssh-copy-id root@174.1.60.$i # 对每台执行
```
### 步骤 2分发部署文件到 8 节点(一次性)
每台节点需要 3 个文件patch 脚本 + flashkda wheel + mooncake wheel放到指定路径
```bash
# 在 .5 上执行(假设文件已存在于 .5 的对应位置;若没有,先从模型团队获取)
FILES="/tmp/patch_k3_sm120.py
/tmp/flash_kda-0.0.1-cp312-cp312-linux_x86_64.whl
/data/flashkda_deploy/wheels/mooncake_transfer_engine_cuda13-0.3.12.post1-cp312-cp312-manylinux_2_28_x86_64.whl"
for h in 1 2 3 4 5 6 7 8; do
ssh 174.1.60.$h "mkdir -p /tmp /data/flashkda_deploy/wheels" # 确保父目录存在
for f in $FILES; do
scp -q $f 174.1.60.$h:/$f
done
echo " .$h 文件就位"
done
# 验证:每台应显示 3/3
for h in 1 2 3 4 5 6 7 8; do
echo -n " .$h: "
ssh 174.1.60.$h "ls /tmp/patch_k3_sm120.py /tmp/flash_kda-0.0.1-cp312-cp312-linux_x86_64.whl /data/flashkda_deploy/wheels/*.whl 2>/dev/null | wc -l"
done
```
### 步骤 3部署 sskj 仓库到 .5 和 .1(一次性)
`deploy_pd.sh` 依赖 sskj 仓库:.5 上用于编排,.1 上用于执行 P 组 deploy 层命令。
```bash
# .5 上已有仓库则跳过;没有则 clone在 .5 上执行)
git clone https://git.meta-stone.net/qqtang/sskj.git /data/yy/sskj
# .1 上也必须 clonedeploy_pd.sh 会在 .1 执行 python -m sskj.deploy
ssh 174.1.60.1 "mkdir -p /data/yy && git clone https://git.meta-stone.net/qqtang/sskj.git /data/yy/sskj"
# 保持两边同步最新
cd /data/yy/sskj && git pull origin main
ssh 174.1.60.1 "cd /data/yy/sskj && git pull origin main"
```
### 步骤 4拉取镜像一次性
```bash
for h in 1 2 3 4 5 6 7 8; do
ssh 174.1.60.$h "docker pull lmsysorg/sglang:kimi-k3" &
done; wait
```
### 步骤 5一键启动每次部署执行
```bash
cd /data/yy/sskj/experiments/pro6000/kimi3_pro6000_pd_rdma
bash deploy_pd.sh start
# 预计 12~18 分钟(模型加载 + CUDA graph + PD warmup
```
### 步骤 6验证
```bash
# 看状态
bash deploy_pd.sh status
# 端到端推理(应有正常文本返回)
curl -s http://174.1.60.5:31000/generate -H "Content-Type: application/json" -d '{"text":"Hello","sampling_params":{"max_new_tokens":16}}'
```
### 停止 / 重启
```bash
bash deploy_pd.sh stop # router → D 组 → P 组 → mc-master
bash deploy_pd.sh restart
```
### 部署文件来源
- `patch_k3_sm120.py``flash_kda-0.0.1-*.whl`:模型团队产物(见 `docs/KIMI_K3_DEPLOY.md` 附录 A
- `mooncake_transfer_engine_cuda13-0.3.12.post1-*.whl``/data/flashkda_deploy/wheels/`
- 若文件缺失,找模型团队提供或重新构建/下载
## 使用
```bash
# 一键启动mc-master → P 组 → D 组 → router
bash deploy_pd.sh start
# 查看状态
bash deploy_pd.sh status
# 停止 / 重启
bash deploy_pd.sh stop
bash deploy_pd.sh restart
# 端到端验证router 入口,自动双发 P/D
curl -s http://174.1.60.5:31000/generate -H "Content-Type: application/json" \
-d '{"text":"Hello","sampling_params":{"max_new_tokens":16}}'
```
## 实测验证2026-08-11
| 测试 | 输入 tokens | 输出 tokens | 结果 |
|---|---|---|---|
| warmup | 6 | 16 | ✅ 200 OK |
| 中等 | 1680 | 512 | ✅ e2e 31.4s |
| 长输入 | 5280 | 256 | ✅ e2e 13.0s |
- P 组 prefill throughput ~112 tok/s5280 token 输入D 组 decode ~26 tok/s
- 两端 GPU 同步工作,**PD 分离链路完整跑通**
- 对比 NIXLMoonCake RDMA 处理长 KV 传输稳定,无 20MB 上限问题
## 文件
| 文件 | 说明 |
|---|---|
| `deploy_pd.sh` | PD 编排脚本mc-master + P + D + router 全生命周期) |
| `config.env` | 实验配置 |
| `deploy/profiles/pro6000/kimi3_pro6000_pd_prefill.env` | P 组prefill部署 profile |
| `deploy/profiles/pro6000/kimi3_pro6000_pd_decode.env` | D 组decode部署 profile |
## 参考
- 飞书 wiki「Kimi-K3 部署手册」PD 分离章节(七~十一章)
- GitHub kvcache-ai/Mooncake: #2511expandable_segments 注册失败)、#2035dmabuf 修复)、#351Bad address