Switch to bridge networking with fixed container port 80 and served name llm

- run.sh: bridge + -p ${HOST_PORT:-24396}:80, health check uses host port
- entrypoint.sh: PORT defaults to 80, SERVED_NAME defaults to llm
  detected port/served name become log hints only
- verify.sh: read host port from port bindings, expect model name llm
- docker-compose.yml: ports mapping instead of network_mode host
- README: update tables, commands and rationale
This commit is contained in:
2026-10-28 14:19:42 +08:00
parent 31994d940f
commit daaf85f4e5
5 changed files with 120 additions and 57 deletions

View File

@@ -10,10 +10,12 @@
- 两个模型共用 Llama 4 chunked-attention 补丁;Maverick 额外使用 FP8 量化 / FP8 MoE 补丁
- CI 使用 ModelHub 标准 Gitea Actions:推送 `v*` 标签后构建、推送镜像并提交审核
| 模型 | 精度 | 自动选择 | GPU 数 | 默认端口 |
| 模型 | 精度 | 自动选择 | GPU 数 | 容器内端口 |
|---|---|---|---|---|
| `Llama-4-Scout-17B-16E-Instruct` | BF16 | TP8 / PP1 | 8 | 8091 |
| `Llama-4-Maverick-17B-128E-Instruct-FP8` | FP8 | TP8 / PP2 | 16 | 8092 |
| `Llama-4-Scout-17B-16E-Instruct` | BF16 | TP8 / PP1 | 8 | 80 |
| `Llama-4-Maverick-17B-128E-Instruct-FP8` | FP8 | TP8 / PP2 | 16 | 80 |
容器内固定监听 80,模型名固定 `llm`,宿主机端口由 `-p` 决定(默认 24396)。
---
@@ -74,7 +76,9 @@ MODEL_HOST_DIR=/mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct
```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
TP/PP : 8/2 (16 GPUs)
port : 127.0.0.1:24396 -> container:80
name : llm
GPUs : 0,1,2,...,15
```
@@ -88,17 +92,20 @@ MODEL_HOST_DIR=/mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct
`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;
- `text_config.num_local_experts == 16` → **Scout**,TP8 / PP1;
- `text_config.num_local_experts == 128` → **Maverick**,TP8 / PP2;
- 字段缺失时用目录名里的 `scout` / `maverick` 兜底;
- 其他情况直接报错,不会用错误的 TP/PP 启动。
容器启动时 `entrypoint.sh` 也会再检测一次。也就是说:
- 用 `run.sh` 启动:宿主侧先检测,决定 GPU 数、容器名、健康检查端口;
- 直接 `docker run` 挂载模型:容器内也会自动检测,按对应 TP/PP/端口启动;
- 显式设置的 `TP` / `PP` / `PORT` / `SERVED_NAME` 会覆盖自动检测;
- 设置 `AUTO_DETECT=0` 可关闭容器内检测;未显式设置的项仍使用 `run.sh` 在宿主侧检测出的默认值。
- 直接 `docker run` 挂载模型:容器内也会自动检测,按对应 TP/PP 启动;
- 显式设置的 `TP` / `PP` / `SERVED_NAME` 会覆盖自动检测;
- 设置 `AUTO_DETECT=0` 可关闭容器内检测。
**端口和模型名不再由检测决定**:容器内端口恒为 80,模型名恒为 `llm`。
检测出的 `port` / `served_name` 只作为日志提示(`hint` 行)。
### 2.2 指定 GPU
@@ -116,6 +123,21 @@ GPUS=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 \
`run.sh` 会检查 GPU 数是否少于 `TP*PP`;少于时直接报错。
### 2.2.1 指定宿主机端口
容器内固定 80,宿主机端口默认 **24396**。串行部署时多个模型可以复用同一个端口:
```bash
# 默认用 24396
./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct
# 改端口
HOST_PORT=24397 ./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct
```
**并行跑多个模型时必须给不同的 `HOST_PORT`**,否则第二个容器 `bind: address already in use`。
不过 Maverick 占满 16 卡,实际和 Scout 无法并存。
### 2.3 额外挂载 / 额外 vLLM 参数
```bash
@@ -144,7 +166,7 @@ MODEL_HOST_DIR=/mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct
# 指定 GPU / 端口 / 额外参数
MODEL_HOST_DIR=/mnt/disk0/models/... \
GPUS=8,9,10,11,12,13,14,15 PORT=8095 \
GPUS=8,9,10,11,12,13,14,15 HOST_PORT=24397 \
docker compose up -d --build
```
@@ -158,8 +180,9 @@ GPUS=8,9,10,11,12,13,14,15 PORT=8095 \
| `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 模型名 |
| `HOST_PORT` | `24396` | 宿主机端口(容器内固定 80) |
| `PORT` | `24396` | `HOST_PORT` 的兼容别名,推荐用 `HOST_PORT` |
| `SERVED_NAME` | `llm` | OpenAI API 模型名,固定 |
| `TP` | Scout 8 / Maverick 8 | 张量并行 |
| `PP` | Scout 1 / Maverick 2 | 流水线并行 |
| `GPUS` | 前 `TP*PP` 张卡 | `CUDA_VISIBLE_DEVICES` |
@@ -173,7 +196,7 @@ GPUS=8,9,10,11,12,13,14,15 PORT=8095 \
| `BUILD` | `1` | `0` 表示跳过构建 |
| `DRY_RUN` | `0` | `1` 只打印命令 |
`TP` / `PP` / `PORT` / `SERVED_NAME` 显式设置时优先于自动检测。
`TP` / `PP` / `SERVED_NAME` 显式设置时优先于自动检测。
---
@@ -207,7 +230,7 @@ GPUS=8,9,10,11,12,13,14,15 PORT=8095 \
./verify.sh --container llama4-scout --with-reasoning
# 直接指定服务地址
./verify.sh --base-url http://127.0.0.1:8092 --served-name llama4-maverick
./verify.sh --base-url http://127.0.0.1:24396 --served-name llm
```
主要参数:
@@ -216,7 +239,7 @@ GPUS=8,9,10,11,12,13,14,15 PORT=8095 \
|---|---|
| `--model-dir PATH` | 模型目录,用于自动判断 Scout/Maverick |
| `--container NAME` | 容器名;默认自动查找 |
| `--port PORT` | 服务端口;默认从模型/容器推断 |
| `--port PORT` | 宿主机端口;默认从容器端口映射推断,兜底 24396 |
| `--served-name NAME` | API 模型名;默认从模型/容器推断 |
| `--base-url URL` | 直接指定服务地址 |
| `--timeout SEC` | 等待/请求超时,默认 180 |
@@ -226,7 +249,7 @@ GPUS=8,9,10,11,12,13,14,15 PORT=8095 \
脚本只依赖 `bash`、`curl`、`python3`;不需要 `jq`。返回码为 0 表示全部通过。
在 `ugly_hopper` 内运行、没有 `docker` CLI 时,`verify.sh` 会自动探测本机 `8091` / `8092` 的 `/health`,并据此选择 Scout 或 Maverick;也可以显式传 `--model-dir` 或 `--port`。
在 `ugly_hopper` 内运行、没有 `docker` CLI 时,`verify.sh` 会先探测 `24396`,再依次探测旧的 `8091` / `8092`;也可以用 `--model-dir` 或 `--port` 显式指定。
也可以直接查看模型检测结果:
@@ -283,36 +306,42 @@ docker pull harbor.4pd.io/modelhubxc/xiejiahao/llama-4-bi150:v0.1.2
镜像不声明 `ENTRYPOINT`,`--entrypoint` 必须显式给。以下命令可直接粘贴。
**Llama-4-Scout-17B-16E(TP8/PP1,8 卡,8091)**
**Llama-4-Scout-17B-16E(TP8/PP1,8 卡,宿主 24396 → 容器 80)**
```bash
docker run -d --name llama4-scout \
--entrypoint /usr/local/bin/llama4-entrypoint.sh \
--workdir /opt/llama4 \
--privileged --pid host --network host --ipc host \
--privileged --pid host --ipc host \
-v /dev:/dev \
-v /mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct:/models/llama4:ro \
--ulimit memlock=-1 --ulimit stack=67108864 \
-p 24396:80 \
-e CUDA_VISIBLE_DEVICES=8,9,10,11,12,13,14,15 \
-e MODEL_PATH=/models/llama4 \
-e PORT=80 \
-e SERVED_NAME=llm \
-e AUTO_DETECT=1 \
-e PYTHONUNBUFFERED=1 \
--restart unless-stopped \
harbor.4pd.io/modelhubxc/xiejiahao/llama-4-bi150:v0.1.2
```
**Llama-4-Maverick-17B-128E-Instruct-FP8(TP8/PP2,16 卡,8092)**
**Llama-4-Maverick-17B-128E-Instruct-FP8(TP8/PP2,16 卡,宿主 24396 → 容器 80)**
```bash
docker run -d --name llama4-maverick \
--entrypoint /usr/local/bin/llama4-entrypoint.sh \
--workdir /opt/llama4 \
--privileged --pid host --network host --ipc host \
--privileged --pid host --ipc host \
-v /dev:/dev \
-v /mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8:/models/llama4:ro \
--ulimit memlock=-1 --ulimit stack=67108864 \
-p 24396:80 \
-e CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 \
-e MODEL_PATH=/models/llama4 \
-e PORT=80 \
-e SERVED_NAME=llm \
-e AUTO_DETECT=1 \
-e PYTHONUNBUFFERED=1 \
--restart unless-stopped \
@@ -323,7 +352,8 @@ docker run -d --name llama4-maverick \
Maverick 占用全部 16 张卡,与其它模型互斥;Scout 只占 8 张,可以和其它小模型共存,此时需改 `-e CUDA_VISIBLE_DEVICES` 避免重叠。
**注意**:`--network host` 下不要写 `-p`,端口映射会被丢弃;要换对外端口就传 `-e PORT=<port>`。
**注意**:两个变体都映射到宿主 `24396`,串行部署没问题;并行时必须改 `-p` 左侧端口。
`-e SERVED_NAME=llm` 让 `/v1/models` 返回 `llm`,客户端不用为换模型改 `model` 字段。
### 5.3 用 run.sh 启动 CI 镜像