Tesla V100-32G 跑 Qwen3.8-27B nvfp4:200W 下 decode 93.9 tok/s、prefill 1019 tok/s(NInfer SM70 / CUDA 12.8)
-
成绩速览(V100-PCIE-32G / 200W / 单请求)
指标 最好 区间 decode 93.9 tok/s(编码任务,640 token,MTP 接受率 92%) 44.9–93.9 tok/s(取决于任务与 MTP 接受率) prefill 1,019.0 tok/s(7.9K prompt) 505.8–1,019.0 tok/s(随上下文深度衰减) TTFT 0.13 s(完全相同的 prompt 重发,前缀 100% 命中) 0.18–0.47 s(短 prompt)→ 1.96 s @2K → 250.27 s @128K 并发 2 路各 124.6K 上下文实测跑通 第二路排队 4m1.1s(prefill 串行) 显存 权重 19.7 GiB + KV 池 262,144 token 启动后 free 1.21 GiB 这篇针对
neroued/Qwen3.8-27B-nvfp4-NInfer这个 nvfp4 制品,写两件事:
① 完整部署流程(含源码锚点、Dockerfile、制品下载校验、启动脚本、报错对照),别人或别人的 agent 照着能直接跑起来;
② 全部实测数字(上下文 / 制品 A/B / 任务类型 / 并发 / 显存容量 / 前缀复用),只列数据,结论很少。给 agent / 想直接照做的人:把第 3 节那个脚本原样存成
deploy-v100-nvfp4.sh,sudo bash跑完即可(驱动、Docker、CUDA 12.8、编译引擎、打镜像、下制品校验、启动、健康检查全在里面)。
所有锚点都已钉死:引擎 repo + commit、制品 repo + revision + sha256、镜像底座、启动参数。文中标注
️ 的四处是必须照做的(非 open 驱动 / v2 容器制品 / 显式 --kv-capacity/--pending-timeout-ms),踩错会直接报错或起不来。
0. 环境
项 值 GPU Tesla V100-PCIE-32GB(GV100,Volta SM70,32G HBM2,PCIe Gen3 x16) 形态 PVE 直通给 Ubuntu 24.04 VM(16 vCPU / 32G RAM / 200G 系统盘) 宿主 CPU Xeon E5-2697 v4 @2.30GHz ×16(Broadwell,无 AVX-512) 驱动 580.178.04(非 open) 功率墙 200 W(V100-PCIE 默认 250 W) 引擎 NInfer V100/sm_70 分支, hamawang/ninfer-v100-20260916@f17d37fc98b78cc025a1037e8adb1f4fb83813fb编译 CUDA 12.8, -DCMAKE_CUDA_ARCHITECTURES=70容器底座 nvidia/cuda:12.8.0-runtime-ubuntu24.04制品 qwen3_8_27b_nvfp4.ninfer(20.02 GiB,container_version 2)运行参数 --max-context 131072 --kv-capacity 262144 --max-concurrency 2 --kv-dtype int8实测占用 权重 19.7 GiB,KV 池 262,144 token,运行时 10.8 GiB,启动后 free 1.21 GiB,ready 18.2 s
1. 部署
1.1 驱动(Volta 必须非 open)
sudo apt-get install -y "linux-headers-$(uname -r)" nvidia-driver-580-server sudo modprobe nvidia && nvidia-smi -L sudo nvidia-smi -pm 1 && sudo nvidia-smi -pl 200-open内核模块只支持 Turing 及更新架构,Volta 装上会报
not supported by open nvidia.ko ... does not include the required GPU System Processor (GSP)。- R580 是 Maxwell / Pascal / Volta 的最后一条驱动分支。
nvidia-smi -pl不跨重启保留,需要开机重施(附脚本里给了 systemd oneshot 单元)。
1.2 引擎源码与构建
git clone https://github.com/hamawang/ninfer-v100-20260916.git /opt/ninfer-v100 cd /opt/ninfer-v100 && git checkout f17d37fc98b78cc025a1037e8adb1f4fb83813fb # 需要 CUDA 12.8 toolkit(CUDA 13 已移除 Volta 的离线编译) bash deploy-v100/scripts/build-v100.sh # = cmake -S . -B build-v100 -G Ninja -DCMAKE_BUILD_TYPE=Release \ # -DCMAKE_CUDA_COMPILER=/usr/local/cuda-12.8/bin/nvcc \ # -DCMAKE_CUDA_ARCHITECTURES=70 -DNINFER_BUILD_BENCHMARKS=ON # cmake --build build-v100 -j6产物(可用于校验你自建的二进制,同 commit + CUDA 12.8 + sm_70):
371fd8de37e73df12b1f61144e43b210a12f9c0ef4acc193f5ae3f11f4294658 build-v100/apps/ninfer 6671447e3cbbf07565dff9417462d01bcf8aa1093aa5c9f83fb6a9a0ce79ac10 build-v100/apps/ninfer-serve1.3 打镜像(完整 Dockerfile)
底座必须与制品编译时的 CUDA 版本对齐(二进制 RUNPATH 硬指
/usr/local/cuda-12.8/...):FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04 ARG DEBIAN_FRONTEND=noninteractive # base 镜像只带 NVIDIA 源、没有 Ubuntu 归档,先换源再装运行库 RUN rm -f /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null; \ printf '%s\n' \ 'Types: deb' \ 'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' \ 'Suites: noble noble-updates noble-backports' \ 'Components: main universe restricted multiverse' \ 'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \ '' \ 'Types: deb' \ 'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' \ 'Suites: noble-security' \ 'Components: main universe restricted multiverse' \ 'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \ > /etc/apt/sources.list.d/ubuntu.sources \ && apt-get update -qq \ && apt-get install -y --no-install-recommends \ ca-certificates libavcodec60 libavformat60 libavutil58 \ libswscale7 libswresample4 libcurl4t64 \ && rm -rf /var/lib/apt/lists/* COPY ninfer ninfer-serve /usr/local/bin/ RUN chmod +x /usr/local/bin/ninfer /usr/local/bin/ninfer-serve WORKDIR /workspace EXPOSE 8080 CMD ["ninfer-serve", "--help"]mkdir -p ctx && cp /opt/ninfer-v100/build-v100/apps/{ninfer,ninfer-serve} ctx/ docker build -t ninfer-v100:0.1.0 ctx/libcuda.so.1不打进镜像,由--gpus从宿主驱动注入(镜像与驱动版本解耦)。1.4 下载 nvfp4 制品(必须钉这个 revision)
mkdir -p /srv/models && cd /srv/models curl -L -C - -o qwen3_8_27b_nvfp4.ninfer \ "https://hf-mirror.com/neroued/Qwen3.8-27B-nvfp4-NInfer/resolve/204e3d92c30d9d05f3300d2f52e443ad1edf6ddf/qwen3_8_27b_nvfp4.ninfer" # 校验(必须一致,否则说明下错版本) sha256sum qwen3_8_27b_nvfp4.ninfer # bb3360522a06e136e0367f5703414d26272b7285c8a6ab6194135c17dbd81b32字段 值 repo neroued/Qwen3.8-27B-nvfp4-NInferrevision(钉死) 204e3d92c30d9d05f3300d2f52e443ad1edf6ddf(2026-08-19)文件 / 字节 qwen3_8_27b_nvfp4.ninfer/ 21,492,695,040(20.02 GiB)sha256 bb3360522a06e136e0367f5703414d26272b7285c8a6ab6194135c17dbd81b32container_version 2 为什么不能下 main:仓库 main(
a107ba1b)上的同名文件是 container v3(23,719,496,192 B),本引擎只认 v2,加载直接失败:ERROR startup failed | inspecting artifact | 31.4 ms FATAL server failed during startup | artifact magic is not NInfer v2容器版本看文件头 8 字节即可判断:
dd if=qwen3_8_27b_nvfp4.ninfer bs=1 count=8 status=none | od -c # 正确: N I N F E R \0 002 # v3 : N I N F E R \0 003实测下载速度(HF 官方站不可达时用 hf-mirror):12.4 MB/s,20 GiB 约 29 分钟;
curl -C -支持断点续传。
制品建议放本地盘:本地盘加载 18.2 s,走 NFS 是 52–59 s。1.5 启动脚本(可直接用)
#!/usr/bin/env bash # ninfer-v100 run.sh —— nvfp4 + 2 并发 × 128K set -euo pipefail NAME=ninfer IMG=ninfer-v100:0.1.0 MODEL_DIR=${MODEL_DIR:-/srv/models} MODEL=${MODEL:-qwen3_8_27b_nvfp4.ninfer} PORT=${PORT:-18080} CTX=${CTX:-131072} # 单请求逻辑上下文上限 KV_CAP=${KV_CAP:-262144} # ★ 共享 KV 池,必须显式给 = 2 × CTX CONC=${CONC:-2} # 并发路数 PREFILL=${PREFILL:-2048} # V100 推荐 PENDING_MS=${PENDING_MS:-600000} # ★ 默认 30s 会把并发长请求挤成 503 API_KEY=${API_KEY:-} # 留空 = 不鉴权 ARGS=(--host 0.0.0.0 --port 8080 --max-context "$CTX" --kv-capacity "$KV_CAP" --max-concurrency "$CONC" --kv-dtype int8 --prefill-chunk "$PREFILL" --pending-timeout-ms "$PENDING_MS" --spec mtp --draft-tokens 3 --lm-head-draft --preserve-thinking --cors) [ -n "$API_KEY" ] && ARGS+=(--api-key "$API_KEY") case "${1:-start}" in start) docker rm -f "$NAME" >/dev/null 2>&1 || true docker run -d --name "$NAME" --restart unless-stopped \ --gpus all --ipc=host \ -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \ -p "${PORT}":8080 -v "$MODEL_DIR":/models:ro \ "$IMG" ninfer-serve "/models/$MODEL" "${ARGS[@]}" echo "started -> http://0.0.0.0:${PORT}" ;; stop) docker stop -t 30 "$NAME";; logs) docker logs -f --tail 100 "$NAME";; status) docker ps -a --filter "name=^${NAME}$";; *) echo "usage: $0 {start|stop|logs|status}"; exit 1;; esac参数说明(都是实测踩出来的)
参数 为什么是这个值 --max-context 131072128K 逻辑上限。超限请求被明确拒绝而不是截断: 400 context_length_exceeded: prepared prompt exceeds Engine max_context 131072--kv-capacity 262144必须显式。nvfp4 权重 19.7 GiB 下 auto只肯给 ~237K,而且 auto 模式要额外留 1 GiB headroom → 直接拒绝启动。显式 262144 正好 = 2×128K,实测启动后 free 1.21 GiB--max-concurrency 2引擎真批处理路数。客户端并发超过它会被饿(实测第 3、4 条掉到 5.7 tok/s) --kv-dtype int8Volta 没有 fp8 / nvfp4 / k8v4 的 KV 内核,只能 bf16或int8--prefill-chunk 2048V100 上的推荐值 --pending-timeout-ms 600000默认 30 s。prefill 是单通道串行的,一条 125K prompt 要 prefill 4 分钟,第二路在队列里等超过 30 s 就被判 503 request_queue_timeout--spec mtp --draft-tokens 3 --lm-head-draftMTP 投机解码;decode 快慢几乎完全由它的接受率决定(见第 2.3 节) 1.6 验收
curl -s localhost:18080/health # {"status":"ok"} curl -s localhost:18080/v1/models # max_model_len = 131072 curl -s localhost:18080/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model":"qwen3.8-27b", "messages":[{"role":"user","content":"只回答两个字:收到"}], "max_tokens":16,"reasoning_effort":"none"}' | head -c 200启动日志里会打出显存账本(
--log-level debug更详细):INFO engine ready | qwen3.8-27b/nvfp4 | total 18.2s | weights 19.7 GiB INFO capacity | KV 262,144 tokens, int8, explicit | pages 4,096/4,096 | runtime 10.8 GiB | free 1.21 GiB INFO listening on http://0.0.0.0:8080 | model qwen3.8-27b | auth disabled1.7 报错对照表
现象 根因 处置 nvidia-smi:couldn't communicate with the NVIDIA driver/nvtop看不到卡驱动没装(直通本身没问题, lspci能看到10de:1db6)装 nvidia-driver-580-servernot supported by open nvidia.ko ... GPU System Processor (GSP)装了 -open驱动,Volta 不支持换非 open: apt purge "nvidia-*-open"再装nvidia-driver-580-servercannot open shared object file: libcudart.so.12底座 CUDA 版本与二进制 RUNPATH 不一致 底座用 cuda:12.8.0-runtime-ubuntu24.04FATAL ... artifact magic is not NInfer v2下了 v3 容器制品(main 上的那个) 钉 revision 204e3d92c30d(v2 容器)minimum Engine runtime reservation requires … but only … available after weights显存不够( auto模式还要额外 1 GiB)显式给 --kv-capacity,并按下表算容量503 request_queue_timeout默认 30 s 排队超时 + prefill 串行 --pending-timeout-ms 600000400 context_length_exceededprompt + 输出超过 --max-context调小 prompt 或调大 --max-context(受显存限制,见 2.5)
2. Benchmark
统一条件:贪心(
temperature=0)、reasoning_effort: none(除注明)、prompt 为同一份技术文档按目标长度拼接;decode = 引擎口径「已提交输出 token / 秒」;TTFT = 服务端 prompt 处理时间(不含排队);功率墙 200 W;负载期功耗中位 195 W、SM 频率中位 1087 MHz(最高 1380 MHz)。2.1 上下文长度扫描(nvfp4 制品,单请求,128 输出 token)
目标上下文 prompt token prefill tok/s TTFT decode tok/s MTP 接受率 2K 1,967 1,003.5 1.96 s 56.8 47%(38/81) 8K 7,907 1,019.0 7.76 s 72.6 71%(45/63) 32K 31,667 868.6 36.46 s 57.2 60%(45/75) 64K 63,311 699.4 90.52 s 36.2 40%(37/93) 128K 126,599 505.8 250.27 s 37.0 60%(45/75) 补充:同一配置下 8K prompt、320 输出上限的持续生成实测 71.5 tok/s(MTP 71%)。
2.2 nvfp4 vs groupwise-int(同一脚本、同一参数,唯一变量是制品)
neroued/Qwen3.8-27B-NInfer@18dfc887423f(groupwise-int,16.96 GiB,sha256eec39564993d…4bf3e)作为对照:shape groupwise-int:prefill / decode / MTP nvfp4:prefill / decode / MTP 1K 987.9 / 41.8 / 51% 1,003.5 / 56.8 / 47% 7K 1,014.0 / 43.3 / 58% 1,019.0 / 72.6 / 71% 30K 864.7 / 42.4 / 65% 868.6 / 57.2 / 60% 61K 696.3 / 31.3 / 52% 699.4 / 36.2 / 40% 123K 505.9 / 29.5 / 63% 505.8 / 37.0 / 60% 编码任务(640 tok,两边 MTP 都 89%) 115.2 / 58.6 / 89% 119.5 / 90.9 / 89% 持续生成(8K,66 tok) 951.1 / 41.6 / 58% 954.5 / 71.5 / 71% 双并发(8K,均缓存命中) 批 wall 3.84 s / 188 tok / 48.9 tok/s 批 wall 2.55 s / 152 tok / 59.7 tok/s 上下文扫描那几行的 decode 不能直接横向比:权重不同 → 生成的文本不同 → MTP 接受率不同(40% vs 52% 之类),短样本下接受率差异会盖过真实速度差。编码任务那行是干净的(prompt、输出长度 640、贪心、MTP 接受率 464/523 vs 467/525 全部对齐):58.6 → 90.9 tok/s。
注:这张表的数字来自成对跑的那一轮;同一 prompt 在 2.3 节另一轮里测得 93.4/93.9 tok/s(MTP 91–92%),两轮差异属运行间波动(同一制品重跑 ±3%)。2.3 任务类型(nvfp4,8K 与 64K 两档)
任务 输出 token 8K:decode / MTP 64K:decode / MTP 写代码(LRU + pytest) 640 93.4 / 91% 93.9 / 92% JSON 字段抽取 24 82.7 / 90% 82.7 / 90% 摘要(5.9K 文档) 56 81.2 / 81% 81.4 / 81% 翻译 48 78.7 / 76% 78.3 / 76% 推理( effort=xhigh,1024 思考 token)1024 70.8 / 61% 70.6 / 61% 找 bug 根因(闭包 late-binding) 253 68.8 / 57% 68.8 / 57% 闲聊 92 55.8 / 42% 55.9 / 42% 写小说 257 44.9 / 26% 47.5 / 31% TTFT 方面:短 prompt(几十 token)在 8K 与 64K 档几乎无差别(0.09–0.47 s),只有 5.9K 文档摘要那档是 5.8 s。
2.4 并发
(a)双并发长上下文(本机生产配置实测,2 路各 ~125K)
路 prompt token TTFT(服务端) 其中排队 prefill tok/s 输出 wall L1 124,632 241.0 s 0 517 61 319.9 s L2 124,632 247.6 s(引擎记 8m8.7s) 4 m 1.1 s 503 61 490.9 s (b)解码批处理(引擎 5 s 窗口口径,groupwise 制品同引擎测得)
batch 聚合 decode tok/s 相对 batch=1 1.00 60.4 1.00× 2.00 87.2 1.44× 3.98 126.8 2.10× (c)端到端(每路冷启动 8K prompt + 320 输出 token,groupwise 制品)
服务端并发 客户端路数 单路端到端 聚合端到端 加速比 2 1 24.4 tok/s 24.4 1.00× 2 2 24.0–24.6 26.5–27.2 1.11× 4 4 23.9 29.3 1.22× (d)服务端日志里的两个并发现象(原文)
# prefill 单通道串行:任一瞬间只有 1 路在 prefill,其他在等 throughput | 5.0s | prefill 409.6 tok/s (2,048 tok) | running 1 (prefill 1) | waiting 1 | host 53.9% # prefill 会饿死 decode:有 prefill 时 decode 掉到个位数 throughput | 5.0s | prefill 819.2 tok/s (4,096 tok) | decode 3.2 tok/s | running 3 (prefill 1, decode-ready 2) | batch 2.00 throughput | 5.0s | | decode 126.8 tok/s | running 4 (decode-ready 4) | batch 3.982.5 显存与容量(这块最实用)
用失败报错反解出的引擎显存公式(32G V100,int8 KV,MTP3):
运行时占用 = 2.75 GiB(固定:state 槽 + workspace + CUDA graph) + KV 池容量 × 35,904 B 权重后可用显存:nvfp4 11.70 GiB / groupwise-int 14.75 GiB实测容量上限(
--max-concurrency 2,容量需为 64 的倍数,均为「能启动 + 能跑通请求」验证过的值):groupwise-int nvfp4 权重 16.7 GiB 19.7 GiB 权重后可用 14.75 GiB 11.70 GiB --kv-capacity auto328,960 token
拒绝启动(差 0.88 GiB)最大共享池 358,912 token 267,456 token 双并发每路可用 ≈179K ≈130K 2×160K(池需 327,680)
余 31,232
差 2.01 GiB;关掉 graph + state 槽也只省 622 MiB,仍差 1.40 GiB单请求边界(
--max-context 131072):HTTP 400 {"error":{"code":"context_length_exceeded", "message":"prepared prompt exceeds Engine max_context 131072", ...}}2.6 前缀复用(同引擎,16K 文档)
(同一组测量:16K 文档,prompt 15,846–15,886 token,同引擎)
场景 prompt token 命中前缀 token TTFT 冷请求 15,846 0 16.47 s 完全相同请求重发 15,846 15,839(100%) 0.13 s 同 prompt、只改 max_tokens(64 → 256) 15,846 15,839(100%) 0.13 s prompt 后追加一句(Chat Completions) 15,855 0 16.72 s 同正文、换会话编号 15,846 0 16.80 s 显式 prompt_cache_breakpoint写入后再追加读取15,855 0 17.00 s Anthropic cache_control写入 → 追加读取15,886 15,879 1.65 s Responses API previous_response_id续轮— 15,917 1.17 s 2.7 运行条件
项 值 功率墙 200 W(默认 250 W,可设 100–250) 负载期功耗 中位 195 W,最高 228 W 负载期 SM 频率 中位 1087 MHz,最高 1380 MHz(卡的最大 SM 时钟即 1380) 空载 37–40 °C / 约 60 W PCIe Gen3 x16(8 GT/s),非瓶颈
3. 一键部署脚本
#!/usr/bin/env bash # ============================================================ # NInfer + Qwen3.8-27B (nvfp4) @ Tesla V100-PCIE-32GB # CUDA 12.8 / sm_70 / Docker / 200W / 2 并发 × 128K # 用法: sudo bash deploy-v100-nvfp4.sh # ============================================================ set -euo pipefail MODEL_DIR=${MODEL_DIR:-/srv/models} PORT=${PORT:-18080}; CTX=${CTX:-131072}; KV_CAP=${KV_CAP:-262144} CONC=${CONC:-2}; POWER_LIMIT=${POWER_LIMIT:-200} SRC_DIR=${SRC_DIR:-/opt/ninfer-v100}; CUDA_ROOT=${CUDA_ROOT:-/usr/local/cuda-12.8} REPO=https://github.com/hamawang/ninfer-v100-20260916.git COMMIT=f17d37fc98b78cc025a1037e8adb1f4fb83813fb ART_URL=https://hf-mirror.com/neroued/Qwen3.8-27B-nvfp4-NInfer/resolve/204e3d92c30d9d05f3300d2f52e443ad1edf6ddf/qwen3_8_27b_nvfp4.ninfer ART_SHA=bb3360522a06e136e0367f5703414d26272b7285c8a6ab6194135c17dbd81b32 IMG=ninfer-v100:0.1.0 step(){ echo; echo "==== $* ===="; } step "1/6 NVIDIA 驱动(非 open)+ 功率墙" if ! command -v nvidia-smi >/dev/null 2>&1; then apt-get update -qq && apt-get install -y "linux-headers-$(uname -r)" nvidia-driver-580-server modprobe nvidia 2>/dev/null || { echo "驱动已装,请重启后重新运行本脚本"; exit 0; } fi nvidia-smi -L nvidia-smi -pm 1 && nvidia-smi -pl "$POWER_LIMIT" # 功率墙不跨重启,落一个开机单元 cat > /usr/local/bin/nvidia-powerlimit.sh <<'EOF' #!/bin/bash for _ in $(seq 1 60); do nvidia-smi -L >/dev/null 2>&1 && break; sleep 5; done nvidia-smi -pm 1 >/dev/null 2>&1 || true nvidia-smi -pl "${1:-200}" EOF chmod +x /usr/local/bin/nvidia-powerlimit.sh step "2/6 Docker + nvidia-container-toolkit" if ! command -v docker >/dev/null 2>&1; then install -m 0755 -d /etc/apt/keyrings curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg \ | tee /etc/apt/keyrings/docker.asc >/dev/null && chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(. /etc/os-release; echo "$VERSION_CODENAME") stable" \ > /etc/apt/sources.list.d/docker.list apt-get update -qq && apt-get install -y docker-ce docker-ce-cli containerd.io fi if ! command -v nvidia-ctk >/dev/null 2>&1; then apt-get update -qq && apt-get install -y nvidia-container-toolkit || { curl -fsSLO https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb dpkg -i cuda-keyring_1.1-1_all.deb && apt-get update -qq && apt-get install -y nvidia-container-toolkit; } fi nvidia-ctk runtime configure --runtime=docker systemctl enable --now docker && systemctl restart docker step "3/6 CUDA 12.8 toolkit(编译引擎)" if [ ! -x "$CUDA_ROOT/bin/nvcc" ]; then curl -fsSLO https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb dpkg -i cuda-keyring_1.1-1_all.deb && apt-get update -qq apt-get install -y cuda-toolkit-12-8 fi "$CUDA_ROOT/bin/nvcc" --version | tail -1 step "4/6 构建引擎" if [ ! -x "$SRC_DIR/build-v100/apps/ninfer-serve" ]; then command -v cmake >/dev/null 2>&1 && command -v ninja >/dev/null 2>&1 || apt-get install -y cmake ninja-build git [ -d "$SRC_DIR/.git" ] || git clone "$REPO" "$SRC_DIR" git -C "$SRC_DIR" checkout "$COMMIT" ( cd "$SRC_DIR" && CUDA_ROOT="$CUDA_ROOT" bash deploy-v100/scripts/build-v100.sh ) fi sha256sum "$SRC_DIR"/build-v100/apps/ninfer "$SRC_DIR"/build-v100/apps/ninfer-serve step "5/6 打镜像 + 下制品" CTXDIR=$(mktemp -d) cp "$SRC_DIR"/build-v100/apps/{ninfer,ninfer-serve} "$CTXDIR"/ cat > "$CTXDIR/Dockerfile" <<'EOF' FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04 ARG DEBIAN_FRONTEND=noninteractive RUN rm -f /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null; \ printf '%s\n' 'Types: deb' 'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' \ 'Suites: noble noble-updates noble-backports' 'Components: main universe restricted multiverse' \ 'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' '' \ 'Types: deb' 'URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu' 'Suites: noble-security' \ 'Components: main universe restricted multiverse' \ 'Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' \ > /etc/apt/sources.list.d/ubuntu.sources \ && apt-get update -qq \ && apt-get install -y --no-install-recommends ca-certificates \ libavcodec60 libavformat60 libavutil58 libswscale7 libswresample4 libcurl4t64 \ && rm -rf /var/lib/apt/lists/* COPY ninfer ninfer-serve /usr/local/bin/ RUN chmod +x /usr/local/bin/ninfer /usr/local/bin/ninfer-serve WORKDIR /workspace EXPOSE 8080 EOF docker build -t "$IMG" "$CTXDIR" mkdir -p "$MODEL_DIR" if [ ! -f "$MODEL_DIR/qwen3_8_27b_nvfp4.ninfer" ]; then curl -L -C - -o "$MODEL_DIR/qwen3_8_27b_nvfp4.ninfer" "$ART_URL" fi echo "$ART_SHA $MODEL_DIR/qwen3_8_27b_nvfp4.ninfer" | sha256sum -c - step "6/6 启动" docker rm -f ninfer >/dev/null 2>&1 || true docker run -d --name ninfer --restart unless-stopped --gpus all --ipc=host \ -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \ -p "${PORT}":8080 -v "$MODEL_DIR":/models:ro "$IMG" \ ninfer-serve /models/qwen3_8_27b_nvfp4.ninfer \ --host 0.0.0.0 --port 8080 \ --max-context "$CTX" --kv-capacity "$KV_CAP" --max-concurrency "$CONC" \ --kv-dtype int8 --prefill-chunk 2048 --pending-timeout-ms 600000 \ --spec mtp --draft-tokens 3 --lm-head-draft --preserve-thinking --cors for i in $(seq 1 40); do [ "$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:${PORT}/health" || true)" = 200 ] \ && { echo "就绪: http://127.0.0.1:${PORT}/v1 (model id: qwen3.8-27b)"; exit 0; } sleep 5 done echo "未就绪,看日志: docker logs ninfer"; exit 1开机自启:容器带
--restart unless-stopped即可;功率墙用上面那个脚本挂一个 oneshot 单元:# /etc/systemd/system/nvidia-powerlimit.service [Unit] Description=Lock V100 power limit After=systemd-modules-load.service Before=docker.service [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/nvidia-powerlimit.sh 200 [Install] WantedBy=multi-user.target -
整个kv在nvfp4的方案里最多只有256k.在单并发长上下文和双并发短上下文中,选择了后者。 Prefill在高上下文时衰减比较严重,均衡选择了c=2, ctx=128k。
V100这两天开始涨价了。 纯文字llm,不做视频的,可以参考。