Auto-detect Scout/Maverick from config.json and add verify script
This commit is contained in:
128
run.sh
128
run.sh
@@ -1,17 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Llama 4 Scout / Maverick 一键构建 + 启动(Iluvatar BI-V150)
|
||||
# Llama 4 统一构建 + 启动(Iluvatar BI-V150)
|
||||
#
|
||||
# ./run.sh scout
|
||||
# ./run.sh maverick
|
||||
# 自动读取模型目录下的 config.json,判断是 Scout 还是 Maverick,然后选择:
|
||||
# Scout : TP8 / PP1 / 8 卡 / 8091 / llama4-scout
|
||||
# Maverick : TP8 / PP2 / 16 卡 / 8092 / llama4-maverick
|
||||
#
|
||||
# 用法:
|
||||
# ./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct
|
||||
# ./run.sh /mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8
|
||||
# MODEL_HOST_DIR=/path/to/model ./run.sh
|
||||
# ./run.sh # 依次尝试两个默认模型目录
|
||||
#
|
||||
# 常用覆盖项:
|
||||
# GPUS=8,9,10,11,12,13,14,15 ./run.sh scout
|
||||
# MODEL_HOST_DIR=/path/to/model ./run.sh maverick
|
||||
# EXTRA_ARGS="--max-model-len 8192" ./run.sh scout
|
||||
# EXTRA_DOCKER_ARGS="-v /mnt/disk1:/data:ro" ./run.sh scout
|
||||
# BUILD=0 ./run.sh scout # 使用已有镜像,不重新构建
|
||||
# DRY_RUN=1 ./run.sh scout # 只打印 docker run 命令
|
||||
# GPUS=8,9,10,11,12,13,14,15 ./run.sh /path/to/scout
|
||||
# EXTRA_DOCKER_ARGS="-v /mnt/disk1:/data:ro" ./run.sh /path/to/model
|
||||
# EXTRA_ARGS="--max-model-len 8192" ./run.sh /path/to/model
|
||||
# TP=8 PP=1 PORT=8095 SERVED_NAME=my-llama4 ./run.sh /path/to/model
|
||||
# BUILD=0 ./run.sh /path/to/model # 使用已有镜像
|
||||
# DRY_RUN=1 ./run.sh /path/to/model # 只打印 docker run 命令
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
@@ -19,67 +26,91 @@ cd "$(dirname "$0")"
|
||||
|
||||
usage() {
|
||||
cat >&2 <<'EOF'
|
||||
用法: ./run.sh <scout|maverick>
|
||||
用法: ./run.sh [MODEL_DIR]
|
||||
|
||||
预设默认值在 presets/<name>.env 中,所有值都可以用环境变量覆盖:
|
||||
IMAGE NAME PORT MODEL_HOST_DIR MODEL_MOUNT SERVED_NAME
|
||||
不传 MODEL_DIR 时,按顺序尝试:
|
||||
/mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct
|
||||
/mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8
|
||||
|
||||
模型类型由 MODEL_DIR/config.json 自动判断,不需要 scout/maverick 参数。
|
||||
|
||||
环境变量覆盖:
|
||||
IMAGE NAME MODEL_HOST_DIR MODEL_MOUNT PORT SERVED_NAME
|
||||
TP PP GPUS MAX_MODEL_LEN MAX_NUM_SEQS GPU_MEM_UTIL
|
||||
ENFORCE_EAGER EXTRA_ARGS EXTRA_DOCKER_ARGS
|
||||
ENFORCE_EAGER AUTO_DETECT EXTRA_ARGS EXTRA_DOCKER_ARGS
|
||||
BUILD=0/1 DRY_RUN=0/1
|
||||
EOF
|
||||
}
|
||||
|
||||
VARIANT="${1:-}"
|
||||
if [[ -z "${VARIANT}" || "${VARIANT}" == "-h" || "${VARIANT}" == "--help" ]]; then
|
||||
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
MODEL_HOST_DIR="${1:-${MODEL_HOST_DIR:-}}"
|
||||
if [[ -z "${MODEL_HOST_DIR}" ]]; then
|
||||
for candidate in \
|
||||
"/mnt/disk0/models/LLM-Research/Llama-4-Scout-17B-16E-Instruct" \
|
||||
"/mnt/disk0/models/LLM-Research/Llama-4-Maverick-17B-128E-Instruct-FP8"; do
|
||||
if [[ -f "${candidate}/config.json" ]]; then
|
||||
MODEL_HOST_DIR="${candidate}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ -z "${MODEL_HOST_DIR}" ]]; then
|
||||
echo "ERROR: 未指定模型目录,也没有找到默认模型目录。" >&2
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PRESET="presets/${VARIANT}.env"
|
||||
if [[ ! -f "${PRESET}" ]]; then
|
||||
echo "ERROR: 未知预设: ${VARIANT}" >&2
|
||||
usage
|
||||
exit 2
|
||||
if [[ ! -f "${MODEL_HOST_DIR}/config.json" ]]; then
|
||||
echo "ERROR: 模型目录不完整: ${MODEL_HOST_DIR}/config.json" >&2
|
||||
echo "请先下载模型,或把 MODEL_DIR 指向正确目录。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
source "${PRESET}"
|
||||
DETECT_OUTPUT="$(python3 detect_model.py "${MODEL_HOST_DIR}")" || exit 1
|
||||
eval "${DETECT_OUTPUT}"
|
||||
|
||||
IMAGE="${IMAGE:-${DEFAULT_IMAGE}}"
|
||||
NAME="${NAME:-${DEFAULT_NAME}}"
|
||||
PORT="${PORT:-${DEFAULT_PORT}}"
|
||||
MODEL_HOST_DIR="${MODEL_HOST_DIR:-${DEFAULT_MODEL_HOST_DIR}}"
|
||||
MODEL_KIND="${DETECTED_MODEL_KIND}"
|
||||
IMAGE="${IMAGE:-llama4-bi150:2026-10-26}"
|
||||
NAME="${NAME:-llama4-${MODEL_KIND}}"
|
||||
PORT="${PORT:-${DETECTED_PORT}}"
|
||||
MODEL_MOUNT="${MODEL_MOUNT:-/models/llama4}"
|
||||
SERVED_NAME="${SERVED_NAME:-${DEFAULT_SERVED_NAME}}"
|
||||
TP="${TP:-${DEFAULT_TP}}"
|
||||
PP="${PP:-${DEFAULT_PP}}"
|
||||
GPUS="${GPUS:-${CUDA_VISIBLE_DEVICES:-${DEFAULT_GPUS}}}"
|
||||
MAX_MODEL_LEN="${MAX_MODEL_LEN:-${DEFAULT_MAX_MODEL_LEN}}"
|
||||
MAX_NUM_SEQS="${MAX_NUM_SEQS:-${DEFAULT_MAX_NUM_SEQS}}"
|
||||
GPU_MEM_UTIL="${GPU_MEM_UTIL:-${DEFAULT_GPU_MEM_UTIL}}"
|
||||
SERVED_NAME="${SERVED_NAME:-${DETECTED_SERVED_NAME}}"
|
||||
TP="${TP:-${DETECTED_TP}}"
|
||||
PP="${PP:-${DETECTED_PP}}"
|
||||
MAX_MODEL_LEN="${MAX_MODEL_LEN:-4096}"
|
||||
MAX_NUM_SEQS="${MAX_NUM_SEQS:-1}"
|
||||
GPU_MEM_UTIL="${GPU_MEM_UTIL:-0.90}"
|
||||
ENFORCE_EAGER="${ENFORCE_EAGER:-1}"
|
||||
AUTO_DETECT="${AUTO_DETECT:-1}"
|
||||
EXTRA_ARGS="${EXTRA_ARGS:-}"
|
||||
EXTRA_DOCKER_ARGS="${EXTRA_DOCKER_ARGS:-}"
|
||||
BUILD="${BUILD:-1}"
|
||||
DRY_RUN="${DRY_RUN:-0}"
|
||||
|
||||
GPU_COUNT=$((TP * PP))
|
||||
|
||||
if [[ -n "${GPUS:-}" ]]; then
|
||||
GPUS="${GPUS}"
|
||||
elif [[ -n "${CUDA_VISIBLE_DEVICES:-}" ]]; then
|
||||
GPUS="${CUDA_VISIBLE_DEVICES}"
|
||||
else
|
||||
GPUS="$(seq -s, 0 $((GPU_COUNT - 1)))"
|
||||
fi
|
||||
GPUS="${GPUS// /}"
|
||||
|
||||
if [[ ! -f "${MODEL_HOST_DIR}/config.json" ]]; then
|
||||
echo "ERROR: 模型目录不完整: ${MODEL_HOST_DIR}/config.json" >&2
|
||||
echo "请先下载模型,或设置 MODEL_HOST_DIR 指向正确目录。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EXPECTED_GPUS=$((TP * PP))
|
||||
if [[ -n "${GPUS}" ]]; then
|
||||
IFS=',' read -r -a GPU_LIST <<< "${GPUS}"
|
||||
if (( ${#GPU_LIST[@]} < EXPECTED_GPUS )); then
|
||||
echo "ERROR: TP*PP=${EXPECTED_GPUS},但 GPUS 只给了 ${#GPU_LIST[@]} 张: ${GPUS}" >&2
|
||||
if (( ${#GPU_LIST[@]} < GPU_COUNT )); then
|
||||
echo "ERROR: ${MODEL_KIND} 需要 TP*PP=${GPU_COUNT} 张卡,但 GPUS 只给了 ${#GPU_LIST[@]} 张: ${GPUS}" >&2
|
||||
exit 1
|
||||
fi
|
||||
if (( ${#GPU_LIST[@]} > EXPECTED_GPUS )); then
|
||||
echo "WARN: TP*PP=${EXPECTED_GPUS},但 GPUS 给了 ${#GPU_LIST[@]} 张;vLLM 只会使用其中 ${EXPECTED_GPUS} 张。" >&2
|
||||
if (( ${#GPU_LIST[@]} > GPU_COUNT )); then
|
||||
echo "WARN: TP*PP=${GPU_COUNT},但 GPUS 给了 ${#GPU_LIST[@]} 张;vLLM 只会使用其中 ${GPU_COUNT} 张。" >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -101,6 +132,8 @@ DOCKER_RUN=(
|
||||
--ulimit stack=67108864
|
||||
-e CUDA_VISIBLE_DEVICES="${GPUS}"
|
||||
-e MODEL_PATH="${MODEL_MOUNT}"
|
||||
-e AUTO_DETECT="${AUTO_DETECT}"
|
||||
-e MODEL_KIND="${MODEL_KIND}"
|
||||
-e SERVED_NAME="${SERVED_NAME}"
|
||||
-e PORT="${PORT}"
|
||||
-e TP="${TP}"
|
||||
@@ -115,6 +148,11 @@ DOCKER_RUN=(
|
||||
"${IMAGE}"
|
||||
)
|
||||
|
||||
echo "==> detected ${MODEL_KIND}: ${DETECTED_DESCRIPTION}"
|
||||
echo " model : ${MODEL_HOST_DIR}"
|
||||
echo " TP/PP : ${TP}/${PP} (${GPU_COUNT} GPUs), port=${PORT}, name=${SERVED_NAME}"
|
||||
echo " GPUs : ${GPUS}"
|
||||
|
||||
if [[ "${DRY_RUN}" == "1" ]]; then
|
||||
printf '%q ' "${DOCKER_RUN[@]}"
|
||||
printf '\n'
|
||||
@@ -131,7 +169,7 @@ fi
|
||||
echo "==> recreate ${NAME}"
|
||||
docker rm -f "${NAME}" 2>/dev/null || true
|
||||
|
||||
echo "==> run ${VARIANT}: GPUs=${GPUS}, TP=${TP}, PP=${PP}, model=${MODEL_HOST_DIR}"
|
||||
echo "==> run ${MODEL_KIND}"
|
||||
"${DOCKER_RUN[@]}"
|
||||
|
||||
echo "==> wait for http://127.0.0.1:${PORT}/health"
|
||||
|
||||
Reference in New Issue
Block a user