Project-level documentation was scattered and duplicated across README.md, BENCHMARK_WORKFLOW.md, and docs/EXPERIMENT_GUIDE.md (directory layout + scripts/common component table repeated 3x). Reorganize into a clear single-source-of-truth structure. Changes: - README.md: drop the 6 stale changelog entries at the top (latest was 07-21; history lives in git log). Replace the duplicated directory- layout + scripts/common sections with a one-line link to docs/EXPERIMENT_GUIDE.md. (151 -> 99 lines) - BENCHMARK_WORKFLOW.md -> docs/BENCHMARK_WORKFLOW.md: relocate into docs/. Replace its duplicated Directory Layout and Quick Start/Adding sections with links to EXPERIMENT_GUIDE / README / NEW_PLATFORM_GUIDE; keep the unique parts (Rules, Naming Conventions, Final JSON Schema, Checklist). (394 -> 224 lines) - docs/EXPERIMENT_GUIDE.md: now the single authority for directory layout + component table + experiment conventions. Add a cross-link from the results.json field list to BENCHMARK_WORKFLOW's full JSON Schema and Naming Conventions. - docs/H200_QUICKSTART.md: deleted (outdated, repeatedly references removed legacy scripts; H200 usage is covered by ADAPTIVE_CONCURRENCY_USAGE and experiment READMEs). - docs/DSV4_INFERENCE_COMPARISON_REPORT.md -> experiments/h200/ dsv4_h200_vllm_mtp_vs_default/results/20260708-160349/: this is an experiment report, not a project doc; relocate next to its sibling report.md. - envs/ASCEND_910C_ENV_SETUP.md §8: expand the vague "pip install sglang" note into a full sglang client image build guide -- pin sglang 0.5.2 (not latest; >=0.5.16 deprecates bench_serving and breaks the parser), --no-deps minimal install loop, docker commit to a local image, with the exact commands used to build local/vllm-ascend:0.23-a3-dsv4-sglang. - experiments/h200/dsv4_h200_vllm_tp2_custom_bench/README.md: fix the now-broken link to BENCHMARK_WORKFLOW.md (../../ -> ../../../docs/). - .gitignore: ignore *.bak.glm52orig scratch backups. Also includes the add16 adaptive_results produced by the dsv4 TP=4/DP=2 runs on 910c.1.
204 lines
8.7 KiB
Markdown
204 lines
8.7 KiB
Markdown
# Ascend 910C 环境搭建与部署指南
|
||
|
||
本文档说明如何在 Ascend 910C NPU 节点上搭建 vLLM-Ascend 推理环境并跑起 sskj 基准测试。
|
||
|
||
## 1. 环境信息(参考机型:910c.1 / NPU-NODE61)
|
||
|
||
| 项目 | 值 |
|
||
|---|---|
|
||
| OS | openEuler 22.03 LTS SP4 (aarch64) |
|
||
| 内核 | 5.10.0-216.0.0.115.oe2203sp4.aarch64 |
|
||
| NPU | 8 × Ascend910(每卡 2 die,共 16 die) |
|
||
| HBM | 64 GB/die,合计 ~1 TB |
|
||
| 驱动 | 25.5.2(Innerversion V100R001C23SPC007B221) |
|
||
| CANN | 9.0.0 + ascend-toolkit |
|
||
| Docker | 26.1.3,默认 runtime = ascend(见 `/etc/docker/daemon.json`) |
|
||
| Python (host) | 3.9.9(仅用于编排脚本,推理在容器内) |
|
||
|
||
## 2. 权限准备 🧑
|
||
|
||
新用户默认无法访问 NPU 设备节点和 Docker,需要管理员加入两个组:
|
||
|
||
```bash
|
||
# 加入 HwHiAiUser 组才能访问 /dev/davinci* 设备节点
|
||
sudo usermod -aG HwHiAiUser <user>
|
||
# 加入 docker 组才能调用 docker(或每次 sudo docker)
|
||
sudo usermod -aG docker <user>
|
||
# 重新登录生效
|
||
exit # 然后重新 ssh
|
||
```
|
||
|
||
验证:
|
||
|
||
```bash
|
||
id # 应看到 HwHiAiUser 和 docker 组
|
||
npu-smi info # 应输出 8 卡 16 die 的状态表
|
||
docker ps # 不应报 permission denied
|
||
```
|
||
|
||
## 3. 加载 vLLM-Ascend 镜像
|
||
|
||
910C 节点离线,vLLM-Ascend 镜像以 tarball 形式存放在 `/mnt/models/`:
|
||
|
||
| tarball | 用途 |
|
||
|---|---|
|
||
| `vllm-ascend-v0.23.0rc1-a3-openeuler.tar` | 通用 v0.23,适合 DSV4-Flash |
|
||
| `vllm-ascend-glm5.2-a3-openeuler.tar` | GLM5.2 调优版(推荐跑 GLM5.2) |
|
||
| `vllm-ascend-v0.22.1rc1-a3.tar` | 旧版 v0.22 |
|
||
| `local-vllm-ascend-0.23-a3.tar` | 本地构建的 0.23 |
|
||
|
||
加载(任选需要的):
|
||
|
||
```bash
|
||
docker load -i /mnt/models/vllm-ascend-glm5.2-a3-openeuler.tar
|
||
docker load -i /mnt/models/vllm-ascend-v0.23.0rc1-a3-openeuler.tar
|
||
docker images | grep vllm-ascend # 记下确切的 REPOSITORY:TAG
|
||
```
|
||
|
||
加载后把镜像 tag 写入对应实验的 `config.env`:
|
||
|
||
```bash
|
||
# experiments/910c/glm52_910c_vllm_tp_dp_matrix/config.env
|
||
DOCKER_IMAGE="<加载后看到的 repository:tag>"
|
||
```
|
||
|
||
## 4. 模型权重
|
||
|
||
当前 `/mnt/models/` 下已有:
|
||
|
||
- `GLM-5.2-w4a8c8/`(95 shards,默认用这个)
|
||
- `GLM-5.2-w8a8/`(181 shards,需切换时改 `MODEL_PATH`)
|
||
|
||
**DeepSeek-V4-Flash 尚未下载**。需要时下载到 `/mnt/models/DeepSeek-V4-Flash`(FP8)或 `/mnt/models/DeepSeek-V4-Flash-INT8`,再改 `experiments/910c/dsv4_910c_vllm_tp_dp_matrix/config.env` 的 `MODEL_PATH`。
|
||
|
||
## 5. 数据集
|
||
|
||
`sglang.bench_serving --dataset-name random` 需要 ShareGPT 种子文件:
|
||
|
||
```bash
|
||
mkdir -p /mnt/yy/sskj/datasets
|
||
# 放入 ShareGPT_V3_unfiltered_cleaned_split.json
|
||
# (从 https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered 下载)
|
||
```
|
||
|
||
`DATASET_PATH` 默认指向 `${ROOT_DIR}/datasets/ShareGPT_V3_unfiltered_cleaned_split.json`,无需改 config。
|
||
|
||
## 6. Ascend Docker Runtime 说明
|
||
|
||
本机的 `/etc/docker/daemon.json` 已配置:
|
||
|
||
```json
|
||
{
|
||
"default-runtime": "ascend",
|
||
"runtimes": {
|
||
"ascend": {
|
||
"path": "/usr/local/Ascend/Ascend-Docker-Runtime/ascend-docker-runtime",
|
||
"runtimeArgs": []
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
因此 `docker run` **无需** `--runtime ascend` 或 `--gpus`,只需通过环境变量 `ASCEND_VISIBLE_DEVICES=0,1,2,3,4,5,6,7` 指定要映射的 NPU 卡号,runtime 会自动把对应 die 的 `/dev/davinci*` 注入容器。
|
||
|
||
## 7. 冒烟测试 🤖
|
||
|
||
```bash
|
||
cd /mnt/yy/sskj/experiments/910c/glm52_910c_vllm_tp_dp_matrix
|
||
|
||
# 1. dry-run:只打印搜索计划,不起服务
|
||
DRY_RUN=1 bash run_adaptive_concurrency_add16.sh
|
||
|
||
# 2. 单 shape 小并发冒烟(TP=8,1K/128,并发上限 8)
|
||
RUN_ID=smoke-$(date +%Y%m%d-%H%M%S) \
|
||
TP_LIST="8" ISL_LIST="1024" OSL_LIST="128" GRID_LIMIT=1 SEARCH_MAX_CONCURRENCY=8 \
|
||
bash run_adaptive_concurrency_add16.sh
|
||
```
|
||
|
||
冒烟常见失败原因:
|
||
|
||
| 现象 | 根因 | 解决 |
|
||
|---|---|---|
|
||
| `dcmi module initialize failed` | 用户不在 HwHiAiUser 组 | 见 §2 |
|
||
| `docker: permission denied` | 用户不在 docker 组 | 见 §2 |
|
||
| 容器内 `ModuleNotFoundError: torch_npu` | 镜像未正确加载 / tag 写错 | `docker images` 核对 |
|
||
| `sglang.bench_serving` ModuleNotFoundError | vllm-ascend 镜像不含 sglang | 见 §8 |
|
||
| 启动即 OOM | TP 过小,专家权重放不下 | 见 config.env 显存预算注释 |
|
||
|
||
## 8. Benchmark Client 说明 ⚠️
|
||
|
||
sskj 的压测客户端是 `sglang.bench_serving`,但 **vllm-ascend 官方镜像不含 sglang**。两个选择:
|
||
|
||
1. **(推荐) 构建带 sglang 的 vllm-ascend 镜像**:见 §8.1,一次性构建后所有实验复用。
|
||
2. **外部 sglang 镜像**:设 `USE_DOCKER_CLIENT=1`,提供 `DOCKER_CLIENT_IMAGE=lmsysorg/sglang:xxx`,用独立容器通过 host 网络打 vLLM 的 OpenAI API。但 sglang 官方镜像多为 x86 + CUDA,aarch64 NPU 节点上拉不到对应架构镜像,不推荐。
|
||
|
||
建议冒烟前先确认客户端方案,否则 adaptive 搜索会在 `engine_run_bench` 阶段失败。
|
||
|
||
### 8.1 构建带 sglang 客户端的 vllm-ascend 镜像
|
||
|
||
> **版本要求**:必须装 **sglang 0.5.2**,不是最新版。
|
||
> - sglang ≥ 0.5.16 已废弃 `sglang.bench_serving`(改为 `sglang.benchmark.serving`),输出格式变了,与 `scripts/common/adaptive_concurrency.py` / `parse_backend.py` 的解析逻辑不兼容。
|
||
> - glm52 实验的解析器修复(commit 98cdb67)针对的就是 0.5.2 的输出格式。dsv4/glm52 实验的 `config.env` 默认镜像 `local/vllm-ascend:0.23-a3-*-sglang` 即基于 0.5.2 构建。
|
||
|
||
**关键原则**:用 `pip install --no-deps` 只装 sglang 本体 + bench_serving 的轻量依赖,**不要装完整 sglang**(会拉 torch/transformers 等重依赖,破坏容器内 vllm 环境)。
|
||
|
||
构建步骤(在 910C 节点上,需 sudo docker):
|
||
|
||
```bash
|
||
# 1. 启动一个临时容器(基础镜像 = 实验用的 vllm-ascend 镜像)
|
||
BASE=quay.io/ascend/vllm-ascend:v0.23.0rc1-a3-openeuler
|
||
sudo docker rm -f sglang-build 2>/dev/null
|
||
sudo docker run -d --name sglang-build \
|
||
--device /dev/davinci0 --device /dev/davinci_manager \
|
||
--device /dev/devmm_svm --device /dev/hisi_hdc \
|
||
-v /usr/local/dcmi:/usr/local/dcmi \
|
||
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
|
||
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
|
||
-v /etc/ascend_install.info:/etc/ascend_install.info \
|
||
$BASE sleep infinity
|
||
|
||
# 2. 装 sglang 0.5.2 本体(--no-deps,不碰 vllm 环境)
|
||
sudo docker exec sglang-build pip install --no-deps "sglang==0.5.2"
|
||
|
||
# 3. 循环补齐 bench_serving 缺失的轻量依赖(自动检测 ModuleNotFoundError 并安装)
|
||
# 会装约 8 个包:ipython/traitlets/stack_data/executing/asttokens/pure_eval/prompt_toolkit/wcwidth
|
||
# (都是 IPython 依赖链,bench_serving 通过 sglang.utils 间接引入)
|
||
sudo docker exec sglang-build bash -c '
|
||
for i in $(seq 1 50); do
|
||
OUT=$(python -c "import sglang.bench_serving" 2>&1)
|
||
[ -z "$OUT" ] && { echo "IMPORT_OK"; break; }
|
||
MOD=$(echo "$OUT" | grep -oE "No module name .[a-zA-Z0-9_]+." | head -1 | sed "s/No module name //;s/.//")
|
||
[ -z "$MOD" ] && { echo "NON_MODULE_ERR: $OUT"; break; }
|
||
echo "iter $i: $MOD"
|
||
pip install --no-deps "$MOD" 2>&1 | grep -i Successfully
|
||
done
|
||
'
|
||
|
||
# 4. 验证
|
||
sudo docker exec sglang-build python -m sglang.bench_serving --help | head -3
|
||
|
||
# 5. commit 成新镜像(tag 按实验命名,如 dsv4 / glm52)
|
||
sudo docker commit sglang-build local/vllm-ascend:0.23-a3-dsv4-sglang
|
||
sudo docker rm -f sglang-build
|
||
```
|
||
|
||
构建完成后,把 `config.env` 的 `DOCKER_IMAGE` 指向新镜像即可。容器内 Python 路径是 `/usr/local/python3.12.13/bin/python3`(不是 `/usr/local/bin/python`,后者不存在),`config.env` 的 `CONTAINER_PYTHON` 已设为此值。
|
||
|
||
## 9. NPU 监控
|
||
|
||
公共库 `adaptive_bench_lib.sh` 的 GPU 监控写死 `nvidia-smi`,910C 实验脚本已用 `npu-smi info` 重写 `adaptive_start_gpu_monitor` / `start_gpu_monitor`,输出与 nvidia-smi 相同的 CSV 列(timestamp, index, memory.used, memory.total, utilization.gpu),下游 `parse_backend.py` 无需改动。
|
||
|
||
手动查看 NPU 状态:
|
||
|
||
```bash
|
||
npu-smi info # 总览
|
||
npu-smi info -t usages -i 0 # 单卡详细利用率
|
||
```
|
||
|
||
## 10. 已知坑
|
||
|
||
1. **TP 与 die 的关系**:910C 每卡 2 die,vllm-ascend 按 die 分配 TP。`ASCEND_VISIBLE_DEVICES=0..7` 暴露 8 卡 = 16 die,因此 TP 最大 16(本实验限 TP≤8)。
|
||
2. **KV cache dtype**:910C 支持 fp8 KV cache,但部分 vllm-ascend 版本在 NPU 上对 fp8 KV 支持不完整。若启动报 `kv-cache-dtype fp8 not supported`,改 `KV_CACHE_DTYPE=fp16`。
|
||
3. **block-size**:NPU 推荐 128(NVIDIA H20 用 256)。若性能异常可尝试 64/128/256 对比。
|
||
4. **DSV4-Flash FP8 显存**:路由专家 ~264 GiB,TP=2/4 在 64GB die 上几乎必 OOM(见 dsv4 config.env 注释)。用 INT8 权重或限 TP≥8。
|