Auto-detect Scout/Maverick from config.json and add verify script
This commit is contained in:
242
README.md
242
README.md
@@ -3,17 +3,17 @@
|
||||
在 16×Iluvatar BI-V150 32GB 上运行 Llama 4 Scout 与 Maverick 的统一 Docker 部署仓库。
|
||||
|
||||
> 本仓库合并自原先独立的 `llama4-scout-deploy` 和 `llama4-maverick-deploy`,
|
||||
> 用一个镜像 + 两个运行预设替代两套重复的 Dockerfile。
|
||||
> 用一个镜像 + 自动模型检测替代两套重复的 Dockerfile 和手动 profile。
|
||||
|
||||
- 基础镜像:`registry.iluvatar.com.cn:10443/customer/sz/vllm0.17.0-4.4.0-x86:v7`(vLLM `0.17.0+corex`)
|
||||
- 一个镜像同时支持 Scout 和 Maverick;模型权重不打进镜像,运行时只读挂载
|
||||
- 两个模型共用 Llama 4 chunked-attention 补丁;Maverick 额外使用 FP8 量化 / FP8 MoE 补丁
|
||||
- CI 使用 ModelHub 标准 Gitea Actions:推送 `v*` 标签后构建、推送镜像并提交审核
|
||||
|
||||
| 模型 | 精度 | 并行 | GPU 数 | 默认端口 |
|
||||
| 模型 | 精度 | 自动选择 | GPU 数 | 默认端口 |
|
||||
|---|---|---|---|---|
|
||||
| `LLM-Research/Llama-4-Scout-17B-16E-Instruct` | BF16 | TP8 | 8 | 8091 |
|
||||
| `LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8` | FP8 | TP8 + PP2 | 16 | 8092 |
|
||||
| `Llama-4-Scout-17B-16E-Instruct` | BF16 | TP8 / PP1 | 8 | 8091 |
|
||||
| `Llama-4-Maverick-17B-128E-Instruct-FP8` | FP8 | TP8 / PP2 | 16 | 8092 |
|
||||
|
||||
---
|
||||
|
||||
@@ -24,149 +24,202 @@ llama4-bi150-deploy/
|
||||
├── Dockerfile
|
||||
├── entrypoint.sh
|
||||
├── apply_patch.py # 幂等应用全部 Llama 4 补丁
|
||||
├── detect_model.py # 从 config.json 判断 Scout / Maverick
|
||||
├── verify.sh # 服务验证脚本
|
||||
├── patches/
|
||||
│ ├── 01_fp8_quant.patch # Maverick FP8 量化
|
||||
│ ├── 02_fp8_moe.patch # Maverick FP8 MoE
|
||||
│ ├── 03_llama4_chunked_attn.patch
|
||||
│ └── corexx_fp8_moe.py # 逐 expert 反量化 BF16 的 FP8 MoE 回退
|
||||
├── presets/
|
||||
│ ├── scout.env
|
||||
│ └── maverick.env
|
||||
├── run.sh # 构建 + 启动 + 等 /health
|
||||
├── docker-compose.yml # 可选,按 profile 启动
|
||||
├── run.sh # 自动识别模型 + 构建 + 启动 + 等 /health
|
||||
├── docker-compose.yml # 可选
|
||||
├── .gitea/workflows/
|
||||
│ ├── docker-build-push.yml
|
||||
│ └── task_info.env
|
||||
└── README.md
|
||||
```
|
||||
|
||||
BI-150 上代码放在:
|
||||
|
||||
```text
|
||||
/root/xjh/llama4-bi150-deploy
|
||||
```
|
||||
|
||||
该路径是 `ugly_hopper` 容器内的 `/root/xjh`,直通宿主机。
|
||||
|
||||
---
|
||||
|
||||
## 2. 构建与启动
|
||||
## 2. 快速开始
|
||||
|
||||
### 2.1 脚本(推荐)
|
||||
不需要传 `scout` / `maverick` 参数,`run.sh` 会读取模型目录里的 `config.json` 自动判断。
|
||||
|
||||
```bash
|
||||
# Scout:8 卡,8091
|
||||
./run.sh scout
|
||||
cd /root/xjh/llama4-bi150-deploy
|
||||
|
||||
# Maverick:16 卡,8092
|
||||
./run.sh maverick
|
||||
# Scout
|
||||
./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct
|
||||
|
||||
# Maverick
|
||||
./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8
|
||||
|
||||
# 也可以用环境变量
|
||||
MODEL_HOST_DIR=/mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8 ./run.sh
|
||||
|
||||
# 不传参数时,依次尝试两个默认模型目录
|
||||
./run.sh
|
||||
```
|
||||
|
||||
`run.sh` 会先 `docker build`,再删除同名容器、启动新容器,并等待 `/health` 最多 10 分钟。
|
||||
启动后会打印检测结果,例如:
|
||||
|
||||
### 2.2 指定 GPU 和模型目录
|
||||
```text
|
||||
==> detected maverick: Llama 4 Maverick 17B-128E Instruct FP8 (TP8+PP2, 16 GPUs)
|
||||
model : /mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8
|
||||
TP/PP : 8/2 (16 GPUs), port=8092, name=llama4-maverick
|
||||
GPUs : 0,1,2,...,15
|
||||
```
|
||||
|
||||
所有预设值都可以用环境变量覆盖:
|
||||
### 2.1 自动检测规则
|
||||
|
||||
`detect_model.py` 读取 `config.json`:
|
||||
|
||||
- `model_type` 必须是 `llama4`;
|
||||
- `text_config.num_local_experts == 16` → **Scout**,TP8 / PP1 / 8091;
|
||||
- `text_config.num_local_experts == 128` → **Maverick**,TP8 / PP2 / 8092;
|
||||
- 字段缺失时用目录名里的 `scout` / `maverick` 兜底;
|
||||
- 其他情况直接报错,不会用错误的 TP/PP 启动。
|
||||
|
||||
容器启动时 `entrypoint.sh` 也会再检测一次。也就是说:
|
||||
|
||||
- 用 `run.sh` 启动:宿主侧先检测,决定 GPU 数、容器名、健康检查端口;
|
||||
- 直接 `docker run` 挂载模型:容器内也会自动检测,按对应 TP/PP/端口启动;
|
||||
- 显式设置的 `TP` / `PP` / `PORT` / `SERVED_NAME` 会覆盖自动检测;
|
||||
- 设置 `AUTO_DETECT=0` 可关闭容器内检测;未显式设置的项仍使用 `run.sh` 在宿主侧检测出的默认值。
|
||||
|
||||
### 2.2 指定 GPU
|
||||
|
||||
默认使用前 `TP*PP` 张卡:Scout 用 `0-7`,Maverick 用 `0-15`。可以覆盖:
|
||||
|
||||
```bash
|
||||
# Scout 使用 8-15 号卡
|
||||
GPUS=8,9,10,11,12,13,14,15 ./run.sh scout
|
||||
# Scout 使用 8-15
|
||||
GPUS=8,9,10,11,12,13,14,15 \
|
||||
./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct
|
||||
|
||||
# Maverick 使用 0-15 号卡
|
||||
GPUS=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ./run.sh maverick
|
||||
# Maverick 使用 0-15(默认)
|
||||
GPUS=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 \
|
||||
./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8
|
||||
```
|
||||
|
||||
# 模型放在其他目录
|
||||
MODEL_HOST_DIR=/mnt/disk1/models/Llama-4-Scout-17B-16E-Instruct ./run.sh scout
|
||||
`run.sh` 会检查 GPU 数是否少于 `TP*PP`;少于时直接报错。
|
||||
|
||||
# 额外挂载一个目录
|
||||
EXTRA_DOCKER_ARGS="-v /mnt/disk1:/data:ro" ./run.sh scout
|
||||
### 2.3 额外挂载 / 额外 vLLM 参数
|
||||
|
||||
# 传递额外 vLLM 参数
|
||||
EXTRA_ARGS="--max-model-len 8192" ./run.sh scout
|
||||
```bash
|
||||
EXTRA_DOCKER_ARGS="-v /mnt/disk1:/data:ro" ./run.sh /path/to/model
|
||||
EXTRA_ARGS="--max-model-len 8192" ./run.sh /path/to/model
|
||||
|
||||
# 已有镜像,不重新构建
|
||||
BUILD=0 IMAGE=registry.example.com/llama4-bi150:v1.0.0 ./run.sh scout
|
||||
BUILD=0 IMAGE=registry.example.com/llama4-bi150:v1.0.0 ./run.sh /path/to/model
|
||||
|
||||
# 只打印 docker run 命令,便于检查
|
||||
DRY_RUN=1 ./run.sh scout
|
||||
# 只打印 docker run 命令
|
||||
DRY_RUN=1 ./run.sh /path/to/model
|
||||
```
|
||||
|
||||
### 2.3 Docker Compose(可选)
|
||||
### 2.4 Docker Compose(可选)
|
||||
|
||||
Compose 使用单个 `llama4` service,同样由 entrypoint 自动检测模型:
|
||||
|
||||
```bash
|
||||
docker compose --profile scout up -d --build
|
||||
docker compose --profile maverick up -d --build
|
||||
# Scout
|
||||
MODEL_HOST_DIR=/mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct \
|
||||
docker compose up -d --build
|
||||
|
||||
# 覆盖模型目录 / GPU
|
||||
SCOUT_MODEL_HOST_DIR=/mnt/disk1/models/scout SCOUT_GPUS=8,9,10,11,12,13,14,15 \
|
||||
docker compose --profile scout up -d --build
|
||||
# Maverick
|
||||
MODEL_HOST_DIR=/mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8 \
|
||||
docker compose up -d --build
|
||||
|
||||
# 覆盖镜像 tag / 额外 vLLM 参数
|
||||
TAG=v1.0.0 SCOUT_EXTRA_ARGS="--max-model-len 8192" \
|
||||
docker compose --profile scout up -d --build
|
||||
# 指定 GPU / 端口 / 额外参数
|
||||
MODEL_HOST_DIR=/mnt/disk0/models/... \
|
||||
GPUS=8,9,10,11,12,13,14,15 PORT=8095 \
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 可配置项
|
||||
|
||||
| 变量 | Scout 默认 | Maverick 默认 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `IMAGE` | `llama4-bi150:2026-10-26` | 同左 | 镜像名 |
|
||||
| `NAME` | `llama4-scout` | `llama4-maverick` | 容器名 |
|
||||
| `PORT` | `8091` | `8092` | 宿主机端口 |
|
||||
| `MODEL_HOST_DIR` | `.../Llama-4-Scout-17B-16E-Instruct` | `.../Llama-4-Maverick-17B-128E-Instruct-FP8` | 宿主机模型目录 |
|
||||
| `MODEL_MOUNT` | `/models/llama4` | 同左 | 容器内挂载点 |
|
||||
| `SERVED_NAME` | `llama4-scout` | `llama4-maverick` | OpenAI API 模型名 |
|
||||
| `TP` | `8` | `8` | 张量并行 |
|
||||
| `PP` | `1` | `2` | 流水线并行 |
|
||||
| `GPUS` | `0,...,7` | `0,...,15` | 传给 `CUDA_VISIBLE_DEVICES` |
|
||||
| `MAX_MODEL_LEN` | `4096` | `4096` | 最大上下文 |
|
||||
| `MAX_NUM_SEQS` | `1` | `1` | 最大并发 |
|
||||
| `GPU_MEM_UTIL` | `0.90` | `0.90` | 显存利用率 |
|
||||
| `ENFORCE_EAGER` | `1` | `1` | 是否 `--enforce-eager` |
|
||||
| `EXTRA_ARGS` | 空 | 空 | 额外 vLLM 参数 |
|
||||
| `EXTRA_DOCKER_ARGS` | 空 | 空 | 额外 docker 参数,如 `-v` |
|
||||
| `BUILD` | `1` | `1` | `0` 表示跳过构建 |
|
||||
| `DRY_RUN` | `0` | `0` | `1` 只打印命令 |
|
||||
| 变量 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `MODEL_HOST_DIR` | 自动尝试两个默认目录 | 宿主机模型目录 |
|
||||
| `MODEL_MOUNT` | `/models/llama4` | 容器内挂载点 |
|
||||
| `IMAGE` | `llama4-bi150:2026-10-26` | 镜像名 |
|
||||
| `NAME` | `llama4-<kind>` | 容器名 |
|
||||
| `PORT` | Scout 8091 / Maverick 8092 | 宿主机端口 |
|
||||
| `SERVED_NAME` | Scout `llama4-scout` / Maverick `llama4-maverick` | OpenAI API 模型名 |
|
||||
| `TP` | Scout 8 / Maverick 8 | 张量并行 |
|
||||
| `PP` | Scout 1 / Maverick 2 | 流水线并行 |
|
||||
| `GPUS` | 前 `TP*PP` 张卡 | `CUDA_VISIBLE_DEVICES` |
|
||||
| `MAX_MODEL_LEN` | `4096` | 最大上下文 |
|
||||
| `MAX_NUM_SEQS` | `1` | 最大并发 |
|
||||
| `GPU_MEM_UTIL` | `0.90` | 显存利用率 |
|
||||
| `ENFORCE_EAGER` | `1` | 是否 `--enforce-eager` |
|
||||
| `AUTO_DETECT` | `1` | 容器内是否按 config 自动检测 |
|
||||
| `EXTRA_ARGS` | 空 | 额外 vLLM 参数 |
|
||||
| `EXTRA_DOCKER_ARGS` | 空 | 额外 docker 参数,如 `-v` |
|
||||
| `BUILD` | `1` | `0` 表示跳过构建 |
|
||||
| `DRY_RUN` | `0` | `1` 只打印命令 |
|
||||
|
||||
`GPUS` 也可以直接用 `CUDA_VISIBLE_DEVICES` 设置。`run.sh` 会检查 GPU 数是否少于 `TP*PP`,少于时直接报错。
|
||||
`TP` / `PP` / `PORT` / `SERVED_NAME` 显式设置时优先于自动检测。
|
||||
|
||||
---
|
||||
|
||||
## 4. 验证
|
||||
## 4. 验证脚本
|
||||
|
||||
`verify.sh` 用于检查已经启动的服务:
|
||||
|
||||
```bash
|
||||
# 健康检查
|
||||
curl -s http://127.0.0.1:8091/health
|
||||
curl -s http://127.0.0.1:8092/health
|
||||
|
||||
# 模型列表
|
||||
curl -s http://127.0.0.1:8091/v1/models | python3 -m json.tool
|
||||
curl -s http://127.0.0.1:8092/v1/models | python3 -m json.tool
|
||||
|
||||
# 文本
|
||||
curl -s http://127.0.0.1:8091/v1/chat/completions \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"model":"llama4-scout","messages":[{"role":"user","content":"你好"}],"max_tokens":64}'
|
||||
./verify.sh
|
||||
```
|
||||
|
||||
Maverick 图片输入测试:
|
||||
它会自动查找运行中的 `llama4-bi150` 容器,读取模型挂载、端口和 served name,然后检查:
|
||||
|
||||
```python
|
||||
from PIL import Image
|
||||
import base64, io, requests
|
||||
1. `/health`
|
||||
2. `/v1/models`
|
||||
3. `/v1/chat/completions`(中文问答)
|
||||
|
||||
img = Image.new("RGB", (336, 336), (220, 20, 20))
|
||||
buf = io.BytesIO(); img.save(buf, format="PNG")
|
||||
b64 = base64.b64encode(buf.getvalue()).decode()
|
||||
常用用法:
|
||||
|
||||
payload = {
|
||||
"model": "llama4-maverick",
|
||||
"messages": [{"role": "user", "content": [
|
||||
{"type": "text", "text": "这张图片主要是什么颜色?只回答颜色。"},
|
||||
{"type": "image_url", "image_url": {"url": "data:image/png;base64," + b64}},
|
||||
]}],
|
||||
"max_tokens": 32,
|
||||
"temperature": 0,
|
||||
}
|
||||
print(requests.post("http://127.0.0.1:8092/v1/chat/completions",
|
||||
json=payload, timeout=300).json()["choices"][0]["message"]["content"])
|
||||
```bash
|
||||
# 指定模型目录(推荐,能准确判断 Scout/Maverick)
|
||||
./verify.sh --model-dir /mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8
|
||||
|
||||
# 指定容器
|
||||
./verify.sh --container llama4-maverick
|
||||
|
||||
# 额外检查图片识别(Maverick)
|
||||
./verify.sh --container llama4-maverick --with-image
|
||||
|
||||
# 额外检查简单推理(期望回答 27)
|
||||
./verify.sh --container llama4-scout --with-reasoning
|
||||
|
||||
# 直接指定服务地址
|
||||
./verify.sh --base-url http://127.0.0.1:8092 --served-name llama4-maverick
|
||||
```
|
||||
|
||||
首次使用统一镜像时,建议把 Scout 和 Maverick 都跑一遍,确认 FP8 补丁没有影响 Scout 的 BF16 路径。
|
||||
主要参数:
|
||||
|
||||
| 参数 | 说明 |
|
||||
|---|---|
|
||||
| `--model-dir PATH` | 模型目录,用于自动判断 Scout/Maverick |
|
||||
| `--container NAME` | 容器名;默认自动查找 |
|
||||
| `--port PORT` | 服务端口;默认从模型/容器推断 |
|
||||
| `--served-name NAME` | API 模型名;默认从模型/容器推断 |
|
||||
| `--base-url URL` | 直接指定服务地址 |
|
||||
| `--timeout SEC` | 等待/请求超时,默认 180 |
|
||||
| `--with-reasoning` | 额外跑推理题 |
|
||||
| `--with-image` | 额外跑图片识别(仅 Maverick) |
|
||||
| `--skip-chat` | 只检查 health 和 models |
|
||||
|
||||
脚本只依赖 `bash`、`curl`、`python3`;不需要 `jq`。返回码为 0 表示全部通过。
|
||||
|
||||
---
|
||||
|
||||
@@ -204,9 +257,7 @@ TASK_TYPE=text-generation
|
||||
|
||||
Maverick 支持图片输入;如果 ModelHub 要求把图文任务单独归类,请把 `TASK_TYPE` 改成平台支持的值。`image-verify/validate` 会在构建前校验,填错会直接失败。
|
||||
|
||||
Runner 需要在 Gitea 实例或仓库中注册,并带有 `amd64-ubuntu-24.04` label。
|
||||
|
||||
Runner 需要配置以下环境变量(不是仓库 secret):
|
||||
Runner 需要在 Gitea 实例或仓库中注册,并带有 `amd64-ubuntu-24.04` label。Runner 需要配置以下环境变量(不是仓库 secret):
|
||||
|
||||
```text
|
||||
DOCKER_REGISTRY
|
||||
@@ -232,3 +283,4 @@ FIXED_TOKEN
|
||||
- 补丁是针对当前精确基础镜像生成的。更换基础镜像后不要直接复用,需要重新生成 diff 并在目标环境验证。
|
||||
- `--privileged --pid host -v /dev:/dev` 是 Iluvatar 运行时要求;只给 `/dev/iluvatar*` 可能报 `cudaGetDeviceCount() ... Error 1001`。
|
||||
- 模型目录只读挂载,容器不会修改宿主机模型文件。
|
||||
- 统一镜像首次使用时,建议 Scout 和 Maverick 都各跑一次 `verify.sh`;尤其是 Scout,因为镜像里也包含 FP8 MoE 补丁,需要确认共享的 `fused_moe.py` 修改没有影响 BF16 路径。
|
||||
|
||||
Reference in New Issue
Block a user