- 先修 litellm(最优先,跑脚本①)
sudo bash fix-litellm.sh 三个 litellm 变 healthy、HTTP=200 就成功,网页和 opencode 立刻能用。失败就把它生成的 /tmp/litellm-fix-*.log 带回来。
- 235B 改 TP=4(脚本②,填 4 张好卡)
sudo bash set-235b-tp4.sh "0,1,3,5" (0,1,3,5 换成你确认的 4 张好卡;235B 加载后看 docker logs -f vllm-public-llm,出现 Application startup complete 即成。OOM 就重跑加第二参数调小 util,如 ... "0,1,3,5" 0.70。)
- DeepSeek 加 --enforce-eager + 测试(简单,直接命令)
sed -i '/--enable-auto-tool-choice/a\ --enforce-eager' /opt/llm-stack/configs/vllm/deepseek-launch.sh sudo /opt/llm-stack/runtime/switch-llm.sh ds tp4 docker logs -f vllm-public-llm (--enforce-eager 关掉 torch.compile,治 DeepSeek 那个 InductorError;ds tp4 让它只用 4 卡——但 DeepSeek 的 tp4 默认落卡可能含坏卡,若日志报错,改用脚本②同样的叠加层思路把它也指到 4 张好卡。DeepSeek 是 dev 镜像、最难,建议你先把 litellm 和 235B 跑通,DeepSeek 最后再试。)
#!/usr/bin/env bash
# ============================================================================
# fix-litellm.sh — 修三套 litellm 离线起不来(502 的根)
# 根因:configs/litellm/{public,gc,smt}.yaml 里 enable_prometheus: true,
# 离线镜像缺 prometheus 依赖 → worker 一启动就崩、三个一起死 → 4000 没人听 →
# nginx 连不上报 Connection refused → 凡走 litellm 的(embed/chat/ocr)全 502。
# 修法:关掉 enable_prometheus,重启三个 litellm,再刷新 nginx 上游缓存。
#
# 用法(机器上): sudo bash fix-litellm.sh
# 若报 $'\r' 错: sed -i 's/\r$//' fix-litellm.sh 再跑。
# ============================================================================
CFG=/opt/llm-stack/configs/litellm
TS=$(date +%Y%m%d-%H%M)
OUT=/tmp/litellm-fix-$TS.log
echo "===== 0. 留底:修复前真实报错(stderr,健康日志里没有的那段) =====" | tee "$OUT"
docker logs litellm-public --tail 150 >> "$OUT" 2>&1
echo "(已存 $OUT)"
echo "===== 1. 关闭 enable_prometheus(三套配置,改前自动备份) ====="
for f in public gc smt; do
y="$CFG/$f.yaml"
[ -f "$y" ] || { echo " 跳过(无 $y)"; continue; }
cp -n "$y" "$y.bak-$TS"
sed -i 's/enable_prometheus:[[:space:]]*true/enable_prometheus: false/I' "$y"
printf " %-12s -> " "$f.yaml"; grep -i enable_prometheus "$y" || echo "(本无此项)"
done
echo "===== 2. 重启三个 litellm(重读配置) ====="
docker restart litellm-public litellm-gc litellm-smt
echo " 等 25 秒让它们起来..."
sleep 25
echo "===== 3. 刷新 nginx 上游 IP 缓存(消除 502) ====="
docker restart nginx-gateway
sleep 6
echo "===== 4. 验证 ====="
docker ps --format '{{.Names}}\t{{.Status}}' | grep -E 'litellm|nginx' | tee -a "$OUT"
echo "--- 经 8080 网关(200=通) ---" | tee -a "$OUT"
for p in public gc smt; do
curl -s -o /dev/null -w " /v1/$p/models HTTP=%{http_code}\n" "http://localhost:8080/v1/$p/models" | tee -a "$OUT"
done
echo "===== 5. 修复后日志尾 ====="
docker logs litellm-public --tail 30 2>&1 | tee -a "$OUT"
echo ""
echo "三个 litellm 变 healthy 且 HTTP=200 即成功;网页/opencode 随即可用。"
echo "若仍失败:把 $OUT 带回来(里面有真实报错)。"
echo "回滚:cp $CFG/public.yaml.bak-$TS $CFG/public.yaml(gc/smt 同理)后 docker restart litellm-public litellm-gc litellm-smt。"
#!/usr/bin/env bash
# ============================================================================
# set-235b-tp4.sh — 把公用方 235B 从 TP=8 改成 TP=4,落到 4 张好卡
# 为什么 TP=4:你这个是 FP8 块量化(块=128)版,1536÷8=192 不整除 → TP=8 数学上
# 不可行;1536÷4=384÷128=3 整除 → TP=4 可行。
# 注意:TP=4 时每卡权重≈55G(TP=8 的两倍),util 必须够大,默认 0.85。
# ⚠ 请尽量选 4 张【好卡且其上没有大占用】的卡;若 OOM,降低 util 或换卡。
#
# 用法(机器上):
# sudo bash set-235b-tp4.sh "0,1,3,5" # 引号内填 4 张好卡(0-7)
# sudo bash set-235b-tp4.sh "0,1,3,5" 0.80 # 第二个参数自定 util(OOM 时调小)
# ============================================================================
set -uo pipefail
CARDS="${1:-0,1,3,5}"
UTIL="${2:-0.85}"
COMPOSE=/opt/llm-stack/compose
TS=$(date +%Y%m%d-%H%M)
n=$(echo "$CARDS" | tr ',' '\n' | grep -c .)
[ "$n" = "4" ] || { echo "必须正好 4 张卡,你给的是 $n 张:$CARDS"; exit 1; }
[ -f "$COMPOSE/docker-compose.fallback-235b.yml" ] || { echo "没找到 235B 叠加层,请先 sudo /opt/llm-stack/runtime/switch-to-235b.sh 切到 235B 再跑本脚本。"; exit 1; }
cd "$COMPOSE" || exit 1
cp -n .env ".env.bak-$TS"
# 1) TP=4 + 抬高 util(TP=4 每卡权重翻倍,原 0.40 装不下)
grep -q '^Q235_TP=' .env && sed -i "s/^Q235_TP=.*/Q235_TP=4/" .env || echo "Q235_TP=4" >> .env
grep -q '^Q235_UTIL=' .env && sed -i "s/^Q235_UTIL=.*/Q235_UTIL=$UTIL/" .env || echo "Q235_UTIL=$UTIL" >> .env
# 2) 落卡:用一个小叠加层覆盖 NVIDIA_VISIBLE_DEVICES(不动原 overlay)
cat > docker-compose.235btp4.yml <<EOF
services:
vllm-public-llm:
environment:
NVIDIA_VISIBLE_DEVICES: "$CARDS"
CUDA_DEVICE_ORDER: "PCI_BUS_ID"
EOF
echo "[*] Q235_TP=4 Q235_UTIL=$UTIL 卡=$CARDS"
echo "[*] 重建 vllm-public-llm(三层叠加:base + fallback-235b + 235btp4)..."
docker compose -f docker-compose.yml -f docker-compose.fallback-235b.yml -f docker-compose.235btp4.yml up -d --force-recreate vllm-public-llm
echo ""
echo "[*] 235B 加载约 3-8 分钟,实时看日志:"
echo " docker logs -f vllm-public-llm"
echo " 成功标志:出现 'Application startup complete',docker ps 里 vllm-public-llm 为 healthy。"
echo " 若日志再出现 '... not divisible by ... 128' = 卡数仍非 4,检查 NVIDIA_VISIBLE_DEVICES。"
echo " 若 OOM/显存不足 = 同卡有小模型抢显存,重跑并把 util 调小,例如:sudo bash set-235b-tp4.sh \"$CARDS\" 0.70"
echo ""
echo "回滚:cp $COMPOSE/.env.bak-$TS $COMPOSE/.env; rm $COMPOSE/docker-compose.235btp4.yml; sudo /opt/llm-stack/runtime/switch-to-235b.sh"
#!/usr/bin/env bash
# ============================================================================
# fix-delivery-doc.sh — 在交付文档最前面插入"现场实测勘误",更正自动生成的错误内容
# 作用对象:/opt/llm-stack/DELIVERY.md 及其副本 /opt/llm-stack/docs/DELIVERY.md
# 做法:不去 sed 改正文(易改坏),而是在最顶部插入一段权威勘误,注明"与下文冲突
# 以本节为准"。可重复运行(带 BEGIN/END 标记,重跑会先删旧勘误再插新的)。
#
# 用法:先按你【最终跑通的状态】改下面几个变量,再:
# sudo bash fix-delivery-doc.sh
# 若报 $'\r':sed -i 's/\r$//' fix-delivery-doc.sh 再跑。
# ============================================================================
# ===================== 按现场最终状态填写(改这里) =====================
PUBLIC_MODEL="Qwen3-235B-A22B-Thinking-2507" # 公用方最终实际用的模型
PUBLIC_TP="4" # 公用方并行度(235B-FP8 只能 4)
PUBLIC_CARDS="0,1,3,5" # 公用方落的 4 张好卡
BAD_CARDS="2,4" # 确认有问题、不可用于大模型的卡(显示 Graphics Device)
SMT_LLM_CARDS="6,7" # SMT 27B 已搬到的卡
# =======================================================================
set -uo pipefail
TS=$(date +%Y%m%d-%H%M)
DOCS=(/opt/llm-stack/DELIVERY.md /opt/llm-stack/docs/DELIVERY.md)
read -r -d '' ERRATA <<EOF || true
<!-- ERRATA-BEGIN -->
# ★ 现场实测勘误(更新于 ${TS},与下文冲突处以本节为准)
> 本文件下半部分由安装脚本在**首启前**自动生成,部分内容是按设计预期写的;经现场
> 8×H100 实测,以下几处需更正。**实际交付状态以本节为准。**
## 1. 硬件勘误
- 8 张卡中 **${BAD_CARDS} 号为非标/有问题卡**:\`nvidia-smi\` 显示为 \`NVIDIA Graphics Device\`(非 H100)、功率 700W(SXM 芯片魔改 PCIe),不参与任何大模型部署。
- 本批 H100 **未配 NVLink 桥**,且为**双路服务器跨槽(topo 显示 SYS)**,卡间走 PCIe,无 NVLink。
- 已用 \`/etc/modprobe.d/disable-nvlink.conf\`(\`NVreg_NvLinkDisable=1\`)关闭 NVLink;如需恢复:删该文件 + \`update-initramfs -u\` + 重启。
## 2. 公用大模型勘误(最重要)
- 文档下文写"公用方 = DeepSeek-V4-Flash、占满 8 卡、tp8-ep"——**在本机起不到**:无 NVLink 导致专家并行(EP)的 all-to-all 失败,且 dev 镜像 torch.compile 报 InductorError。
- **实际公用方已改为:\`${PUBLIC_MODEL}\`,TP=${PUBLIC_TP},落卡 ${PUBLIC_CARDS}。**
- 若仍要用 DeepSeek:必须加 \`--enforce-eager\`(关 torch.compile)+ 改 tp4 + 落到好卡,且 **不要用 dp-ep**(仍带 EP,会同样失败)。无 NVLink 机器策略阶梯应为 **tp8-ep → tp8 → tp4**(跳过 dp-ep)。
## 3. Qwen3-235B(FP8)勘误
- 此为 **FP8 块量化(块=128)版,只能 TP=4**:1536÷8=192 不被 128 整除,**TP=8 在数学上不可行**(vLLM 直接报 \`not divisible by ... block_n = 128\`)。
- 入口脚本/文档中"TP=8 默认、别改小"的说法对**本 FP8 版无效**,请按 TP=4 使用。
## 4. SMT 对话模型(Qwen3.6-27B)勘误
- 已从问题卡搬到 **${SMT_LLM_CARDS} 号卡**,运行正常。
## 5. 监控勘误
- 三套 litellm 配置已**关闭 \`enable_prometheus\`**(离线镜像缺 prometheus 依赖会导致 litellm worker 崩溃、进而全网关 502)。
- 影响:Grafana 里 **litellm 层**的请求/延迟/token 面板无数据;**vLLM 引擎自身指标、所有推理/路由/网页/API 功能均不受影响**。联网补齐依赖后可改回 \`true\` 恢复。
## 6. 本次现场修复清单
- 关闭 litellm \`enable_prometheus\` 并重启三套 litellm + nginx → 解决全网关 502。
- 公用方改为 ${PUBLIC_MODEL} TP=${PUBLIC_TP}(避开 ${BAD_CARDS} 号坏卡)。
- SMT 27B 迁至 ${SMT_LLM_CARDS} 号卡。
<!-- ERRATA-END -->
EOF
for DOC in "${DOCS[@]}"; do
[ -f "$DOC" ] || { echo "跳过(不存在):$DOC"; continue; }
cp -n "$DOC" "$DOC.bak-$TS"
# 重跑:先删旧勘误块(BEGIN..END),避免重复插入
sed -i '/<!-- ERRATA-BEGIN -->/,/<!-- ERRATA-END -->/d' "$DOC"
tmp=$(mktemp)
{ printf '%s\n\n' "$ERRATA"; cat "$DOC"; } > "$tmp" && mv "$tmp" "$DOC"
echo "已更新:$DOC (原文件备份 $DOC.bak-$TS)"
done
echo ""
echo "完成。打开 /opt/llm-stack/DELIVERY.md,最顶部即为现场勘误。"
echo "如需重改:改本脚本顶部变量后再跑一次即可(会自动替换旧勘误)。"