Unified Llama 4 Scout/Maverick BI-V150 deployment bundle

This commit is contained in:
2026-10-26 16:24:16 +08:00
commit caddeadd15
16 changed files with 1201 additions and 0 deletions

148
run.sh Executable file
View File

@@ -0,0 +1,148 @@
#!/usr/bin/env bash
#
# Llama 4 Scout / Maverick 一键构建 + 启动(Iluvatar BI-V150)
#
# ./run.sh scout
# ./run.sh maverick
#
# 常用覆盖项:
# 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 命令
#
set -euo pipefail
cd "$(dirname "$0")"
usage() {
cat >&2 <<'EOF'
用法: ./run.sh <scout|maverick>
预设默认值在 presets/<name>.env 中,所有值都可以用环境变量覆盖:
IMAGE NAME PORT MODEL_HOST_DIR MODEL_MOUNT SERVED_NAME
TP PP GPUS MAX_MODEL_LEN MAX_NUM_SEQS GPU_MEM_UTIL
ENFORCE_EAGER EXTRA_ARGS EXTRA_DOCKER_ARGS
BUILD=0/1 DRY_RUN=0/1
EOF
}
VARIANT="${1:-}"
if [[ -z "${VARIANT}" || "${VARIANT}" == "-h" || "${VARIANT}" == "--help" ]]; then
usage
exit 2
fi
PRESET="presets/${VARIANT}.env"
if [[ ! -f "${PRESET}" ]]; then
echo "ERROR: 未知预设: ${VARIANT}" >&2
usage
exit 2
fi
# shellcheck disable=SC1090
source "${PRESET}"
IMAGE="${IMAGE:-${DEFAULT_IMAGE}}"
NAME="${NAME:-${DEFAULT_NAME}}"
PORT="${PORT:-${DEFAULT_PORT}}"
MODEL_HOST_DIR="${MODEL_HOST_DIR:-${DEFAULT_MODEL_HOST_DIR}}"
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}}"
ENFORCE_EAGER="${ENFORCE_EAGER:-1}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
EXTRA_DOCKER_ARGS="${EXTRA_DOCKER_ARGS:-}"
BUILD="${BUILD:-1}"
DRY_RUN="${DRY_RUN:-0}"
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
exit 1
fi
if (( ${#GPU_LIST[@]} > EXPECTED_GPUS )); then
echo "WARN: TP*PP=${EXPECTED_GPUS},但 GPUS 给了 ${#GPU_LIST[@]} 张;vLLM 只会使用其中 ${EXPECTED_GPUS} 张。" >&2
fi
fi
DOCKER_EXTRA=()
if [[ -n "${EXTRA_DOCKER_ARGS}" ]]; then
# 按空白拆分;路径中不要带空格。
read -r -a DOCKER_EXTRA <<< "${EXTRA_DOCKER_ARGS}"
fi
DOCKER_RUN=(
docker run -d --name "${NAME}"
--privileged
--pid host
--network host
--ipc host
-v /dev:/dev
-v "${MODEL_HOST_DIR}:${MODEL_MOUNT}:ro"
--ulimit memlock=-1
--ulimit stack=67108864
-e CUDA_VISIBLE_DEVICES="${GPUS}"
-e MODEL_PATH="${MODEL_MOUNT}"
-e SERVED_NAME="${SERVED_NAME}"
-e PORT="${PORT}"
-e TP="${TP}"
-e PP="${PP}"
-e MAX_MODEL_LEN="${MAX_MODEL_LEN}"
-e MAX_NUM_SEQS="${MAX_NUM_SEQS}"
-e GPU_MEM_UTIL="${GPU_MEM_UTIL}"
-e ENFORCE_EAGER="${ENFORCE_EAGER}"
-e EXTRA_ARGS="${EXTRA_ARGS}"
"${DOCKER_EXTRA[@]}"
--restart unless-stopped
"${IMAGE}"
)
if [[ "${DRY_RUN}" == "1" ]]; then
printf '%q ' "${DOCKER_RUN[@]}"
printf '\n'
exit 0
fi
if [[ "${BUILD}" == "1" ]]; then
echo "==> build ${IMAGE}"
docker build -t "${IMAGE}" .
else
echo "==> skip build (BUILD=0), image=${IMAGE}"
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}"
"${DOCKER_RUN[@]}"
echo "==> wait for http://127.0.0.1:${PORT}/health"
for _ in $(seq 1 120); do
if curl -sf "http://127.0.0.1:${PORT}/health" >/dev/null 2>&1; then
echo "ready: http://127.0.0.1:${PORT}/v1/models"
exit 0
fi
sleep 5
done
echo "ERROR: 服务 10 分钟未就绪,查看日志:" >&2
echo " docker logs -f ${NAME}" >&2
exit 1