- sskj.deploy runtime 支持 NODE_HOSTS 多节点编排(ssh 分发/本地 rank/LOCAL_NODE_RANK)
与 ENGINE=vllm 启动(SERVER_CMD),容器名按 rank 自动唯一
- scripts/common/deploy_cli.sh 新增 deploy_stop/status/multinode helper 与 node-rank 透传
- src/sskj/common/env.py 修复嵌套 ${VAR:-${OTHER}/path} 展开(平衡花括号扫描)
- deploy/profiles/pro6000/ 新增 6 个 profile: tp16/tp16_eagle/glm52(多节点)、
sglang/vllm tp_dp_matrix、qwen3(单节点)
- 6 个实验 start/stop 脚本改为 deploy 薄包装,run_bench/adaptive 的 server 启停走
deploy_render_args/deploy_start/deploy_stop,tp16 新增 matrix.json
- 首次入库 glm52_pro6000_sglang_multinode_tp16 实验目录;ops/README.md 补 pro6000 章节
- 实测通过: 单节点 dsv4 sglang/vllm 链路 + tp16 双节点启动/bench/清理
5.7 KiB
5.7 KiB
GLM-5.2-FP8 多机部署(SGLang TP=16,2×RTX 6000D 节点)
在 pro6000D.1 + pro6000D.3 两台机器(各 8×RTX 6000D)上多机部署 GLM-5.2-FP8, 并对齐 H20 / DSV4 实验的 benchmark 方法做 TP×DP 矩阵测试。
为什么必须多机
GLM-5.2 是 MoE 模型:总参数约 735B,FP8 权重约 700GB(256 路由专家 + 1 共享 专家,每 token 激活 8 个,DeepSeek-V3 架构)。单机 8 卡 RTX 6000D 显存共 685GB, 装不下 700GB 权重,因此 2 节点 16 卡是必需项,不是优化项。
架构
HTTP 请求 (bench_serving)
│
▼
┌──────────────┐ NCCL/RoCE (41.6GB/s) ┌──────────────┐
│ pro6000D.1 │ ◄══════════════════════► │ pro6000D.3 │
│ node-rank 0 │ 计算网 10.101/10.102 │ node-rank 1 │
│ 持有 1/2 权重 │ │ 持有 1/2 权重 │
│ HTTP :30031 │ │ 不暴露 HTTP │
└──────────────┘ └──────────────┘
- node0(pro6000D.1):主节点,对外暴露 HTTP API,接收所有请求。
- node1(pro6000D.3):从节点,只做计算,不对外服务。
- 两机通过 NCCL 连接:
--dist-init-addr <node0_ip:port> --nnodes 2 --node-rank <0|1>。 - NCCL bootstrap 走管理网(174.1.51.x),数据面走 RoCE 计算网(mlx5_0/mlx5_3)。
- benchmark 客户端只打 node0 的 HTTP,感知不到背后是两台机器。
前置条件(两台机器都要满足)
- 模型文件:两机都要有完整的 GLM-5.2-FP8,路径统一为
/data/hf_models/GLM-5.2-FP8(141 个 safetensors + index.json)。- pro6000D.1:下载中(截至编写时 112/141 分片)。
- pro6000D.3:当前没有,需补齐(从 .1 rsync 传过去或重新下载)。
- Docker 镜像:两机都要有
lmsysorg/sglang:nightly-dev-cu13-20260720-b3570a45(sglang dev,原生支持 GLM-5.2 的glm_moe_dsa架构)。- pro6000D.1:已有。
- pro6000D.3:下载中。
- SSH 互通:node0 能
ssh pro6000D.3免密登录(已配置)。 - NCCL 跨机已验证:双 NIC 调优后 all_reduce busbw 41.6 GB/s(见带宽报告)。
文件说明
| 文件 | 作用 |
|---|---|
config.env |
全局配置:模型路径、TP=16、上下文 256K、NCCL 调优、节点拓扑 |
start_sglang_node.sh <rank> |
单节点启动(参数化 rank),node0/node1 共用 |
start_sglang_multinode.sh <tp> <dp> |
多机编排:sync→起 node1→起 node0→等 health |
stop_sglang_multinode.sh <tp> <dp> |
多机停止:停 node0(本地)+ node1(ssh) |
start_sglang_dp.sh <tp> <dp> |
run_bench 入口,委托给 multinode 编排 |
run_bench.sh |
TP×DP 矩阵 benchmark(复用 DSV4 模板,改 stop 为多机) |
matrix.json |
ISL×OSL 测试矩阵(复用 DSV4) |
adaptive_config.env |
自适应并发搜索配置(复用 DSV4) |
NCCL 调优(关键,不可省)
跨机必须带以下环境变量(已固化在 config.env,注入容器),否则带宽从 41.6 跌到 21 GB/s:
NCCL_IB_HCA=mlx5_0,mlx5_3 # 启用两张 RoCE 网卡
NCCL_MIN_NCHANNELS=8 # 强制 8 channel 分流到两卡
NCCL_IB_QPS_PER_CONNECTION=4 # 每连接 4 QP 提升 RoCE 并行
NCCL_NET_GDR_LEVEL=PHB # GPUDirect RDMA
NCCL_SOCKET_IFNAME=eth1 # bootstrap 走管理网网卡
用法
冒烟测试(单场景验证端到端)
cd /data/yy/sskj/experiments/pro6000/glm52_pro6000_sglang_multinode_tp16
GRID_LIMIT=1 DRY_RUN=0 bash run_bench.sh
全矩阵(low/high 两个并发点)
CONCURRENCY_SAMPLES=2 bash run_bench.sh
手动起停(不走 bench)
bash start_sglang_dp.sh 16 1 # 起两机,等 node0 health
bash stop_sglang_multinode.sh 16 1 # 停两机
手动单独起 node1(调试)
ssh pro6000D.3 'cd /data/yy/sskj/experiments/pro6000/glm52_pro6000_sglang_multinode_tp16 && bash start_sglang_node.sh 1'
启动流程说明
start_sglang_multinode.sh 做的事:
- rsync 实验目录到 node1(让 node1 有 config.env + start_sglang_node.sh)
- ssh 后台起 node1:
ssh pro6000D.3 '... start_sglang_node.sh 1',node1 启动容器后进入 rendezvous 等待窗口,等 node0 连接 - 本地起 node0:
start_sglang_node.sh 0,node0 发起 NCCL 连接,两机会合后 一起加载模型 - 轮询 node0 /health:就绪后返回(最多等 480×5s=40 分钟,多机加载慢)
node1 的日志在远端 /tmp/glm52_node1_inner.log 和本实验 runtime/logs/ 下。
与 H20 基线对比
- H20 基线:
experiments/h20/glm_h20_vllm_tp_dp_matrix,单机 8 卡 vLLM TP=8。 - 本实验:2 机 16 卡 SGLang TP=16。
- 框架不同(vLLM vs SGLang)、并行不同(单机 TP=8 vs 多机 TP=16),
对比时需注明。但 benchmark 方法一致(sglang bench_serving + 同一 matrix.json
- 自适应并发),吞吐/延迟指标可对照。
- 用
compare.py对比两边 results。
注意事项
- 单机 TP=8 装不下:735GB 权重 ÷ 8 卡 ≈ 92GB/卡 > 85.6GB 单卡上限,会 OOM。 必须多机。
- CUDA 版本不一致(.1 是 12.8、.3 是 13.0)不影响:两机都在 cu130 容器内跑, 宿主机 CUDA 版本无关。
- node1 不暴露 HTTP:所有请求打 node0,node1 纯计算。
- 加载慢:700GB 权重 + NCCL 建连,首次加载预计 10-20 分钟,health 轮询 上限设了 40 分钟。