Unified Llama 4 Scout/Maverick BI-V150 deployment bundle
This commit is contained in:
148
run.sh
Executable file
148
run.sh
Executable 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
|
||||
Reference in New Issue
Block a user