<?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[3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享]]></title><description><![CDATA[<p dir="auto">大家好。第一次在这里发表聊天， 有什么不对的请多多包含。</p>
<p dir="auto">花了2个多月 用SGlang 跑 Deepseek 4.1 Flash 1017. 终于达到理想的结果。 看了很久视频今天打算分享我设置 3 + 1 设置。 本来要买四张 RTX Pro 6000D（节省开销） 84GB 后来第四张 显卡买了 收到故障 ， 当时显卡从 5万一张飙升至7万 商家就 质保变退款。 无奈之下第四张卡买了 满血 96GB 工作站版 凑数 4 张 显卡来跑AI。 （其实4张84GB 也能跑但是区别在 总上下文）</p>
<p dir="auto">Sglang 引擎可以支持 权重不平衡分配，所以意外的满血版多容纳了一些权重。 经过2个多月的修改，设置，引擎提升 终于达到了 Prefill 11000 （0-500K之间） - 7000 （988K）token 每秒。 目前最多三个并发 总上下文 3百多万</p>
<p dir="auto"><img src="https://upload.lcz.me/uploads/902a4d78-1634-463b-b287-bb092029e45f.jpeg" alt="image.jpeg" class="img-markdown  img-fluid" /><br />
<img src="https://upload.lcz.me/uploads/90c29340-a5ed-4bdf-8295-14c8503eabfd.jpeg" alt="image.jpeg" class="img-markdown  img-fluid" /></p>
<p dir="auto">一并发的输出 （写代码更快）<br />
<img src="https://upload.lcz.me/uploads/213e68ef-358c-442d-8075-914d91848879.jpeg" alt="image.jpeg" class="img-markdown  img-fluid" /></p>
<p dir="auto">三并发输出<br />
<img src="https://upload.lcz.me/uploads/ce36e53e-35a1-446a-b251-1ead1079f1b2.jpeg" alt="image.jpeg" class="img-markdown  img-fluid" /></p>
<p dir="auto">显卡设备 - AMD EPYC 7F52 + 512GB DDR4<br />
<img src="https://upload.lcz.me/uploads/5d61b02b-772c-401d-bc5c-91866e858995.jpeg" alt="image.jpeg" class="img-markdown  img-fluid" /></p>
<p dir="auto">大佬们如果想要本地跑快点的Deepseek v4.1 Flash 1017, 这个方案提供参考。 以下是我设置日志</p>
<h1>DeepSeek V4.1 Flash：在 4 张 RTX PRO 6000 上实现 100 万上下文</h1>
<p dir="auto"><strong>2026 年 10 月 21 日 · 阅读约 30 分钟</strong></p>
<p dir="auto">四张 PCIe Blackwell 显卡，无 NVLink：100 万 token 上下文，冷启动预填充 149 秒，解码 212 tok/s，现已支持三个并发会话。</p>
<blockquote>
<p dir="auto">点击放大</p>
</blockquote>
<p dir="auto">四张没有 NVLink 的 PCIe Blackwell 显卡，现在以完整的 1,048,576 token 窗口服务 DeepSeek-V4.1-Flash：988K token 的冷启动提示预填充耗时 149 秒（6,618 tok/s），解码约 212 tok/s。</p>
<p dir="auto">十一个星期前，同样这四张卡在 llama.cpp 上只能跑到 60 tok/s 的解码速度，而且根本无法支撑长上下文。要走到完整的 100 万窗口、再达到这样的速度，花了两个月的硬件工作、一次没人算进去的内存分配、一次只有在替换卡到手即坏、最终凑成一套不匹配的卡组后才成为可能的非均匀专家切分，以及一个我们忘了带到新启动器上的环境变量。这是完整的历程——包括失败的部分。</p>
<h2>历程：从 630 秒到 149 秒</h2>
<blockquote>
<p dir="auto">988K token 冷启动预填充：三周内从 630 秒降到 149 秒。点击放大</p>
</blockquote>
<p dir="auto">这不是靠一个灵光一现的点子实现的。前后大约十一个星期，其中两周花在与模型无关的硬件上，最后三周用来让 100 万 token 窗口装得下、然后再让它变快。以下是完整路径，包括失败的部分。</p>
<h2>八月：先证明这件事可行</h2>
<p dir="auto">我们最初在 llama.cpp 上（2026-08-11）跑 DeepSeek-V4-Flash 加 DSpark 草稿模型，因为那是当时唯一能在 sm_120 工作站 Blackwell 上跑起来的栈。它确实能跑，但很慢：解码 60.1 tok/s，上下文只有几万 token。</p>
<p dir="auto">那个月得到两件事：</p>
<ul>
<li><strong>草稿模型比引擎本身更重要。</strong> 加上 DSpark 草稿模型后，在相同权重下解码从 60.1 提升到 102.4 tok/s，即 1.7 倍。</li>
<li><strong>机器本身是坏的。</strong> PCIe 错误风暴达到每分钟 23 次，追查下来是一块坏板子和 SlimSAS 线缆。换了新的 Tyan S8030GM2NE 和线缆后降到零。然后 <code>amd_iommu=off iommu=pt</code> 加上 NCCL 点对点，把 TP4 预填充从 977 提升到 2,149 tok/s，解码从 75 提升到 91.3。</li>
</ul>
<p dir="auto">最后这一点值得细想：在完全还没做任何模型层面工作之前，仅仅一个内核参数就让预填充翻了一倍多。</p>
<h2>九月：互联成了天花板</h2>
<p dir="auto">到九月底，我们已经用四张卡提供服务，瓶颈是全归约（all-reduce），而不是算力。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>日期</th>
<th>改动</th>
<th>全归约总线带宽</th>
</tr>
</thead>
<tbody>
<tr>
<td>2026-09-21</td>
<td>NCCL_P2P_LEVEL 从 SYS 改为 PHB</td>
<td>6.21 → 9.31 GB/s</td>
</tr>
<tr>
<td>2026-09-28</td>
<td>为三张 GPU 加 Broadcom PEX 88096 交换芯片</td>
<td>9.31 → 19.53 GB/s</td>
</tr>
<tr>
<td>2026-10-17</td>
<td>为 DS4.1 设置 NCCL_P2P_LEVEL=PHB</td>
<td>3.83 → 19.57 GB/s</td>
</tr>
</tbody>
</table>
<p dir="auto">第三行是最痛的。我们为 DeepSeek V4 设过 PHB，但忘了把它带到 DS4.1 的启动器上。整整三周，发往交换芯片之外那张 GPU 的流量都在走主机内存。2026-10-17 修好后，冷启动 498K 从 150 秒降到 75 秒，冷启动 988K 从 374 秒降到 223 秒——比这篇文章里其他任何单项改动带来的收益都大。</p>
<p dir="auto"><strong>教训：你对一个启动器做的设置，不等于你对整台机器做的设置。</strong> 我们这个设置就那样静静待着，悄悄吃掉了 40% 的预填充性能。</p>
<p dir="auto">2026-09-29 首次 DS4.1 服务：400K 窗口，350K 时预填充 2,564 tok/s，解码 96-108 tok/s。</p>
<h2>内存墙：为什么是 400K 而不是 100 万</h2>
<p dir="auto">这是耗时最长的部分，而且它不是调参问题——而是一笔没有被计入的分配。</p>
<p dir="auto">每一次尝试 100 万上下文都死于同样的特征：请求中途 OOM，失败点还会漂移，而且对 <code>mem-fraction-static</code> 完全免疫。我们从 0.92 调到 0.94，失败点纹丝不动。这本该立刻告诉我们：这块内存是被预算器看不见的东西占走的。</p>
<p dir="auto">我们最终在 OOM 那一刻取了分配器快照，答案是 V4.1 的稠密预填充 indexer：fp32 的 <code>[chunk × context]</code> 分数张量加上 bool 候选掩码，约占全部预填充内存增长的 94%，而且分配在 <code>mem_fraction_static</code> 的核算范围之外。</p>
<p dir="auto">上游有同样的 bug，而且已经命名了它（SGLang issue #35201）："indexer 与上下文成正比的 logits 分配未被 mem_fraction_static 计入——长上下文预填充必然 OOM。"已经有人把我们的问题写下来了。</p>
<p dir="auto">增长是线性且巨大的：<strong>每 1,000 token 增长 13.7 MiB</strong>。到 100 万 token 就是 13.7 GB 没人预算过的内存。</p>
<p dir="auto">两个运行时补丁解决了它，无需重新编译：</p>
<ul>
<li>给 indexer 拷贝预算加 <strong>256 MiB 上限</strong>。</li>
<li>改用 <strong>int32 候选块 id 的行分块预填充 indexer</strong>——手工移植上游 SGLang PR #40217。</li>
</ul>
<p dir="auto">这使窗口从 400K → 600K → 800K → 100 万，第一次冷启动 988K 通过耗时 629.7 秒。</p>
<h2>第二个内存天花板：非均匀专家</h2>
<p dir="auto">100 万上下文跑通后，新的限制出现了：三张 84 GiB 的卡没有余量，而那张 96 GB 的卡却半闲置着。</p>
<p dir="auto">以下是干净重启后测得的数字：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>干净重启后</th>
<th>PRO 6000（rank 0）</th>
<th>每张 6000D</th>
</tr>
</thead>
<tbody>
<tr>
<td>主模型加载后剩余</td>
<td>21.34 GiB</td>
<td>9.52-9.56 GiB</td>
</tr>
<tr>
<td>内存池与 CUDA 图之后剩余</td>
<td>15.86 GiB</td>
<td>4.02-4.12 GiB</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>PRO 6000 上有 11.8 GiB 完全没被使用。</strong> 2026-10-11，一个冷启动的 784K 提示在三张 6000D 上因差不到 0.5 GiB 而失败，而 rank 0 还有约 16 GB 空闲。</p>
<p dir="auto">修复方案是<strong>非均匀专家切分</strong>——96 GB 的卡承担 384 个路由专家中的 108 个，84 GiB 的卡各承担 92 个，而不是原版的 96/96/96/96。一个专家位置在全部 40 层上占 0.70 GiB，所以移走四个大约能给每张 6000D 释放 2.7 GiB。</p>
<blockquote>
<p dir="auto">84 GiB 6000D 上的峰值空闲显存。点击放大</p>
</blockquote>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th></th>
<th>均等切分</th>
<th>非均匀 108/92/92/92</th>
</tr>
</thead>
<tbody>
<tr>
<td>6000D 主模型</td>
<td>72.63 GiB</td>
<td>69.97 GiB</td>
</tr>
<tr>
<td>内存池后剩余</td>
<td>4.64-4.77 GiB</td>
<td>7.31-7.44 GiB</td>
</tr>
<tr>
<td>冷启动 988K 峰值空闲</td>
<td>~1.3 GB</td>
<td>~3.8 GB</td>
</tr>
</tbody>
</table>
<p dir="auto">上线前我们离线验证了路由：45 项检查确认每个专家都恰好被一个 rank 加载、并在它被加载进去的那个槽位里运行；另有一项内核检查显示非均匀切分与单 rank 结果的接近程度与均等切分相当（0.002337 对 0.002347），并故意放了一个损坏的对照组（0.933535）来证明这个测试能区分错误路由和正确路由。</p>
<h2>那张坏掉的卡反而成了优势</h2>
<p dir="auto">原计划是四张完全相同的 RTX 6000D。第四张到手就是坏的。</p>
<p dir="auto">再等一张 6000D 意味着延迟，所以我们买了 96 GB 的 RTX PRO 6000——那是当时真正有货的型号。三张比第四张小 12 GB 的卡，不是任何人会刻意设计的配置；它只是当一张卡坏掉、而你又只能拿到能拿到的那张替换卡时，最终得到的结果。</p>
<p dir="auto">在搭建过程的大部分时间里，它看起来像个负担。原版 SGLang 假定所有 rank 相同，在混装卡组上拒绝启动，而且小的那几张正是耗尽内存的。</p>
<p dir="auto">然后非均匀切分把它翻了盘。因为 96 GB 的卡空间更大，它能比其他的承担更多专家——108 对每张 92，而不是原版的 96/96/96/96。把四个专家位置从小卡上移走，每张大约释放 2.7 GiB，这正是"冷启动 784K 提示因差 0.5 GiB 而挂掉"和"从容运行"之间的差别。</p>
<p dir="auto">正是这份余量，把"很快，但上下文上限约 400K"变成了三个并发的 100 万会话。如果没有一张卡能承担更重的份额，就没有任何地方可以再平衡——每张卡都一样紧缺，也就无解了。</p>
<p dir="auto">所以这个优势不是运气。坏卡迫使我们用了混装机器；非均匀切分把一个约束变成了容量。如果第四张 6000D 是好的，我们会有四张相同的 84 GiB 卡、总显存更少、也没有可再分配的余量——三槽配置根本不会存在。</p>
<p dir="auto"><strong>可以推广的要点：在张量并行机器里，不均匀的卡本身不是问题——只有当切分是均等的时候它才是问题。</strong> 原版 SGLang 假定各 rank 相同，不一致时就不启动。按能力而不是按数量来切分，混装机器可以胜过同构机器，因为大卡能吸收小卡无法承受的不均衡。</p>
<p dir="auto"><strong>如果搭建途中你的卡坏了，就这么做：不要凑同型号，买你能买到的最大替换卡，然后重新平衡分片。</strong></p>
<h2>十月：缓存、分块，以及换引擎</h2>
<p dir="auto">内存问题解决后，剩下的工作就是速度和缓存。</p>
<ul>
<li><strong>2026-10-04</strong> — 预填充 chunk 从 1,024 改为 4,096，Claude Code 的 system 消息保持内联。冷启动 988K 从 629.7 降到 373.4 秒；每轮提示缓存复用从约 35K 中的 8,192 提升到 99.9%。</li>
<li><strong>2026-10-16</strong> — HiCache 文件层，32 个缓存尾部，2.1M GPU 池。重启后恢复 777K 会话，从 269.7 秒的重新预填充降到从磁盘恢复的 5.1 秒。六个 agent 共 2.7M token，100% 复用。</li>
<li><strong>2026-10-18</strong> — DeepSeek-V4.1-Flash-1017 权重（仅权重更新；速度上无明显变化，质量在噪声范围内），KV 文件层迁到三块 NVMe 组成的 RAID0。339K token 的提示从缓存恢复仅 2.90 秒，而计算需要 55.56 秒，而且它经受住了一次断电。</li>
<li><strong>2026-10-21</strong> — 换引擎。冷启动 988K 从 223 降到 149 秒，解码从约 108 升到约 212 tok/s，空闲显存从 1.7 升到 4.2 GiB。</li>
</ul>
<h3>完整调优日志</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>日期</th>
<th>步骤</th>
<th>收益</th>
</tr>
</thead>
<tbody>
<tr>
<td>2026-10-21</td>
<td>更新的 SGLang 引擎（2026-10-19 SM120 构建）+ 我们的切分、indexer 预算和附加组件；chunk 2,048 配 expandable_segments</td>
<td>冷启动 988K 223 → 149 秒；解码 ~108 → ~212 tok/s；空闲显存 1.7 → 4.2 GiB</td>
</tr>
<tr>
<td>2026-10-18</td>
<td>DeepSeek-V4.1-Flash-1017 权重 + 10 月 16 日编码器修复；KV 文件层放到 NVMe RAID0</td>
<td>速度与内存相同；质量在噪声内；断电后 2.9 秒恢复 339K 提示</td>
</tr>
<tr>
<td>2026-10-17</td>
<td>为 DS4.1 设置 NCCL_P2P_LEVEL=PHB（此前没有）</td>
<td>全归约 3.83 → 19.57 GB/s；冷启动 498K 150 → 75 秒；冷启动 988K 374 → 223 秒</td>
</tr>
<tr>
<td>2026-10-17</td>
<td>为 Claude Code 加 /v1/messages 兼容层</td>
<td>请求不再被拒绝后重试；PDF、redacted thinking、超长提示都得到处理</td>
</tr>
<tr>
<td>2026-10-16</td>
<td>HiCache 文件层 + 32 个缓存尾部 + 2.1M GPU 池</td>
<td>重启后恢复 777K 从 269.7 → 5.1 秒；6 个 agent 共 2.7M token，100% 复用</td>
</tr>
<tr>
<td>2026-10-12</td>
<td>非均匀专家切分 108/92/92/92</td>
<td>84 GiB 卡上空闲显存 1,322 → 3,798 MiB；解码 108.8 → 110.3 tok/s</td>
</tr>
<tr>
<td>2026-10-04</td>
<td>预填充 chunk 1,024 → 4,096；Claude Code system 消息保持内联</td>
<td>冷启动 988K 629.7 → 373.4 秒；每轮缓存复用约 35K 中的 8,192 → 99.9%</td>
</tr>
<tr>
<td>2026-10-03</td>
<td>Indexer scratch 预算 256 MiB + 行分块预填充 indexer（移植上游 #40217）</td>
<td>窗口 400K → 600K → 800K → 100 万；首次冷启动 988K 通过耗时 629.7 秒</td>
</tr>
<tr>
<td>2026-09-29</td>
<td>DS4.1-Flash 首次服务：SGLang，TP4 + EP4，Engram 表放在主机内存</td>
<td>400K 窗口，350K 时预填充 2,564 tok/s，解码 96-108 tok/s</td>
</tr>
<tr>
<td>2026-09-28</td>
<td>为三张 GPU 加 Broadcom PEX 88096 交换芯片</td>
<td>全归约 9.31 → 19.53 GB/s；V4 预填充 42K 时 +51%，672K 时 +20%</td>
</tr>
<tr>
<td>2026-09-21</td>
<td>NCCL P2P level 从 SYS 改为 PHB</td>
<td>全归约 6.21 → 9.31 GB/s；V4 预填充 +14-24%</td>
</tr>
<tr>
<td>2026-09-20</td>
<td>新主板（Tyan S8030GM2NE），SlimSAS 线缆更换</td>
<td>PCIe 错误风暴 23/分钟 → 0</td>
</tr>
<tr>
<td>2026-08-25</td>
<td>内核 amd_iommu=off iommu=pt + NCCL 点对点</td>
<td>TP4 预填充 977 → 2,149 tok/s，解码 75 → 91.3</td>
</tr>
<tr>
<td>2026-08-11</td>
<td>DeepSeek V4-Flash 在 llama.cpp 上配 DSpark 草稿模型</td>
<td>解码 60.1 → 102.4 tok/s（1.7 倍）</td>
</tr>
</tbody>
</table>
<h2>真正重要的东西（按重要性排序）</h2>
<p dir="auto">如果你只从这十一个星期里带走一件事：</p>
<ol>
<li><strong>为这个模型设置 NCCL PHB</strong> —— 冷启动 988K 从 374 秒降到 223 秒。一个环境变量，被遗忘了三周。</li>
<li><strong>indexer 补丁</strong> —— 它是把窗口从 400K 做到 100 万的前提。在它解决之前，别的都不重要。</li>
<li><strong>更新的引擎</strong> —— 223 → 149 秒，解码翻倍。收益真实，但它需要底下的内存工作才能用得上。</li>
<li><strong>非均匀专家切分</strong> —— 在那些受限的卡上把余量从 1.3 GB 提到 3.8 GB。</li>
<li><strong>Chunk 4,096 和 HiCache</strong> —— 630 → 373 秒，重启从 4.5 分钟降到 5 秒。</li>
</ol>
<p dir="auto">规律是：<strong>最大的收益来自配置和内存核算，而不是聪明的优化。</strong> 这个模型一直都有这个能力。我们大部分时间都花在发现"内存被花在了我们没看的地方"。</p>
<h2>机器配置</h2>
<p dir="auto">一台工作站，无 NVLink：四张 Blackwell 卡在 PCIe 4.0 上，其中三张位于 PCIe 交换芯片之后。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>部件</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>GPU（服务用）</td>
<td>1x RTX PRO 6000 Blackwell Workstation（96 GB）+ 3x RTX 6000D（可用 84 GiB），均为 PCIe 4.0</td>
</tr>
<tr>
<td>PCIe 拓扑</td>
<td>GPU 0-2 位于 Broadcom PEX 88096 交换芯片之后；GPU 3 独占一个 CPU 根端口</td>
</tr>
<tr>
<td>CPU / 内存</td>
<td>AMD EPYC 7F52（16 核 Zen 2），主板 Tyan S8030GM2NE，512 GB DDR4-2933 ECC</td>
</tr>
<tr>
<td>内核</td>
<td>amd_iommu=off iommu=pt pcie_aspm=off pci=realloc</td>
</tr>
<tr>
<td>缓存盘</td>
<td>KV 文件层在三块 NVMe 的 RAID0 上（/mnt/scratch，上限 1000G）；权重在 2 TB NVMe 上</td>
</tr>
<tr>
<td>服务</td>
<td>SGLang main 2026-10-19（ormandj SM120 镜像）+ 我们的运行时补丁，TP4 + EP4，DSpark 投机解码，fp8 KV</td>
</tr>
<tr>
<td>模型</td>
<td>DeepSeek-V4.1-Flash-1017：40 层，hidden 5,120，384 个路由专家（激活 6 个）；Engram 表（189 GiB）放在主机内存</td>
</tr>
</tbody>
</table>
<h3>为什么只有三张卡在交换芯片之后</h3>
<p dir="auto">四张里有三张是中国市场的 RTX 6000D（可用 84 GiB），而不是完整的 96 GB 版本——448 位总线上 28 颗 3 GB GDDR7，156 个 SM，为出口管制做了削减。原计划是四张 6000D；第四张到手即坏，96 GB 的卡是作为替换买来的。但它与主板的交互方式还有一个容易被忽略的点，这也是这台机器不是"四张卡全在一个交换芯片后"的原因。</p>
<p dir="auto"><strong>简短版：</strong> Tyan S8030GM2NE 不让我们调整 PCIe 内存映射 I/O（MMIO）资源分配。没有这个，四张大显存 Blackwell 卡在交换芯片之后放不进平台的地址空间，所以三张在交换芯片后，第四张占自己的 CPU 根端口。</p>
<p dir="auto"><strong>机制（尽力还原）。</strong> 这部分是根据平台行为和公开报告推断的，不是我们自己抓的 BIOS dump——请把它当作一个在你的板子上需要验证的假设。</p>
<p dir="auto">每张 Blackwell 卡都会向固件请求一个非常大的 BAR1 窗口来暴露其显存：这一级别的大概是每卡 128 GB 量级。四张就是大约半个 TB 的 MMIO 地址空间，固件必须在不重叠的前提下切分并对齐，再分配到各根端口。服务器和工作站 BIOS 通常把 Above 4GB MMIO Limit 默认设为 40 位（1 TB）——听起来很宽裕，直到分配器的 2 的幂对齐吃掉了其中大部分。当它无法放置每个窗口时，通常的结果是 POST 卡在 D4"PCI resource allocation error. Out of resources"代码，或者某张卡干脆永远枚举不出来。</p>
<p dir="auto">暴露 Above 4GB MMIO Limit 和 Re-Size BAR 的板子可以让你抬高这个上限（通常建议 44 位 / 16 TB），从而装下四张。我们的 S8030 没给我们这个控制项，所以四张全在交换芯片后不是一个选项。</p>
<p dir="auto">所以这个拓扑是对固件限制的变通，而不是我们为性能选择的方案：</p>
<ul>
<li>GPU 3 独占自己的 CPU 根端口，在交换芯片之外。</li>
<li>发往它的流量除非告诉 NCCL 这一跳在主机桥内，否则不能做点对点拷贝——这正是 NCCL_P2P_LEVEL=PHB 在这台机器上值 40% 预填充的原因。</li>
<li>三张挂在交换芯片上的卡彼此走 PIX/PXB；第四张是更长的路径。</li>
</ul>
<p dir="auto"><strong>我们接下来会试的（未验证）：</strong> 一块能让你抬高 above-4G MMIO 上限并启用 Re-Size BAR 的板子，应该能让四张卡都在 PCIe 交换芯片之后。如果能，每一对都会变成 PIX/PXB，全归约不再跨越根复合体，P2P 带宽应该还能进一步提升。我们没测过这个——这是从拓扑推出的假设，不是结果。它大概也能让我们去掉 PHB 覆盖，因为那时 PHB 就不再是正确的级别了。</p>
<p dir="auto"><strong>如果你要搭这套，两条实用提示：</strong></p>
<ul>
<li><strong>买板子之前先确认那个 BIOS 设置。</strong> 在我们的硬件上，它就是"三卡在交换芯片后"和"四卡在交换芯片后"之间唯一的差别。</li>
<li><strong>失败并不总是明显的。</strong> 有些板子能 POST，但会静默地留下一张卡未分配；另一些会卡在 D4。在假设分配正确之前，确认 <code>nvidia-smi -L</code> 显示全部四张，且 <code>lspci -vv</code> 中每个 BAR 的 current size 与其 supported 列表相符。</li>
</ul>
<h2>换引擎买到了什么</h2>
<p dir="auto">同样的四张 GPU，同样的 1017 权重，同样的 2.1M token KV 池——这个对比早于第三个槽位，所以下面两列都是双槽配置。引擎变了，每个头条数字都动了。</p>
<blockquote>
<p dir="auto">四张 RTX PRO 6000，无 NVLink——换引擎买到了什么。点击放大</p>
</blockquote>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>指标</th>
<th>旧引擎（10 月 17-18 日）</th>
<th>新引擎（10 月 21 日）</th>
</tr>
</thead>
<tbody>
<tr>
<td>上下文窗口</td>
<td>1,048,576</td>
<td>1,048,576</td>
</tr>
<tr>
<td>GPU KV 池</td>
<td>2.1M token</td>
<td>2.1M token</td>
</tr>
<tr>
<td>冷启动 498K 预填充</td>
<td>74.8 秒</td>
<td>54.2 秒（9,189 tok/s）</td>
</tr>
<tr>
<td>冷启动 988K 预填充</td>
<td>222.5 秒</td>
<td>149.3 秒（6,618 tok/s），needle 2/2</td>
</tr>
<tr>
<td>解码，短提示</td>
<td>108.4 tok/s</td>
<td>212.3 tok/s</td>
</tr>
<tr>
<td>解码，约 1.04M 上下文</td>
<td>103.5 tok/s</td>
<td>184.3 tok/s</td>
</tr>
<tr>
<td>峰值最低空闲显存</td>
<td>1,706-1,922 MiB</td>
<td>4,210 MiB</td>
</tr>
<tr>
<td>两个约 948K 提示同时</td>
<td>未测</td>
<td>都得到回答，259.6 秒</td>
</tr>
<tr>
<td>Needle，878,591 token 处 5 个深度</td>
<td>--</td>
<td>5/5</td>
</tr>
<tr>
<td>工具调用 / 多轮 / 视觉</td>
<td>4/4, 4/4, 11/11</td>
<td>4/4, 4/4, 11/11</td>
</tr>
</tbody>
</table>
<p dir="auto">新引擎是 <code>ghcr.io/ormandj/sglang-deepseek-v41-flash-sm120:v0.4.3</code>：2026-10-19 的 SGLang main 加 32 个补丁，FlashInfer 0.7.2，为 SM120（Blackwell 工作站）卡构建。之前的引擎是约 2026-09-10 的 dev 构建加我们自己的补丁。</p>
<h3>冷启动预填充：223 秒到 149 秒</h3>
<blockquote>
<p dir="auto">988K token 冷启动预填充 149 秒，从 223 秒降下来。点击放大</p>
</blockquote>
<p dir="auto">冷启动测量，无任何缓存，两个引擎在每个级别都 needle 2/2。</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>提示</th>
<th>498K</th>
<th>598K</th>
<th>698K</th>
<th>798K</th>
<th>898K</th>
<th>988K</th>
</tr>
</thead>
<tbody>
<tr>
<td>旧</td>
<td>74.8</td>
<td>96.9</td>
<td>122.4</td>
<td>152.0</td>
<td>186.8</td>
<td>222.5</td>
</tr>
<tr>
<td>新</td>
<td>54.2</td>
<td>69.4</td>
<td>86.5</td>
<td>105.8</td>
<td>127.5</td>
<td>149.3</td>
</tr>
</tbody>
</table>
<p dir="auto">短提示预填充改善幅度类似：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>提示 token</th>
<th>4.1K</th>
<th>32.8K</th>
<th>131K</th>
<th>336K</th>
</tr>
</thead>
<tbody>
<tr>
<td>旧</td>
<td>6,190</td>
<td>8,216</td>
<td>8,233</td>
<td>7,526</td>
</tr>
<tr>
<td>新</td>
<td>7,882</td>
<td>11,291</td>
<td>11,441</td>
<td>10,662</td>
</tr>
</tbody>
</table>
<h3>解码：各处大约翻倍</h3>
<blockquote>
<p dir="auto">解码在每个上下文长度上都大约翻倍。点击放大</p>
</blockquote>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>上下文</th>
<th>35</th>
<th>11.6K</th>
<th>47.7K</th>
<th>96K</th>
<th>194K</th>
<th>379K</th>
<th>750K</th>
<th>1,036K</th>
</tr>
</thead>
<tbody>
<tr>
<td>旧</td>
<td>108.4</td>
<td>113.0</td>
<td>99.5</td>
<td>113.8</td>
<td>109.8</td>
<td>107.8</td>
<td>112.8</td>
<td>103.5</td>
</tr>
<tr>
<td>新</td>
<td>212.3</td>
<td>201.2</td>
<td>216.9</td>
<td>211.5</td>
<td>197.7</td>
<td>198.7</td>
<td>180.6</td>
<td>184.3</td>
</tr>
</tbody>
</table>
<p dir="auto">在 100 万上下文下增益仍然保持：184 tok/s，而旧引擎只有 104。峰值空闲显存从 1.7 GiB 升到 4.2 GiB，正是这一点让更深的 KV 池变得安全。</p>
<h3>它不是开箱即用的</h3>
<p dir="auto">四轮才到位。</p>
<ol>
<li><strong>原版配置。</strong> 预填充快了 36-48%，解码约 1.9 倍，但该配置假定四张 96 GB 卡。在我们 84 GiB 的 6000D 上它只装得下约 40 万 token 的 KV——没有 100 万窗口。</li>
<li><strong>移植我们的专家切分。</strong> 108/92/92/92 切分加 256 MiB indexer 预算，chunk 2048、mem 0.915。100 万通过：988K 冷启动 149.1 秒。</li>
<li><strong>生产用的 chunk 4096。</strong> 能启动，但长预填充崩了：500K 冷启动用了 278.7 秒，而对照是 54 秒。在这个引擎上不可用。</li>
<li><strong>生产设置加完整池。</strong> Chunk 2048、mem 0.93、2.1M 上限、所有客户端附加组件、32 个缓存尾部和 HiCache 文件层。全部通过。这就是随后的双槽服务；第三个槽位是之后加的（见下），把池提到 3.15M、mem 0.942。</li>
</ol>
<h3>为什么 chunk 4,096 在这里会失败</h3>
<p dir="auto">这是最有意思的部分，而且它不是一个简单的"缓冲区太大"。</p>
<p dir="auto">在 4,096 行时，引擎的内存在第一个 chunk 就被占满。FlashInfer MoE scratch 空间是每次调用时分配的、没有预分配缓冲区；mHC 残差缓冲区翻倍；而在 4,096+ 行时引擎会切换到单独的大批量代码路径，包括第二条 CUDA 流，它们持有内存更久并造成碎片。无论如何，约有 1.85 GiB 被预留给预录制的解码尾部 CUDA 图。</p>
<p dir="auto">这触发了一个反馈回路。V4.1 预填充 indexer 根据空闲 GPU 内存来决定其分数 tile 的大小。几乎没有空闲时，tile 缩到只有几行——每个 index 层最多约 1,000 次微小内核启动，每次都重读整个上下文。因此代价随上下文增长：随着上下文增长，预填充从约 11K tok/s 掉到约 1.1K tok/s。而在 2,048 时约有 4 GB 保持空闲，所以 tile 能保持较大。</p>
<p dir="auto"><strong>现场数据也一致。</strong> 其他在 RTX PRO 6000 上跑这个模型的人在生产中用 chunk 2,048；在 8 张 GPU 上，4,096 并不更快（128K 时 6,301 对 6,853 tok/s）。我们自己的测量：即便装得下，4,096 也只能买到约 4% 的预填充提升。</p>
<h3>原版配置实际给你什么</h3>
<p dir="auto">在任何调优之前，引擎自带配置已经快得多——而且在我们这些卡上 100 万上下文不可用。这一点值得知道，因为它告诉你收益来自哪里、墙在哪里。</p>
<p dir="auto">在相同 chunk 4,096 和与旧生产服务相同的提示规模下运行：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>提示 token</th>
<th>旧引擎（tok/s）</th>
<th>原版新引擎</th>
</tr>
</thead>
<tbody>
<tr>
<td>4.1K</td>
<td>6,190</td>
<td>8,424</td>
</tr>
<tr>
<td>8.2K</td>
<td>7,310</td>
<td>10,356</td>
</tr>
<tr>
<td>32.8K</td>
<td>8,216</td>
<td>11,816</td>
</tr>
<tr>
<td>131K</td>
<td>8,233</td>
<td>11,995</td>
</tr>
<tr>
<td>336K</td>
<td>7,526</td>
<td>11,132</td>
</tr>
</tbody>
<tbody>
<tr>
<td>上下文</td>
<td>旧解码</td>
<td>原版解码</td>
</tr>
<tr>
<td>---</td>
<td>---</td>
<td>---</td>
</tr>
<tr>
<td>35</td>
<td>108.4</td>
<td>214.3</td>
</tr>
<tr>
<td>96K</td>
<td>113.8</td>
<td>215.7</td>
</tr>
<tr>
<td>379K</td>
<td>107.8</td>
<td>200.4</td>
</tr>
</tbody>
</table>
<p dir="auto">所以开箱即用：预填充 +36-48%，解码约 1.9 倍。引擎本身就是那个收益。此后的一切都是关于让它装得下。</p>
<h3>为什么原版在这里撑不住 100 万</h3>
<p dir="auto">上游的配置假定四张 96 GB 卡。我们三张 6000D 是 85.6 GB，没有非均匀专家切分时每张装 74.1 GiB 权重，而不是生产的 72.6——而那张 96 GB 的 PRO 6000 却有约 17 GB 闲置。</p>
<p dir="auto">五次启动尝试，按顺序：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>启动</th>
<th>设置</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>原样</td>
<td>拒绝：TP 内存不均衡</td>
</tr>
<tr>
<td>2</td>
<td>mem 0.93, chunk 8192</td>
<td>KV 664,832，然后预热时 OOM（980 MiB 空闲）</td>
</tr>
<tr>
<td>3</td>
<td>mem 0.91</td>
<td>拒绝：权重导致 0.916 以下无 KV</td>
</tr>
<tr>
<td>4</td>
<td>mem 0.925, chunk 8192</td>
<td>KV 393,984，然后预热时 OOM（248 MiB 空闲）</td>
</tr>
<tr>
<td>5</td>
<td>mem 0.925, chunk 4096</td>
<td>服务成功——KV 399,872，峰值 84.65 / 85.65 GB</td>
</tr>
</tbody>
</table>
<p dir="auto">第 5 次能跑，但只有约 40 万 KV 而不是 2.1M：没有 100 万上下文，没有余量，也没有第二个 agent 的空间。速度是真的；容量不是。</p>
<p dir="auto">修复方案是非均匀专家切分（96 GB 卡承担 108 个专家，84 GiB 卡各 92 个），它把 6000D 的权重降到 71.5 GiB，并把差额交给 KV 池。<strong>这一个改动就是把"快但只有 400K"变成"快且有 2.1M"的关键。</strong></p>
<h3>给你自己搭建的启示</h3>
<p dir="auto">如果你用四张 96 GB 卡，原版配置可能直接就能用。在混装或 84 GiB 卡上，预期要先重新平衡专家——而且不要把原版配置的基准数字当成你会拿到的数字，因为它测的是一个你的机器可能装不下的内存形状。</p>
<h2>10 月 18 日的权重</h2>
<p dir="auto">DeepSeek 的 1017 版本是一个仅权重更新——相同的配置、张量名、分片和分词器；分片哈希不同。</p>
<p dir="auto">在旧引擎上，原始版 vs 1017 是打平：冷启动 988K 253.5 秒对 257.1 秒，解码 108.9 对 106.1 tok/s。饱和测试集上的质量：HumanEval 157/164 对 156/164，GSM8K 297/300 对 296/300。DeepSeek 报告的增益在更难的推理和 agent 基准上，而这些测试集达不到那个水平。</p>
<p dir="auto">我们还移植了 DeepSeek 的 10 月 16 日编码器修复：推理努力级别 low/high/max 对应 50/75/100，仅携带工具结果的消息不再开启新回合，以及 <code>ns::name</code> 工具命名空间。新引擎已经包含这些。</p>
<p dir="auto"><strong>试过并否决的：</strong> 参考模型在 wo_a 之前对注意力输出做的 fp8 往返，损失约 13% 解码（106.1 到 92.7 tok/s），质量无可测变化。保持关闭。</p>
<h2>三个并发 100 万会话</h2>
<p dir="auto">单会话时引擎已经很快了。对 agent 工作真正重要的问题不一样：这台机器能同时撑住三个完整的 100 万 token 会话而不倒吗？</p>
<p dir="auto"><strong>能。</strong> 现在生产上服务三个槽位，4 个槽位试过并否决。</p>
<h3>取舍：池 vs 余量</h3>
<p dir="auto">一个能装下完整 1,048,576 token 上下文的槽位不是免费的。每个约花 1.7 GB KV 池加约 0.07 GB 解码 CUDA 图。</p>
<blockquote>
<p dir="auto">6000D 启动后的空闲显存。点击放大</p>
</blockquote>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>槽位</th>
<th>池</th>
<th>mem</th>
<th>启动后空闲（6000D / GPU0）</th>
</tr>
</thead>
<tbody>
<tr>
<td>2（之前）</td>
<td>2,099,968</td>
<td>0.93</td>
<td>5.97 / 6.55 GB</td>
</tr>
<tr>
<td>3（现在）</td>
<td>3,149,824</td>
<td>0.942</td>
<td>4.23 / 4.82 GB</td>
</tr>
<tr>
<td>4</td>
<td>4,199,936</td>
<td>0.96</td>
<td>2.50 / 3.09 GB</td>
</tr>
</tbody>
</table>
<p dir="auto">池就是 N × 1,050,000。在 mem 0.93 时，栈构建 2,599,936 token（无上限），每 +0.01 的 mem 分数增加约 547k。</p>
<p dir="auto"><strong>为什么 4 槽失败。</strong> 池装得下，功能检查也通过了——工具、多轮 4/4、视觉 11/11、OCR 3/3。然后第一个普通的 2k token 请求就挂了：</p>
<pre><code>cutlass_fused_moe: "Tried to allocate 124.00 MiB ... 40.12 MiB is free" on GPUs 1 and 2
</code></pre>
<p dir="auto">调度器退出，之后每个请求都被拒绝。那个阶段的最低空闲是 6000D 上的 898 MiB。<strong>在 84 GiB 卡上，4 槽不是一个能扛住真实流量的配置——池装得下，负载装不下。</strong></p>
<h3>3 槽实际交付了什么</h3>
<p dir="auto">功能上：工具通过，多轮 4/4，视觉 11/11，OCR 3/3，以及超长提示按预期返回 Anthropic 措辞的 400。</p>
<p dir="auto">多流同时解码（短提示，thinking 关闭——与 212 tok/s 的单流数字不可比，后者用的是不同的测试框架）：</p>
<blockquote>
<p dir="auto">三个并发流。点击放大</p>
</blockquote>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>流数</th>
<th>每流</th>
<th>合计</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>189.6 tok/s</td>
<td>190.0</td>
</tr>
<tr>
<td>2</td>
<td>154.4 tok/s</td>
<td>295.7</td>
</tr>
<tr>
<td>3</td>
<td>137.4 tok/s</td>
<td>392.4</td>
</tr>
</tbody>
</table>
<p dir="auto">从一流到三流，总吞吐翻倍，而每流速度下降约 28%。这是预期的形状，也是 agent 工作正确的取舍：<strong>三个 agent 在推进，胜过单个 agent 全速跑。</strong></p>
<p dir="auto"><strong>预填充不变。</strong> 三槽和双槽产生的预填充曲线在噪声范围内相同：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>提示</th>
<th>2 槽</th>
<th>3 槽</th>
</tr>
</thead>
<tbody>
<tr>
<td>131K</td>
<td>11,441 tok/s</td>
<td>11,431</td>
</tr>
<tr>
<td>498K 冷启动</td>
<td>54.2 秒</td>
<td>54.1 秒</td>
</tr>
<tr>
<td>988K 冷启动</td>
<td>149.3 秒</td>
<td>149.4 秒</td>
</tr>
</tbody>
</table>
<p dir="auto">这些冷启动级别是在 3 槽激活时测的，不是从双槽服务沿用的——needle 检查在这个配置上跑过：每个级别 2/2。单流解码也保持在 decode_bench 的 ±10 噪声内（短上下文 212.2，1,036K 时 177.1）。</p>
<p dir="auto">值得精确说明探测了什么、没探测什么，因为这两者容易混淆：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>测试</th>
<th>槽位</th>
<th>Needle 检查</th>
</tr>
</thead>
<tbody>
<tr>
<td>冷启动预填充，131K-988K</td>
<td>3</td>
<td>每个级别 2/2</td>
</tr>
<tr>
<td>三个并发 988K 会话</td>
<td>3</td>
<td>未探测——正确性由答案判断，不是 needle</td>
</tr>
<tr>
<td>两个并发约 948K 提示（较早）</td>
<td>2</td>
<td>未探测</td>
</tr>
</tbody>
</table>
<p dir="auto">所以 3 槽配置对单请求冷启动预填充做了 needle 验证，窗口声明正是依赖这一点。并发运行证明调度器能撑住三个长会话并返回正确答案；它们没有额外证明三个会话都在驻留时的 needle 检索。<strong>这是证据上的一个缺口，不是已知的失败。</strong></p>
<p dir="auto">三个真实的 988K 会话同时跑——2.96M token，占池的 94%——全部正确回答：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>会话</th>
<th>提示 token</th>
<th>首 token</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>988,050</td>
<td>150.2 秒</td>
<td>PASS</td>
</tr>
<tr>
<td>2</td>
<td>988,055</td>
<td>297.0 秒</td>
<td>PASS</td>
</tr>
<tr>
<td>3</td>
<td>988,050</td>
<td>443.9 秒</td>
<td>PASS</td>
</tr>
</tbody>
</table>
<h3>教训：槽位增加解码并发，不增加预填充吞吐</h3>
<p dir="auto">看那些首 token 时间：150 秒、297 秒、444 秒。预填充是一个接一个跑的，每个约 6,680 tok/s。</p>
<p dir="auto">这是因为 2,048 token 的预填充 chunk 被所有运行中的请求共享。后面的长提示要等前面的跑完。所以三个槽位给你三个 agent 同时思考，但它们不能让三个长提示的预填充整体更快。</p>
<p dir="auto"><strong>如果你的负载是三个 agent 各自冷启动 900K 提示，预期最后一个要等。如果是三个 agent 跑长期存活的缓存会话——agent 工作通常就是这种——你能拿到完整收益，因为前缀缓存意味着你根本不需要重新预填充。</strong></p>
<h3>真正重要的浸泡测试</h3>
<p dir="auto">基准不是生产测试，所以 3 槽配置被拿去跑了一个 agent 式浸泡测试：三个类 Claude-Code 会话分别预热到 698K / 754K / 780K token（同时 2.23M），每回合带 3-15K 工具输出加一个 <code>&lt;system-reminder&gt;</code>，每 4 回合起 2 个并行子 agent，800K 时压缩。</p>
<p dir="auto"><strong>56 个请求，0 错误，PASS。</strong></p>
<ul>
<li>压缩：3/3（S3 804,298 用 26.5 秒，S2 802,023 用 11.2 秒，S1 802,489 用 6.8 秒）——每个都从缓存读取了其前序提示的 100.0%。</li>
<li>600K-804K 上下文的 agent 回合：22 个。中位数 6.0 秒，最大 18.5 秒。</li>
<li>子 agent 冷启动：8 个（54K-67K），排队时最大 25.3 秒。</li>
<li>缓存复用：42 个判定回合中最差 96.2%；每个长上下文回合都在 99%+。</li>
<li>最低空闲：GPU0 2,585；6000D 1,960-2,042 MiB。</li>
</ul>
<p dir="auto">三个低于 99% 的回合都是压缩后的小上下文（前序 5-10K），最后一个不完整页没被缓存——不是真正的回退。</p>
<p dir="auto"><strong>一个值得重复的测量陷阱：</strong> 第一次试跑把缓存复用算成"缓存 ÷ 整个提示"，这在某回合往小上下文里加了很多东西时会低估复用（一个 5K 子 agent 上的 3K 工具输出被打成 51-60% 并 FAIL）。按会话的前序提示来算是诚实的度量——服务器数据在两次运行中完全相同。<strong>如果你在测前缀缓存复用，在相信那个数字之前先决定你要的是哪个分母。</strong></p>
<h2>最终设置</h2>
<p dir="auto">现有启动器上的三个环境变量覆盖——除默认值外不改文件：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>设置</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>MAX_RUNNING_REQUESTS / MAX_NUM_SEQS</td>
<td>3</td>
</tr>
<tr>
<td>MAX_TOTAL_TOKENS（池下限）</td>
<td>3,150,000</td>
</tr>
<tr>
<td>MEMORY_FRACTION</td>
<td>0.942</td>
</tr>
</tbody>
</table>
<p dir="auto">HiCache 层的主机内存随池增长（比例 2）；有 287 GB 可用，这没问题。</p>
<p dir="auto"><strong>诚实的限制：客户端只有在真的同时发超过两个请求时才受益。</strong> 如果你的 agent 工具把子 agent 扇出限制在 2，第三个槽位大部分时间是闲的——它是为"两个会话加一个子 agent 重叠"那一刻准备的余量，不是你总能看到的吞吐倍增器。</p>
<h3>重要的设置</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>设置</th>
<th>值</th>
<th>原因</th>
</tr>
</thead>
<tbody>
<tr>
<td>预填充 chunk</td>
<td>2,048</td>
<td>4,096 在这个引擎上会让长预填充崩溃（见上）；2,048 保持约 4 GB 空闲，使 indexer tile 保持较大</td>
</tr>
<tr>
<td>PYTORCH_CUDA_ALLOC_CONF</td>
<td>expandable_segments:True</td>
<td>必需。没有它引擎会把约 5.7 GiB 搁置成 reserved-but-unused，连 256 token 请求都失败</td>
</tr>
<tr>
<td>启动预热</td>
<td>无</td>
<td>上游的 --warmups serving_coverage 在 84 GiB 卡上 OOM</td>
</tr>
<tr>
<td>--mem-fraction-static</td>
<td>0.942</td>
<td>配合 --max-total-tokens 3150000；实际设定用量的是上限而不是分数</td>
</tr>
<tr>
<td>NCCL_P2P_LEVEL</td>
<td>PHB</td>
<td>让 NCCL 对交换芯片外那张 GPU 使用直接 GPU 到 GPU 拷贝（全归约 3.83 对 19.57 GB/s）</td>
</tr>
<tr>
<td>KV 池</td>
<td>3.15M token，fp8</td>
<td>三个 100 万会话保持驻留</td>
</tr>
<tr>
<td>--swa-prefix-tails</td>
<td>32</td>
<td>配 HiCache 时主机层保留被逐出的尾部</td>
</tr>
<tr>
<td>HiCache</td>
<td>file 后端，write-through</td>
<td>GPU -&gt; 主机内存（4.2M token）-&gt; NVMe；会话经受重启</td>
</tr>
<tr>
<td>专家切分</td>
<td>108 / 92 / 92 / 92</td>
<td>96 GB 卡比 84 GB 卡承担更多专家</td>
</tr>
<tr>
<td>Indexer 预算</td>
<td>256 MiB</td>
<td>上游现在已对 indexer 分块；我们只给它的分数预算设上限</td>
</tr>
<tr>
<td>并发</td>
<td>--max-running-requests 3</td>
<td>三个槽位；每流速度降约 28%，但合计大致翻倍</td>
</tr>
</tbody>
</table>
<p dir="auto">沿用的客户端附加组件：Claude Code <code>/v1/messages</code> 兼容、对话中 system 消息保持内联以便前缀缓存复用、采样默认 0.95 / 1.0、推理努力 "off" 别名，以及重复循环防护。</p>
<h2>如何自己得到这个结果</h2>
<p dir="auto">如果你有四张 Blackwell 工作站卡并想要这个结果，<strong>工作顺序比任何单个 flag 都重要。</strong> 这是实际奏效的顺序。</p>
<h3>1. 先把互联弄对</h3>
<p dir="auto">下游的一切都被 PCIe 限制。这些卡没有 NVLink，所以所有跨 GPU 流量都走 PCIe，拓扑决定你的天花板。</p>
<ul>
<li><strong>在负载下检查链路宽度，而不是空闲时。</strong> 我们有一张卡因为坏 riser 只训练到 x8。空闲时看着正常。它损失了约 15% 预填充（冷启动 988K 253.5 秒对 223.0 秒），直到我们对比 nvidia-smi 链路宽度和 lspci -vv 才发现。每次打开机箱后都要复查。</li>
<li><strong>了解你的拓扑。</strong> <code>nvidia-smi topo -m</code> 告诉你哪些卡共享交换芯片、哪些在自己的根端口上。我们的是：三张在 Broadcom PEX 88096 之后，一张直连。</li>
<li><strong>设置 NCCL_P2P_LEVEL=PHB。</strong> 没有它，发往交换芯片外那张 GPU 的流量会走主机内存。在我们机器上那是全归约 3.83 对 19.57 GB/s——5 倍差距，表现为冷启动 988K 的 374 秒对 223 秒。</li>
<li><strong>内核 flag 很重要。</strong> 我们用 <code>amd_iommu=off iommu=pt pcie_aspm=off pci=realloc</code> 启动。在我们上一块板子上，仅 <code>iommu=pt</code> 就把 TP4 预填充从 977 提升到 2,149 tok/s。</li>
</ul>
<h3>2. 在追速度之前先定 KV 池大小</h3>
<p dir="auto">100 万窗口首先是一个内存问题。三件事解锁了它：</p>
<ul>
<li><strong>非均匀专家切分。</strong> 96 GB 卡比 84 GiB 卡承担更多专家：108 / 92 / 92 / 92。这把 84 GiB 卡上的最低空闲显存从 1,322 提到 3,798 MiB。</li>
<li><strong>把 indexer scratch 预算限制在 256 MiB</strong>（DSV41_INDEXER_BUDGET_MIB）。这是把窗口从 400K -&gt; 600K -&gt; 800K -&gt; 100 万推上去的东西。</li>
<li><strong>用分层缓存。</strong> HiCache 配 file 后端把 KV 层放到 NVMe，所以 777K 会话 5.1 秒回来，而不是 269.7 秒重新预填充。</li>
</ul>
<p dir="auto">如果你在 84 GiB 卡上，预期要调切分而不是照抄一个：比例是你卡组构成的函数。</p>
<h3>3. 用长预填充来选 chunk 大小，而不是短提示</h3>
<p dir="auto">这是最容易犯的错误。Chunk 4,096 在这个引擎上并不更快——它能启动、通过短测试，然后在长上下文上崩掉（500K 冷启动：278.7 秒对 chunk 2,048 的 54 秒）。</p>
<p dir="auto"><strong>不要因为它在 32K 上装得下就接受某个 chunk 大小。测一个 500K+ 的冷启动提示。</strong> 失败模式是一个反馈回路，而不是 OOM 崩溃：空闲内存耗尽时 indexer 缩小 tile，这倍增内核启动次数，而这又随上下文增长让问题更糟。</p>
<h3>4. 设好分配器，跳过预热</h3>
<p dir="auto"><code>PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True</code> 在这个引擎上是必需的。没有它我们看到约 5.7 GiB 被搁置为 reserved-but-unused，连 256 token 请求都失败。注意这和我们旧引擎的发现相反，那时它会导致失控生成。</p>
<p dir="auto">不要用上游的 <code>--warmups serving_coverage</code>。它在 84 GiB 卡上 OOM。</p>
<p dir="auto">设 <code>--mem-fraction-static 0.942</code> 配 <code>--max-total-tokens 3150000</code>。实际设定池的是显式 token 上限，不是分数。</p>
<h3>5. 信任之前先验证</h3>
<p dir="auto">能抓到我们错误的检查：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>检查</th>
<th>抓到了什么</th>
</tr>
</thead>
<tbody>
<tr>
<td>负载下的 nvidia-smi 链路宽度</td>
<td>一张卡训练到 x8——15% 预填充</td>
</tr>
<tr>
<td>冷启动 500K+ 预填充，而不只是短提示</td>
<td>Chunk 4,096 在长上下文上崩溃</td>
</tr>
<tr>
<td>多深度 needle 测试</td>
<td>静默的上下文退化</td>
</tr>
<tr>
<td>峰值最低空闲显存</td>
<td>100 万窗口是否真的安全</td>
</tr>
<tr>
<td>两个并发长提示</td>
<td>真实 agent 负载下的行为</td>
</tr>
</tbody>
</table>
<h3>6. 预期要保留你自己的补丁</h3>
<p dir="auto">原版配置是为四张 96 GB 卡调优的。在混装或 84 GiB 配置上你会带上自己的专家切分、indexer 预算和 chunk 大小。我们的记在上面的设置表里——把它们当作一个开始测量的起点，而不是可以照抄的配置。</p>
<p dir="auto">好消息：这个引擎已经包含我们之前手工移植的 indexer 分块和编码器修复，所以需要维护的东西比以前少了。</p>
<h2>死胡同</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>尝试</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>Chunk 4,096（新引擎）</td>
<td>能启动，但长预填充崩溃：500K 冷启动 278.7 秒对 54 秒</td>
</tr>
<tr>
<td>上游启动预热</td>
<td>在 84 GiB 卡上 OOM</td>
</tr>
<tr>
<td>注意力输出的 fp8 往返</td>
<td>解码 -13%，无质量收益</td>
</tr>
<tr>
<td>Chunk 12,288 / 16,384（旧引擎）</td>
<td>第一个 chunk 就 OOM</td>
</tr>
<tr>
<td>Chunk 10,240（旧引擎）</td>
<td>装得下，988K 时快 8.6%，但 KV 池减半</td>
</tr>
<tr>
<td>Chunk 8,192（旧引擎）</td>
<td>快 6.8%，代价 1.6 GB 显存；否决</td>
</tr>
<tr>
<td>更大的 indexer 预算（1,024 MiB）</td>
<td>39 次分配失败，无加速</td>
</tr>
<tr>
<td>fp4 indexer flag（旧引擎）</td>
<td>慢 25-29%；新引擎默认开启</td>
</tr>
<tr>
<td>expandable_segments（旧引擎）</td>
<td>有害：失控生成。在新引擎上反过来了，是必需的</td>
</tr>
<tr>
<td>SGLang 自定义全归约、torch 对称内存、NCCL NVLS</td>
<td>在 4 张纯 PCIe SM120 卡上不可用</td>
</tr>
</tbody>
</table>
<h2>两个硬件教训</h2>
<p dir="auto">一张卡因为坏 riser 只训练到 PCIe x8。它损失了约 15% 预填充（冷启动 988K 253.5 秒对 x16 的 223.0 秒），直到我们在负载下检查链路宽度才发现。换 riser 后：221.8 秒，解码 108.4。<strong>每次打开机箱后都检查 nvidia-smi / lspci。</strong></p>
<p dir="auto">PHB 伴随着一次主机硬复位（一个 AMD "data fabric sync flood"）。之后的重启是干净的，目前还不清楚 PHB 是否相关。在照抄这个之前值得知道。</p>
<h2>我们还没有证明的</h2>
<p dir="auto">这些数字的诚实边界：</p>
<ul>
<li><strong>新引擎上没有重跑质量测试集。</strong> 相同权重，功能与 needle 检查通过，但这个引擎上的 HumanEval/GSM8K 还没做。</li>
<li><strong>重启后的缓存恢复没有重测。</strong> 早先"777K 5.1 秒回来"的结果属于旧引擎。</li>
<li><strong>引擎的 PCIe-IPC 全归约在这些混装卡上从未启用</strong>（"every rank must use identical collective arguments"），所以全归约跑在 NCCL 上。上面的每个数字都是在没有它的情况下——可能还有更多可用。</li>
<li><strong>10 月 21 日晚起进入生产，尚未浸泡。</strong> 所有数字都是基准流量。</li>
<li><strong>三个并发 988K 会话没有做 needle 探测。</strong> 三个都正确回答了，但三个 100 万会话驻留时的 needle 检索未测——见 3 槽一节的表格。3 槽上的单请求冷启动预填充是 needle 验证的 2/2。</li>
</ul>
<h2>致谢</h2>
<p dir="auto">DeepSeek 的 DeepSeek-V4.1-Flash-1017。SGLang 项目。ormandj 的 SM120 镜像（<a href="http://ghcr.io/ormandj/sglang-deepseek-v41-flash-sm120%EF%BC%89%E3%80%82%E6%9C%80%E5%88%9D%E7%9A%84" rel="nofollow ugc">ghcr.io/ormandj/sglang-deepseek-v41-flash-sm120）。最初的</a> 4x RTX PRO 6000 DS4.1 配置 0xSero/deepseek-v4.1-flash-4x-rtx-pro-6000（现在在 sybil-solutions 下）是旧引擎的基础。SGLang PR #43376 和 issue #40877 为 chunk 分析提供了参考；上游 PR #40217 是 indexer 分块思路的来源。</p>
<p dir="auto"><strong>方法：</strong> 冷启动提示与 needle 检查用 <code>scripts/coldctx_run.py</code>，短预填充用 <code>scripts/bench_openai_ctx.py</code>，解码用 <code>scripts/decode_bench.py</code>（512 token 的 2-3 次运行取中位数；单次运行波动约 ±10 tok/s）。</p>
<hr />
]]></description><link>https://lcz.me/topic/2952</link><generator>RSS for Node</generator><lastBuildDate>Thu, 12 Nov 2026 15:26:20 GMT</lastBuildDate><atom:link href="https://lcz.me/topic/2952.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 10 Nov 2026 04:23:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Thu, 12 Nov 2026 04:41:56 GMT]]></title><description><![CDATA[<p dir="auto">这比官方还要快，太猛了</p>
]]></description><link>https://lcz.me/post/32774</link><guid isPermaLink="true">https://lcz.me/post/32774</guid><dc:creator><![CDATA[张光璞]]></dc:creator><pubDate>Thu, 12 Nov 2026 04:41:56 GMT</pubDate></item><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Wed, 11 Nov 2026 14:12:45 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/kop-wang" aria-label="Profile: kop-wang">@<bdi>kop-wang</bdi></a> 你好，回本就别想太多了<img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/1f602.png?v=a055419e292" class="not-responsive emoji emoji-android emoji--joy" style="height:1.4em;width:auto;vertical-align:middle" title="😂" alt="😂" />。 ，目前这个设置是花了近两年来终于可以符合我的需求。之前八张5090 显存不够 看起来威武跑起来什么都差一点点哈哈。 过几天我发布一下我四台苹果M3Ultra 256GB 的经历。</p>
]]></description><link>https://lcz.me/post/32677</link><guid isPermaLink="true">https://lcz.me/post/32677</guid><dc:creator><![CDATA[Edmund Tan]]></dc:creator><pubDate>Wed, 11 Nov 2026 14:12:45 GMT</pubDate></item><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Wed, 11 Nov 2026 09:41:32 GMT]]></title><description><![CDATA[<p dir="auto">感謝分享DeepSeek-V4.1-Flash-1017;<br />
明年我們論壇上 會有越來越多 RTX Pro 系列玩家<br />
讚讚讚~</p>
]]></description><link>https://lcz.me/post/32602</link><guid isPermaLink="true">https://lcz.me/post/32602</guid><dc:creator><![CDATA[kos or]]></dc:creator><pubDate>Wed, 11 Nov 2026 09:41:32 GMT</pubDate></item><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Wed, 11 Nov 2026 09:17:44 GMT]]></title><description><![CDATA[<p dir="auto"><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2b50.png?v=a055419e292" class="not-responsive emoji emoji-android emoji--star" style="height:1.4em;width:auto;vertical-align:middle" title="⭐" alt="⭐" /> 本帖由<strong>优秀</strong>升级为<strong>精华</strong>（两者互斥，只补差价），作者 <strong>+3 积分</strong>，累计 6 分。</p>
<blockquote>
<p dir="auto">补差凭证：优秀升精华 +3 分 · 编号 ef2952-5173-1</p>
</blockquote>
]]></description><link>https://lcz.me/post/32595</link><guid isPermaLink="true">https://lcz.me/post/32595</guid><dc:creator><![CDATA[Xiaote]]></dc:creator><pubDate>Wed, 11 Nov 2026 09:17:44 GMT</pubDate></item><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Wed, 11 Nov 2026 09:17:02 GMT]]></title><description><![CDATA[<p dir="auto">仰望一下壕， 顺便吐槽一下梁文峰的优化能力，好奇那些站点放出的deepseek flash 1017 token plan是用的什么硬件和框架做到的。 。。。token费用低于本地跑模型的电费。。。<br />
难道乌兰察布的电费真的到了地板价？</p>
]]></description><link>https://lcz.me/post/32594</link><guid isPermaLink="true">https://lcz.me/post/32594</guid><dc:creator><![CDATA[stxpnet]]></dc:creator><pubDate>Wed, 11 Nov 2026 09:17:02 GMT</pubDate></item><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Tue, 10 Nov 2026 07:24:37 GMT]]></title><description><![CDATA[<p dir="auto"><img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=a055419e292" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:1.4em;width:auto;vertical-align:middle" title="✅" alt="✅" /> 版主审定：本帖设为<strong>优秀</strong>，作者 <strong>+3 积分</strong>奖励，继续加油！</p>
<blockquote>
<p dir="auto">奖励凭证：优秀 +3 分 · 编号 e2952-5173-1</p>
</blockquote>
]]></description><link>https://lcz.me/post/32378</link><guid isPermaLink="true">https://lcz.me/post/32378</guid><dc:creator><![CDATA[Xiaote]]></dc:creator><pubDate>Tue, 10 Nov 2026 07:24:37 GMT</pubDate></item><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Tue, 10 Nov 2026 07:23:46 GMT]]></title><description><![CDATA[<p dir="auto">很有价值的帖。楼主是否根据目前的性能，计算了下理论回本周期？我觉得应该是很有参考价值的。</p>
]]></description><link>https://lcz.me/post/32377</link><guid isPermaLink="true">https://lcz.me/post/32377</guid><dc:creator><![CDATA[kop wang]]></dc:creator><pubDate>Tue, 10 Nov 2026 07:23:46 GMT</pubDate></item><item><title><![CDATA[Reply to 3 x RTX Pro 6000D + 1 x RTX Pro 6000 跑官方 Deepseek v4.1 Flash 1017 分享 on Tue, 10 Nov 2026 04:52:08 GMT]]></title><description><![CDATA[<p dir="auto">论坛卧虎藏龙，一天内见证两例跑满血DS-V４.1-Flash-1017的Case。真是壕无人性啊。<img src="https://lcz.me/assets/plugins/nodebb-plugin-emoji/emoji/android/1f924.png?v=a055419e292" class="not-responsive emoji emoji-android emoji--drooling_face" style="height:1.4em;width:auto;vertical-align:middle" title=":drooling_face:" alt="🤤" /></p>
]]></description><link>https://lcz.me/post/32355</link><guid isPermaLink="true">https://lcz.me/post/32355</guid><dc:creator><![CDATA[xiongjie gao]]></dc:creator><pubDate>Tue, 10 Nov 2026 04:52:08 GMT</pubDate></item></channel></rss>