# 新平台接入指南（New Platform Onboarding SOP）

> 目标：新显卡（GPU/NPU）到货后，用最短时间跑起与既有平台口径一致的推理性能实验。
> 读者：执行接入的人或 Agent。带 🤖 的步骤 Agent 可自动完成；带 🧑 的步骤需要人确认或提供信息。

## 0. 前置准备 🧑

接入前确认以下信息就绪，缺一项都会卡住后续步骤：

| 项目 | 说明 | 示例 |
|---|---|---|
| 机器与驱动 | 8 卡整机，驱动/固件可用，`nvidia-smi` 或厂商等价工具（`xpu-smi`）能看到全部卡 | — |
| 推理镜像 | 该平台可用的 vLLM / SGLang 镜像或 native 环境 | `vllm/vllm-openai:latest`、`iregistry.baidu-int.com/xpu/sglang-p800-...` |
| 模型权重 | 模型在本机的路径与精度格式 | `/data1/hf_models/DeepSeek-V4-Flash`（FP8）、`/data1/models/DeepSeek-V4-Flash-INT8` |
| 上下文上限 | 该平台显存能支撑的 max context | H20：1M；P800 INT8：140k |
| 数据集 | ShareGPT 种子文件（random workload 用） | `datasets/ShareGPT_V3_unfiltered_cleaned_split.json` |
| 显存约束 | 单卡显存，预判 TP/DP 可行性（见 §4.2） | P800 96 GiB/卡 → TP2 放不下 INT8 专家权重 |

## 1. 平台配置 🤖

1. 新建 `platforms/<chip>.env`（参考 `platforms/nvidia_h20.env` / `platforms/kunlun_p800.env`），至少包含 `CHIP`、`ACCELERATOR`、`HARDWARE`、`ENGINE`、`DEFAULT_PORT`、`MODEL_ROOT`；Docker 平台再加 `DOCKER_IMAGE`、`CONTAINER_NAME`；需要运行时补丁的加 `PATCH_ROOT` 并把补丁放到 `platforms/patches/<chip>/`。
2. 在 `scripts/common/platform.sh` 的自动探测分支里加上新平台（当前只识别 P800 / H20 / 其他 NVIDIA→H200，**新 NVIDIA 卡不改会被误判成 H200**）。
3. 在 `platforms/README.md` 的平台表中加一行。

## 2. 复制实验目录 🤖

**NVIDIA 平台**（有官方 vLLM/SGLang 镜像）直接复制 H20 目录——它是路径正确、维护最新的范本，且 NVIDIA 平台间 `start_*_docker.sh` 零改动可复用：

```bash
cp -r experiments/h20/dsv4_h20_vllm_tp_dp_matrix experiments/<chip>/dsv4_<chip>_vllm_tp_dp_matrix
cp -r experiments/h20/dsv4_h20_sglang_tp_dp_matrix experiments/<chip>/dsv4_<chip>_sglang_tp_dp_matrix
# 清理复制过来的结果与缓存
rm -rf experiments/<chip>/*/adaptive_results experiments/<chip>/*/results experiments/<chip>/*/__pycache__
```

**非 NVIDIA 平台**（XPU 等）同样从 H20 目录复制，但需按 §4 重写启动脚本与平台回调，以 `experiments/p800/dsv4_p800_sglang_tp_dp_matrix` 为范例。

> 不要抄 `experiments/h200/` 或 `experiments/pro6000/` 的目录结构组织方式以外的内容：那里存在 `dsl`（应为 `osl`）的批量误改名残留，新目录以 H20 版为准。

## 3. 修改三件套配置 🤖（🧑 确认关键参数）

### 3.1 `config.env`（核心参数面板）

| 必改项 | 说明 |
|---|---|
| `EXPERIMENT` | 实验名，与目录名一致 |
| `MODEL_NAME` / `MODEL_PATH` / `SERVED_MODEL_NAME` | 本机模型路径（机器相关） |
| `DOCKER_IMAGE` / `CONTAINER_NAME` | 平台镜像；容器名专用化避免冲突 |
| `VLLM_PORT` / `SGLANG_PORT` | 避开已占用端口 |
| `CUDA_VISIBLE_DEVICES` / `XPU_VISIBLE_DEVICES` | 设备选择 |
| `MAX_MODEL_LEN` / `CONTEXT_LENGTH` | 按平台显存与需求设定 |
| `GPU_MEMORY_UTILIZATION` / `MEM_FRACTION_STATIC` | 显存水位（H20 0.9 / P800 0.8） |
| `KV_CACHE_DTYPE`、`BLOCK_SIZE` / `PAGE_SIZE` | KV cache 精度与块大小 |
| `PARALLEL_CONFIGS` | 按显存裁剪（见 §4.2） |
| `DATASET_PATH` | 本机数据集路径 |

### 3.2 `adaptive_config.env`

一般保持默认即可（起步 C=16、×2 或 +16 步进、TTFT_SLO_MS=4000、TTFT_GROUP_SKIP_MS=8000、num_prompts=5×C）。显存小或单请求 prefill 慢的平台，可适当降低 `SEARCH_MAX_CONCURRENCY`。

### 3.3 `matrix.json`

按 `CONTEXT_LENGTH` 和显存砍 shape：超出上下文上限的 ISL 删掉，显存放不下的组合标 `N`。参照 H20（1M 上下文，7 个 ISL 档）与 P800（140k 上下文，5 个 ISL 档）两版的取舍。

## 4. 非 NVIDIA 平台的额外工作（以 P800 为范例）🧑🤖

### 4.1 需要重写的地方

- **`start_*_docker.sh`**：设备映射（如 `/dev/xpu*`）、厂商 env 变量、引擎 launch args（attention backend、量化、kv-cache dtype、cuda graph 等价物开关）、补丁挂载（如 P800 挂 `bench_serving.py` 补丁补 P95 指标）、容器内 bootstrap。
- **`run_adaptive_concurrency*.sh` 的 5 个 `engine_*` 回调**：`engine_start_server` / `engine_stop_server`（pid kill 还是 `docker rm -f`）、`engine_run_bench`（独立客户端容器还是 `docker exec` 进服务端容器）、`engine_detect_oom`（日志文件还是 `docker logs`）、`engine_build_server_args`。
- **GPU 监控**：公共库的 `adaptive_start_gpu_monitor` 写死 `nvidia-smi`，非 NVIDIA 平台在 run 脚本里用厂商工具重写该函数（P800 即用 `xpu-smi` 覆盖）。
- **warmup 能力差异**：部分厂商镜像的 bench_serving 不支持 `--warmup-requests`，需设 `BENCH_WARMUP_MAX_REQUESTS=0` 并在 adaptive_config.env 里注明。

### 4.2 显存可行性预判（避免白跑）

MoE 模型的专家权重在未开 EP 时按 TP 组切分、DP 副本间不共享：每卡专家权重 ≈ 专家总权重 / TP。实例：DSV4-Flash-INT8 路由专家约 264 GiB，P800 单卡 96 GiB → TP=2 每卡需 137 GiB，启动即 OOM，TP≥4 才可行。接入时先算一遍，把不可行的配置从 `PARALLEL_CONFIGS` 去掉，并把根因写进 config.env 注释（照 P800 的做法）。

## 5. 冒烟 🤖

```bash
cd experiments/<chip>/dsv4_<chip>_<engine>_tp_dp_matrix

# 1. dry-run：只打印计划，不起服务
DRY_RUN=1 bash run_adaptive_concurrency_add16.sh

# 2. 单 shape 小并发：验证起服务、发压测、出指标全链路
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

# 3. 检查 smoke 产物：adaptive_results/smoke-*/adaptive_points.jsonl 应有 COMPLETED 点
```

冒烟失败的常见原因：镜像 launch args 不被支持（查服务端日志）、端口冲突、数据集路径不存在、显存不足（回 §4.2）。

## 6. 正式跑 🤖

```bash
tmux new-session -d -s <chip>-<engine>-adaptive \
  "cd $(pwd) && bash run_adaptive_concurrency_add16.sh"
```

- 心跳监控：`scripts/common/adaptive_heartbeat.sh` 或 `tail -f adaptive_results/<run_id>/logs/orchestrator.log`。
- 中断了用 `RESUME_RUN_ID=<run_id>` 断点续跑（按已终态 shape 去重）。
- 完整参数说明见 `experiments/ADAPTIVE_CONCURRENCY_USAGE.md`。

## 7. 分析、报告与归档 🤖（🧑 确认发布）

1. **分析**：用 Python 从 `adaptive_points.jsonl` / `adaptive_shapes.jsonl` 实算（SLO：TTFT P95 < 3s 且 TPOT P95 < 50ms，严格小于），禁止目测估算。
2. **飞书报告**：按飞书 wiki「显卡性能报告 / 性能报告编写指南（README）」的骨架写到「显卡性能报告/<平台>」节点下；图表用 `envs/charts/bin/python` + matplotlib 生成。
3. **多维表格**：在「模型推理适配 Bench 迭代跟踪」的对应平台表（没有则按现有 schema 新建）按"每成功探测点一行"回填；`SLO达标状态` 按上述口径判定。
4. **提交**：实验代码 + `adaptive_results/<run_id>/` 下的汇总级文件入库——`adaptive_points.jsonl`、`adaptive_shapes.jsonl`、`adaptive_summary.jsonl/md`、`run_manifest.json`、`shapes.tsv`，这些是云端共享的数据资产；`tp*_dp*/` 子目录（raw_outputs 逐请求数据、metrics、logs、gpu_logs、server_cmd.txt）与中间日志一律不入库。

## 8. 完成检查清单

- [ ] `platforms/<chip>.env` 已建，`platform.sh` 探测分支已加，`platforms/README.md` 已更新
- [ ] `config.env` / `adaptive_config.env` / `matrix.json` 三件套已按平台调整
- [ ] smoke 通过（有 COMPLETED 探测点）
- [ ] 正式 run 的 `run_manifest.json` 参数正确
- [ ] 飞书报告已发布到对应平台节点下
- [ ] 多维表格已回填
- [ ] git 提交不含日志、raw_outputs、gpu_logs

## 9. 已知坑

1. **公共库路径层级**：`experiments/<platform>/<experiment>/` 下的脚本引用公共组件必须是 `${SCRIPT_DIR}/../../../scripts/common`；`experiments/TEMPLATE/` 下是 `../../`。写错会在 source 阶段直接失败。
2. **机器相关绝对路径**：模型、数据集、venv 路径随机器不同（`/data1/...`、`/data3/...`），换机器先改 config.env，不要在脚本里写死。
3. **TTFT SLO 停止 ≠ 饱和**：add16 流派的搜索在 P95 TTFT 超 4000ms 即停，绝大多数 shape 不会到达 TPS 平台期，报告中的"最佳 TPS"是 TTFT 边界内最高值，分析时不要当成吞吐上限。
4. **`dsl` 命名坑**：h200/pro6000 目录部分文件把 `osl` 误改名成 `dsl`（含 CSV 表头），复制时以 h20 目录为准。
5. **结果结构以 jsonl 为准**：`.gitignore` 排除 csv/logs，跨机器汇总数据时用 `adaptive_points.jsonl`、`adaptive_shapes.jsonl`、`adaptive_summary.*`、`run_manifest.json`。

## 10. 新模型接入（GLM5.2）

GLM5.2 **完全复用**本 SOP 的实验与报告流程，差异只在配置层：

1. 新目录命名 `experiments/<platform>/glm52_<platform>_<engine>_tp_dp_matrix/`；
2. `config.env` 改模型路径、`SERVED_MODEL_NAME`、量化方式（按发布精度）、`CONTEXT_LENGTH`（按模型实际上限）、引擎 launch args（attention backend / rope / 量化 flag 等按模型要求）；
3. `matrix.json` 按模型上下文上限调整 ISL 档；
4. SLO 口径、报告骨架、多维表格结构不变；多维表格的 `模型名称` 选/新增 GLM5.2 对应选项。
