<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Tesla V100-32G 跑 Qwen3.8-27B nvfp4：200W 下 decode 93.9 tok/s、prefill 1019 tok/s（NInfer SM70 / CUDA 12.8）]]></title><description><![CDATA[<p dir="auto"><strong>成绩速览（V100-PCIE-32G / 200W / 单请求）</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>指标</th>
<th>最好</th>
<th>区间</th>
</tr>
</thead>
<tbody>
<tr>
<td>decode</td>
<td><strong>93.9 tok/s</strong>（编码任务，640 token，MTP 接受率 92%）</td>
<td>44.9–93.9 tok/s（取决于任务与 MTP 接受率）</td>
</tr>
<tr>
<td>prefill</td>
<td><strong>1,019.0 tok/s</strong>（7.9K prompt）</td>
<td>505.8–1,019.0 tok/s（随上下文深度衰减）</td>
</tr>
<tr>
<td>TTFT</td>
<td><strong>0.13 s</strong>（完全相同的 prompt 重发，前缀 100% 命中）</td>
<td>0.18–0.47 s（短 prompt）→ 1.96 s @2K → 250.27 s @128K</td>
</tr>
<tr>
<td>并发</td>
<td>2 路各 124.6K 上下文实测跑通</td>
<td>第二路排队 4m1.1s（prefill 串行）</td>
</tr>
<tr>
<td>显存</td>
<td>权重 19.7 GiB + KV 池 262,144 token</td>
<td>启动后 free 1.21 GiB</td>
</tr>
</tbody>
</table>
<p dir="auto">这篇针对 <strong><code>neroued/Qwen3.8-27B-nvfp4-NInfer</code> 这个 nvfp4 制品</strong>，写两件事：<br />
① 完整部署流程（含源码锚点、Dockerfile、制品下载校验、启动脚本、报错对照），别人或别人的 agent 照着能直接跑起来；<br />
② 全部实测数字（上下文 / 制品 A/B / 任务类型 / 并发 / 显存容量 / 前缀复用），<strong>只列数据，结论很少</strong>。</p>
<blockquote>
<p dir="auto"><strong>给 agent / 想直接照做的人</strong>：把第 3 节那个脚本原样存成 <code>deploy-v100-nvfp4.sh</code>，<code>sudo bash</code> 跑完即可（驱动、Docker、CUDA 12.8、编译引擎、打镜像、下制品校验、启动、健康检查全在里面）。<br />
所有锚点都已钉死：引擎 repo + commit、制品 repo + <strong>revision</strong> + sha256、镜像底座、启动参数。文中标注 <img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/26a0.png?v=ec85ec55bc1" class="not-responsive emoji emoji-android emoji--warning" style="height:1.4em;width:auto;vertical-align:middle" title="⚠" alt="⚠" />️ 的四处是必须照做的（非 open 驱动 / v2 容器制品 / 显式 <code>--kv-capacity</code> / <code>--pending-timeout-ms</code>），踩错会直接报错或起不来。</p>
</blockquote>
<hr />
<h2>0. 环境</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>项</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>GPU</td>
<td>Tesla V100-PCIE-32GB（GV100，Volta SM70，32G HBM2，PCIe Gen3 x16）</td>
</tr>
<tr>
<td>形态</td>
<td>PVE 直通给 Ubuntu 24.04 VM（16 vCPU / 32G RAM / 200G 系统盘）</td>
</tr>
<tr>
<td>宿主 CPU</td>
<td>Xeon E5-2697 v4 @2.30GHz ×16（Broadwell，无 AVX-512）</td>
</tr>
<tr>
<td>驱动</td>
<td><strong>580.178.04（非 open）</strong></td>
</tr>
<tr>
<td>功率墙</td>
<td><strong>200 W</strong>（V100-PCIE 默认 250 W）</td>
</tr>
<tr>
<td>引擎</td>
<td>NInfer V100/sm_70 分支，<code>hamawang/ninfer-v100-20260916</code> @ <code>f17d37fc98b78cc025a1037e8adb1f4fb83813fb</code></td>
</tr>
<tr>
<td>编译</td>
<td>CUDA 12.8，<code>-DCMAKE_CUDA_ARCHITECTURES=70</code></td>
</tr>
<tr>
<td>容器底座</td>
<td><code>nvidia/cuda:12.8.0-runtime-ubuntu24.04</code></td>
</tr>
<tr>
<td>制品</td>
<td><code>qwen3_8_27b_nvfp4.ninfer</code>（20.02 GiB，container_version 2）</td>
</tr>
<tr>
<td>运行参数</td>
<td><code>--max-context 131072 --kv-capacity 262144 --max-concurrency 2 --kv-dtype int8</code></td>
</tr>
<tr>
<td>实测占用</td>
<td>权重 19.7 GiB，KV 池 262,144 token，运行时 10.8 GiB，启动后 free <strong>1.21 GiB</strong>，ready <strong>18.2 s</strong></td>
</tr>
</tbody>
</table>
<hr />
<h2>1. 部署</h2>
<h3>1.1 驱动（Volta 必须非 open）</h3>
<pre><code class="language-bash">sudo apt-get install -y "linux-headers-$(uname -r)" nvidia-driver-580-server
sudo modprobe nvidia &amp;&amp; nvidia-smi -L
sudo nvidia-smi -pm 1 &amp;&amp; sudo nvidia-smi -pl 200
</code></pre>
<ul>
<li><code>-open</code> 内核模块只支持 Turing 及更新架构，Volta 装上会报<br />
<code>not supported by open nvidia.ko ... does not include the required GPU System Processor (GSP)</code>。</li>
<li><strong>R580 是 Maxwell / Pascal / Volta 的最后一条驱动分支</strong>。</li>
<li><code>nvidia-smi -pl</code> 不跨重启保留，需要开机重施（附脚本里给了 systemd oneshot 单元）。</li>
</ul>
<h3>1.2 引擎源码与构建</h3>
<pre><code class="language-bash">git clone https://github.com/hamawang/ninfer-v100-20260916.git /opt/ninfer-v100
cd /opt/ninfer-v100 &amp;&amp; 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
</code></pre>
<p dir="auto">产物（<strong>可用于校验你自建的二进制</strong>，同 commit + CUDA 12.8 + sm_70）：</p>
<pre><code>371fd8de37e73df12b1f61144e43b210a12f9c0ef4acc193f5ae3f11f4294658  build-v100/apps/ninfer
6671447e3cbbf07565dff9417462d01bcf8aa1093aa5c9f83fb6a9a0ce79ac10  build-v100/apps/ninfer-serve
</code></pre>
<h3>1.3 打镜像（完整 Dockerfile）</h3>
<p dir="auto">底座必须与制品编译时的 CUDA 版本对齐（二进制 RUNPATH 硬指 <code>/usr/local/cuda-12.8/...</code>）：</p>
<pre><code class="language-dockerfile">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&gt;/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' \
      &gt; /etc/apt/sources.list.d/ubuntu.sources \
    &amp;&amp; apt-get update -qq \
    &amp;&amp; apt-get install -y --no-install-recommends \
        ca-certificates libavcodec60 libavformat60 libavutil58 \
        libswscale7 libswresample4 libcurl4t64 \
    &amp;&amp; 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"]
</code></pre>
<pre><code class="language-bash">mkdir -p ctx &amp;&amp; cp /opt/ninfer-v100/build-v100/apps/{ninfer,ninfer-serve} ctx/
docker build -t ninfer-v100:0.1.0 ctx/
</code></pre>
<p dir="auto"><code>libcuda.so.1</code> <strong>不打进镜像</strong>，由 <code>--gpus</code> 从宿主驱动注入（镜像与驱动版本解耦）。</p>
<h3>1.4 下载 nvfp4 制品（<strong>必须钉这个 revision</strong>）</h3>
<pre><code class="language-bash">mkdir -p /srv/models &amp;&amp; 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
</code></pre>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>字段</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>repo</td>
<td><code>neroued/Qwen3.8-27B-nvfp4-NInfer</code></td>
</tr>
<tr>
<td><strong>revision（钉死）</strong></td>
<td><code>204e3d92c30d9d05f3300d2f52e443ad1edf6ddf</code>（2026-08-19）</td>
</tr>
<tr>
<td>文件 / 字节</td>
<td><code>qwen3_8_27b_nvfp4.ninfer</code> / 21,492,695,040（20.02 GiB）</td>
</tr>
<tr>
<td>sha256</td>
<td><code>bb3360522a06e136e0367f5703414d26272b7285c8a6ab6194135c17dbd81b32</code></td>
</tr>
<tr>
<td>container_version</td>
<td><strong>2</strong></td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>为什么不能下 main</strong>：仓库 main（<code>a107ba1b</code>）上的同名文件是 <strong>container v3</strong>（23,719,496,192 B），本引擎只认 v2，加载直接失败：</p>
<pre><code>ERROR startup failed | inspecting artifact | 31.4 ms
FATAL server failed during startup | artifact magic is not NInfer v2
</code></pre>
<p dir="auto">容器版本看文件头 8 字节即可判断：</p>
<pre><code class="language-bash">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
</code></pre>
<blockquote>
<p dir="auto">实测下载速度（HF 官方站不可达时用 hf-mirror）：<strong>12.4 MB/s</strong>，20 GiB 约 29 分钟；<code>curl -C -</code> 支持断点续传。<br />
制品建议放<strong>本地盘</strong>：本地盘加载 18.2 s，走 NFS 是 52–59 s。</p>
</blockquote>
<h3>1.5 启动脚本（可直接用）</h3>
<pre><code class="language-bash">#!/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" ] &amp;&amp; ARGS+=(--api-key "$API_KEY")

case "${1:-start}" in
  start)
    docker rm -f "$NAME" &gt;/dev/null 2&gt;&amp;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 -&gt; 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
</code></pre>
<p dir="auto"><strong>参数说明（都是实测踩出来的）</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>参数</th>
<th>为什么是这个值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--max-context 131072</code></td>
<td>128K 逻辑上限。超限请求被明确拒绝而不是截断：<code>400 context_length_exceeded: prepared prompt exceeds Engine max_context 131072</code></td>
</tr>
<tr>
<td><code>--kv-capacity 262144</code></td>
<td><strong>必须显式</strong>。nvfp4 权重 19.7 GiB 下 <code>auto</code> 只肯给 ~237K，而且 auto 模式要额外留 1 GiB headroom → <strong>直接拒绝启动</strong>。显式 262144 正好 = 2×128K，实测启动后 free 1.21 GiB</td>
</tr>
<tr>
<td><code>--max-concurrency 2</code></td>
<td>引擎真批处理路数。客户端并发<strong>超过</strong>它会被饿（实测第 3、4 条掉到 5.7 tok/s）</td>
</tr>
<tr>
<td><code>--kv-dtype int8</code></td>
<td>Volta <strong>没有</strong> fp8 / nvfp4 / k8v4 的 KV 内核，只能 <code>bf16</code> 或 <code>int8</code></td>
</tr>
<tr>
<td><code>--prefill-chunk 2048</code></td>
<td>V100 上的推荐值</td>
</tr>
<tr>
<td><code>--pending-timeout-ms 600000</code></td>
<td>默认 30 s。prefill 是<strong>单通道串行</strong>的，一条 125K prompt 要 prefill 4 分钟，第二路在队列里等超过 30 s 就被判 <code>503 request_queue_timeout</code></td>
</tr>
<tr>
<td><code>--spec mtp --draft-tokens 3 --lm-head-draft</code></td>
<td>MTP 投机解码；decode 快慢几乎完全由它的接受率决定（见第 2.3 节）</td>
</tr>
</tbody>
</table>
<h3>1.6 验收</h3>
<pre><code class="language-bash">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
</code></pre>
<p dir="auto">启动日志里会打出显存账本（<code>--log-level debug</code> 更详细）：</p>
<pre><code>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 disabled
</code></pre>
<h3>1.7 报错对照表</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>现象</th>
<th>根因</th>
<th>处置</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>nvidia-smi</code>: <code>couldn't communicate with the NVIDIA driver</code> / <code>nvtop</code> 看不到卡</td>
<td>驱动没装（直通本身没问题，<code>lspci</code> 能看到 <code>10de:1db6</code>）</td>
<td>装 <code>nvidia-driver-580-server</code></td>
</tr>
<tr>
<td><code>not supported by open nvidia.ko ... GPU System Processor (GSP)</code></td>
<td>装了 <code>-open</code> 驱动，Volta 不支持</td>
<td>换非 open：<code>apt purge "nvidia-*-open"</code> 再装 <code>nvidia-driver-580-server</code></td>
</tr>
<tr>
<td><code>cannot open shared object file: libcudart.so.12</code></td>
<td>底座 CUDA 版本与二进制 RUNPATH 不一致</td>
<td>底座用 <code>cuda:12.8.0-runtime-ubuntu24.04</code></td>
</tr>
<tr>
<td><code>FATAL ... artifact magic is not NInfer v2</code></td>
<td>下了 v3 容器制品（main 上的那个）</td>
<td>钉 revision <code>204e3d92c30d</code>（v2 容器）</td>
</tr>
<tr>
<td><code>minimum Engine runtime reservation requires … but only … available after weights</code></td>
<td>显存不够（<code>auto</code> 模式还要额外 1 GiB）</td>
<td>显式给 <code>--kv-capacity</code>，并按下表算容量</td>
</tr>
<tr>
<td><code>503 request_queue_timeout</code></td>
<td>默认 30 s 排队超时 + prefill 串行</td>
<td><code>--pending-timeout-ms 600000</code></td>
</tr>
<tr>
<td><code>400 context_length_exceeded</code></td>
<td>prompt + 输出超过 <code>--max-context</code></td>
<td>调小 prompt 或调大 <code>--max-context</code>（受显存限制，见 2.5）</td>
</tr>
</tbody>
</table>
<hr />
<h2>2. Benchmark</h2>
<p dir="auto"><strong>统一条件</strong>：贪心（<code>temperature=0</code>）、<code>reasoning_effort: none</code>（除注明）、prompt 为同一份技术文档按目标长度拼接；decode = 引擎口径「已提交输出 token / 秒」；TTFT = 服务端 prompt 处理时间（<strong>不含排队</strong>）；功率墙 200 W；负载期功耗中位 195 W、SM 频率中位 1087 MHz（最高 1380 MHz）。</p>
<h3>2.1 上下文长度扫描（nvfp4 制品，单请求，128 输出 token）</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>目标上下文</th>
<th style="text-align:right">prompt token</th>
<th style="text-align:right">prefill tok/s</th>
<th style="text-align:right">TTFT</th>
<th style="text-align:right">decode tok/s</th>
<th style="text-align:right">MTP 接受率</th>
</tr>
</thead>
<tbody>
<tr>
<td>2K</td>
<td style="text-align:right">1,967</td>
<td style="text-align:right"><strong>1,003.5</strong></td>
<td style="text-align:right">1.96 s</td>
<td style="text-align:right">56.8</td>
<td style="text-align:right">47%（38/81）</td>
</tr>
<tr>
<td>8K</td>
<td style="text-align:right">7,907</td>
<td style="text-align:right"><strong>1,019.0</strong></td>
<td style="text-align:right">7.76 s</td>
<td style="text-align:right">72.6</td>
<td style="text-align:right">71%（45/63）</td>
</tr>
<tr>
<td>32K</td>
<td style="text-align:right">31,667</td>
<td style="text-align:right">868.6</td>
<td style="text-align:right">36.46 s</td>
<td style="text-align:right">57.2</td>
<td style="text-align:right">60%（45/75）</td>
</tr>
<tr>
<td>64K</td>
<td style="text-align:right">63,311</td>
<td style="text-align:right">699.4</td>
<td style="text-align:right">90.52 s</td>
<td style="text-align:right">36.2</td>
<td style="text-align:right">40%（37/93）</td>
</tr>
<tr>
<td>128K</td>
<td style="text-align:right">126,599</td>
<td style="text-align:right"><strong>505.8</strong></td>
<td style="text-align:right"><strong>250.27 s</strong></td>
<td style="text-align:right">37.0</td>
<td style="text-align:right">60%（45/75）</td>
</tr>
</tbody>
</table>
<p dir="auto">补充：同一配置下 8K prompt、320 输出上限的持续生成实测 <strong>71.5 tok/s</strong>（MTP 71%）。</p>
<h3>2.2 nvfp4 vs groupwise-int（同一脚本、同一参数，唯一变量是制品）</h3>
<p dir="auto"><code>neroued/Qwen3.8-27B-NInfer</code> @ <code>18dfc887423f</code>（groupwise-int，16.96 GiB，sha256 <code>eec39564993d…4bf3e</code>）作为对照：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>shape</th>
<th>groupwise-int：prefill / decode / MTP</th>
<th>nvfp4：prefill / decode / MTP</th>
</tr>
</thead>
<tbody>
<tr>
<td>1K</td>
<td>987.9 / 41.8 / 51%</td>
<td><strong>1,003.5 / 56.8</strong> / 47%</td>
</tr>
<tr>
<td>7K</td>
<td>1,014.0 / 43.3 / 58%</td>
<td><strong>1,019.0 / 72.6</strong> / 71%</td>
</tr>
<tr>
<td>30K</td>
<td>864.7 / 42.4 / 65%</td>
<td><strong>868.6 / 57.2</strong> / 60%</td>
</tr>
<tr>
<td>61K</td>
<td>696.3 / 31.3 / 52%</td>
<td><strong>699.4 / 36.2</strong> / 40%</td>
</tr>
<tr>
<td>123K</td>
<td>505.9 / 29.5 / 63%</td>
<td><strong>505.8 / 37.0</strong> / 60%</td>
</tr>
<tr>
<td>编码任务（640 tok，两边 MTP 都 89%）</td>
<td>115.2 / <strong>58.6</strong> / 89%</td>
<td>119.5 / <strong>90.9</strong> / 89%</td>
</tr>
<tr>
<td>持续生成（8K，66 tok）</td>
<td>951.1 / <strong>41.6</strong> / 58%</td>
<td>954.5 / <strong>71.5</strong> / 71%</td>
</tr>
<tr>
<td>双并发（8K，均缓存命中）</td>
<td>批 wall 3.84 s / 188 tok / <strong>48.9 tok/s</strong></td>
<td>批 wall 2.55 s / 152 tok / <strong>59.7 tok/s</strong></td>
</tr>
</tbody>
</table>
<blockquote>
<p dir="auto">上下文扫描那几行的 decode <strong>不能直接横向比</strong>：权重不同 → 生成的文本不同 → MTP 接受率不同（40% vs 52% 之类），短样本下接受率差异会盖过真实速度差。<strong>编码任务那行是干净的</strong>（prompt、输出长度 640、贪心、MTP 接受率 464/523 vs 467/525 全部对齐）：<strong>58.6 → 90.9 tok/s</strong>。<br />
注：这张表的数字来自<strong>成对跑的那一轮</strong>；同一 prompt 在 2.3 节另一轮里测得 93.4/93.9 tok/s（MTP 91–92%），两轮差异属运行间波动（同一制品重跑 ±3%）。</p>
</blockquote>
<h3>2.3 任务类型（nvfp4，8K 与 64K 两档）</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>任务</th>
<th style="text-align:right">输出 token</th>
<th style="text-align:right">8K：decode / MTP</th>
<th style="text-align:right">64K：decode / MTP</th>
</tr>
</thead>
<tbody>
<tr>
<td>写代码（LRU + pytest）</td>
<td style="text-align:right">640</td>
<td style="text-align:right"><strong>93.4 / 91%</strong></td>
<td style="text-align:right"><strong>93.9 / 92%</strong></td>
</tr>
<tr>
<td>JSON 字段抽取</td>
<td style="text-align:right">24</td>
<td style="text-align:right">82.7 / 90%</td>
<td style="text-align:right">82.7 / 90%</td>
</tr>
<tr>
<td>摘要（5.9K 文档）</td>
<td style="text-align:right">56</td>
<td style="text-align:right">81.2 / 81%</td>
<td style="text-align:right">81.4 / 81%</td>
</tr>
<tr>
<td>翻译</td>
<td style="text-align:right">48</td>
<td style="text-align:right">78.7 / 76%</td>
<td style="text-align:right">78.3 / 76%</td>
</tr>
<tr>
<td>推理（<code>effort=xhigh</code>，1024 思考 token）</td>
<td style="text-align:right">1024</td>
<td style="text-align:right">70.8 / 61%</td>
<td style="text-align:right">70.6 / 61%</td>
</tr>
<tr>
<td>找 bug 根因（闭包 late-binding）</td>
<td style="text-align:right">253</td>
<td style="text-align:right">68.8 / 57%</td>
<td style="text-align:right">68.8 / 57%</td>
</tr>
<tr>
<td>闲聊</td>
<td style="text-align:right">92</td>
<td style="text-align:right">55.8 / 42%</td>
<td style="text-align:right">55.9 / 42%</td>
</tr>
<tr>
<td>写小说</td>
<td style="text-align:right">257</td>
<td style="text-align:right">44.9 / 26%</td>
<td style="text-align:right">47.5 / 31%</td>
</tr>
</tbody>
</table>
<p dir="auto">TTFT 方面：短 prompt（几十 token）在 8K 与 64K 档几乎无差别（0.09–0.47 s），只有 5.9K 文档摘要那档是 5.8 s。</p>
<h3>2.4 并发</h3>
<p dir="auto"><strong>（a）双并发长上下文（本机生产配置实测，2 路各 ~125K）</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>路</th>
<th style="text-align:right">prompt token</th>
<th style="text-align:right">TTFT（服务端）</th>
<th style="text-align:right">其中排队</th>
<th style="text-align:right">prefill tok/s</th>
<th style="text-align:right">输出</th>
<th style="text-align:right">wall</th>
</tr>
</thead>
<tbody>
<tr>
<td>L1</td>
<td style="text-align:right">124,632</td>
<td style="text-align:right">241.0 s</td>
<td style="text-align:right">0</td>
<td style="text-align:right">517</td>
<td style="text-align:right">61</td>
<td style="text-align:right">319.9 s</td>
</tr>
<tr>
<td>L2</td>
<td style="text-align:right">124,632</td>
<td style="text-align:right">247.6 s（引擎记 8m8.7s）</td>
<td style="text-align:right"><strong>4 m 1.1 s</strong></td>
<td style="text-align:right">503</td>
<td style="text-align:right">61</td>
<td style="text-align:right">490.9 s</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>（b）解码批处理（引擎 5 s 窗口口径，groupwise 制品同引擎测得）</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="text-align:right">batch</th>
<th style="text-align:right">聚合 decode tok/s</th>
<th style="text-align:right">相对 batch=1</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:right">1.00</td>
<td style="text-align:right">60.4</td>
<td style="text-align:right">1.00×</td>
</tr>
<tr>
<td style="text-align:right">2.00</td>
<td style="text-align:right">87.2</td>
<td style="text-align:right">1.44×</td>
</tr>
<tr>
<td style="text-align:right">3.98</td>
<td style="text-align:right">126.8</td>
<td style="text-align:right">2.10×</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>（c）端到端（每路冷启动 8K prompt + 320 输出 token，groupwise 制品）</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="text-align:right">服务端并发</th>
<th style="text-align:right">客户端路数</th>
<th style="text-align:right">单路端到端</th>
<th style="text-align:right">聚合端到端</th>
<th style="text-align:right">加速比</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:right">2</td>
<td style="text-align:right">1</td>
<td style="text-align:right">24.4 tok/s</td>
<td style="text-align:right">24.4</td>
<td style="text-align:right">1.00×</td>
</tr>
<tr>
<td style="text-align:right">2</td>
<td style="text-align:right">2</td>
<td style="text-align:right">24.0–24.6</td>
<td style="text-align:right">26.5–27.2</td>
<td style="text-align:right">1.11×</td>
</tr>
<tr>
<td style="text-align:right">4</td>
<td style="text-align:right">4</td>
<td style="text-align:right">23.9</td>
<td style="text-align:right">29.3</td>
<td style="text-align:right">1.22×</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>（d）服务端日志里的两个并发现象（原文）</strong></p>
<pre><code># 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.98
</code></pre>
<h3>2.5 显存与容量（这块最实用）</h3>
<p dir="auto">用失败报错反解出的引擎显存公式（32G V100，int8 KV，MTP3）：</p>
<pre><code>运行时占用 = 2.75 GiB（固定：state 槽 + workspace + CUDA graph） + KV 池容量 × 35,904 B
权重后可用显存：nvfp4 11.70 GiB / groupwise-int 14.75 GiB
</code></pre>
<p dir="auto">实测容量上限（<code>--max-concurrency 2</code>，容量需为 64 的倍数，均为「能启动 + 能跑通请求」验证过的值）：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th></th>
<th>groupwise-int</th>
<th>nvfp4</th>
</tr>
</thead>
<tbody>
<tr>
<td>权重</td>
<td>16.7 GiB</td>
<td><strong>19.7 GiB</strong></td>
</tr>
<tr>
<td>权重后可用</td>
<td>14.75 GiB</td>
<td>11.70 GiB</td>
</tr>
<tr>
<td><code>--kv-capacity auto</code></td>
<td>328,960 token</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/274c.png?v=ec85ec55bc1" class="not-responsive emoji emoji-android emoji--x" style="height:1.4em;width:auto;vertical-align:middle" title="❌" alt="❌" /> 拒绝启动（差 0.88 GiB）</td>
</tr>
<tr>
<td><strong>最大共享池</strong></td>
<td><strong>358,912 token</strong></td>
<td><strong>267,456 token</strong></td>
</tr>
<tr>
<td>双并发每路可用</td>
<td>≈179K</td>
<td><strong>≈130K</strong></td>
</tr>
<tr>
<td>2×160K（池需 327,680）</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ec85ec55bc1" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:1.4em;width:auto;vertical-align:middle" title="✅" alt="✅" /> 余 31,232</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/274c.png?v=ec85ec55bc1" class="not-responsive emoji emoji-android emoji--x" style="height:1.4em;width:auto;vertical-align:middle" title="❌" alt="❌" /> 差 2.01 GiB；关掉 graph + state 槽也只省 622 MiB，仍差 1.40 GiB</td>
</tr>
</tbody>
</table>
<p dir="auto">单请求边界（<code>--max-context 131072</code>）：</p>
<pre><code>HTTP 400 {"error":{"code":"context_length_exceeded",
  "message":"prepared prompt exceeds Engine max_context 131072", ...}}
</code></pre>
<h3>2.6 前缀复用（同引擎，16K 文档）</h3>
<p dir="auto">（同一组测量：16K 文档，prompt 15,846–15,886 token，同引擎）</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>场景</th>
<th style="text-align:right">prompt token</th>
<th style="text-align:right">命中前缀 token</th>
<th style="text-align:right">TTFT</th>
</tr>
</thead>
<tbody>
<tr>
<td>冷请求</td>
<td style="text-align:right">15,846</td>
<td style="text-align:right">0</td>
<td style="text-align:right">16.47 s</td>
</tr>
<tr>
<td>完全相同请求重发</td>
<td style="text-align:right">15,846</td>
<td style="text-align:right">15,839（100%）</td>
<td style="text-align:right"><strong>0.13 s</strong></td>
</tr>
<tr>
<td>同 prompt、只改 max_tokens（64 → 256）</td>
<td style="text-align:right">15,846</td>
<td style="text-align:right">15,839（100%）</td>
<td style="text-align:right"><strong>0.13 s</strong></td>
</tr>
<tr>
<td>prompt 后追加一句（Chat Completions）</td>
<td style="text-align:right">15,855</td>
<td style="text-align:right"><strong>0</strong></td>
<td style="text-align:right">16.72 s</td>
</tr>
<tr>
<td>同正文、换会话编号</td>
<td style="text-align:right">15,846</td>
<td style="text-align:right">0</td>
<td style="text-align:right">16.80 s</td>
</tr>
<tr>
<td>显式 <code>prompt_cache_breakpoint</code> 写入后再追加读取</td>
<td style="text-align:right">15,855</td>
<td style="text-align:right"><strong>0</strong></td>
<td style="text-align:right">17.00 s</td>
</tr>
<tr>
<td>Anthropic <code>cache_control</code> 写入 → 追加读取</td>
<td style="text-align:right">15,886</td>
<td style="text-align:right">15,879</td>
<td style="text-align:right"><strong>1.65 s</strong></td>
</tr>
<tr>
<td>Responses API <code>previous_response_id</code> 续轮</td>
<td style="text-align:right">—</td>
<td style="text-align:right">15,917</td>
<td style="text-align:right"><strong>1.17 s</strong></td>
</tr>
</tbody>
</table>
<h3>2.7 运行条件</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>项</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>功率墙</td>
<td>200 W（默认 250 W，可设 100–250）</td>
</tr>
<tr>
<td>负载期功耗</td>
<td>中位 195 W，最高 228 W</td>
</tr>
<tr>
<td>负载期 SM 频率</td>
<td>中位 1087 MHz，最高 1380 MHz（卡的最大 SM 时钟即 1380）</td>
</tr>
<tr>
<td>空载</td>
<td>37–40 °C / 约 60 W</td>
</tr>
<tr>
<td>PCIe</td>
<td>Gen3 x16（8 GT/s），非瓶颈</td>
</tr>
</tbody>
</table>
<hr />
<h2>3. 一键部署脚本</h2>
<pre><code class="language-bash">#!/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 &gt;/dev/null 2&gt;&amp;1; then
  apt-get update -qq &amp;&amp; apt-get install -y "linux-headers-$(uname -r)" nvidia-driver-580-server
  modprobe nvidia 2&gt;/dev/null || { echo "驱动已装，请重启后重新运行本脚本"; exit 0; }
fi
nvidia-smi -L
nvidia-smi -pm 1 &amp;&amp; nvidia-smi -pl "$POWER_LIMIT"
# 功率墙不跨重启，落一个开机单元
cat &gt; /usr/local/bin/nvidia-powerlimit.sh &lt;&lt;'EOF'
#!/bin/bash
for _ in $(seq 1 60); do nvidia-smi -L &gt;/dev/null 2&gt;&amp;1 &amp;&amp; break; sleep 5; done
nvidia-smi -pm 1 &gt;/dev/null 2&gt;&amp;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 &gt;/dev/null 2&gt;&amp;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 &gt;/dev/null &amp;&amp; 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" \
    &gt; /etc/apt/sources.list.d/docker.list
  apt-get update -qq &amp;&amp; apt-get install -y docker-ce docker-ce-cli containerd.io
fi
if ! command -v nvidia-ctk &gt;/dev/null 2&gt;&amp;1; then
  apt-get update -qq &amp;&amp; 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 &amp;&amp; apt-get update -qq &amp;&amp; apt-get install -y nvidia-container-toolkit; }
fi
nvidia-ctk runtime configure --runtime=docker
systemctl enable --now docker &amp;&amp; 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 &amp;&amp; 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 &gt;/dev/null 2&gt;&amp;1 &amp;&amp; command -v ninja &gt;/dev/null 2&gt;&amp;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" &amp;&amp; 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 &gt; "$CTXDIR/Dockerfile" &lt;&lt;'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&gt;/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' \
      &gt; /etc/apt/sources.list.d/ubuntu.sources \
    &amp;&amp; apt-get update -qq \
    &amp;&amp; apt-get install -y --no-install-recommends ca-certificates \
        libavcodec60 libavformat60 libavutil58 libswscale7 libswresample4 libcurl4t64 \
    &amp;&amp; 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 &gt;/dev/null 2&gt;&amp;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 ] \
    &amp;&amp; { echo "就绪: http://127.0.0.1:${PORT}/v1  (model id: qwen3.8-27b)"; exit 0; }
  sleep 5
done
echo "未就绪，看日志: docker logs ninfer"; exit 1
</code></pre>
<p dir="auto"><strong>开机自启</strong>：容器带 <code>--restart unless-stopped</code> 即可；功率墙用上面那个脚本挂一个 oneshot 单元：</p>
<pre><code class="language-ini"># /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
</code></pre>
]]></description><link>https://lcz.me/topic/2065</link><generator>RSS for Node</generator><lastBuildDate>Fri, 23 Oct 2026 16:55:27 GMT</lastBuildDate><atom:link href="https://lcz.me/topic/2065.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 03 Oct 2026 10:54:48 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Tesla V100-32G 跑 Qwen3.8-27B nvfp4：200W 下 decode 93.9 tok/s、prefill 1019 tok/s（NInfer SM70 / CUDA 12.8） on Sun, 04 Oct 2026 00:09:49 GMT]]></title><description><![CDATA[<p dir="auto">整个kv在nvfp4的方案里最多只有256k.在单并发长上下文和双并发短上下文中，选择了后者。 Prefill在高上下文时衰减比较严重，均衡选择了c=2, ctx=128k。<br />
V100这两天开始涨价了。 纯文字llm，不做视频的，可以参考。</p>
]]></description><link>https://lcz.me/post/22109</link><guid isPermaLink="true">https://lcz.me/post/22109</guid><dc:creator><![CDATA[davidwei0826]]></dc:creator><pubDate>Sun, 04 Oct 2026 00:09:49 GMT</pubDate></item></channel></rss>