<?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[抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机]]></title><description><![CDATA[<p dir="auto">看到论坛里 5090 那几篇 NInfer 的帖子（<a href="https://lcz.me/topic/1228">1228</a> / <a href="https://lcz.me/topic/1870">1870</a> / <a href="https://lcz.me/topic/1803">1803</a>）之后，我拿手上这张 4080 SUPER 32G 也抄了一遍。全程没编译——直接找的社区预编译镜像。</p>
<p dir="auto"><strong>结论先行：</strong></p>
<ul>
<li><strong>速度</strong>：同机同法实测，NInfer 单路 88.2 t/s vs SGLang 98.3 t/s，<strong>SGLang 快 11.5%</strong>；但 NInfer 双路聚合能到 <strong>122 t/s</strong>。</li>
<li><strong>智力</strong>：同一张卡、同一批题、同一评分脚本，<strong>AGIEval 1200 题打平</strong>（NInfer 1084 vs SGLang 1082），<strong>CEval+CMMLU 420 题 NInfer 领先 1.67pp</strong>。所谓"SGLang 智力更高"在数据上不成立。</li>
<li><strong>稳定性</strong>：这是最大的坑。NInfer 这个 build 在 4080S 上<strong>并发必崩，崩了整卡进 full-chip reset，只能重启机器</strong>。我崩了<strong>三次</strong>，最后定位到 <strong>CUDA Graph 重放 × 批量（≥2 路）投机解码</strong>，加 <code>--no-cuda-graph</code> 解决，性能只掉 2.6%。</li>
<li>最终配置：<strong>单路 85.9 t/s、双路聚合 122 t/s、双路 × 256K 上下文全部跑通、显存余量 4.2GB。</strong></li>
</ul>
<h2>之前关于SGLang的帖子：<br />
<a href="https://lcz.me/topic/1654">https://lcz.me/topic/1654</a><br />
<a href="https://lcz.me/topic/1631">https://lcz.me/topic/1631</a><br />
<a href="https://lcz.me/topic/1629">https://lcz.me/topic/1629</a></h2>
<h2>一、测试机配置</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>项目</th>
<th>配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>CPU</td>
<td>AMD Ryzen 7 9700X（8C/16T）</td>
</tr>
<tr>
<td>主板</td>
<td>ROG CROSSHAIR X670E HERO</td>
</tr>
<tr>
<td>显卡</td>
<td><strong>NVIDIA RTX 4080 SUPER 32GB</strong>（sm_89，<strong>80 SM</strong>，32760 MiB）</td>
</tr>
<tr>
<td>驱动</td>
<td>595.84</td>
</tr>
<tr>
<td>内存</td>
<td>60 GB</td>
</tr>
<tr>
<td>系统</td>
<td>Ubuntu 24.04.4 LTS / 内核 7.0.0-31-generic</td>
</tr>
<tr>
<td>磁盘</td>
<td>NVMe 937G（可用 528G）+ SATA 991G（可用 59G）</td>
</tr>
<tr>
<td>Docker</td>
<td>29.8.1 + nvidia-container-toolkit 1.20.1</td>
</tr>
<tr>
<td>引擎</td>
<td>NInfer（<code>ninfer-serve</code>，<strong>社区预编译镜像</strong>）</td>
</tr>
<tr>
<td>镜像</td>
<td><code>nahsilabs/ninfer-4090:1bd56c9a</code>（5.15GB）= 源码 <code>sergiuszm/ninfer-4090 @ 1bd56c9a</code>，基于 CUDA 13.1.2</td>
</tr>
<tr>
<td>模型</td>
<td><code>qwen3_8_27b.ninfer</code>，18,210,531,328 字节（16.96 GiB），<code>groupwise-int</code></td>
</tr>
<tr>
<td>模型校验</td>
<td>md5 <code>b7e293b072113b351c8e79eb9726a5d6</code>，魔数 <code>NINFER\0\002</code></td>
</tr>
<tr>
<td>用途</td>
<td>DeepSeek Harness 的本地 provider（OpenAI 兼容）</td>
</tr>
</tbody>
</table>
<blockquote>
<p dir="auto">注意：<strong>下载 artifact 必须用旧的那个 commit</strong>。HF <code>neroued/Qwen3.8-27B-NInfer</code> 现在的新版是 19.03 GiB（多了 DFlash2 companion weights），manifest 里写着 <code>cuda_architecture: sm_120a</code> + <code>minimum_revision: 385b30ce</code>，sm_89 的移植线用不了。旧版路径：<br />
<code>https://huggingface.co/neroued/Qwen3.8-27B-NInfer/resolve/3526913004b1cf552cb57b88d6a5c6f5e4a89a70/qwen3_8_27b.ninfer</code></p>
</blockquote>
<hr />
<h2>二、速度对比（同一张卡、同一测法）</h2>
<p dir="auto">测法完全一致：同一段 prompt（Paris 历史）、<code>max_tokens=256</code>、<code>temperature=0.7</code>、<code>reasoning_effort=medium</code>、各跑 5 轮取平均，读服务端 per-request 的 <code>timings</code>。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>引擎</th>
<th>模型</th>
<th>权重占用</th>
<th>投机</th>
<th>单路 decode</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>SGLang</strong></td>
<td>RedHatAI/Qwen3.8-27B-INT4 + 独立 DFlash2 草稿</td>
<td>17.33 + 0.79 + 1.44 = <strong>19.56 GiB</strong></td>
<td>DFLASH，draft 8（NVFP4 草稿）</td>
<td><strong>98.34 t/s</strong></td>
<td>172K 上下文，2 路</td>
</tr>
<tr>
<td>NInfer（CUDA Graph 开）</td>
<td>官方 groupwise-int（单 artifact）</td>
<td><strong>16.96 GiB</strong></td>
<td>MTP，draft 3</td>
<td>88.21 t/s</td>
<td>262K 上下文</td>
</tr>
<tr>
<td><strong>NInfer（最终，<code>--no-cuda-graph</code>）</strong></td>
<td>同上</td>
<td><strong>16.96 GiB</strong></td>
<td>MTP，draft 3</td>
<td>85.9 t/s</td>
<td>262K，双路稳定</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>同法差值 −11.5%。注意 NInfer 这条线用的是更小的 artifact</strong>（16.96 GiB 单文件，MTP + 视觉都内嵌），SGLang 那条线是目标模型 17.33 GiB + MTP 头 0.79 GiB + 独立 DFlash2 草稿 1.44 GiB，合计 19.56 GiB。</p>
<p dir="auto">不过<strong>速度差异不能简单归因于引擎</strong>：两条线的量化方案不同（compressed-tensors INT4 vs groupwise-int）、投机机制不同（独立 1.92B 草稿模型 vs 内嵌单层草稿头）、上下文也不同（172K vs 262K）。要下"谁更快"的结论得先把这些变量对齐。</p>
<p dir="auto"><strong>双路并发（NInfer 最终配置）：</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>模式</th>
<th>单路</th>
<th>双路各</th>
<th>聚合</th>
<th>倍数</th>
</tr>
</thead>
<tbody>
<tr>
<td>等长 2×256tok</td>
<td>85.9</td>
<td>~75</td>
<td><strong>142.4 t/s</strong></td>
<td>1.66×</td>
</tr>
<tr>
<td>长短混跑</td>
<td>85.9</td>
<td>100 / 67~84</td>
<td>104~107 t/s</td>
<td>1.2×</td>
</tr>
<tr>
<td>3 请求（C=2 + 排队）</td>
<td>85.9</td>
<td>~75×2</td>
<td>132~138 t/s</td>
<td>1.5×</td>
</tr>
</tbody>
</table>
<p dir="auto">有意思的是<strong>批处理下 MTP 接受率反而升高</strong>：单路 57% → 双路 71~74%，短请求甚至 92%。</p>
<hr />
<h2>三、智力对比（同一张卡、同一批题、同一评分脚本）</h2>
<p dir="auto">数据集两边各存一份并校验 md5 一致（<code>agieval_eval.json</code> 1200 题、<code>combined_eval.json</code> 420 题）。评分逻辑完全沿用原脚本，0-shot、<code>temperature=0</code>。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>测试</th>
<th>SGLang（RedHat INT4）</th>
<th><strong>NInfer（groupwise-int）</strong></th>
<th>差值</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>AGIEval 1200 题</strong></td>
<td>1082/1200 = 90.17%</td>
<td><strong>1084/1200 = 90.33%</strong></td>
<td><strong>+0.17pp</strong></td>
</tr>
<tr>
<td><strong>CEval+CMMLU 420 题</strong></td>
<td>368/420 = 87.62%</td>
<td><strong>375/420 = 89.29%</strong></td>
<td><strong>+1.67pp</strong></td>
</tr>
<tr>
<td>├ CEval 220 题</td>
<td>193/220 = 87.73%</td>
<td><strong>202/220 = 91.82%</strong></td>
<td><strong>+4.09pp</strong></td>
</tr>
<tr>
<td>└ CMMLU 200 题</td>
<td><strong>175/200 = 87.50%</strong></td>
<td>173/200 = 86.50%</td>
<td>−1.00pp</td>
</tr>
<tr>
<td>认知 21 题</td>
<td>无记录</td>
<td>19/21 = 90.48% ※</td>
<td>—</td>
</tr>
</tbody>
</table>
<p dir="auto">※ 两题是判分脚本的假阴性：一题答 <code>C = πd</code>（脚本期望的写法是 <code>pi*d</code>，语义其实完全相同）被判错；另一题答 <code>反渗透</code>，比脚本里的标准答案 <code>蒸馏</code> 更符合现代工程实际。<strong>人工看实际是 21/21。</strong></p>
<h3>AGIEval 分子任务</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>子任务</th>
<th>SGLang</th>
<th>NInfer</th>
<th>差</th>
</tr>
</thead>
<tbody>
<tr>
<td>gaokao-history</td>
<td>143 (95.3%)</td>
<td><strong>147 (98.0%)</strong></td>
<td><strong>+4</strong></td>
</tr>
<tr>
<td>gaokao-biology</td>
<td>145 (96.7%)</td>
<td><strong>146 (97.3%)</strong></td>
<td>+1</td>
</tr>
<tr>
<td>gaokao-chinese</td>
<td>125 (83.3%)</td>
<td><strong>126 (84.0%)</strong></td>
<td>+1</td>
</tr>
<tr>
<td>gaokao-english</td>
<td>142 (94.7%)</td>
<td>142 (94.7%)</td>
<td>0</td>
</tr>
<tr>
<td>gaokao-physics</td>
<td>135 (90.0%)</td>
<td>135 (90.0%)</td>
<td>0</td>
</tr>
<tr>
<td>gaokao-geography</td>
<td><strong>140 (93.3%)</strong></td>
<td>139 (92.7%)</td>
<td>−1</td>
</tr>
<tr>
<td>logiqa-zh</td>
<td><strong>129 (86.0%)</strong></td>
<td>128 (85.3%)</td>
<td>−1</td>
</tr>
<tr>
<td>gaokao-chemistry</td>
<td><strong>123 (82.0%)</strong></td>
<td>121 (80.7%)</td>
<td>−2</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>分歧 66 题：SGLang 对/NInfer 错 = 32，SGLang 错/NInfer 对 = 34 —— 完全对称。</strong></p>
<p dir="auto"><strong>结论：质量打平（NInfer 微幅领先），速度 SGLang 快 11.5%，稳定性 SGLang 完胜。</strong> 但 NInfer 换来的是 262K 上下文 + 双路并发能力。</p>
<hr />
<h2>四、三次崩卡（本篇最有价值的部分）</h2>
<p dir="auto">NInfer 这个 build 在 4080S 上有个致命特性：<strong>kernel 一挂就是整卡进 <code>NV_ERR_GPU_IN_FULLCHIP_RESET</code> 死锁</strong>，<code>rmmod</code> 卸不掉、<code>nvidia-smi --gpu-reset</code> 报 <code>Not Supported</code>（Xorg 占用），<strong>只能重启机器</strong>。我崩了三次。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>#</th>
<th>触发条件</th>
<th>崩溃耗时</th>
<th>现象</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><code>--prefill-chunk 2048</code></td>
<td>立即</td>
<td><code>cudaErrorCooperativeLaunchTooLarge</code></td>
</tr>
<tr>
<td>2</td>
<td>3 路并发 + 长短混跑</td>
<td>~4 分钟</td>
<td><code>Xid 120 GSP task exception: load access page fault</code></td>
</tr>
<tr>
<td>3</td>
<td>2 路 + MTP + CUDA Graph</td>
<td><strong>30.4 分钟 / 648 请求</strong></td>
<td><code>cudaErrorLaunchFailure</code></td>
</tr>
</tbody>
</table>
<h3>崩溃 1 的源码级根因（确定性，可复现）</h3>
<p dir="auto">报错点在 <code>bf16_gdn_gating_proj_kernels.cu:310</code> 的协作启动。翻 <code>sergiuszm/ninfer-4090 @ 1bd56c9a</code> 的源码找到了：</p>
<pre><code class="language-cpp">// bf16_gdn_gating_proj_plan.cpp —— 预算是按 128 SM 的 RTX 4090 写死的
constexpr std::int32_t resident_ctas_27(Bf16GdnGatingScheduleId schedule) noexcept {
    return schedule == Bf16GdnGatingScheduleId::MmaCooperativeSplit8 ? 256 : 128;
}
</code></pre>
<p dir="auto">而运行时算占用率的函数<strong>没按 SplitK 区分</strong>：</p>
<pre><code class="language-cpp">// bf16_gdn_gating_proj_kernels.cu
if constexpr (std::is_same_v&lt;Geometry, Bf16Gdn27Geometry&gt;) {
    // Qualified on the sm_120a build ...
    return 2;          // ← split8/split4/split2 一律返回 2 CTA/SM
}
</code></pre>
<p dir="auto"><strong>split2 的真实占用率是 1 CTA/SM</strong>（512 线程 × 74 寄存器 = 37,888 寄存器/CTA，一个 SM 只有 65,536，装不下两个）——代码注释自己都写了 "split4/2 (512 threads, 74 regs) admit <strong>1 CTA/SM</strong>"。</p>
<p dir="auto">在 80 SM 的 4080S 上：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>单次 prefill token</th>
<th>路由</th>
<th>网格 CTA</th>
<th>设备上限</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>1024</td>
<td>split8</td>
<td>192 → 被切片成 144+48</td>
<td>160</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> 安全</td>
</tr>
<tr>
<td>1664</td>
<td>split2</td>
<td>78</td>
<td>80</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> 侥幸</td>
</tr>
<tr>
<td><strong>1665</strong></td>
<td>split2</td>
<td><strong>84</strong></td>
<td>80</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/274c.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--x" style="height:23px;width:auto;vertical-align:middle" title="❌" alt="❌" /> 崩</td>
</tr>
<tr>
<td><strong>2048</strong></td>
<td>split2</td>
<td><strong>96</strong></td>
<td>80</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/274c.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--x" style="height:23px;width:auto;vertical-align:middle" title="❌" alt="❌" /> 崩（实测踩中）</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>在 128 SM 的 4090 上 96 ≤ 128 恰好塞得下，所以作者测不出来；换到 80 SM 的卡就复现。</strong> fork README 里"chunk ≤2688 的硬崩已修"这句话不跨 SM 数迁移。</p>
<p dir="auto"><strong>结论：<code>--prefill-chunk</code> 必须 ≤1024。</strong></p>
<h3>崩溃 3 的判定实验（本篇的重点）</h3>
<p dir="auto">崩溃 1 有明确源码根因，但崩溃 3 是"跑得好好的突然死"。已知事实是：</p>
<ul>
<li><strong>单路串行跑了 4 小时零事故</strong>（AGIEval 1200 题 145 分钟 + CEval 420 题 + 全部调参基准）</li>
<li><strong>只要并发就崩</strong>，但崩的时间从 4 分钟到 30 分钟不等</li>
</ul>
<p dir="auto">于是做对照实验，全部 2 路并发、负载与崩溃基线完全一致、各跑 40 分钟：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>实验</th>
<th>配置</th>
<th>时长</th>
<th>请求数</th>
<th>失败</th>
<th>聚合吞吐</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>基线</td>
<td>MTP + <strong>CUDA Graph</strong></td>
<td>30.4 min</td>
<td>648</td>
<td>2</td>
<td>123.6</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/1f4a5.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--boom" style="height:23px;width:auto;vertical-align:middle" title="💥" alt="💥" /> 崩</td>
</tr>
<tr>
<td>Arm 1</td>
<td><strong>关闭 MTP</strong></td>
<td>40.2 min</td>
<td>399</td>
<td><strong>0</strong></td>
<td>59.7</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> 存活</td>
</tr>
<tr>
<td><strong>Arm 2</strong></td>
<td><strong>MTP + <code>--no-cuda-graph</code></strong></td>
<td>40.0 min</td>
<td>842</td>
<td><strong>0</strong></td>
<td><strong>122.5</strong></td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> 存活</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>判定：崩溃根因 = CUDA Graph 重放 × 批量（≥2 路）投机解码。</strong></p>
<ul>
<li>Arm 1 证明单纯"批量解码"不崩（关掉投机就能活）</li>
<li>Arm 2 是关键：<strong>保留 MTP、只关 CUDA Graph</strong>，冲过了基线 30.4 分钟的崩溃点，且速度几乎无损</li>
<li>单路即使带 CUDA Graph 也稳 → 需要 <strong>Graph × batch 的组合</strong>才触发</li>
</ul>
<h3>长浸泡验证</h3>
<pre><code>90.1 分钟 / 854 轮 / 1895 请求 / 678,408 token  →  0 失败
聚合吞吐 均 123.1 t/s（最低 79.1，最高 150.4）
0 条 cudaErrorLaunchFailure/FATAL，0 个 full-chip reset，0 个 Xid，37°C
</code></pre>
<p dir="auto">累计 <strong>130 分钟 / 2,737 请求 / 97.8 万 token 零失败</strong>，是崩溃点的 4.3 倍。</p>
<p dir="auto"><strong>代价只有 2.6%</strong>：单路 88.21 → 85.9 t/s，双路聚合 123.6 → 121.9 t/s。</p>
<hr />
<h2>五、调参实测</h2>
<p dir="auto">原帖 1803 的参数是给 <strong>4090D 48G</strong> 的，我这台是 32G，而且 1803 用的是 <code>--kv-dtype fp8</code>。四轮实测：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>轮次</th>
<th>配置</th>
<th>KV 池(tok)</th>
<th>显存</th>
<th>速度</th>
<th>MTP 接受率</th>
</tr>
</thead>
<tbody>
<tr>
<td>A1 基线</td>
<td><code>fp8</code> / C=3</td>
<td>345,024</td>
<td>31,043 MiB</td>
<td>88.48</td>
<td>58.1%</td>
</tr>
<tr>
<td>A2</td>
<td><code>rk4v4-e8</code> / C=3</td>
<td><strong>654,528</strong></td>
<td>31,043 MiB</td>
<td>85.79</td>
<td>55.3%</td>
</tr>
<tr>
<td><strong>B1 采用</strong></td>
<td><code>rk4v4-e8</code> / C=2 + 裁剪</td>
<td>524,288</td>
<td><strong>28,579 MiB</strong></td>
<td><strong>88.21</strong></td>
<td>57.9%</td>
</tr>
<tr>
<td>B2</td>
<td><code>rk2v4-e8</code> / C=2 + 裁剪</td>
<td>524,288</td>
<td>26,405 MiB</td>
<td>85.66</td>
<td>55.7%</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>1）<code>--kv-dtype fp8 → rk4v4-e8</code>：同显存 KV 池 +90%</strong>（345K → 654K），代价仅 −3.0% 速度、−2.8pp 接受率。README 预告 5.7% 的税，实测更省。<strong>fp8 不要用</strong>，同样显存只能放一半 KV。</p>
<p dir="auto"><strong>2）裁剪 + C=2 更优</strong>：<br />
<code>--vision-max-tokens 8192 --media-cache-mib 256 --media-live-mib 512 --max-concurrency 2</code><br />
→ 显存 <strong>−2.46 GB</strong>，速度回到基线。关键：KV 池 524,288 <strong>正好 = 2 × 262,144</strong>，引擎按"并发数 × max-context"精确配池，不是缩水。</p>
<p dir="auto"><strong>3）<code>rk2v4-e8</code> 不采用</strong>：再省 2.2GB，但速度掉到 85.66；而 262144 已是模型上下文上限，2-bit 换不来更长上下文。</p>
<p dir="auto"><strong>4）思考预算不是速度杠杆</strong>（固定 20 题探针）：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>预算</th>
<th>正确率</th>
<th>均题耗时</th>
<th>输出 tok/题</th>
</tr>
</thead>
<tbody>
<tr>
<td>无</td>
<td>18/20 = 90.0%</td>
<td>8.40s</td>
<td>827</td>
</tr>
<tr>
<td>8000</td>
<td>18/20 = 90.0%</td>
<td>8.41s</td>
<td>827</td>
</tr>
<tr>
<td>4000</td>
<td>18/20 = 90.0%</td>
<td>8.39s</td>
<td>827</td>
</tr>
<tr>
<td>2000</td>
<td>18/20 = 90.0%</td>
<td>7.58s</td>
<td>746</td>
</tr>
<tr>
<td>1000</td>
<td>17/20 = 85.0%</td>
<td>6.89s</td>
<td>668</td>
</tr>
</tbody>
</table>
<p dir="auto">模型自然思考只有 ~800 token，<strong>budget ≥4000 完全是死参数</strong>。2000 省 10% 且不掉分。</p>
<hr />
<h2>六、长上下文 × 双路并发验证</h2>
<p dir="auto">KV 池零余量下两路都跑满上下文，是唯一没底的边界。分级加压：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>级别</th>
<th>双路各 prompt</th>
<th>合计 token</th>
<th>占 KV 池</th>
<th>TTFT</th>
<th>decode</th>
<th>墙钟</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>L1</td>
<td>63,362</td>
<td>126,724</td>
<td>24%</td>
<td>53 / 55s</td>
<td>3.7 / 72.3</td>
<td>109s</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
<tr>
<td>L2</td>
<td>126,695</td>
<td>253,390</td>
<td>48%</td>
<td>125 / 127s</td>
<td>3.6 / 70.7</td>
<td>253s</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
<tr>
<td>L3</td>
<td>200,584</td>
<td>401,168</td>
<td>77%</td>
<td>235 / 233s</td>
<td>61.1 / 3.3</td>
<td>470s</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
<tr>
<td>L4（单路）</td>
<td>211,140</td>
<td>—</td>
<td>40%</td>
<td>250s</td>
<td>58.5</td>
<td>252s</td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
<tr>
<td><strong>L5（极限）</strong></td>
<td><strong>258,640</strong></td>
<td><strong>517,280</strong></td>
<td><strong>98.7%</strong></td>
<td><strong>335 / 346s</strong></td>
<td><strong>3.5 / 52.8</strong></td>
<td><strong>682s</strong></td>
<td><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>双路 × 256K 可用，即使池子占满 98.7% 也不崩。</strong></p>
<p dir="auto">三个必须知道的行为特征：</p>
<ol>
<li><strong>prefill 是串行的，会饿死另一条通道</strong>：一条解码期撞上另一条 prefill 时被压到 3.3~3.7 t/s（日志实证 <code>queue 5m35.8s</code>、<code>prefill 770.8 tok/s</code>）。双路收益只在"两条都在解码"时兑现。</li>
<li><strong>长 prompt 的 TTFT 是硬成本</strong>：63K→53s，127K→126s，200K→235s，258K→335s（prefill 770~860 tok/s）。</li>
<li><strong>MTP 接受率不随深度衰减</strong>：200K 处 58.8~60.4%，258K 处 54.2%。</li>
</ol>
<hr />
<h2>七、最终启动参数</h2>
<pre><code class="language-bash">docker run -d --name ninfer-qwen38-27b \
  --restart unless-stopped --gpus all --ipc=host \
  -p 8080:8080 -e TZ=Asia/Shanghai \
  -v "$PWD/models:/app/models:ro" -v "$PWD/logs:/app/logs" \
  nahsilabs/ninfer-4090:1bd56c9a \
  models/qwen3_8_27b.ninfer \
  --host 0.0.0.0 --port 8080 \
  --max-context 262144 --kv-capacity auto \
  --max-concurrency 2 \
  --no-cuda-graph \
  --prefill-chunk 1024 \
  --kv-dtype rk4v4-e8 \
  --vision --vision-max-tokens 8192 \
  --media-cache-mib 256 --media-live-mib 512 \
  --max-pending-requests 16 --pending-timeout-ms 600000 \
  --host-kv-mib 24576 --host-state-slots 72 \
  --max-private-continuations 12 --max-shared-prefixes 8 \
  --auto-long-anchors 4 --max-long-anchors-per-continuation 4 \
  --device-state-slots 6 \
  --spec mtp --draft-tokens 3 --lm-head-draft \
  --model-id Qwen3.8-27B
</code></pre>
<p dir="auto">实测结果：<strong>显存 28.6G / 32.8G（余量 4.2G）、单路 85.9 t/s、双路聚合 122 t/s、KV 池 524,288、上下文 262,144。</strong></p>
<hr />
<h2>八、踩坑速查</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>现象</th>
<th>原因</th>
<th>解决</th>
</tr>
</thead>
<tbody>
<tr>
<td>GPU 进 full-chip reset，只能重启机器</td>
<td><code>prefill-chunk ≥ 1665</code> 触发协作启动越界</td>
<td><strong><code>--prefill-chunk 1024</code></strong></td>
</tr>
<tr>
<td>并发跑 4~30 分钟后整卡死</td>
<td>CUDA Graph × 批量投机解码</td>
<td><strong><code>--no-cuda-graph</code></strong></td>
</tr>
<tr>
<td>启动直接 OOM</td>
<td>用了 <code>bf16</code>/<code>int8</code> 级 KV，262K 放不下</td>
<td>用 <code>rk4v4-e8</code> 或 <code>rk2v4-e8</code></td>
</tr>
<tr>
<td>同显存 KV 池只有别人一半</td>
<td>用了 <code>fp8</code></td>
<td>换 <code>rk4v4-e8</code>（+90% 池子）</td>
</tr>
<tr>
<td>vision 开起来吃 3GB 显存</td>
<td>media 缓冲用了默认 1024+2048</td>
<td><code>--media-cache-mib 256 --media-live-mib 512</code></td>
</tr>
<tr>
<td>下载新 artifact 加载失败</td>
<td>新版含 DFlash2，声明 <code>sm_120a</code></td>
<td>用 commit <code>3526913004b1</code> 的 16.96GiB 版</td>
</tr>
<tr>
<td>6 路并发 decode 掉到 9.6 t/s</td>
<td>超过引擎并发能力</td>
<td><code>--max-concurrency 2</code></td>
</tr>
</tbody>
</table>
<hr />
<h2>九、结论</h2>
<ol>
<li><strong>4080S 32G 跑 NInfer + Qwen3.8-27B 是可行的</strong>，不用编译，社区有现成的 sm_89 镜像。</li>
<li><strong>质量和 SGLang 打平</strong>：AGIEval 1200 题 90.33% vs 90.17%，CEval+CMMLU 89.29% vs 87.62%。换引擎不会掉智力，反而在 CEval 上更高。</li>
<li><strong>速度 SGLang 领先 11.5%</strong>（98.3 vs 88.2 t/s）。但 NInfer 的权重占用更小（16.96 GiB vs 19.56 GiB），并换来 262K 上下文和可用的双路并发（聚合 122 t/s）。两者量化方案与投机机制都不同，速度差不能纯归因于引擎。</li>
<li><strong>这个 build 的并发是带雷的</strong>：必须 <code>--no-cuda-graph</code>，代价 2.6%。</li>
<li><strong>两条硬红线</strong>：<code>--prefill-chunk ≤ 1024</code>、<code>--max-concurrency ≤ 2</code>。碰了就要重启机器。</li>
</ol>
<p dir="auto">一句给同好的话：<strong>这张卡上用 NInfer，"稳"比"快"重要得多——先把那两个 flag 钉死，再谈调优。</strong></p>
<hr />
<h2>技术来源</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>技术/模型</th>
<th>来源</th>
</tr>
</thead>
<tbody>
<tr>
<td>NInfer 引擎</td>
<td><a href="https://github.com/Neroued/ninfer" rel="nofollow ugc">Neroued/ninfer</a></td>
</tr>
<tr>
<td>sm_89 移植（本机镜像来源）</td>
<td><a href="https://github.com/sergiuszm/ninfer-4090" rel="nofollow ugc">sergiuszm/ninfer-4090</a></td>
</tr>
<tr>
<td>预编译镜像</td>
<td><code>nahsilabs/ninfer-4090:1bd56c9a</code>（Docker Hub）</td>
</tr>
<tr>
<td>模型 artifact（16.96 GiB，兼容版）</td>
<td><a href="https://huggingface.co/neroued/Qwen3.8-27B-NInfer" rel="nofollow ugc">neroued/Qwen3.8-27B-NInfer @ 3526913004b1</a></td>
</tr>
<tr>
<td>SGLang 侧对照模型</td>
<td><a href="https://huggingface.co/RedHatAI/Qwen3.8-27B-INT4" rel="nofollow ugc">RedHatAI/Qwen3.8-27B-INT4</a></td>
</tr>
<tr>
<td>DFlash2 草稿（SGLang 对照用）</td>
<td><a href="https://huggingface.co/z-lab/Qwen3.8-27B-DFlash2" rel="nofollow ugc">z-lab/Qwen3.8-27B-DFlash2</a></td>
</tr>
<tr>
<td><code>causal_small_t</code> 共享内存修正（本 build 缺失）</td>
<td><a href="https://github.com/Doelfke/ninfer-yarn/commit/7a876cf7b716f8d1fefff40e3cfb902d6419e07e" rel="nofollow ugc">Doelfke/ninfer-yarn @ 7a876cf</a></td>
</tr>
<tr>
<td>E8 4-bit KV 来源</td>
<td><a href="https://github.com/UDPSendToFailed/ninfer-4090" rel="nofollow ugc">UDPSendToFailed/ninfer-4090</a></td>
</tr>
</tbody>
</table>
<p dir="auto"><em>全部数据取自 <code>ninfer-serve</code> 服务端 per-request 日志与容器日志，不是客户端 SSE 计数（客户端计数会明显低估）。三次崩溃的 <code>dmesg</code> / <code>journalctl -b -1</code> 证据、源码片段、以及 1895 请求的浸泡日志均可复现。</em></p>
]]></description><link>https://lcz.me/topic/1901</link><generator>RSS for Node</generator><lastBuildDate>Fri, 25 Sep 2026 21:27:18 GMT</lastBuildDate><atom:link href="https://lcz.me/topic/1901.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 22 Sep 2026 21:30:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to 抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机 on Thu, 24 Sep 2026 14:09:43 GMT]]></title><description><![CDATA[<blockquote>
<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/terry" aria-label="Profile: terry">@<bdi>terry</bdi></a> <a href="/post/20315">说</a>:</p>
<p dir="auto">测试很详细，是个行家，有人说16G也能跑，我都想测试下4060Ti了<img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/1f602.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--joy" style="height:23px;width:auto;vertical-align:middle" title="😂" alt="😂" /></p>
</blockquote>
<p dir="auto">我只是提问题，都是AI在干活。AI让我们这群门外汉看起来像那么回事了 <img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/1f602.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--joy" style="height:23px;width:auto;vertical-align:middle" title=":joy:" alt="😂" /></p>
]]></description><link>https://lcz.me/post/20504</link><guid isPermaLink="true">https://lcz.me/post/20504</guid><dc:creator><![CDATA[Enigma]]></dc:creator><pubDate>Thu, 24 Sep 2026 14:09:43 GMT</pubDate></item><item><title><![CDATA[Reply to 抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机 on Thu, 24 Sep 2026 14:05:36 GMT]]></title><description><![CDATA[<blockquote>
<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/che" aria-label="Profile: Che">@<bdi>Che</bdi></a> <a href="/post/20309">说</a>:</p>
<p dir="auto">看起来KVCache相当省啊。可惜在速度上NInfer对40系提升不像5090那么大</p>
</blockquote>
<p dir="auto">32G 显存, 能双路 256K，我已经很满意啦</p>
]]></description><link>https://lcz.me/post/20502</link><guid isPermaLink="true">https://lcz.me/post/20502</guid><dc:creator><![CDATA[Enigma]]></dc:creator><pubDate>Thu, 24 Sep 2026 14:05:36 GMT</pubDate></item><item><title><![CDATA[Reply to 抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机 on Wed, 23 Sep 2026 13:55:45 GMT]]></title><description><![CDATA[<p dir="auto">测试很详细，是个行家，有人说16G也能跑，我都想测试下4060Ti了<img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/1f602.png?v=ecb7c61779a" class="not-responsive emoji emoji-android emoji--joy" style="height:23px;width:auto;vertical-align:middle" title="😂" alt="😂" /></p>
]]></description><link>https://lcz.me/post/20315</link><guid isPermaLink="true">https://lcz.me/post/20315</guid><dc:creator><![CDATA[terry]]></dc:creator><pubDate>Wed, 23 Sep 2026 13:55:45 GMT</pubDate></item><item><title><![CDATA[Reply to 抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机 on Wed, 23 Sep 2026 13:41:03 GMT]]></title><description><![CDATA[<p dir="auto">看起来KVCache相当省啊。可惜在速度上NInfer对40系提升不像5090那么大</p>
]]></description><link>https://lcz.me/post/20309</link><guid isPermaLink="true">https://lcz.me/post/20309</guid><dc:creator><![CDATA[Che]]></dc:creator><pubDate>Wed, 23 Sep 2026 13:41:03 GMT</pubDate></item><item><title><![CDATA[Reply to 抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机 on Tue, 22 Sep 2026 22:02:51 GMT]]></title><description><![CDATA[<p dir="auto">这份定位很扎实，尤其崩3的对照（关 MTP 存活 / 只关 CUDA Graph 存活 / 单路带 Graph 也稳）把「Graph × batch≥2 投机」这个组合条件锁死了，比只报「并发崩」有用得多。几点可复现/可迁移的补充：</p>
<ol>
<li>
<p dir="auto">崩1的根因是「按 128 SM 写死的 resident CTA 预算 + 未按 split 区分 CTA/SM」，换 SM 数（80 的 4080S、92 的 4090D）就会在临界 chunk 翻车，1664/1665 的边界很干净。建议把 resident_ctas 改成 min(schedule_ctas, occupancy_per_sm × sm_count) 反哺 fork 作者；在那之前用 --prefill-chunk ≤1024 是对的。</p>
</li>
<li>
<p dir="auto">崩3 建议再拆一刀：固定 batch=2，但让批里始终只有 1 个请求在跑（另一路只挂空），看是否仍崩。若仍崩 = 图重放本身有问题；若不崩 = 一个 capture 里塞了多请求的 KV 偏移。这能决定修法是「每 batch-size 各捕获」还是「投机 head 关 capture」。</p>
</li>
<li>
<p dir="auto">速度 −11.5% 别急着归引擎：你自己也列了量化方案、投机机制、上下文三个变量都不同。要下结论至少把 SGLang 那条压到 262K、并把「内嵌头 vs 独立草稿」对齐到同一侧。AGIEval 分歧 32/34 完全对称、CEval/CMMLU 在 ±4pp 内，质量打平的结论站得住。</p>
</li>
<li>
<p dir="auto">262K 双路只余 4.2GB 偏紧，建议做一次 needle-in-haystack（关键信息埋 200K+ 位置）确认是「跑通且召回不丢」，而不是 KV 换页。--no-cuda-graph 掉 2.6% 换稳定，这个 trade 很划算。</p>
</li>
</ol>
]]></description><link>https://lcz.me/post/20144</link><guid isPermaLink="true">https://lcz.me/post/20144</guid><dc:creator><![CDATA[Xiaote]]></dc:creator><pubDate>Tue, 22 Sep 2026 22:02:51 GMT</pubDate></item><item><title><![CDATA[Reply to 抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机 on Tue, 22 Sep 2026 21:39:24 GMT]]></title><description><![CDATA[<p dir="auto"><img src="https://upload.lcz.me/uploads/aab2d1b1-b504-4784-bf25-bbb0784bfeb0.jpeg" alt="image.jpeg" class=" img-fluid img-markdown" /></p>
]]></description><link>https://lcz.me/post/20142</link><guid isPermaLink="true">https://lcz.me/post/20142</guid><dc:creator><![CDATA[Enigma]]></dc:creator><pubDate>Tue, 22 Sep 2026 21:39:24 GMT</pubDate></item><item><title><![CDATA[Reply to 抄作业翻车三次：4080S 32G 上 NInfer 跑 Qwen3.8-27B，双路 256K 全部跑通，崩卡根因定位到 CUDA Graph × 批量投机 on Tue, 22 Sep 2026 21:37:42 GMT]]></title><description><![CDATA[<p dir="auto"><img src="https://upload.lcz.me/uploads/8ba953ed-0bf4-4e41-81bf-8a31605040cc.png" alt="Screenshot_20260922194737.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://lcz.me/post/20141</link><guid isPermaLink="true">https://lcz.me/post/20141</guid><dc:creator><![CDATA[Enigma]]></dc:creator><pubDate>Tue, 22 Sep 2026 21:37:42 GMT</pubDate></item></channel></rss>