<?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[RTX 4090 24GB 單卡 ninfer實測]]></title><description><![CDATA[<hr />
<h2>前言：ninfer 是啥，跟別人比強在哪、殘在哪</h2>
<p dir="auto">前一陣子分享了AMD端Halogen推論引擎的性能表現，<br />
最近開始對這種專門優化的推論引擎蠻有興趣，我把手上的單卡RTX4090 24GB拿來實測，<br />
要強調的主要就是這推論框架對20~24GB的卡非常適合</p>
<p dir="auto"><strong>ninfer</strong>（<a href="https://github.com/Neroued/ninfer" rel="nofollow ugc"><code>Neroued/ninfer</code></a>，2.2k stars）是一個從零手刻的 C++/CUDA 推理引擎，專門只幹一件事：<strong>把 Qwen3.5 Dense / MoE 幾個指定 checkpoint，在單張顯卡上推到物理極限</strong>。沒有通用架構支援，沒有多卡，沒有有的沒的——一個 GPU、一個常駐模型、開機定死的 KV 池，1~8 個併發請求。</p>
<p dir="auto"><strong>它跟主流引擎的差別</strong>：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th></th>
<th>llama.cpp</th>
<th>vLLM / SGLang</th>
<th>ninfer</th>
</tr>
</thead>
<tbody>
<tr>
<td>支援模型</td>
<td>幾乎全宇宙（GGUF 生態）</td>
<td>主流開源全包</td>
<td><strong>只有 3 個</strong>：Qwen3.6-27B、Qwen3.8-27B、Qwen3.6-35B-A3B（+自轉權重）</td>
</tr>
<tr>
<td>權重格式</td>
<td>GGUF（到處都載得到）</td>
<td>Safetensors</td>
<td><strong>自有 <code>.nfer</code> 打包格式</strong>，官方 artifact Heisenberg 下載</td>
</tr>
<tr>
<td>硬體</td>
<td>CPU/GPU、多卡、offload，什麼都能跑</td>
<td>多卡、分散式、生產級調度</td>
<td><strong>單卡 only</strong>，官方只要 RTX 5090（<code>sm_120a</code>，build 直接拒絕別的架構）；4090 靠社群 port</td>
</tr>
<tr>
<td>併發</td>
<td>continuous batching 相對完整</td>
<td>連續批處理、prefix cache、前綴搶佔、QoS 全套</td>
<td><strong>1~8 請求、FIFO、無搶佔、無 QoS、無 swap、無 offload</strong></td>
</tr>
<tr>
<td>API</td>
<td>OpenAI 相容</td>
<td>OpenAI 相容</td>
<td>OpenAI Chat + Responses + Anthropic 三種，tool call 只解析不執行</td>
</tr>
<tr>
<td>多模態</td>
<td>mmproj 外掛</td>
<td>原生</td>
<td>原生（圖/多圖/影片混排，<code>--vision</code> 獨立開關）</td>
</tr>
<tr>
<td>推測解碼</td>
<td>MTP / DFlash（看版本）</td>
<td>EAGLE / MTP 等</td>
<td>MTP（1~5 draft）、DFlash（35B）、DFlash2（Qwen3.8 + companion weights，1~15 draft）</td>
</tr>
<tr>
<td>KV 精度</td>
<td>q8_0 / q4_0 等</td>
<td>fp8 等</td>
<td>BF16 / INT8 / FP8 / <strong>NVFP4</strong> / K8V4 / E8 lattice（<code>rk2v4</code> 這種 2-bit key 只有這家有）</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>一句話定位</strong>：llama.cpp 是瑞士刀（什麼模型都能跑、什麼硬體都能上），vLLM 是公車（載多人、多模型、生產調度），<strong>ninfer 是 F1——只跑一條賽道（Qwen3.5家族 + 單卡），但在這條賽道上 decode 比誰都快、同 VRAM ctx 比誰都大</strong>（本篇實測：4090 上 262K + vision，llama.cpp 同卡只能 213K）。</p>
<p dir="auto"><strong>代價</strong>：換模型要整個換（不能隨手抓個 GGUF 就跑）；併發一深就排隊（prefill 還跨 lane 互卡）；社群 port小（本文用的 4090 版），出問題自己解；DFlash2 這種新功能有版本配對失敗（v2/v3 artifact × 新舊引擎，本文實測踩過兩次啟動失敗才配對成功）。</p>
<p dir="auto"><strong>適合誰</strong>：單卡、固定一個主力模型、要長 ctx + 高速 decode 的個人/小團隊 agent 用戶。</p>
<hr />
<h2>1. 測試軟硬體配置與模型量化格式</h2>
<p dir="auto"><strong>Server</strong>：Ubuntu 26.04（kernel 7.0.0-28）、i9-14900K（32 緒）、RAM 61GB、<strong>RTX 4090 24GB</strong>（24564 MiB，driver 595.91）、Docker 29.1.3 + NVIDIA Container Toolkit。<br />
VRAM 保留：~1.3GB 我自己另外要留Embedding與Rereanker使用。</p>
<p dir="auto"><strong>三個引擎，同一個模型家族（Qwen3.8-27B），三種量化</strong>：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>引擎</th>
<th>權重</th>
<th>KV cache</th>
<th>ctx 上限（含 vision）</th>
</tr>
</thead>
<tbody>
<tr>
<td>llama.cpp（b10156）</td>
<td>Unsloth <code>UD-Q4_K_M</code> GGUF（16GB，Dynamic V3.0）+ mmproj-F16</td>
<td>q4_0</td>
<td>212992</td>
</tr>
<tr>
<td>ninfer rk4v4</td>
<td>官方 groupwise-int（Text Q4/Q5，emb+head q8，17GB）</td>
<td>rk4v4-e8（4-bit key，E8 lattice）</td>
<td>240640</td>
</tr>
<tr>
<td>ninfer rk2v4</td>
<td>同上</td>
<td>rk2v4-e8（<strong>2-bit</strong> key，E8 lattice）</td>
<td><strong>262144 原生全滿</strong></td>
</tr>
</tbody>
</table>
<p dir="auto">nfer 本體是 <code>alanthinker/ninfer-4090-yarn</code>（官方 <code>Neroued/ninfer</code> 只認 RTX 5090 <code>sm_120a</code>，4090 只能用社群 sm_89 port）。llama.cpp 側掛 froggeric chat template + MTP + reasoning-budget 2048。</p>
<h2>2. 配置流程教學</h2>
<p dir="auto">直接用docker非常簡單</p>
<pre><code class="language-bash"># 1. 拉 fork 並 Docker build（host 工具鏈缺什麼都沒關係，全在 image 裡）
git clone --depth 1 https://github.com/alanthinker/ninfer-4090-yarn.git /data/ninfer-4090
cd /data/ninfer-4090 &amp;&amp; docker build --tag ninfer-4090:sm89 .

# 2. 下權重——關鍵坑：fork 只吃 v2 artifact，main 分支現已是 v3（magic NINFER 0003）
#    且 09-06 版混了 DFlash2 companion weights（fork 會報 dflash2/feature_projection 拒載）
#    鎖定 08-14 commit（3526913004b1，magic NINFER 0002，17GB）：
curl -L -C - --fail --output models/qwen3_8_27b.ninfer \
  'https://huggingface.co/neroued/Qwen3.8-27B-NInfer/resolve/3526913004b1/qwen3_8_27b.ninfer'
xxd -l 16 models/qwen3_8_27b.ninfer   # 確認 NINFER ....0002

# 3. 起服（rk2v4 + vision + MTP3，262144 全滿版；rk4v4 把兩處數字換 240640、--kv-dtype 換 rk4v4-e8）
docker run -d --name ninfer --gpus all --publish 8080:8080 \
  --volume $PWD/models:/workspace/models:ro ninfer-4090:sm89 \
  ninfer-serve /workspace/models/qwen3_8_27b.ninfer \
  --host 0.0.0.0 --port 8080 --max-context 262144 --kv-capacity 262144 \
  --max-concurrency 1 --max-pending-requests 16 --pending-timeout-ms 600000 \
  --prefill-chunk 1024 --kv-dtype rk2v4-e8 --spec mtp --draft-tokens 3 \
  --lm-head-draft --vision --preserve-thinking
</code></pre>
<p dir="auto"><strong>ctx 定尺寸心法</strong>：server 啟動會 fail-fast，缺多少精確到 byte（實例：要 5398826240、只有 5307427328，差 87MB → 245760 降 240640 一次過）。先估大再往下收，兩次重啟內必中。OpenAI 相容端點直接沿用 <code>:8080/v1</code>，model id 填 <code>qwen3.8-27b</code>，tool calling 照走。</p>
<h2>3. 速度實測</h2>
<p dir="auto">方法：同文本（fox 重複句）、每檔冷啟動全量 prefill、decode 80 token、取 server 回報 timings。單位 tok/s。</p>
<p dir="auto"><strong>prefill</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>深度</th>
<th>llama.cpp</th>
<th>ninfer rk4v4</th>
<th>ninfer rk2v4</th>
</tr>
</thead>
<tbody>
<tr>
<td>8K</td>
<td>2660</td>
<td>2076</td>
<td>2054</td>
</tr>
<tr>
<td>32K</td>
<td>2480</td>
<td>1963</td>
<td>1906</td>
</tr>
<tr>
<td>64K</td>
<td>2180</td>
<td>1790</td>
<td>1700</td>
</tr>
<tr>
<td>128K</td>
<td>1747</td>
<td>1521</td>
<td>1397</td>
</tr>
<tr>
<td>200K</td>
<td>1427</td>
<td>1302</td>
<td>1164</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>decode（MTP 全開，KV 全駐留 at-depth）</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>深度</th>
<th>llama.cpp(Dflash2)</th>
<th>ninfer rk4v4（acceptance）</th>
<th>ninfer rk2v4</th>
</tr>
</thead>
<tbody>
<tr>
<td>8K</td>
<td>102</td>
<td>117（59%）</td>
<td>106（50%）</td>
</tr>
<tr>
<td>32K</td>
<td>74</td>
<td>132（76%）</td>
<td>125（73%）</td>
</tr>
<tr>
<td>64K</td>
<td>71</td>
<td>112（68%）</td>
<td>98（58%）</td>
</tr>
<tr>
<td>128K</td>
<td>57</td>
<td>104（69%）</td>
<td>96（65%）</td>
</tr>
<tr>
<td>200K</td>
<td>46</td>
<td>102（80%）</td>
<td>72（49%）</td>
</tr>
</tbody>
</table>
<h2>4. 速度比較：llama.cpp vs ninfer rk4v4 vs ninfer rk2v4</h2>
<ul>
<li><strong>prefill 全線 llama 贏</strong>：−22%（8K）收斂到 −9%（200K），跟 fork 自承的 16–24% 一致。單發長文問答 llama  wall-clock 最快。</li>
<li><strong>decode 全線 ninfer 贏</strong>：llama 隨深度一路掉（102→46），ninfer 全程平緩（rk4v4 最低 102）。agent 迴圈（prefill 一次、decode 幾十輪）總帳 ninfer 大勝。</li>
<li><strong>rk2v4 vs rk4v4</strong>：prefill −1~−11%（越深越虧，lattice 解碼開銷），200K decode 102→72 是最大一刀；其餘檔位 decode 只差 ~10%。</li>
<li><strong>200K+ 是 ninfer 獨佔區</strong>：llama 213K 上限實測 200K 已是極限（1427/46 且無 vision 餘裕），rk2v4 直上 262144。</li>
</ul>
<h2>5. 精準度與智商比較：rk4v4 vs rk2v4</h2>
<p dir="auto">微基準 cosine：98.678% vs 96.155%（key 方向差 ~7°）。實測四關，兩邊逐題對打：</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>關卡</th>
<th>rk4v4</th>
<th>rk2v4</th>
</tr>
</thead>
<tbody>
<tr>
<td>單針取回 100K / 200K / 258K（<code>XK-73912</code>）</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="✅" /><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>
<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="✅" /><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="✅" /><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>20 組相似代碼混淆取真（100K / 200K）</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="✅" /><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>
<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="✅" /><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>雙跳推理 150K（更名+密碼二段跳 → <code>44-Blue-19</code>）</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>
<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>工具參數精確傳遞 100K（<code>WO-2026-88471</code>）</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>
<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>五胞胎函數取號</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="❌" />（答 4）</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="❌" />（答 4，一字不差）</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>能考的格子全中</strong>，2.5% cosine 在取針、混淆、雙跳、工具四種高壓題、258K 深度下完全量不出來。</li>
<li>唯一共同翻車（五胞胎函數）兩邊錯得一模一樣——權重本體的數數極限，同權重必同錯，與 KV 無關；反而證明 rk2v4 行為與 rk4v4 逐字級一致。</li>
<li>附帶教訓：兩次「脫靶」都是 thinking 燒光 max_tokens（content 空、finish=length），不是取錯——生產環境 output 開大（16384）即避開。</li>
</ul>
<h2>6. 結論</h2>
<ul>
<li>** 262K 全滿 + vision，KV量化 rk2v4**：精準度零可觀測損失，拿 10% 速度換 22K ctx（rk4v4 卡死 240640，258K 的題連考場都進不去）。</li>
<li><strong>要每 tok 最快，KV量化用rk4v4</strong>：decode、prefill都快一截，尤其是長ctx衰退小，滿意。</li>
<li><strong>llama.cpp 留著的理由只剩一個</strong>：純prefill場景、或是需要切到其他模型。</li>
<li>**rk4v4就速度與容量最均衡，尤其是長ctx下decode明顯好過rk2v4更不用說llama.cpp、而200K下prefill也接近llama.cpp的水平，因為我有保留1.3G做另外用途，若不保留確定是262K+vision可以開到滿的。</li>
</ul>
<hr />
]]></description><link>https://lcz.me/topic/1853</link><generator>RSS for Node</generator><lastBuildDate>Fri, 25 Sep 2026 21:27:24 GMT</lastBuildDate><atom:link href="https://lcz.me/topic/1853.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 21 Sep 2026 07:09:45 GMT</pubDate><ttl>60</ttl></channel></rss>