@perter 看來成功了 有測試速度嗎
-
[實測V] 你的 Windows 預設少給你 9%:用 Strata 的人請去 log 搜 large pages! -
[實測V] 你的 Windows 預設少給你 9%:用 Strata 的人請去 log 搜 large pages!補充:方法學、被否決的參數、以及我撤回的三個結論
我怎麼排除記憶體升速的干擾
同日我把 RAM 從 4800 換到 5200,兩件事一起變,所以 5090 那組分不開。引擎在
pinned.cu:88留了一個開關STRATA_NO_LARGEPAGES=1,註解寫「same run, same boot」,所以我用閒置的 5080 跑了一次同開機、同記憶體速度、只差這個變數:大頁開 大頁關 每輪耗時 247.0 ms 358.6 ms GPU 等專家串流 187.7 290.8 CPU 專家池 37.9 40.6 prefill 1138.90 1128.99 每輪快 31.1%,差異 92% 落在「GPU 等專家串流」那項。最有力的是
pool那行:關大頁那邊每層 CPU 專家只有開那邊的三分之一(1.23 對 3.92),做少三倍的事,時間還更高(40.623 對 37.910)。而 prefill 兩邊一模一樣。prefill 是整台最吃記憶體頻寬的階段,如果 4800→5200 有實質幫助它一定動 —— 它没動。所以 5090 那 8.9% 基本全部是大頁。
限制:兩邊專家路由發散了(每層 CPU 專家 3.92 對 1.23),所以 −31% 只取方向不取倍數;而且 5080 只有 12% 專家常駐(5090 是 35%)、x4 連結、卡本身慢,都是只取方向的理由。
同一個設定的擺幅
同一個設定(spec 8、fetch 開、大頁開)一天內量五次:131.2 / 129.9 / 114.9 / 120.3 / 121.3,擺幅 11.5%。真實 agent 流量的上下文長短自己會變。所以這篇所有對比只用前後接著跑的兩組,5% 以內一律當沒發生過;跌 15% 以上的才站得住。
被否決的參數(前後接著跑)
設定 結果 請求數 --batch 4 --batch-mtp−41% 7 --pool-workers 24−24.5% 36 --spec-min-p 0.5−23% 50 --spec-split−3.5%(重疊項) 56 --lookup-chain 3−5.7% 30 --pcie-frac 0.35−0.4% 52 --suffix-draft 8−3.5% 25 --pool-workers 24值得講:log 印「24 pool workers on logical processors 2,4,...,30」,24 個 worker 只列了 15 個邏輯核心。超出核心數的 worker 不綁核,會跟做 GPU 交接的主執行緒搶位置。想加 worker 之前先確認自己的核心數。--pcie-frac從預設 0.25 提到 0.35 完全沒分別(121.3 對 120.8),接受率升 2.6 個百分點但多出來的串流成本剛好抵消 —— 平台區,作者的預設值在我這台也對,雖然我是 Gen5 x16。--spec 8對--spec 6係 +4.6%,兩個唔同記憶體條件下重複出同一個倍數。這跟 2038 §9「--spec 4才是最佳值」相反,但量化、記憶體容量、pcie_frac都變了,兩篇都別外推到對方的條件。另外kMaxT = 8是硬上限(draft_policy.hpp:24、verify_kernels.hpp:21),構造時std::clamp就夾住,所以--spec 12靜默變回 8,不報錯、不變慢,就是沒效果。我撤回的三個結論
一、
--spec-split「重疊本身賠 17.9%」。 早期量到 92.0 tok/s,對當時基準 −29.9%,我就當成重疊的鍋。後來連續跑三組設定、中間不隔時間重測才拆開:PCIe fetch 開對關 +7.3%(中位數 +18.7%),重疊開對關(fetch 都關)只有 −3.5%(中位數 −0.5%)。那個 −30% 大部分是流量自己變了。 一個看起來很紮實的 −30%,重測變成 −3.5%。順帶講為什麼我最後沒改引擎的碼:
--spec-split預設關閉並關閉 fetch 不是保守,是正確性 —— fetch 靠逐出另一個專家來收新的,逐出規則是「本視窗沒用到的才逐出」(expert_source.cpp:3390),而 split 把視窗切兩半,第一半看不到第二半需要誰。修法存在,但用上面的分解算,把 fetch 接回去也只是從落後 10% 變回打平。二、「流量擺幅只有 0.5%」。 我只看了頭兩次採樣(差 0.5%)就以爲這台很穩定,拿那個 0.5% 去判所有對比。實際擺幅 11.5%。連帶影響:
--suffix-draft 8、--lookup-chain 3、--spec 6這三項改列「還不能確定」,不是出局。三、「prefill 撞到的是電,557 W 對 600 W」。 這個是在寫這篇的過程中被推翻的。
用 1 秒取樣抓了 15 分鐘、798 個樣本(同一台 5090、同一個設定、真實流量):
指標 實測 上限 功率 中位 293.3 W 600 W 功率 p90 / p99 / 最高 452.5 / 589.6 / 592.1 W 600 W 功率超過 550 W 的樣本 76 / 798(9.5%) — GPU 使用率 >80% 時的功率中位 295.2 W 600 W 時脈 最低 / 中位 / 最高 2850 / 2902 / 2940 MHz 3090 MHz sw_power_cap亮起0 次 / 798 — hw_slowdown亮起0 次 / 798 — 形狀:功率是尖峰型的,不是平台型的。 它會瞬間衝到 592 W 貼住上限,但 GPU 忙著的時候中位數只有 295 W —— 多數時間離上限還有 300 W 的餘裕。而供電限制旗標和降速旗標,798 個樣本一次都沒亮。
所以「撞到供電牆」沒有直接證據。剩下唯一的線索是時脈:最高 2940 MHz,從來沒碰到 3090 的最大加速值。這符合供電受限的樣子,但也可能只是那 15 分鐘的溫度和負載就停在這裡。正確說法是「長 prompt 那段有一道我沒證明到的牆」,不是「供電牆」。
想自己抓一份,這條就夠:
nvidia-smi --query-gpu=timestamp,power.draw,power.limit,utilization.gpu,clocks.sm,clocks_throttle_reasons.sw_power_cap,clocks_throttle_reasons.hw_slowdown --format=csv,noheader,nounits -i 0關鍵是最後兩個
clocks_throttle_reasons.*。只看power.draw會跟我一樣,被一個尖峰騙成一堵牆。未測項目與已知限制
長 context 的品質(YaRN accuracy)完全沒測,這篇全部是速度和容量。大頁和記憶體速度沒做最嚴格分離,5080 那組是替代證據。
STRATA_ADAPT_FETCH另外兩個子參數沒測,因為--pcie-frac已經是平台區,同一條曲線上其他旋鈕大概率也在平台上。三組格式的對照不是同一時期:引擎 0.1.31→0.1.41、記憶體 61.4→192 GiB、速度 6000→4800→5200、
pcie_frac0.55→0.25、--spec4→8,而且大頁只有最後一組開了。所以那是三個完整設定的對比,不是單變量實驗;凡是我把差異歸給格式本身的地方,都是推論。流量沒按 client 分開,18081 上所有請求混在一起算。這批 98.5% 在 60K context 以上(120–200K 佔 63.6%),所以 131.5 是長上下文 agent 的數字;短 context 只有 0.4% 的樣本(10 個),方向清楚但數量不足,實測 151.8。
-
[實測V] 你的 Windows 預設少給你 9%:用 Strata 的人請去 log 搜 large pages!先給結論
- 在 Windows 上跑 Strata 的人,大概率都少了約 9% 解碼速度,而引擎在 log 里告訴你這很正常。
- prefill 不是一個數字,是一條 34 倍的曲線(231 到 7,962 tok/s),取決於你給它多少新 token,不取決於設定。
- 三種格式里,解碼最快的仍是 IQ2_XS(167.8 / 130.8 / 131.5);NVFP4 只在讀長文件時贏。
- 這批流量 98.5% 在 60K context 以上,所以 131 是長上下文 agent 的數字,不是聊天的數字(短 context 實測 151.8)。
- 方法學、七個被否決的參數、我推翻自己的三個結論,在留言區。
你今天就能做的一件事
不用改任何參數:
secpol.msc→ 本地策略 → 用戶權限分配 → 「鎖定記憶體頁」→ 加入你的帳號 → 重新登入。
去你的引擎 log 搜
large pages四個字。看到error 1314或using 4 KB pages,你就是那個少了 9% 的人。環境
項目 內容 機器 RTX 5090 32,607 MiB(Gen5 x16)· 9950X3D · 192 GB DDR5-5200 模型/引擎 Qwen3.8-Flash-Next NVFP4 pack(4.5-bit,48 層 × 512 experts)· Strata 0.1.41 · Windows 流量 真實 agent 請求 2,279 個,98.5% 在 60K context 以上,不是跑分腳本 環境變更 10/4 記憶體從 64 GB 加到 192 GB(4800 → 5200 MT/s) 原因
引擎開機配置一個 63.3 GiB 的 pinned arena 放專家權重,先試 2 MB 大頁,失敗就無聲退回 4 KB 頁。63.3 GiB 用 4 KB 頁是 1,660 萬個 TLB 項目,而專家權重是隨機跳著讀的,等於每次跳躍查一次頁表。源碼
pinned.hpp:8-14寫得很直白:「every block of every expert matvec takes TLB misses」,同一檔也把 4 KB 退回稱為「the common case and not an error path」。Linux 用MAP_HUGETLB,不需要逐帳號權限,這個坑是 Windows 獨有;repo 里兩份社群 Windows 記錄(RX 9070 XT、R9700)留著同一個error 1314,所以不止我一個。重新登入不能省:token 在登入那一刻才建立。enable 那半步不用你做,引擎在
VirtualAlloc之前自己呼叫AdjustTokenPrivileges(pinned.cu:72-84),你只需要 assign。另外三個錯誤碼源碼特意分開註解(pinned.cu:101-105),很多人撈在一起當成同一個 bug:1314 是權限未 assign、1450 是大頁池給不出連續的 2 MB 區塊(這個才需要重開機清碎片)、87 是大小不是 2 MB 的倍數。我原本以為 1450 是我沒重開機,看完源碼才知道搞錯。4 KB 頁 大頁 差 解碼平均 118.5 129.0 +8.9% 中位數 114.5 130.6 +14.1% 最慢的那 10% 94.6 109.2 +15.4% 草稿接受率 71.3% 72.8% 沒變 prefill 7,747 7,565 沒變 形狀:最慢那批改善比平均還大,正是缺頁該有的樣子;接受率沒變,所以不是投機變好,是每一輪的固定成本變低了。
prefill 不是一個數字

我原本想報「prefill 8,000 tok/s」。那個數字是真的,但會誤導:把 2,279 個真實請求按「這次要讀多少新 token」分桶,就是上面那個樣子。看到別人報 prefill 兩三千,不要以為自己設定錯了,那多數是真實流量的正常值(prompt cache 命中 91.6%,每次其實只有幾千個新 token);看到 8,000 也要先問對方拿多長的 prompt 量。想讓 prefill 快只有兩條路:每次讀多一點新 token,或者讓它命中 cache —— 我換了十幾個參數,同一個區間里一個都動不了。
到底換哪種格式?

IQ3_S 那組是 2038 留言區我補的真實流量數(11,241 個請求),條件跟這篇最接近:同一張卡、同一顆 CPU、同樣 192 GB、同樣真實流量。
一句話:輸出為主選 IQ2_XS,那兩成差距用設定補不回來(它權重小,同樣 32 GB 擺得下 16,640 個專家,NVFP4 只擺得下 8,586 個);讀長文件為主選 NVFP4,全新長 prompt 它 7,962 對 IQ2_XS 受控測 128K 全量的 4,257,快近一倍,而權重是 4.5 bit 級。
可以直接抄的設定:
--spec 8 --spec-min-p 0.7 --pool-workers 15 pcie-frac 用預設 0.25 不加 split 不加 batch GPU 0 + Windows「鎖定記憶體頁」權限這篇承接 1228 、 1462 、 1967 、 2038 。記憶體從 64 GB 加到 192 GB 之後,2038 里「61.4 GiB 是硬限制」和 parking 那些結論的前提已經失效,請把它們當成 64 GB 時代的記錄。

幫我一個忙
去你的引擎 log 搜
large pages,把結果貼上來:是error 1314、error 1450,還是resident without a lock? 加上你的卡和記憶體容量。我手上只有一份 Windows 樣本加兩份社群記錄。如果 1314 是普遍現象,這 9% 就是整個 Windows 社群一起漏掉的,值得往上游提。已經開過這個權限的人,也想知道你實測差多少。
本帖由本地全棧生成:Strata NVFP4(Qwen3.8-Flash-Next @ RTX 5090)出 token,DSH 負責讀 log、跑統計、核對數據、起草與修訂,圖由本地生成。全部數字可從引擎 log 逐項核對。有錯先係佢錯,歡迎打臉。
Tags: rtx5090 strata qwen-flash nvfp4 large-pages
-
[實測IV] Strata / Qwen3.8 Flash IQ2_XS 單卡跑到 424K 155t/s — parking 能留幾條對話:含三個不利發現@stxpnet 我在dsh上跑了上跑了一周(1/10 -6/10)高強度的用也沒發生也沒發生循環問題
現在用IQ3_S也沒問題
IQ3_S 在 DSH 上的實際平均速度
資料來源:strata-iq3_s-5090.log,涵蓋 2026-10-06 16:09 → 2026-10-09 12:52(2.85 天),11,241 個 request、12,502,938 個 generated tokens、26.56 小時的 decode 時間。
指標 值 decode(加權平均,總 token ÷ 總時間) 130.8 tok/s decode 中位數 129.4 tok/s decode 算術平均(每 request) 128.4 tok/s p10 / p90 109.7 / 146.2 tok/s min / max 7.8 / 237.2 tok/s prefill(加權平均) 2,832 tok/s 含 prefill 的端到端 113.6 tok/s 平均每 request 1,112 generated tokens,prompt 129,900 tokens prefix reuse 97.2% 的 prompt tokens 按 context 大小(加權 decode):
prompt tokens n decode 60K–100K 2,383 131.4 100K–140K 3,298 130.6 140K–170K 2,568 131.9 170K–300K 2,439 127.1 幾乎平的 —— 到 170K 以上才掉 3.3%。
跟 IQ2_XS 同一張卡、同樣真實流量的對比
strata-iq2_xs-5090-maxslot.log(10-04 → 10-07,10,153 requests、8,780,547 tokens):
IQ2_XS IQ3_S 差 decode 加權 167.8 130.8 −22.0% decode 中位 168.4 129.4 −23.2% p10 / p90 143.4 / 193.8 109.7 / 146.2 含 prefill 136.4 113.6 −16.7% prefill 2,407 2,832 +17.7%(IQ3_S 較快) prefix reuse 97.9% 97.2% 一個跟我之前 benchmark 不一致的地方(要講清楚)
我之前那輪受控測試(4,096 token 隨機 prompt、greedy、128 tokens)量到 IQ3_S 比 IQ2_XS 慢 34.4%。真實使用只有 22.0%。原因是 benchmark 用隨機 token 檔 + greedy,draft acceptance 很低(50 of 92);真實文字好預測得多,加上 97% 的 prefix reuse 讓 expert hit rate 不同。所以真實懲罰比 benchmark 小,兩個數字我都留著。
這組數字的限制
- log 是 engine 的 serve log,18081 就是 DSH 的 backend,所以這些是 DSH 打的 request;但我無法把 DSH 跟其他打同一個 port 的 client(例如 chat 網頁)分開。
- DSH 自己的 dsh-token-usage\index.json 是舊的(
writtenAt2026-08-20,而且完全沒有 strata 那列),所以無法交叉驗證。 - serve log 的行沒有時間戳,所以做不出每日分解。
- 這個窗口包含 10-06 16:09 那個 18085 實驗(短暫共存)和 10-07 16:18 用 bat 啟動的那次 —— 都算在 11,241 個 request 裡。
4/10 加ram了(64GB -> 192GB) 中間速度(3600-4800 MT/s)有浮動不太準 現在穩定在4800 MT/s

-
[實測IV] Strata / Qwen3.8 Flash IQ2_XS 單卡跑到 424K 155t/s — parking 能留幾條對話:含三個不利發現這篇是 2026-10-01/02 我跑完整個 campaign 的記錄,承接前三篇 1228、1462、1967。
問題一開始很簡單:兩張空閒的卡有沒有用。跑著跑著變成另一件事——單卡把 context 從 256K 推到 1M 時,KV pool、parking 和能同時保留的對話數量會撞到哪裡。

先給結論:256K 上,本機 Strata 與 NInfer 在無投機口徑下基本打平。真正的差別在 parking(Strata 單卡獨有)、記憶體(61.4 GiB 是硬限制)和投機窗口(
--spec 4優於--spec 8)。Phase 1–5 的數字有
summary.json、results.json、startup.txt可核對。Phase 6 是即時執行,數字來自引擎 log 原文,沒有 benchmark.py 的 artifact,下面都標明。
0. 結論

圖裡的六格是可量化的結論:256K 的 prefill、256K 的 decode、各 context 的 parking 上限、兩個 instance 的 batch wall time、available RAM、WS private。下面六條是圖表達不了、但同樣屬於這篇的結論:
- Remote expert cache 是錯誤用法。它只分配第一張卡還沒 claim 的 cold tail:一次 request 的 1,057 次 layer launch 裡 2,919 個 entry、28.5 MiB、等待 368 ms、GPU 使用率 0–12%。第一張卡已經持有約 99.4% 的 routed mass。
- KV offload 關不掉。
--kv-resident N的意義是「在 VRAM 保留 N 個 cell/QSA layer 的鏡像,其餘完整的 K/V 留在 pinned host RAM」。提高 N 不會縮小 pinned pool,只改變 VRAM mirror、streaming 命中率和 expert cache 大小。 - Parking 只支持單 GPU。
generate.cpp:1220-1223拒絕--layer-split,所以 B3 的 4,993 tok/s 與 parking 互斥。圖第 3 格的全部數字都是單卡配置。 --spec 8比--spec 4慢(§9)。每 round 多產出 token,但每秒少做 round,decode 淨輸 2–8%。引擎自己的 cost model 也算出 window 4 是 optimum。- YaRN 延伸的 quality 我沒測。1.5–4.0× factor 沒有 needle 或 perplexity 測試。這篇的長 context 數字是速度與容量,不是 accuracy。
- 跟 NInfer 比(同一張 5090,詳見 §8):Strata 能在 32 GB 卡上跑 125B-A6B 到 256K,NInfer 不能(expert 文件 34 GB 超出 VRAM,且沒有 CPU expert tier)。用本機自己的記錄、口徑對齊後:無投機 decode 兩邊基本相同(Strata 在 64K/128K/256K 略勝);真實 agent 流量 Strata 155.1 優於 NInfer MTP3 143.6、不及 DFlash2 183.4。NInfer 的優勢在小 prompt prefill、C=1–8 真 batching,和 DFlash2 這類 Strata 沒有的 drafter。
Standing config:424K +
--resident-experts+ parking 26,624 MiB / 4 slots / 1,024 MiB floor。3 條對話在滿格 context 下同時保留,prefill 是 256K 的 91–92%。
1. 環境與測法
- 卡:RTX 5090 32,607 MiB(Gen5 x16,PCIe probe 51.9–52.4 GB/s,
pcie_frac 0.55)、RTX 5080 16,303 MiB(Gen4 x4,probe 6.5 GB/s)、RTX 5060 Ti 16,311 MiB(Gen4 x4,6.5 GB/s)。 - CPU / 記憶體:Ryzen 9 9950X3D;2 × 32 GiB DDR5,實跑 6000 MT/s(G.Skill F5-6400J3239G32G,BIOS 報
ConfiguredClockSpeed 6000,Windows 可見 61.4 GiB)。沒有 ECC、沒有注冊記憶體——所有容量與帶寬的結論都受這 61.4 GiB 限制。 - SSD:模型 GGUF、pack 與 MTP draft layer 都在同一張 Samsung SSD 9100 PRO 4 TB NVMe(C:),跟 DDR5 同一個消費級平台;另有一張 GIGABYTE 1 TB NVMe(F:,IQ3 用)和 SATA 860 EVO(D:)。專家權重以 mmap 讀入,路徑是 NVMe → OS file cache(同一组 DDR5)→ PCIe → VRAM,所以 SSD 這一層跟
--resident-experts爭同一份 61.4 GiB。實測引擎 working set 約 37 GiB、系統 free RAM 只剩約 1.2 GiB——parking 的准入檢查用的就是這個 free 口徑。 - 模型:
qwen3.8-flash-next-iq2_xs(48 layers × 512 experts = 24,576 個 expert pair,native context 262,144)。12 層 QSA 持有 KV,36 層 GDN 持有 running state。 - 系統:Windows,engine 0.1.31,port 18081。
測法:
- Phase 1–5:未修改的
bench/results/2026-09-30-community-rtx-5090/benchmark.py。每次執行用新的 nonce prompt(跨執行不重用)、greedy、256 token 輸出上限、streaming、--targets 4096,32768,128000,256000 --runs 3。TTFT 與 decode 速率取自引擎/metrics的 per-request 記錄,RAM 用 Windows counter。Run-to-run 離散約 5%(256K)、15%(4K)。 - Phase 6:固定 filler prompt(12 個單字循環,實測 4.562 chars/token),每條對話用獨立 seed,一次輸入至接近 context 上限,
max_tokens 400。TTFT 由 client 的第一個 delta 計算,parking 事件讀引擎 log 原文,RAM 用Win32_OperatingSystem.FreePhysicalMemory——就是引擎准入檢查所用的同一個「free」口徑。
2. Phase 1–3:多卡
每加一張卡便损失 decode:136.7 → 120.7 → 98.9。256K 的 prefill 只有 B3 贏(4,993 對 4,079),但 B3 跟 parking 互斥。
Configs(可與
summary.json核對):# config VRAM 中的 experts 备注 A "gpu": 016,640(68%) 只有 5090,48 層 B "gpu": [0,1],--layer-split auto18,139 auto 選了 K=47(5080 只得 1 層、0.72 GiB) B2 "gpu": [0,1],--layer-split "",--expert-cache-device1 700023,920(97.3%) 5080 作為纯 remote cache B3 "gpu": [0,1],--layer-split 3624,208(98.5%) 5090 為 0–35、5080 為 36–47(6,144 slots / 8.48 GiB) C "gpu": [0,1,2],--layer-split 28,4224,576(100%) 5090 為 0–27、5080 為 28–41、5060 Ti 為 42–47 Decode tok/s(3 次的中位數):
prompt A 5090 B auto K=47 B2 remote 7000 B3 K=36 C 3-GPU 4,096 144.8 — 141.5 160.9 129.7 32,768 165.5 — 156.6 157.0 123.8 128,000 153.7 — 143.2 142.2 108.3 256,000 136.7 — — 120.7 98.9 ~31,000(probe) 173.7* 125.0 113.7 183.1 — * 第一輪 A(
2026-10-01-5090-only)在 4K/32K/128K 是 170.3 / 173.7 / 153.7;同一方法重跑(-4targets)是 144.8 / 165.5 / 153.7。4K 的離散約 15%,所以單次差異小於 10% 沒有統計意義。
Prefill tok/s / TTFT:
prompt A 5090 B3 K=36 C 3-GPU 4,096 2,857 / 1.5 s 1,893 / 2.2 s 1,278 / 3.2 s 32,768 4,187 / 7.9 s 4,136 / 8.0 s 2,298 / 14.3 s 128,000 4,257 / 30.3 s 5,017 / 25.7 s 2,886 / 44.5 s 256,000 4,079 / 63.2 s 4,993 / 51.7 s 2,773 / 92.8 s 我看到的東西:
- 256K 以下,prompt-heavy 工作的最佳配置是 B3。256K prompt 加 1–8K 輸出時整体較快;但 pure long-decode 仍然以單 5090 為佳。
- 每加一個 stage 便损失 decode:136.7 → 120.7 → 98.9。第三張卡雖然持有 100% 的 experts,卻是全部分段最差。
- Remote cache 是第二張卡的錯誤用法(
remote_experts.cpp:140-148:只分配第一張卡尚未 claim 的 pairs)——1,057 次 layer launch 裡 2,919 個 entry、28.5 MiB(unpacked 388.3 MiB)、等待 368 ms、GPU 使用率 0–12%。第一張卡已經持有熱的 68%(約 99.4% 的 routed mass)。 - 手动 split 才真正用到第二張卡。K=36 時 5080 擁有 12 層、cache 其全部 6,144 個 pairs,request 期間 GPU 使用率 38–99%,24,208/24,576(98.5%)的 experts 在 VRAM。較窄的 split 較差:auto 按预測的 window 時間選了 K=47,讓 5080 有 9.87 GiB 閒置。
- 代价是 x4 PCIe link 和每個 verify window 一次 hand-off。兩張 helper 卡 probe 為 6.5 GB/s;三個 stage 增加第二次 hand-off,所以 32K prefill 從 4,136 掉到 2,298 tok/s。
- CPU 是設計上必須工作,不是 cache miss。engine 的 idle CPU 是 0%,但 256K request 期間
strata.exe是 950–1,040%(約 10 個核心)——QSA/GDN/rope 的 host-side path,除非啟用--native-qsa、--native-gdn、--native-rope。decode 期間的 expert hit rate 測得 99.9%。 - RAM 是 256K 的真正上限。3-GPU 的 256K 執行用掉 58.9 / 61.4 GB(96%)。
- Warm-up 要算進去。啟动後第一條 request 較慢(B3 的 4K prefill 在 ladder 裡是 1,893,後续 probe 是 3,155)。
3. Phase 4:記憶體與速度 flags(同一台機器、同一條 256K request,以 B3 為主)
--mmap-experts在速度上是免費的,而且把 25.6 GiB 的 locked arena 換成可被 OS 回收的 file-backed pages。variant prefill tok/s decode tok/s TTFT available RAM strata WS WS private B3(resident arena,int8 KV) 4,945 114.8 52.2 s 3.0–3.4 GB 37.4 GB ~37 GB B3 + --kv q4_04,047 115.6 63.6 s 5.1–5.4 GB 40.0 GB 39.9 GB B3 + --mmap-experts4,850 119.4 53.2 s 3.2–3.6 GB 42.1 GB 8.0–8.2 GB A 5090 only + --resident-experts3,929 116.3 65.6 s 23.0 GB 17.8 GB 15.2 GB A 5090 only,resident arena(control) 4,079 136.7 63.2 s 未取樣 — — 三件事值得講:
--mmap-experts速度不變,但 lock 消失了:25,626 MiB 的VirtualLockarena 變成 file-backed pages(clean、可被 OS 回收)。Windows 的「available」counter 仍然偏低,因為 mapped GGUF pages 仍 resident,但它们跟 locked arena 不是一回事。--resident-experts=--mmap-experts --resident-cpu-experts+resident_pin+resident_soft+resident_headroom = 4 GiB(generate.cpp:1177-1187)。環境變量可覆盖:STRATA_RESIDENT_PIN=0、STRATA_RESIDENT_HEADROOM_GIB=N。--resident-cpu-experts要求--mmap-experts與 static--expert-profile,並且拒絕 layer split 與 remote cache(1279-1288)。--shared-expert-arena是 Linux-only,這裡用不了。
順帶一條:這就是為什麼 §1 說 SSD 那一層跟
--resident-experts爭同一份 RAM。26.6 GiB 的 parking 预算把可用 RAM 壓到 13.58 GiB,减去 4 GiB headroom 只剩 9.58 GiB,而 resident complement 需要 10.53 GiB——所以引擎報 warning、fallback 到 mmap。兩個 arm 都在這個條件下跑,所以 §9 的 A/B 仍然成立。
4. Phase 5:兩個獨立 instance(真正的 C=2)——兩次都不可行
平行效率 0.33×(C:)和 0.17×(F:)。瓶颈是 VRAM,不是磁盤帶寬。
Instance 1(5090,port 18081,
--resident-experts,16,920 slots / 23.2 GiB,15 pool workers)跟 instance 2(5080,port 18082,--mmap-experts,6,503 slots / 8.71 GiB = 26.5%,8 pool workers,無 vision),兩者 context 都是 262,144。Workload:一條 23,523-token prompt、greedy、128 輸出 token、streaming。lane TTFT total decode expert hit VRAM 5090(18081) 7.00 s 8.42 s ~90 tok/s 94.3% 31.1 GB used 5080(18082,C:) 48.55 s 53.10 s ~28 tok/s 56.9% 14.8 GB used,445 MiB free 兩條 request 的 batch:在 5090 排隊是 14.27 s,兩條 lane 平行是 42.62 s → 0.33×。
第二次我把 pack、兩個 GGUF shard 與 MTP head(72.1 GB、74 個文件)用 robocopy 複制到空閒的 F: NVMe(GIGABYTE GP-ASM2NE6100TTTD,Gen4,397 GB free),耗時 18 s(4.2 GB/s),instance 2 改讀 F:,flags 跟先前相同(
--mmap-experts、6,503 slots、262K context)。測試結束後那份複制已删除,F: 目前不含任何 Strata 文件。lane TTFT total engine prefill engine decode 5090(C:, --resident-experts)8.61 s 9.36 s 2,799 tok/s 162.3 tok/s 5080(F:, --mmap-experts)72.56 s 77.27 s 325 tok/s 26.9 tok/s 兩條 request 的 batch:排隊 12.86 s,平行 73.55 s → 0.17×。先前
版本(0.33×)之所以較快,只因為
已有 26.4 GB 的 warm standby cache,而 F: 從冷狀態開始。- 2 秒取樣:C: 讀取 0–26 MB/s(完全沒有 contention),F: 讀取 0.8–1.3 GB/s、約 70% disk time → 磁盤帶寬不是瓶颈。
- Available RAM 從 10.9 GB 掉到 0.31 GB 並維持:file-backed pages 消耗 RAM 的方式跟
相同。 - Per-token cost:5080 lane 是 3.01 ms/token prefill、19.75 ms/token decode;5090 lane 是 0.25 與 4.07 ms/token。
- 結論:第二條 lane 由 VRAM 決定。16 GB 卡需要約 7.9 GB 用於非 expert 部分,剩下 8.71 GiB 只能容納 24,576 個 expert pair 中的 26.5%;其餘 73.5% 走 mmap + CPU pool,即使 page cache 已 warm 仍需約 20 ms/token(引擎自身把 warm mmap 估為 34.78 ms/token)。第二條 262K lane 要快,必須用能容納 experts 的卡(也就是另一張 32 GB 級卡),或者用較小的模型。把文件搬到第二個 NVMe 不改變結果。
5. Phase 6:KV pool、parking 與 context ladder
能同時保留的對話:256K 4 條、384K 3 條、424K 3 條、448K 2 條、512K 以上 0 條。checkpoint 約 118 MB 跟 context 長度無關,真正的成本是 positional KV,約 17–19 KB/token。
5.1 Parking 的記憶體模型
SavedConversation複制ConversationKv(k、v、k_scale、v_scale、pooled rows;bytes()用.capacity())與ConversationCheckpoint(gdn、ple、tails、dead、block_pos):- checkpoint(running state)約 118 MB,跟 context 長度無關(
generate.cpp:804-815):36 個 GDN recurrence、conv history、per-QSA indexer tail 與 PLE history。Positional KV 不由 checkpoint 複制,它被 rewind。 - 真正的 parking 成本是 positional KV,約 17–19 KB/token(int8、12 個 QSA layer)。
- 准入规则(
generate.cpp:4009):只有needed + --conversation-cache-min-free-mib <= physically free RAM才 park。「physically free」不含 Windows standby 與 file cache。 - Parking 只支持單 GPU:
generate.cpp:1220-1223拒絕--layer-split("conversation parking does not yet support --layer-split")。所以 B3 的 4,993 tok/s 與 parking 互斥。

5.2 Context ladder(全部實測;parking budget 26,624 MiB / 4 slots / floor 1,024 MiB,256K 使用 18,432)
context YaRN factor KV pool(pinned RAM) expert cache resident arena cold prefill 相對 256K park/條 同時 parked 256K 1.0 2.32 GiB 16,982 / 22.77 GiB 通過,13.10 GiB 4,431 100% 4.20 GiB @241K 4 384K 1.5 4.64 GiB 16,815 / 22.56 通過,11.56 4,079–4,173 92–94% 6.19 GiB @380K 3 424K 1.65625 5.12 GiB 16,767 / 22.49 通過,11.52 4,010–4,083 91–92% 6.71 GiB @417K 3 432K 1.6875 5.22 GiB 16,757 / 22.47 通過,11.23 3,966–4,081 90–92% 6.82 GiB @425K 3,但需要 floor 512 448K 1.75 5.41 GiB 16,738 / 22.45 通過,11.13 3,946–4,024 89–91% 7.04 GiB @440K 2 512K 2.0 6.19 GiB 16,652 / 22.33 差 290 MiB 不通過 3,516–3,693 79–83% 需要 8,079 MiB 0(被拒) 1M 4.0 12.38 GiB 13,965 / 18.71 不通過 2,578–2,724 58–61% 需要 15,781 MiB 0(被拒) - Pool 由 boot 時可用的 RAM 決定,不由 context 固定。同一個 256K 與
--kv-resident 32768,三次 boot 報 2.32 GiB,另一次報 3.09 GiB。從 384K 往上是線性(4.64 → 5.12 → 5.22 → 5.41 → 6.19 → 12.38)。 - Arena 與 parking 爭用同一份 RAM。512K 的 log 是
resident complement 10.69 GiB exceeds available RAM (14.40 GiB) minus the 4 GiB safety headroom,所以不通過、fallback 到 mmap、page cache 消耗 RAM,parking 被拒。1M 是14.31 GiB exceeds available RAM (10.33 GiB) minus the 4 GiB headroom。 - 1M 有兩個 variant,兩者都不可行:
--kv-resident 32768(cache 15,974 / 21.44 GiB,arena 不通過:11.58 GiB 對 7.56 − 4.00)與--kv-resident 262144(cache 13,965 / 18.71 GiB,arena 不通過:14.31 對 10.33 − 4.00)。上表的 1M 列用第二個 variant。512K 也測過--kv-resident 262144,pool 仍是 6.19 GiB。


5.3 各 context 的 log 原文
- 256K(4 條 × 241K):
parked 241123 tokens ... parked=3 bytes=13536720828 evictions=0,四條全部命中,restored 241112 tokens (checkpoint) in 341.7 ms。 - 384K(3 條 × 380K):
parked=3 bytes=19918823816 evictions=0;第 4 條被拒:skip parking (need 6332 MiB plus 1024 MiB floor),當時 free 是 4,289 MiB(差 3,067 MiB)。重访是 2.38 / 1.90 / 2.15 s 命中,第 4 條 MISS(91.4 s 重新 prefill)。 - 424K(3 條 × 417K,默認 floor 1,024 MiB):沒有 skip 記錄;
parked 417308 tokens ... bytes=7205814172、restored 416901 tokens (checkpoint) ... parked=2 bytes=20781436496(live 6.36 GB + 2 × 7.21 GB,即 3 條在 pool 中)。重访是 4.63 / 2.24 / 2.38 s 命中;decode 是 174.8 / 196.9 / 196.0 tok/s(accepted 299–300 / 400)。 - 432K(3 條 × 425K):floor 1,024 MiB 時第 3 條被拒:
need 6986 MiB plus 1024 MiB floor,free 是 7,727 MiB(差 283 MiB)。改成 floor 512 MiB 後,同一组對話 3 條全部 park,重访是 4.72 / 2.19 / 2.30 s 命中,結束時 free 是 1,774 MiB。 - 448K(2 條 × 440K):
bytes=7557571128(每條 7.04 GiB)、evictions=0、重访 4.68 / 2.56 s 命中;第 3 條需要 8.0 GB,而 free 只有 7.8 GB。 - 512K / 1M:parking 被拒(
need 8079 MiB plus 1024 MiB floor、need 15781 MiB plus 1024 MiB floor)。同一條對話的連续 turn 仍可通過 live checkpoint chain 重用(512K:TTFT 1.41 s、prefill 55 ms),但換對話便要重新 prefill(512K 的 A/B 交錯 → MISS、137 s;1M 命中 107.8 tok/s、cold 61.7 tok/s)。
6. 三個不利但重要的發現
縮短對話換不到第 4 個 slot;424K × 3 耗尽 headroom;slots 與 bytes 是兩件事。
1. 縮短對話無法換取第 4 個 slot。
380K、340K、330K 三次測試,3 條 park 完成後的 free RAM 都約 5.6 GB(4,289 / 5,585 / 5,615 MiB),第 4 條每次都差 1.0–3.0 GiB。省下來的 RAM 進入 file cache,而准入檢查只計 physically free RAM。要保留 4 條必須實際增加 RAM,或者接受 floor 接近 0(也就是沒有安全邊際)。

2. 424K × 3 會耗尽 headroom。
3 條 park 後 free 只剩 2.5 GB。當同時存在另一條 live 對話(真實 agent 流量,prompt 83–90K、hit rate 98%)時,RAM 達到 54.6 / 61.4 GiB,restore 從 1.4 s 變成 25.9–27.0 s(
restored 416901 tokens (checkpoint) in 25918.3 ms)。「可保留 3 條」和「hit path 仍然快」是兩件事。
機制尚未證明(最可能是 parked blob 需經 page cache),但觀察是實測。
3. Slots 與 bytes 是兩件事。
上面的上限指「每條對話接近完整 context」。同一個 424K config 在真實 agent 流量下,4 條 118–138K token 的對話可同時 parked(
parked=4 bytes=20315885712、evictions=0),第 5 條才觸發一次 eviction(evictions=1)。所以「424K 可保留 3 條」指 3 條接近滿滿;如果每條約 130K,4 個 slot 仍可使用。
7. 配置建議(整個 campaign)
要 4 條就留在 256K;要 3 條就 424K。prefill 為主且不需要 parking 才用 B3。
- 長 context 且同時保留 3 條對話:424K(
--max-context 434176 --rope-scaling yarn --rope-scale 1.65625)加--conversation-cache-mib 26624 --conversation-cache-slots 4 --conversation-cache-min-free-mib 1024。這是目前的 standing config。 - 需要 4 條:維持 256K(每條 4.20 GiB,mib ≥ 18,432)。
- 需要 432K 以上:432K 需要 floor 512;448K 只能 2 條;512K 需要 96 GB RAM 才有 headroom。
- 如果 prefill 是主要工作(單次 256K prompt、不需要 parking):B3
--layer-split 36,4,993 tok/s / TTFT 51.7 s。但它與 parking 互斥。 - 投機窗口:
--spec 4(§9)。--spec 8沒有數據支持。 - RAM budget:兩條 262K instance 約需 57 GB → 64 GB 是 practical floor,96 GB 較充裕,128 GB 有餘裕。
8. Strata 對 NInfer(同一台機器,全部用本機實測過的數字)

這一節第一版我寫錯了兩次:用了官方表,又把 Strata 含投機的 decode 直接對 NInfer 的 MTP0 列。下面全部改用本機自己的記錄——前三篇 1228、1462、1967 和本地 campaign 記錄(
out/campaign_0902_mirror/、out/dflash3/campaign/、out/dflash3/campaign_v4/),並且把投機與否分開算。8.1 真實 agent 流量(同一台機器、同一類工作、兩邊都開投機)
NInfer MTP3 era NInfer DFlash2 K=7 era Strata --spec 4期間 / 樣本 09-04 → 09-07,12,479 req 09-07 → 09-08,5,879 req 10-01 → 10-02,282 個 agent request(prompt ≥30K) prompt 中位 72,062 72,492 167,244 cache 命中 79.8%(加權)/ 97–99%(per req) 82.3% / 97–99% 98.9%(per req) decode 中位 143.6 183.4 155.1 decode p95 / max 192.1 / 342.9 282 / 436.9 191.9 / 216.7 acceptance(加權) 60.7% 33.0% 77.5% tokens/round 2.82 3.31 3.07 並發 C=3(真 batching) C=3 C=1(一次一個 request) 口徑相同時 Strata 155.1 介於 NInfer 兩代之間:優於 MTP3(+8.0%),不及 DFlash2(−15.4%)。
但 NInfer 那兩栏是 C=3 真 batching,Strata 是單 request 一條 lane。所以這裡比的是單條 lane 的 per-request 速度,不是吞吐。
另外 Strata 的 prompt 中位數(167K)比 NInfer(72K)大得多,樣本也小得多(282 對 12,479)。這一點我要講清楚,不然數字會誤導。
8.2 無投機口徑(prompt 長度對齊)
prompt Strata(無投機等价,下限) NInfer MTP0(09-02 本地 run) 8K 61.1 69.3 64K 69.8 63.7 128K 62.0 58.5 256K 55.5 50.3 Strata 那一列不是我直接量的。引擎在 native (IQ) pack 上拒絕
--spec < 2(generate.cpp:1738-1743、generate.cpp:3611),所以 Strata 沒有真正的 MTP0 數字。它由 log 中每個 request 的投機統計推算:rounds = 生成 token − 被接受 draft,round rate = rounds ÷ decode 時間。因為 verify window 比單 token 前推更贵(suffix_drafter_test.cpp:3:每 token 約多 10 ms),這個數是下限。口徑對齊後兩邊基本相同,Strata 在 64K/128K/256K 略勝。原本「NInfer decode 快 1.6 倍」是口徑不對齊造成的。
8.3 Prefill(不受投機影響)
prompt Strata NInfer(post 1462 solo prefill,本機) NInfer(09-02 本地 MTP0 run) 4K / 8K 2,857(4,096) — 8,621(7,680) 32K / 47K 4,187(32,768) 6,004(47k) 5,316(64,512) 105K / 128K 4,257(128,000) 4,096(105k) 3,635(130,048) 143K / 157K — 3,403 / 3,174 — 210K / 256K 4,079(256,000) 2,587(210k) 2,224(260,096) 小 prompt 的差距(3–6 倍)是真實的:Strata 的 prefill 受 PCIe expert streaming 限制(probe 52 GB/s、
pcie_frac 0.55)。但到 105K 以上兩者已經接近甚至反轉(Strata 4,257 對 NInfer 4,096;256K 4,079 對 2,224)。TTFT 也一樣:NInfer 09-02 run 在 128K/256K 是 35.8 / 117.0 s,Strata 是 30.3 / 63.2 s。只有 8K 時 NInfer 更快(0.90 s 對 1.5 s)。
8.4 DFlash
Strata 沒有 DFlash 等价。它的投機是 MTP window 加 suffix lookup(
--suffix-draft 3、--mtp-max-t)。NInfer 的 DFlash2 是 5 層 draft(約 1.6B 參數),每 round draft 7 token 再 verify;本機實測 K=7 C=1 corpus 198.7 tok/s、acceptance 36.6%、每 round 3.31 token(post 1967)。Strata 的 MTP+lookup 每 round 3.07 token(真實流量加權),量級接近 MTP3(2.82),達不到 DFlash2 的 3.31–6.5。架構上的分別:NInfer 支持 C=1–8 真 batching 與 context cache(prefix reuse、anchors、host KV tier);Strata 的 serve 一次只處理一個 request,跨對話重用要靠 parking,而 parking 只支持單 GPU。NInfer 跑不了 IQ2_XS(expert 文件 34 GB 超出 32 GiB VRAM,且沒有 CPU expert tier)——這裡是引擎對引擎,不是同一個 model。
9. 投機窗口:
--spec 4對--spec 8(實測 A/B)同一台機器、同一個配置、同一方法,只改
--spec。
--spec 8贏在每 round 的 token 數,輸在每秒的 round 數——淨結果是 decode 慢 2–8%。prompt spec 4 decode spec 8 decode Δ tokens/round(4 → 8) round/s(4 → 8) 4K 148.9 145.2 −2.5% 2.44 → 3.01 61.1 → 48.2 32K 165.0 151.3 −8.3% 2.53 → 2.84 65.1 → 53.2 128K 146.0 142.8 −2.2% 2.53 → 2.88 57.6 → 49.6 256K 127.8 124.0 −3.0% 2.35 → 2.81 54.4 → 44.1 兩邊都是 3 runs 取中位數、同一配置(424K + parking 26,624 MiB / 4 slots / 1,024 MiB floor)、同一
--spec-min-p 0.5。
4K 的第一輪是冷 cache(prefill 536 / 544 tok/s),中位數不受它影響。為什麼輸
接受率下降:spec 4 是 65–72%,spec 8 是 46–65%。窗口越深,條件接受率越低——第 4 個 draft 之後的 token 不值得 verify。
spec 8 每 round 多產出 0.4–0.6 個 token,但每秒少做 12–17 個 round。
多出來的 draft 要付 verify 時間,換回的 accepted token 抵不上成本。這個結果跟引擎自己的 cost model 吻合。
controller.hpp的常數(2026-09-23 三場測量)在 0.86 prior 下算出 optimum 是 k=3 drafts(window 4),也就是--spec 4;用draft_policy_test.cpp那條實測 cost 曲線(19.0 + 10.5·(t−1) ms)算,optimum 是 k=2–3。而 log 顯示 spec 4 實際使用的窗口是 2.2 drafts/round——policy 自己選的就是 optimum。spec 8 把 cap 抬到 8,policy 開始 over-draft。--spec的硬上限是 8(kVerifyMaxT)。--spec 4實際 effective cap 是 6(--suffix-draft 3加 2),MTP window 上限 4;--spec 8是 cap 8、MTP window 8。所以:
--spec 4是這台機器的最佳值,--spec 8沒有數據支持。 想再往上只有靠 lookup window,而 policy 已經逐 case 自己選。
10. 沒測和沒做完的
- IQ3(
ISTA-DASLab/Qwen3.8-Flash-Next-GSQ-RCO-GGUF)的速度 A/B(5090-only 與 5090+5080 K=36 兩個 config)還沒跑。文件已下載完成,四份都跟 HF API 逐 byte 核對:IQ3_S 54,817,524,224 / 28,800,138,432;IQ3_XXS 47,039,860,096 / 28,800,138,432。 - YaRN 延伸的 quality 我沒測。1.5–4.0× factor 完全沒有 needle 或 perplexity 測試。這篇所有長 context 數字是速度與容量,不是 accuracy。
- 沒試的 candidates:
--kv k8v4(816 對 1,056 B/cell,不能與--kv-resident並用)、--kv-resident的 cell 數、--expert-cache-per-layer(參考測量的 2.97% → 21.4% hits at 8K)、--prefill CHUNK(auto = 8192)、--ple-io mmap|ram、--pool-workers/--no-host-worker,以及 MTP knobs(--mtp-max-t、--spec-min-p、--suffix-draft;--spec已測,見 §9)。 --shared-expert-arena(Linux-only)沒試。
11. 複現
Phase 1–5:
benchmark.py --targets 4096,32768,128000,256000 --runs 3,每個 config 一份config-used.json、metrics.json、summary.json、results.json、raw per-request JSON 與startup.txt。Phase 6:改
--max-context與--rope-scaling yarn --rope-scale <factor>,boot 後發送 3–4 條接近上限的獨立對話,看引擎 log 的conversation cache:記錄(parked=N bytes=B evictions=E、skip parking (physical RAM admission; need X MiB plus Y MiB floor))與/metrics的conversation_cache_mib / slots / min_free_mib。准入檢查用的「free」跟FreePhysicalMemory是同一口徑,差額可直接核對。Phase 8(§9):同一 config 跑兩次,只改
--spec,artifacts 在2026-10-02-spec8/與2026-10-02-spec4/。Artifacts:
2026-10-01-5090-only/、-5090-only-4targets/、-5090plus5080/、-5090plus5080-remotecache/、-layersplit-K36/、-layersplit-K36-256k/、-layersplit-K36-256k-r3/、-3gpu-K28-42/、-memctl-B3/、-kvq4-B3-256k/、-mmapexperts-B3-256k/、-residentexperts-A-256k/。Phase 6 沒有 artifact 目錄(即時執行,僅有引擎 log)。
12. 參考
- 前三篇(同一台機器,NInfer):1228、1462、1967
- Strata:https://github.com/Niko1221/Strata
-
Qwen3.8-27B RTX 5090 DFlash2 滿載實測 III三篇其實係同一顆卡(5090 32G)× 同一個模型(Qwen3.8-27B)嘅三個階段,headline 速度口徑都唔同,整合成對比:
帖 KV / Spec 配置 Headline 速度 口徑 1228(I) int8 KV,MTP3 C=4 461.1 tok/s(C=8 766.6) 飽和 decode(single-request corpus) 1462(II) 全 nvfp4,MTP3 C=3 @ 105K(450K pool、419K 全上卡零 offload) 每路 146 t/s 3 並發真實 session(256-token 短輸出;長輸出 155–419) 1967(III) nvfp4,DFlash2 K=7 C=4 @ 262K 517.7 tok/s(C=1 198.7 / C=8 243.2) 75-request 混合 corpus 演進:I 係 int8 KV + MTP3(結論:agent 負載 98.6% 係 prefill、最佳 C=2);II 換咗
--kv-dtype nvfp4(pool 262K → 450K);III 用 DFlash2 K=7 取代 MTP3(acceptance 同速度嘅取捨)。三個數字口徑唔同(飽和 decode / 每路 session / corpus makespan),唔可以直接比大小——可比嘅係方向:同一顆卡,由 int8 + MTP3 年代走到 nvfp4 + DFlash2 年代。 -
Qwen3.8-27B RTX 5090 DFlash2 滿載實測 III0. 先給結論
問題 答案 證據 最佳 K? K=7(C=1–4 全部);C=8 例外,K=3 贏 K×C 15 點全矩陣;acceptance 與速度反相關 官方預設 K=7 差嗎? 就是最優:517.7 @ C=4 K=15 在每個 C 都輸(−10.6% ~ −17.8%) acceptance 低是否一定慢? 不是,完全相反 K=3 acceptance 61% 但 K=7 36% 更快;int8 那輪(v3)K=1 81.3% 是最慢(128.5) 最佳 C? C=4:517.7 tok/s = 2.6× C=1 K=7、ctx 262,144;C=8 反而崩到 243.2 max-context @ 每個 C? C=1–4:262,144(256K 全上);C=8:131,072(K=3/7)/ 122,880(K=15,131,072 planning OOM,見 §6) boot probe 實測;int8 C=8(K=7)只是 65,536(2× 差) 加 --vision 之後 max-context? C=3+vision:239,616(262,144 差 406,210,816 B;240,640 差 9,845,248 B) 09-11 planning probe;vision 固定 allocation ~406 MB、與 ctx 線性無關(slope 18,432.2 B/ctx 與 v4b 一致) C=8 是否 8 路? 陷阱:avg batch 1.26–2.28,Σqueue 10K–18K s 對照 C=4:avg batch 3.44、Σqueue 2 s K=15 × C=8? 131,072 無法 boot(planning OOM 差 139 MiB);122,880 可以 reservation 8.54 GB + 1 GiB headroom > 9.47 GB 可用(差 145,308,672 B) context 尺寸影響速度嗎? 影響(int8 era:131K 194.9 vs 65K 225.6 tok/s,−13.6%);nvfp4 下 C≤4 直接全 256K,這個 knob 變成「C 取捨 memory」 int8 那輪(v3)同 seed 70/75 輸出逐 token 相同 一句話:production nvfp4 KV 下面,這個 stage 的 DFlash2 sweet spot 是 K=7、C=4、ctx 262,144:517.7 tok/s,官方單 request anchor(192.5)的 2.7 倍。 四個 structural finding:(1)K=7 在 C≤4 全部最優,K=15 在每個 C 都輸——int8 那輪(v3)C=1 131K 時 K=15 仍是 +2.2% 贏,nvfp4 262K 下 ranking 翻轉,更長 draft window 的成本在更大 arena / 更大 ctx 下被放大;(2)C=4 是 frontier,C=8 在任何 KV dtype 都是陷阱——auto KV cap 只有 ~1.0–1.1× full request,表面 8 路、實際 1–2 路;(3)KV dtype 決定 boot 邊界:同樣 C=8(K=7),int8 65,536 → nvfp4 131,072,「64K 太少」不是硬件牆,是 dtype × C 的組合結果。(4)--vision 帶走 ~406 MB ctx-independent 固定 reservation:C=3 + vision 的 ctx 上限是 239,616 不是 262,144——production serve 09-11 起就是這個配置。


1. Serve 數據摘要(09-07 → 09-27 19:38)
serve log 全期(09-07 → 09-27 19:38):131,276+ 完成請求、131 次 engine start / 94 次 graceful stop / 32 次 startup FATAL,全部有診斷(逐日拆開見 §7)。

這是這顆 serve 的真實 production 流量:DSH agent session(寫這個 post 的 agent 就是其中之一:多輪 context、tool-call loop、圖片、256K 長 context)+ 09-19 → 09-22 的合成 training-data 生成 batch(~99.9K 請求、佔總量 76%)。逐日拆開見 §7。
serve 配置喺呢期經歷過多次變換(int8 → nvfp4 KV、MTP3/DFlash2 spec 切換、多輪 ctx boot probe——spec 逐日拆開見 §7);而家 production 配置係 C=3 @ 239,616 vision-enabled(boot 邊界推導見 §6)。
2. 測試方法
II 篇是 nvfp4 pool、419K 全上卡、C=3、MTP3 約 146 tok/s;本篇直接回答 deployment 三連問:K 應該設多少、C 應該開多少、max-context 與 C 如何取捨。
本篇有兩 campaign:v3(8 點,int8 KV,目的是量測 memory boot 邊界和 context 尺寸成本——現在降級為參考數據)和 v4(15 點,nvfp4 KV = production dtype,K∈{3,7,15} × C∈{1,2,3,4,8} 全矩陣)。v4b 不是第三輪——v4 中途更換了 serve instance,最後的 K=15×C=8 補測(122,880)和 boot probe 在第二個 instance(v4b)上完成,同一輪矩陣、同一套數據。為什麼 v3 的 int8 數字要重做:production live serve 跑 nvfp4 KV,KV bytes 減半、boot 邊界翻倍,int8 數字對 deployment 無參考價值——v3 整個 campaign 都是因為 harness hardcode 了
--kv-dtype int8才變成 int8,已修復(§12)。所有 point 是 current-stage build、同一個 75-request corpus、同一顆 RTX 5090。原始數據在
out/dflash3/campaign/(v3)和out/dflash3/campaign_v4/(v4,summary.json為 authoritative 數據源,server request log 逐 request)。- RTX 5090 32GB,single GPU;artifact:
qwen3_8_27b_nvfp4.ninfer(09-10 campaign 時 21.4 GiB;09-27 現在 23.7 GiB)。 - 15 fixtures × 5 seeds = 75 requests,shuffle seed
20260811(75 個 request 里 15 個是 AIME long-decode:5×aime15、5×aime30、5×aime01,其餘 60 個是 structured/code/translation/reasoning/story)。 - stochastic(temp 0.6 / top-p 0.95 / top-k 20 / presence 1.0)、KV capacity auto、prefill chunk 1024、nvfp4 KV(production dtype)、no-prefix-reuse、startup-fixed concurrency 1–8。
- v4 矩陣(15 點):K∈{3,7,15} × C∈{1,2,3,4,8},每個 point 跑在該 C 最大可 boot 的 context(C=1–4:262,144;C=8:131,072;唯一例外 K=15×C=8:122,880,因為 131,072 startup planning OOM,見 §6)。2026-09-10 11:56 → 21:14 HKT(14 點)+ 21:59 → 22:56(K=15 C=8 降 ctx 補測)。
- v3(8 點,int8 KV 參考):K-sweep(C=1, ctx 131,072;K=1/3/7/15)+ C-sweep(K=7, ctx 65,536;C=1/2/4/8)+ C=8 boot probe。09-09 22:14 → 09-10 07:07 HKT。
- 每個 point 完整 75/75 requests;makespan = 最後一個 request finish 的 full interval;decode tok/s = 總 decode tokens ÷ makespan。
官方 K=7 C=1:
weights makespan corpus decode acceptance nvfp4 3,611.5s 192.5 tok/s 37.0% groupwise-int 5,181.5s 147.0 tok/s 39.2% 本 build 重驗 K=7 C=1(nvfp4 KV、ctx 262,144、75/75 完整 corpus,v4 2026-09-10):makespan 3,567.3s、corpus decode 198.7 tok/s(708,973 tok / 3,567.3s)、acceptance 36.6%——與官方 anchor 192.5 偏差 +3.2%(v3 int8 重驗是 194.9 tok/s / 37.0%,+1.3%——兩種 KV dtype 在 C=1 相差 <3%)。分 workload(nvfp4 C=1 262K):
workload decode tok/s acceptance tokens/round structured 359.4 74.3% 6.20 code 275.1 53.3% 4.73 translation 247.2 46.2% 4.23 reasoning 195.6 36.3% 3.54 story 123.3 16.0% 2.12 3. Acceptance paradox

nvfp4 單 request:
workload MTP3 DFlash2 K7 delta AIME01 195.2 321.1 +64.5% Code 194.3 265.5 +36.6% Translation 192.3 255.9 +33.1% Structured 219.8 356.8 +62.3% Story 126.1 121.3 -3.8% acceptance 是 draft position 中多少,不是一 round 產生多少。DFlash2 在 AIME15 只有 35.2% acceptance,但仍有 3.47 tokens/round;所以要同時報 acceptance、tokens/round 和 decode tok/s。
- crossover 是 workload-dependent(回應 §10 1870 那個 271.7):Story 對 MTP3 −3.8%(基本打和、微負),其餘四個 workload 全部明顯贏(+33.1% ~ +64.5%)、corpus 整體(C=1 262K 重驗)+27.9%。選 spec 看 workload 分佈,不是 spec 名。
4. K sweep:哪個 K 是 sweet spot?
v4 nvfp4、per-C max context(C=1–4:262K;C=8:131K,K=15 是 120K)、75-request corpus、2026-09-10 11:56 → 22:56 HKT:
K C=1 C=2 C=3 C=4 C=8 acceptance 1* 128.5 — — — — 81.3% 3 165.9 299.9 403.4 496.1 339.9 60.4–62.7% 7(官方預設) 198.7 345.3 458.6 517.7 243.2 36.1–37.3% 15 177.6 283.9 398.2 453.4 210.9 18.1–19.2% * K=1 是 v3 era 唯一的 C=1 @ 131K int8 點(K floor 結論仍然成立;v4 不重跑 K=1)。

- 速度 floor 在 K≥3 出現:K=3/7/15 在每個 C 都 ≥165.9 tok/s;K=1 只是 1.81 tokens/round(fill 不滿每 round 的 verify 成本),128.5 tok/s 跌出 floor。
- acceptance 與速度在 K sweep 里反相關:acceptance 由 61–63% 跌到 18–19%,decode 速度不跌反升(C=1–4 下)。DFlash2 的 verify 很平(一次 fused round 驗完整條 window),「草稿長但中少」仍然贏「草稿短但中多」。
- K=7 在每個 C≤4 最優(198.7 / 345.3 / 458.6 / 517.7);K=15 在每個 C 都輸:C=1 −10.6%、C=2 −17.8%、C=3 −13.2%、C=4 −12.4%、C=8 −13.3%。注意與 v3 的差異:v3 int8 C=1 131K 下 K=15 仍是 +2.2% 贏 K=7——ranking 隨 KV dtype + ctx 翻轉,更大 arena / 更大 ctx 放大了長 draft window 的每 round 成本。
- C=8 例外:K=3 贏(339.9 vs 243.2 vs 210.9,K=3 比 K=7 快 +39.8%)。KV starvation 下 acceptance 決定 request 多快讓位:K=3 每 request 佔用 KV 時間短,queue 轉得快。
- 回應論壇 K∈{2,4,6,8} 的問題:1870 與論壇討論一直問「even-K grid 是否更好?」——本篇 K×C 15 點矩陣就是那個問題的 systematized answer:K=7 在每個 C 都贏(C=1–4:198.7 / 345.3 / 458.6 / 517.7;C=8 例外 K=3 339.9)。{2,4,6,8} grid 不在矩陣里,但 acceptance
速度反相關(K=3 60–63% → K=15 18–19%、decode 速度不跌反升)顯示 K=7 附近每 round verify 成本最平——「草稿稍長、命中率稍低」淨效果仍然贏。 - 誠實 caveat:stochastic sampling 使各 K 的總 tokens 不完全一樣(704K–752K),K=7 vs K=15 的差值是下界估計;K=1 行是 int8 數據。
5. C sweep:DFlash2 會不會 scale?
K=7、v4 nvfp4、75-request corpus、2026-09-10 實測(DFlash2 C>1 是官方未發布,這是本篇最大新數據):
C decode tok/s makespan s ctx auto KV cap avg batch 最長 request s 1 198.7 3,567 262,144 262,144 1.00 352 2 345.3 2,117 262,144 365,312 1.95 404 3 458.6 1,640 262,144 326,336 2.87 441 4 517.7 1,360 262,144 287,296 3.44 498 8 243.2 2,979 131,072 131,264 1.29 1,844 
- C=1→C=2 +73.8%、C=2→C=3 +32.8%、C=3→C=4 +12.9%、C=4→C=8 −53.0%。 DFlash2 有真 batch scaling,但在 32GB 5090 上 C=4 就是 frontier,C=8 是崩。
- 對照 current build MTP3 nvfp4 重驗(155.3 / 279.6 / 403.1 / 419.0 @ C=1/2/4/8):DFlash2 K=7 在 C=1/2/4 全部贏 MTP3:+27.9% / +23.5% / +28.4%;C=8 DFlash2 243.2 輸 MTP3 419.0 達 −41.9%。MTP3 每次 draft 1 token、不需要 per-request 7-token draft window 的 KV,KV starvation 到不了它;DFlash2 的 window 要為每個 request 預留整條 window。
- production 配置 C=3:458.6 tok/s(K=7 @ 262K text mode);09-11 起 live serve 轉 vision-enabled(C=3 @ 239,616 + --vision,見 §6),現在 instance pid 90317(09-27 19:35 重啟,見 §1)。
- 機制:C 越大,CUDA graph 預算(batch 1..C 逐個 capture)吃掉越多 memory,auto KV cap 越小:C=2 365,312(1.39× ctx)、C=4 287,296(1.10×)、C=8 131,264(1.00×——連 1 個 full 128K request 都只是剛剛夠)。C=8 那三個 run 實際上是「8 路表面、1–2 路真實」(avg batch 1.26–2.28;server request log 逐 request queue_wait:C=8 Σ 9,968–17,941 s、最長單個 755–1,919 s;對照 C=4 Σ queue 2 s)。
- context 尺寸的隱性成本(v3 int8 era):C=1@65K 225.6 vs C=1@131K 194.9 = +15.7%。兩度跑同一個 seed,70/75 個 request 輸出完全一樣——唯一差異是 5 個 aime15 被 65K ctx 截短。即 ~99.8% 相同的 work 下,2 倍大的 KV arena 本身就是 ~15.7% 的成本(paged KV attention 對 arena 尺寸的邊際成本 + 更大 context window 的 CUDA graph capture;此處未做消融,是觀察不是因果)。nvfp4 下 C≤4 可以直接全 262K,這個 knob 不再是「context 尺寸」而是「C 取捨 memory」——但 arena 成本的方向不變。
6. max-context × max-C:每個 C 多高的 context 才能 boot?
v4 nvfp4 boot probe(2026-09-10 11:55–11:56 和 v4b 21:59–22:00 HKT):
C max ctx(nvfp4 實測) int8 對照(v3) 1 262,144 131,072(K-sweep ctx) 2 262,144 — 3 262,144 —(v3 無 int8 C=3 點;live serve 向來就是 nvfp4 @ 262K) 4 262,144 — 8(K=3/7) 131,072 65,536(8 個 probe 實測邊界) 8(K=15) 122,880 —(131,072 planning OOM) - KV dtype 決定邊界:C=8 下 int8 KV 65,536 → nvfp4 KV 131,072,翻倍。64K 從來不是硬件牆,是 (C, KV dtype) 組合的結果。C≤4 在 nvfp4 下直接 boot 到全 262,144(v3 int8 C=1 只測到 131K,無更高 probe)。
- K=15 × C=8 @ 131,072 startup planning OOM(v4b 21:59 實測):
minimum Engine runtime reservation requires 8,541,422,080 bytes in addition to 1,073,741,824 bytes of headroom, but only 9,469,855,232 bytes are available after weights——差 145,308,672 B(≈139 MiB)。降 ctx 到 122,880 就 FIT(auto KV cap 123,136),55 分鐘後(22:00 → 22:56 HKT)15/15 矩陣齊。機制:planning reservation 隨 ctx 線性增(int8 C=8 probe 斜率 33.0 KiB/ctx;nvfp4 ≈ 18.0 KiB/ctx,與 KV bytes 減半一致),K=15 比 K=7 多 ~143 MiB draft-state reservation,而 K=7 @ 131,072 扣完 1 GiB headroom 只剩 4,678,912 B(~4.5 MiB)slack——所以 K=7 擦邊通過、K=15 差 139 MiB 死在 planning。 - 對照:同一顆 32GB 卡,live serve 用 C=3 @ 262,144 正常 boot(text mode)。即 concurrency 與 context 的取捨是 hard reservation,不是 soft pressure——C=3 × 262K 活得過,C=8 × 131K(K=15)死在 startup。
- --vision 再切走 ~406 MB(09-11 實測):C=3、K=7、nvfp4 下 262,144 + --vision planning FATAL——reservation 8,506,604,800 + 1 GiB headroom > 9,174,135,808 可用,差 406,210,816 B(≈387 MiB);
--media-cache-mib 256 --media-live-mib 512完全不減少 planning reservation(實測同一個數)。由大 ctx 逐檔 probe:240,640 FATAL(reservation 8,110,239,232,差 9,845,248 B ≈ 9.4 MiB)、239,616 FIT(slack ~4.5 MiB)→ C=3 + vision 的上限是 239,616(91% 256K)。slope 核實:(8,506,604,800 − 8,110,239,232) / (262,144 − 240,640) = 18,432.2 B/ctx——與 v4b 測得的 nvfp4 slope(18,432.5)一致,即 vision 固定部分與 ctx 完全無關。production serve 09-11 起就是這個配置(C=3 @ 239,616 + --vision + media 256/512 MiB),現在(09-27 19:35 重啟、pid 90317)仍然是。 - 而 C=8 @ 131K 本身就是陷阱(nvfp4 版)。auto KV cap 131,264 ≈ 1.00× full 128K request——與 int8 65K era 的 71,616(1.09×)一樣,C=8 在這顆卡上永遠只能裝下 ~1 個 full request。server request log 逐 request 證據(v4 nvfp4):
- 短 requests(<1.5K output tokens,C=1 時 ~4s decode):C=8 下它們的最長排隊達到 755 / 1,376 / 1,919 s(K=3/7/15)。K=15 C=8 有 5 個 <1.5K token 的 request 排隊 >300 s(K=3 也是 5 個、K=7 有 2 個)。
- 長 AIME requests(65,536 token output limit):真出到 65K output 的那幾個,排隊 127–615(K=3)/ 820–1,334(K=7)/ 860–1,504(K=15)s 之後獨佔 422–458 / 335–366 / 399–428 s decode。最長單一 request 1,073 / 1,844 / 2,141 s(K=3/7/15)——大部分是排隊(K=7 最長那個:queue 1,651 s + decode 193 s)。
- 對照 C=4(同一 workload、同一 seed):Σqueue 2 s、最長 0.2 s、avg batch 3.44——完全不堵。C=8:Σqueue 9,968(K=3)/ 15,679(K=7)/ 17,941(K=15)s,avg batch 2.28 / 1.29 / 1.26。
- v4 全部 15 點 零
context_capacitytruncation(finish_reason 全部 stop_token / output_limit)——C=8 的痛點是純 queue,不是容量截斷;v3 int8 C=8 當時有 6 個 request 被context_capacity截斷(全部是 AIME 65K-output limit requests)。
- Deployment implication:8 路 full 128K 要 8 × 131,072 = 1,048,576 tokens ≈ 7.99× 現 cap——這不是 context 尺寸能 fix 的,是 memory fix(更大卡 / 2 卡 / 把 per-request max 壓到 ~16K)。32GB 5090 + 27B nvfp4 的真實 frontier 是 C=4 @ 262K(517.7 tok/s、avg batch 3.44、Σqueue 2 s)——而 workload 實際併發(15 個 AIME long + 60 個短)在 C=4 下完全裝得下。
7. 真實流量:這個 post 就跑在這個 serve 上面
09-07(DFlash2 serve 一上線)→ 09-27 19:38,serve log 解析到 131,276+ 個完成請求(09-07 → 09-09 01:28 = 10,416;09-09 23:54 → 09-27 = 120,860;09-09 01:28 → 23:54 有 log 輪換窗口未計入)。這些流量是這顆 production serve 的真實負載,由兩類 consumer 組成:DSH agent session(寫這個 post 的 agent 就是其中之一)和 09-19 → 09-22 的合成 training-data 生成 batch(~99.9K 請求、佔總量 76%):
日期 完成請求 帶圖請求 09-07 5,548 — 09-08 4,604 — 09-09 273† — 09-10 205 0 09-11 1,762 103 09-12 266 32 09-13 1,148 408 09-14 1,087 305 09-15 1,375 0 09-16 2,435 0 09-17 2,415 0 09-18 3,229 0 09-19 41,103 0 09-20 21,279 43 09-21 31,090 0 09-22 6,413 0 09-23 3,009 0 09-24 1,447 0 09-25 2,520 113 09-26 63 32 09-27 5 5 總 131,276+ 1,041 † 09-09 = CSV 264(到 01:28)+ log 9(23:54+);09-26 至 15:22 停機止(請求全部在 00 時)、09-27 至 19:38。帶圖請求 09-11 vision-enabled 才開始有。
- 用法:多輪 context(觀察到 19 → 200+ 個 message 的 session)、tool-call loop(09-23 → 09-25 有 75–91% 的請求是 tool-call turn;09-26 / 09-27 為不完整日,分別 90% / 80%)、長 context(max prompt 239,121(09-14),貼住 239,616 上限)、per-turn KV 重用(agent turn 大部分 prefix cache 命中:觀察到 87.5% turn closure、最高 99.5% private endpoint;09-07 → 09-09 era 整體約 82%)。
- 兩類 workload 同一個 serve:interactive agent loop(09-23 → 09-25:每日 1.4K–3.0K 請求、75–91% tool calls、100% stream、prompt 90K–180K;09-22 已有 2,624 個 stream / maxout 65,536 的 DSH 請求與 batch 並行)和合成 training-data 生成 batch(09-19 → 09-22:四天 ~99.9K 請求——單模板短 prompt(每日中位 ~153/289/307 tok、主模板 211/287/305–309)、1–2 messages、max output 400–2,200、non-stream、順序執行、每日 19–24 個活躍小時;batch 對兩個 spec 做 A/B:09-19 MTP3 83%、09-20 混合、09-21 DFlash2 97%、09-22 MTP3 58%)。
- performance(dflash2 行):decode per-request rate 每日 median 95–390 tok/s(09-19 ~5K 個短輸出 turns(output median ~60 tok)rate 偏高、median 390;長輸出請求 ~135–200,與 §2 的 C=1 anchor 198.7 同一量級);pooled acceptance 每日 14.3–44.7%(workload 混合主導,舊期 33.5%、log 期 29.0%、整體 29.8%);prefill 1.4–5.6k tok/s;151K prompt 無 cache 時 TTFT 46 s,70K prompt 87.5% cache 命中時 2.5 s——agent loop 的真實 TTFT 就是 cache 重用的故事。
- Vision 已入 production(09-11 起):1,041 個帶 media 的請求(包括 3 圖 session 和 2048×1320 圖)。09-11 兩個明確 API 測試:64×64 紅 PNG(130 prompt tok / 64 輸出,decode 156.8 tok/s)和 2048×1320 pipeline 圖(2,693 prompt tok、prefill 491 ms;512 decode tok / 2,057 ms = 248.5 tok/s;dflash2 draft 826 → accepted 392 = 47.4%)。
- spec era:dflash2 完成 77,325(含 09-07 → 09-09 的 10,416;log 期 66,909)、MTP3 完成 53,866(99% 集中在 09-19 → 09-22——training-data batch 用的另一個 spec,與 DFlash2 A/B,不是 fallback)、107 個 cancelled(server log 只記錄 cancelled 狀態、原因未查證;不納入 prefill / decode / acceptance 統計)。
- operations:131 次 engine start(最後 09-27 19:35:03)、94 次 graceful stop(最後 09-26 15:22:52)、32 次 startup FATAL——全部有診斷:262K+vision planning OOM ×3、240,640+vision OOM ×1(差 9,845,248 B)、GPU occupied ×6(available < 9.2 GB)、CUDA driver insufficient ×9(09-13)、v2 artifact unsupported ×10(09-16,build 升級期間)、dflash2/feature_projection ×2(09-07/08 era)。09-10 兩個大 gap(00:26 → 08:25、11:54 → 21:51)= v3 / v4 campaign 期間 18080 serve 離線(GPU 歸 18090 benchmark)——連作者 agent 都離線了;09-26 15:22 → 09-27 19:35 ~28 h down(人工重啟)。
8. vLLM 對照
vLLM 0.28.0 成功起到了 DFlash2:QUASAR-QAT NVFP4 19.15 GiB + DFlash2 draft 3.58 GiB、spec_tokens=6、fp8 KV 86,057 tokens、acceptance 約 18.7–27.2%、single-request generation 約 50–92.6 tok/s;max model len 被 route 壓到 81,920。draft 必須與 target 同 device,雙卡拆分不是簡單解法。(vLLM 用 fp8 KV、NInfer 用 nvfp4 KV——KV dtype 不同,數字不是 apples-to-apples,只是 existence proof。)
9. Completion outcomes

nvfp4:40 stop / 35 limit;groupwise:36 stop / 39 limit。這不是 correctness 評分。groupwise AIME30 有 repetition-loop outlier:
-?重複 32,046 次,不能當成性能勝利。10. 論壇動態:其他人對同一個 engine 帖了什麼(截至 09-27)
帖 硬件 / 配置 關鍵數字 與本篇的關係 1870 第三方 RTX 5090 + NInfer + DFlash2 271.7 tok/s(long reasoning) 單一 workload 數字;方向與本篇 §3 crossover 結論一致(長推理 DFlash2 明顯贏),數字為何合理見 §11 1897 雙 RTX 5070 Ti,TP2 + MTP3 C=1 114.5 → C=8 567.0 tok/s;正在 port DFlash2 MTP3 的 C=8 scaling 雙卡也成立;本篇單卡 C=8 陷阱(§5)是 32GB memory 邊界問題,不直接適用 TP2,但 draft-KV 成本機制是共享的 1901 RTX 4080S + NInfer(setup 自稱「抄作業」自我們帖 1228/1803 和 1870) NInfer 88.2 vs SGLang 98.3 tok/s;3 次 crash(CUDA Graph × batch speculative 衝突); --no-cuda-graph−2.6%;dual 256K OK不同 GPU 的複現:4080S 上 NInfer 低於 SGLang(不同硬件,結論與本篇 5090 DFlash2 不同);crash → CUDA Graph × batch 衝突是新坑(已加入 §13) 我們的時間線(讀論壇數字的參考):09-01 23:49 vLLM session 首次出現 DFlash2;09-07 00:00–00:04 pull fast-forward 到
487f8977(83 commits 里 25 個是 dflash2);09-09 00:06 current upstream build 編好,live serve 用--spec dflash2 --draft-tokens 7 --lm-head-draft。companion weights 包含feature_projection、6 層 draft path、grouped convolution、candidate selector 和 codebook。11. 如何讀 1870:271.7 tok/s 與 517.7 tok/s 為何不衝突
1870 在 5090 上報告 DFlash2 long reasoning 271.7 tok/s。這個數與本篇的數據不衝突——它們量的不是同一樣東西:
- workload 軸不同:271.7 是單一 long-reasoning workload 的數;本篇 517.7 是 75-request 混合 corpus、C=4、corpus-level 數字(總 decode tokens ÷ makespan)。單一 workload 的數只證得那個 workload 的性能下界,不是 deployment frontier。
- DFlash2 在長推理贏最多:本篇 §3——vs MTP3:AIME01 +64.5%(321.1 tok/s)、Structured +62.3%、Code +36.6%、Translation +33.1%、Story −3.8%。1870 選 long reasoning,恰恰就是 DFlash2 最強的那個 workload——方向與本篇數據一致。
- 量級合理:271.7 < 本篇 AIME01 單 request 321.1 tok/s(C=1、262K、no prefix reuse)。差值可以用 ctx 大小、prefix cache 重用和度量口径解釋——真實流量長輸出請求 ~135–200 tok/s、短輸出 burst 更高(§7)。
- 讀第三方數字,先問三件事:什麼 workload、什麼 C、ctx 是否全值。單一數字是那個 workload 的下界;deployment frontier 仍然要 C×ctx 矩陣(本篇 §4–§6)。
- client SSE 計時不可信:1870 留言區實測,client SSE 計時比 server log 低估約 4.5×——讀第三方數字之前,先確認計時來源是 server-side log(本貼 §7 全部用 server-side log)。
12. 重現
~/.dsh_mine_venv/bin/python ~/ninfer-upstream-src/tools/bench/run_serve_concurrency.py \ --serve ~/ninfer-upstream-build/apps/ninfer-serve \ --artifact qwen3_8_27b=~/ninfer_artifacts/qwen3_8_27b_nvfp4.ninfer \ --mode dflash2_7 --sampling stochastic \ --suite corpus-makespan --concurrency 4 \ --max-context 262144 --kv-capacity auto --kv-dtype nvfp4 --prefill-chunk 1024 \ --port 18090 --output /mnt/c/work/ninfer/out/dflash3/repro注:upstream harness 原本 hardcode 了
--kv-dtype int8(validator 亦預期kv_cache=int8-group64)——這就是 v3 整個 campaign 變成 int8 的原因。v4 patch 加了--kv-dtype {int8,nvfp4}flag(預設 int8,backward-compat),nvfp4 時 validator 預期kv_cache=nvfp4(engine 對 nvfp4 KV 的報告字串);backup 在tools/bench/run_serve_concurrency.py.bak_pre_v4。runner 腳本:campaign/runner_v4.sh(v4 matrix)+campaign/runner_v4b.sh(K=15 C=8 補測);per-C boot probe 由大 ctx 試到細。13. 坑表
坑 影響 只看 acceptance 會誤判 DFlash2 慢(K=1 81.3% 最慢、K=15 18% 在 C≤4 都慢于 K=7) benchmark 的 KV dtype 不等于 production int8 campaign 把 C=8 boot 邊界量低了 2×(65K vs 131K),整個 matrix 對 deployment 無意義——harness 就是 hardcode 了 int8 才出事 C=8 只用 makespan/tps 論速度 243 tok/s 掩蓋了 Σqueue 15,679 s、真實併發 1.29 路(C=4 同 workload 是 3.44 路、Σqueue 2 s) K=15 × C=8 不看 planning reservation 131,072 差 139 MiB OOM;planning reservation 隨 ctx 線性增,降 ctx 122,880 就 FIT 262K + --vision 直接起 planning FATAL 差 406,210,816 B;media 256/512 MiB flags 不減少 planning reservation——由大 ctx 逐檔 probe 落去(240,640 差 9.4 MiB、239,616 FIT) 用 client SSE 計時 1870 留言區實測:client SSE 計時低估 4.5×——server log 纔是 ground truth;§7 真實流量數字全部用 server-side log workload 裝得落 65K 都開 131K 白送 13.6% 速度(225.6→194.9 tok/s,KV arena 成本,int8 era 實測) groupwise Story 退化 workload-specific,不可用平均數掩蓋 completion limit 當 correctness 必須另做 accuracy/compliance 評測 本貼由本地全棧生成:NInfer 出 token——寫這個 post 的 agent 就是 DSH harness 裡面的 agent,直接經 OpenAI-compatible /v1 跑在這個 NInfer live serve 上面(09-11 起 vision-enabled、C=3 @ 239,616、現在 instance pid 90317(09-27 19:35 重啟);這個 conversation 的每個 turn——多輪 context、tool calls、圖片——都是 §7 流量裡面的真實 request)、v3、v4 和 v4b 補測期間 GPU 歸 benchmark、連作者都離線了、圖由本地 Python 畫。歡迎複現或打臉。
Tags:
rtx5090qwen-27bdsharnessspeculative-decodingdflash2 - RTX 5090 32GB,single GPU;artifact:
-
3並發146 t/s @105K nvfp4:Qwen3.8-27B RTX 5090 滿載實測 II,全 nvfp4 450K pool、419K 全上卡零 offload0. 先給結論
項目 結果 本篇測什麼 上一篇測「真實 agent 負載 13.7 小時」,這篇純速度:prefill / decode 在 DSH compact 上限下的壓力曲線(含 NInfer 近期新增的 nvfp4 KV feature)、官方 docs 方法學對照、並發度對照 Server --kv-dtype nvfp4 --kv-capacity 450560 --max-concurrency 3 --max-context 262144 --spec mtp(RTX 5090 單卡,CUDA 13.3,build 21a0e85f)Prefill 行為 嚴格 FIFO 串行:TTFT = 隊列位置 × 該路的 solo prefill 時間; --max-concurrency完全不加速 prefillSolo prefill 47k → 6,004 tok/s;105k → 4,096;143k → 3,403;157k → 3,174;210k → 2,587 tok/s 壓力 TTFT ladder(s1,C=3,每路 105k) 25.7 / 53.3 / 81.2 s(= solo × 1/×2/×3) C=3 vs C=4(同一 104k workload) C4 多一路(101.7 s),prefill 斜率不變;C4 的真實成本 = parent session 被擠到 host 冷層 → 維持 C=3 docs/performance.md 對照 MTP0 prefill +0.3…+3.4%、decode −1.8…−4.9%;MTP3 per-fixture 最大偏差 −7.6%(在參考值 1σ 內);makespan C4 +7.2%、C8 −17.8%(本 build C8 不再 memory-throttled,avg batch 3.32 vs 參考 2.36)→ 零回歸 C=3 最佳 context size 131,072:compact 上限 104,857 × 3 路並發 + 本 session = 419,428 ≤ 450,560 pool,全 device 容納、零 host offload(s1 實測) 一句話:prefill 是串行的,context 上限是算出來的——C=3 + 131,072 + nvfp4 450K pool 是這顆卡上「3 路滿載並發 + 活的 agent session」全在 device 的最大窗口。
1. 跟上一篇的分別
上一篇(lcz.me/topic/1228,13.7 小時真實編程負荷,int8 KV)的結論是「agent 負載 98.6% 是 prefill,最佳 C=2」。這篇換三個變量:
- KV 換 nvfp4——NInfer 近期新增的 feature(
--kv-dtype nvfp4,上一篇的路線還是 int8 KV);pool 從 262,144 提到 450,560 tokens(reservation 省約 1 GiB,token 容量反而多 73%); - 把 context 窗口鎖在 DSH 實際會觸發 compact 的上限(
floor(0.8 × contextWindow),thresholdRatio 0.8)去壓力測試,而不是拍一個整數; - 拿官方
docs/performance.md的完整方法學(MTP0 長 prompt profile + MTP3 corpus × C=1/2/4/8)跑一遍,跟發布參考值逐項對。
2. 環境與測法
項目 內容 模型 / artifact qwen3.8-27b nvfp4,21,492,695,040 bytes(20.02 GiB) Server(壓力段) --max-context 262144 --kv-dtype nvfp4 --kv-capacity 450560 --max-concurrency 3 --pending-timeout-ms 600000 --spec mtp --draft-tokens 3 --lm-head-draft --prefill-chunk 1024KV pool 450,560 tokens = 7,040 page groups(max 12,288),reservation 9.89 GiB,slack ≈0.96 GiB;host 冷層 8 GiB / 8 state slots 壓力輸入 隨機字/十六進制/數字文本,獨立 seed × 每 scenario;校準 100 KB ≈ 47,663 tokens(0.47 tok/byte,tokenizer 最壞情況) 測法 base 先 solo 一條量 solo 速度;其餘各路同時提交;TTFT / prefill / decode 全部取 engine log 的 status=done行(engine-measured,非 client 牆鐘)零中斷保證 每段 90s grace → kill → VRAM<4000MiB 確認 → 跑 → trap restore EXIT;全程 /health guard;本 DSH session 就在該 server 上解碼,壓力窗口內照常工作(prefix cache hit 55,923 tok)Doc campaign 完全照 docs/performance.md:INT8 KV、 --no-prefix-reuse、max-context 131,072、--kv-capacity auto、stochastic(temp 0.6 / top-p 0.95 / top-k 20 / presence 1.0)、30 fixtures × 5 seeds、fixed shuffle3. 壓力測試:s1–s4 + C4

3-1. TTFT ladder(各路同時提交,engine-measured)
Scenario C 每路 tokens Solo base 並發 TTFT ladder(s) s1(131k line) 3 104,846–105,648 26.4 s / 4,096 tok/s 25.7 / 53.3 / 81.2 s4(145k target) 3 142,186–143,900 44.6 s / 3,403 tok/s 45.5 / 91.1 / 136.5 C4 對照 4 104,122–104,452 ≈4,358 tok/s(全新 server) 23.9 / 49.8 / 75.8 / 101.7 s2 2 156,860–157,804 49.6 s / 3,174 tok/s 49.9 / 101.9(第 3 條排隊) s3 2 210,376–210,854 81.5 s / 2,587 tok/s 81.6 / 165.5(第 3 條排隊) 每條線都恰好是 solo prefill 時間 × 1/×2/×3——prefill 嚴格 FIFO 串行,每路都在用 solo 速度跑。所以 TTFT 的規劃公式非常簡單:
TTFT(第 k 條) ≈ k × (prompt_tokens / solo_prefill_tps)。3-2. Solo prefill 隨 context 遞減

prompt tokens 47k 105k 143k 157k 210k prefill tok/s 6,004(全新 server 6,241) 4,096 3,403 3,174 2,587 TTFT 7.6–8.0 s 26.4 s 44.6 s 49.6 s 81.5 s 3-3. Decode
256-token 短 output 下,每路 95–146 tok/s(MTP3)。output 太短 batching 收益未完全展開;長 output 的數字見第 5 節 doc campaign(155–419 tok/s)。
3-4. Pool 從不 OOM、從不排隊阻塞
所有壓力窗口
materializing=0、無 pool-queue 等待、零 request 失敗。s3 / s4(pool 被 3×157k / 3×143k 占滿)的實際代價是:閒置的 parent session(就是這篇所在的 DSH 對話)被 dematerialize 到 host 冷層(host_active_ms 小幅抬升),它後續的請求照常完成。s1(3×105k + session ≈ 419k ≤ 450,560)則完全沒有 offload——全部狀態留 device。4. C=3 vs C=4(同一 104k workload)
路(FIFO 序) C=3 TTFT C=4 TTFT 1 25.7 s 23.9 s 2 53.3 s 49.8 s 3 81.2 s 75.8 s 4 (無) 101.7 s C4 的 prefill 略快(≈4,358 vs ≈4,090 tok/s)是因為那是全新、無 resident session 的 server,不是並發度帶來的——斜率(每路的 solo 時間)兩邊一樣。C=4 的真實成本:4 路占滿 pool 後 parent session 被擠到 host 層。結論:維持 C=3。
5. docs/performance.md 對照官方發布值
方法學完全照搬(INT8 KV / 131,072 / kv-capacity auto / stochastic / fixed shuffle / 75 requests per point)。
5-1. MTP0 context-length profile(Long NIAH,n=5)

prompt tokens Prefill ref → ours Decode ref → ours 7,680 8,340.4 → 8,621.3(+3.4%) 71.2 → 69.3(−2.7%) 64,512 5,297.9 → 5,315.7(+0.3%) 65.7 → 63.7(−3.1%) 130,048 3,544.7 → 3,635.0(+2.5%) 59.6 → 58.5(−1.8%) 260,096 2,203.1 → 2,224.0(+0.9%) 52.9 → 50.3(−4.9%) 5-2. MTP3 corpus makespan(75 requests/point)

C Makespan ref → ours Decode tok/s ref → ours Avg batch ref → ours 1 4,670.3 → 4,446.9(−4.8%) 161.1 → 155.3 1.00 → 1.00 2 2,510.8 → 2,607.1(+3.8%) 294.7 → 279.6 1.98 → 1.96 4 1,647.7 → 1,766.4(+7.2%) 432.9 → 403.1 3.29 → 3.20 8 2,164.9 → 1,780.1(−17.8%) 334.2 → 419.0(+25.4%) 2.36 → 3.32 發布參考值裡 C=8 被 memory pressure 壓到 avg batch 2.36(比 C=4 慢 31%);本 build 的 C=8 avg batch 3.32,已追平 C=4(1,780 vs 1,766 s)。C=4 仍是 makespan 最優點;C=3 是 450K pool + live session 的線上的操作點。 makespan Δ 混雜 stochastic 抽樣長度(decode tokens 690k–746k 各異),decode tok/s 較乾淨。
5-3. MTP3 per-fixture(C=1 point,n=5/fixture)

Fixture Decode ref → ours Acceptance ref → ours aime 01 195.2 → 197.0(+0.9%) 76.0% → 79.3% aime 15 151.4 → 149.4(−1.3%) 56.2% → 56.6% aime 30 167.5 → 154.8(−7.6%) 64.6% → 58.1%(ref 自身 σ=23.7 tok/s,1σ 內) Code(3 fixtures 池化) 194.3 → 188.2(−3.1%) 76.4% → 76.4% Story(3 fixtures 池化) 126.1 → 124.9(−0.9%) 37.4% → 38.2% Translation(3 fixtures 池化) 192.3 → 190.3(−1.0%) 75.0% → 75.5% Structured(3 fixtures 池化) 219.8 → 216.7(−1.4%) 90.8% → 90.9% 最大偏差 −7.6%(aime 30,stochastic 高變異 fixture,在參考值自身 1σ 內),其餘均在 ±3.1%。判定:零回歸。 300/300 requests 完成,無 request / CUDA / OOM 失敗。
6. 為什麼 131,072 是 C=3 的最佳 context
DSH 的自動 compact 在上限 =
floor(0.8 × contextWindow)(thresholdRatio 0.8)觸發;policy 只讀settings.yaml的 contextWindow,從不參考 server 的 model discovery。pool 規劃 = 3 路在上限 + 1 條活的 session 在上限 ≤ 450,560:
contextWindow compact 上限 3 路 + session Pool 450,560 131,072 104,857 3×104,857 + 104,857 = 419,428
容納,margin 31,132196,608 157,286 3×157,286 = 471,858
超 21,298(只能 C=2)262,144 209,715 3×209,715 = 629,145
超 178,585(只能 C=2)實測佐證:s1(3×105k,131k line)
materializing=0、session 全程留 device;s4(3×143k)3 路照跑,session 轉 host 冷層繼續工作。131,072 是「3 路滿載並發 + 活 session 全在 device」的最大窗口。 配置:server 保持--max-context 262144(只作 backstop),DSHsettings.yaml改contextWindow: 131072,host restart 後生效。7. 新發現 / 坑
--max-concurrency不加速 prefill。 NInfer 的 prefill 是 FIFO 串行:每路用 solo 速度跑,TTFT 就是隊位 × solo 時間。並發度只決定「同時能 decode 幾條」。- 改 server
--max-context防不了 compact。 DSH compact policy 只讀settings.yaml的 contextWindow;只把 server 調大,session 照樣在 0.8× 老窗口觸發 compact;走錯方向(server 比 DSH 窗口小)反而會觸發CONTEXT_WINDOW_EXCEEDED→ forced max balanced head reduction + 1 retry 的錯誤路徑。 - Pool overflow 不 OOM、不排隊。 超限時 engine 把最低優先的 resident(閒置 session)dematerialize 到 host 冷層,不是拒絕請求。體感代價 = 那個 session 自己的請求多一點 host 往返。
- 輸入 tokenization 校準:0.47 tok/byte。 隨機字/十六進制/數字是 tokenizer 最壞情況;100 KB ≈ 47.7k tok;600 KB 直接超 262,144 tok(server error)。做 calibration 記得用 ≤100 KB 的切片。
- nvfp4 pool 比 int8 大(nvfp4 KV 是 NInfer 近期新增的 feature,
--kv-dtype nvfp4)。int8 262,144 pool reservation ≈11.20 GiB;nvfp4 450,560 = 9.89–10.21 GiB——省下的 ~1 GiB 直接變成多 73% 的 token 容量。 - C=8 在本 build 不再 memory-throttled(doc campaign:avg batch 3.32 vs 參考 2.36),makespan 比發布值快 17.8%;但 C=4 仍是 makespan 最優。
8. 最終配置
層 值 Server --max-context 262144 --kv-dtype nvfp4 --kv-capacity 450560 --max-concurrency 3 --prefill-chunk 1024 --pending-timeout-ms 600000 --spec mtp --draft-tokens 3 --lm-head-draftKV pool 450,560 tokens(7,040/12,288 page groups),reservation 9.89 GiB DSH settings.yamlcontextWindow: 131072(compact 上限 104,857),thresholdRatio 0.8操作點 C=3:3×104,857 + session 104,857 = 419,428 ≤ 450,560,零 host offload 9. 限制與未測
- 壓力輸入是最壞 tokenization 的隨機文本:真實 prompt 每 byte 更快,但真實 agent 負荷吃 prefix cache(上一篇 97–99% hit)——兩種 workload 的 prefill 數字不要直接互比。
- 壓力段 output 只有 256 tok:batching 的 decode 收益未完全展開;doc campaign 的 4,096+ output 更代表實戰(155–419 tok/s)。
- stochastic 抽樣:per-fixture decode 有 ±5% 級別抽樣噪聲(參考值 aime 30 自身 σ=23.7 tok/s)。
- doc campaign 用 INT8 KV(方法學固定),跟壓力段的 nvfp4 數字不同 pool、不同 dtype,不可直接互比。
- C4 ladder 跑在全新 server(無 resident session),solo baseline 比 s1 快 ~7%(23.9 vs 26.4 s),C3/C4 對照不是嚴格同條件——但結論(斜率不變、成本在 host offload)不受影響。
- WSL2;全部數字可從 serve log 的
status=done行與結果目錄逐項核對。
數據與複現:全部結果目錄在本機 WSL home 下:壓力
~/ninfer_stress_032756/(s1–s3)、~/ninfer_stress_s4_033927/(s4)、~/ninfer_c4_test_083409/(C4);doc campaign~/ninfer_doc_test_20260902_035140/(mtp0_corpus/summary.csv、mtp3_makespan/points/*.json、每 request server jsonl),pointer~/ninfer_doc_test_latest;engine build21a0e85f,docs 參考docs/performance.md。本篇由本地全棧生成:NInfer(自寫引擎)驅動 DeepSeek Harness(agent 框架)跑完全部測試與數據整理,圖表由本地 Python 生成,全部數字可從上述結果目錄與
ninfer_serve.log逐項核對。歡迎複現或打臉。 - KV 換 nvfp4——NInfer 近期新增的 feature(
-
RTX 5090 Qwen3.8-27B dsh 全套實測:自寫推理引擎 NInfer × DeepSeek Harness × 開源編碼 agent 任務 —— 跑 13 小時真實編程任務的數據、6 個坑、以及「並發不是越大越快」@terry 我找到4090版本 可以試試
Qwen 3.8 27b 128k 開MTP3 有77.5 tok/s
https://github.com/sergiuszm/ninfer-4090 -
RTX 5090 Qwen3.8-27B dsh 全套實測:自寫推理引擎 NInfer × DeepSeek Harness × 開源編碼 agent 任務 —— 跑 13 小時真實編程任務的數據、6 個坑、以及「並發不是越大越快」然後我發現了如果對Qwen 3.8 27b說趕時間會進入「專注」模式
-
RTX 5090 Qwen3.8-27B dsh 全套實測:自寫推理引擎 NInfer × DeepSeek Harness × 開源編碼 agent 任務 —— 跑 13 小時真實編程任務的數據、6 個坑、以及「並發不是越大越快」 -
RTX 5090 Qwen3.8-27B dsh 全套實測:自寫推理引擎 NInfer × DeepSeek Harness × 開源編碼 agent 任務 —— 跑 13 小時真實編程任務的數據、6 個坑、以及「並發不是越大越快」裝到了

-
RTX 5090 Qwen3.8-27B dsh 全套實測:自寫推理引擎 NInfer × DeepSeek Harness × 開源編碼 agent 任務 —— 跑 13 小時真實編程任務的數據、6 個坑、以及「並發不是越大越快」 -
RTX 5090 Qwen3.8-27B dsh 全套實測:自寫推理引擎 NInfer × DeepSeek Harness × 開源編碼 agent 任務 —— 跑 13 小時真實編程任務的數據、6 個坑、以及「並發不是越大越快」啟動腳本︰
# ninfer-serve.sh #!/bin/bash # NInfer host control: ninfer-serve.sh start | stop | status # Binary reports usage.prompt_tokens_details.cached_tokens (OpenAI chat-completions), # so DSH shows real KV prefix cache hit % instead of 0%. # Default = text-only at 262K context (full int8 KV pool, ~10.45 GiB). # Vision is optional: VISION=1 ninfer-serve.sh start switches to 192K context + --vision # with media buffers trimmed from defaults (1G+2G) to 256M+512M so the fixed Vision # buffers fit the ~10.4 GiB free after weights on the 5090 (at 262K they do not). # C=2: median agent prompt scales to ~86K at 192K; two frontiers (~172K) fit the pool, # so requests reuse their frontier (97-99% cached). set -u PORT=18080 LOG=/home/user/ninfer_serve.log APP=/home/user/ninfer-build/apps/ninfer-serve ART=/home/user/ninfer_artifacts/qwen3_8_27b_nvfp4.ninfer if [ "${VISION:-0}" = "1" ]; then CTX=196608 VISION_FLAGS="--vision --media-cache-mib 256 --media-live-mib 512" else CTX=262144 VISION_FLAGS="" fi is_running() { pgrep -f "ninfer-serve.*qwen3_8_27b" >/dev/null 2>&1; } case "${1:-start}" in start) if is_running; then echo "already running (pid $(pgrep -of 'ninfer-serve.*qwen3_8_27b'))" exit 0 fi export LD_LIBRARY_PATH=/home/user/ninfer_deps/prefix/usr/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH:-} cd /home/eason || exit 1 setsid nohup "$APP" "$ART" \ --host 0.0.0.0 --port $PORT --device 0 \ --max-context $CTX --prefill-chunk 1024 --kv-dtype int8 \ $VISION_FLAGS \ --max-concurrency 2 --pending-timeout-ms 600000 \ --spec mtp --draft-tokens 3 --lm-head-draft >>"$LOG" 2>&1 & for i in $(seq 1 30); do sleep 5 if curl -s http://127.0.0.1:$PORT/health | grep -q ok; then echo "NInfer up: pid $(pgrep -of 'ninfer-serve.*qwen3_8_27b'), ctx=$CTX vision=${VISION:-0}, log $LOG" exit 0 fi done echo "server did not become healthy in 150s; last log lines:"; tail -5 "$LOG"; exit 1 ;; stop) if ! is_running; then echo "not running"; exit 0; fi pkill -f "ninfer-serve.*qwen3_8_27b" for i in $(seq 1 10); do sleep 2; is_running || break; done if is_running; then echo "still running (try: fuser -k $PORT/tcp)"; exit 1; fi echo "stopped" ;; status) if is_running; then echo "running pid $(pgrep -of 'ninfer-serve.*qwen3_8_27b')"; curl -s http://127.0.0.1:$PORT/health; echo else echo "not running" fi ;; *) echo "usage: $0 start|stop|status (VISION=1 for vision mode)"; exit 2;; esac記得把
{ip}換掉:: start.bat @echo off setlocal title NInfer Start rem --- self-elevate (netsh portproxy + firewall need admin) --- net session >nul 2>&1 if %errorlevel% neq 0 ( echo Requesting administrator rights... powershell -NoProfile -Command "Start-Process '%~f0' -Verb RunAs" exit /b ) echo [1/4] Starting NInfer server in WSL Ubuntu (port 18080, MTP3 on)... wsl -d Ubuntu -- bash /mnt/c/Users/user/Desktop/ninfer-serve.sh start if errorlevel 1 goto :fail for /f "usebackq" %%i in (`wsl -d Ubuntu -- hostname -I`) do set WSL_IP=%%i echo [2/4] Repairing LAN portproxy: 0.0.0.0:18080 -> %WSL_IP%:18080 ... netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=18080 >nul 2>&1 netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=18080 connectaddress=%WSL_IP% connectport=18080 echo [3/4] Ensuring firewall rule ... powershell -NoProfile -Command "if (-not (Get-NetFirewallRule -DisplayName 'NInfer serve 18080' -ErrorAction SilentlyContinue)) { New-NetFirewallRule -DisplayName 'NInfer serve 18080' -Direction Inbound -Protocol TCP -LocalPort 18080 -Action Allow -Profile Private,Public | Out-Null; Write-Host 'firewall rule added' } else { Write-Host 'firewall rule exists' }" echo [4/4] Verifying via LAN IP ... powershell -NoProfile -Command "try { $r = Invoke-RestMethod -Uri http://{ip}:18080/health -TimeoutSec 8; Write-Host ('LAN OK: ' + ($r | ConvertTo-Json -Compress)) } catch { Write-Host ('LAN FAIL: ' + $_.Exception.Message) }" echo. echo Done. Server URL for other devices: http://{ip}:18080 echo Model qwen3.8-27b (nvfp4), MTP3 on, no vision, KV int8. pause exit /b 0 :fail echo Start failed - check WSL log: wsl -d Ubuntu -- tail -20 /home/eason/ninfer_serve.log pause -
RTX 5090 Qwen3.8-27B dsh 全套實測:自寫推理引擎 NInfer × DeepSeek Harness × 開源編碼 agent 任務 —— 跑 13 小時真實編程任務的數據、6 個坑、以及「並發不是越大越快」0. 先給結論
這篇跟論壇上其他 Qwen3.8-27B 帖的角度不同:那幾篇測的是「引擎快幾快」,這篇測的是「一整套本地 agent 環境在真實工作負載下體感如何」。全部數字都來自 2026-08 下旬的實際運行(含 13.7 小時、1,200+ 個真實請求的完整 log),測法都寫在後面,歡迎複現或打臉。
項目 結果 硬體 RTX 5090 32GB(單卡, --device 0)模型 Qwen3.8-27B NVFP4(20.02 GiB artifact) 單請求 decode(實測中位數) 143 tok/s(最低 48,最高 216) 98,919-token prompt 的 TTFT 23.3 秒(C=2 無排隊);同樣 prompt 在 C=4 擁堵時 140–190 秒 13.7 小時真實 agent 工作負荷 1,205 個請求 / 142.8M prompt tokens / 2.05M 生成 tokens,全部跑完 最大發現 真實 agent 負載 98.6% 是 prefill 工作量 → 最佳並發度從「sweep 裡的 4」翻轉成 2 能力 GPQA-Diamond 88.38%(NInfer 官方評估);結構化輸出 MTP 接受率 90.8% 一句話:5090 跑 Qwen3.8-27B NVFP4 做本地編程 agent,decode 速度不是瓶頸,TTFT 和 KV 容量規劃才是;整套環境可以用,但要把並發度和 context 開關想清楚。
1. 三個組件各自是什麼
組件 角色 說明 NInfer 推理引擎(GPU 端) from-scratch C++/CUDA 引擎,編譯目標 sm_120a / CUDA 13.1,只支援明確註冊的 checkpoint( .ninfer格式,closed set 設計,不做通用 runtime)。INT8 group-64 paged KV、CUDA Graphs、MTP 投機解碼、prefix reuse、OpenAI + Anthropic 兩套 HTTP APIDeepSeek Harness (DSH) agent harness(Web GUI) DeepSeek AI 的開源 agent 框架(MIT,developer preview),「everything is a plugin」架構。我拿它當編程 agent 的主運行時:subagent / goal / 任務排程都跑在它上面,LLM provider 指向我本機的 NInfer(OpenAI 兼容 /v1/chat/completions)編碼 agent 插件(VS Code) 編程 agent(同時是被開發對象) Roo Code 停更後由原貢獻者延續的開源專案。我在個人 fork 上做 task-tree 控制與取消系列(見第 6 節),本文的 13.7 小時 DSH 工作負荷就是開發這個插件時產生的 關係:NInfer 出 token,DSH 用 token 跑 agent,編碼 agent 插件是被開發的對象(同時是產品同類,對照它的任務模型來設計本地環境)。
2. 環境
項目 內容 OS Windows 11 + WSL2 Ubuntu(kernel 6.6.87.2-microsoft-standard-WSL2) CPU Ryzen 9 9950X3D 16C/32T GPU RTX 5090 32GB(主角;多卡機,其餘卡未使用, --device 0強制)驅動 610.88 模型 artifact qwen3_8_27b_nvfp4.ninfer,21,492,695,040 bytes(20.02 GiB)服務配置(最終) --max-context 196608 --kv-dtype int8 --vision --media-cache-mib 256 --media-live-mib 512 --max-concurrency 2 --spec mtp --draft-tokens 3 --lm-head-draft網路 WSL NAT → Windows 經 netsh portproxy暴露在家庭 LAN192.168.x.x:18080。auth 是關閉的——只敢放在可信任的家庭網路,見第 8 節3. 效能數據(全部附測法)
3-1. NInfer 官方發布數字(同顆 5090,INT8 KV + CUDA Graphs)
MTP3 飽和 decode(1 秒完整區間內 batch = 設定並發度):
C=1 C=2 C=4 C=8 C8/C1 143.8 tok/s(接受率 48.9%) 267.6 461.1 766.6 5.33× 單請求 corpus:7,680-token prompt → prefill 8,340 tok/s;260,096-token prompt → prefill 2,203 tok/s、decode 52.9(MTP0)。MTP3 結構化輸出 219.8 tok/s、接受率 90.8%、3.72 tokens/round。
注意 Qwen3.8 的 MTP 接受率(45–49%)明顯低於 Qwen3.6(67–71%)——看 3.8 的 aggregate 數字時要連接受率一起看,不是引擎退化,是這代模型草稿頭猜得較差。
3-2. 我自己在 WSL 的 makespan 掃描(2026-08-11)
測法:75 個固定 corpus 請求(seed 20260811),
--max-context 131072,mtp3/draft 3,量完整 makespan。C makespan aggregate decode 相對 C=1 1 4,530 s 166.0 tok/s 1.0× 2 2,538 s 285.7 1.78× 4 1,698 s 426.2 2.67×(最優) 8 2,285 s 326.3 1.98×(反而更慢) 這張表是 decode-dominated 負載下的標準答案:4 最優、8 反效果(batch 利用率掉到 2.29)。
3-3. 13.7 小時真實 agent 負載(本節全文最該看)
測法:2026-08-19 23:16 → 08-20 12:03,C=4、262K context、WSL。負載 = DSH 開發編碼 agent 時的多 subagent 編程請求(含 tool calls、thinking、100–241 則訊息的長 history),完整 server log 存檔。
指標 數值 完成請求數 1,205 prompt tokens / 生成 tokens 142.8M / 2.05M → 98.6% 是 prefill 工作 實際 makespan 13.7 小時 同負載若 C=1 順序跑(估算:solo prefill 3,500–5,000 tok/s + decode 166) 11.4–14.8 小時 per-request decode 實測 min 48 / median 143 / max 216 tok/s,沒有一個低於 48 TTFT(100K+ prompt) 138–193 秒 DSH 界面顯示的「速度」 11–23 tok/s 三個直接結論:
- C=4 和 C=1 總時間差不到 ±10%——因為 98.6% 的工作是 prefill,而 prefill 同一時間只有一個請求在做(log
prefilling=1),並發對它零幫助;decode 佔 1.4%,batching 優勢救不回來。3-2 的「C=4 最優」在這種負載下直接失效。 - 「51 tok/s」是顯示假象。DSH 的 tok/s = 輸出 token ÷ 總 LLM 時間(TTFT + 排隊 + decode),而 TTFT+排隊佔了 84–91% 的 LLM 時間。實際 decode 是 143,差 7 倍。不要拿 agent harness 顯示的速度去評 engine——跟參考帖「只報數字不報測法等於沒有資訊」是同一課。
- decode 從來沒有變慢(min 48 tok/s)。用戶體感的「有時 10–30 t/s」全部來自 prefill/排隊,不是生成階段退化。
4. KV cache / prefix reuse:整篇最實用的規劃方法
NInfer 的 paged KV pool 容量 =
--max-context(explicit 模式)。262K context + int8 KV = 10.45 GiB,weights 之後淨餘 10.47 GiB,零餘裕。而呢個 agent 的 prompt 中位數是 117,841 tokens(window 的 45%)。實測 reuse 分佈(1,157 個請求):
prompt 尺寸 full_reset(重做全部 prefill) 有 cache hit <50K 39% 60% 50–100K 78% 21% 100–160K 97% 2% ≥160K 100% 0% 條件很直白:C 個 frontier 同時駐留需要的容量 = C × 中位 prompt。C=4 × 117K = 470K > 262K pool → 不斷逐出 → 全部 full_reset。小 context(<50K)重用得好好的(97–99% hit),所以引擎機制本身沒問題,是容量規劃問題。
兩個推論:
- 縮 context 救不了:agent 會按比例 compaction,prompt 永遠是 window 的 ~45%,比例不變,C=4 永遠 miss。
- 正確做法是 C=2(2 × 86K = 172K < 192K pool)。改成 C=2 + 192K 之後實測:98,919-token prompt TTFT 23.3s(純 prefill,無排隊),decode 184 tok/s。對比同尺寸 prompt 在 C=4 擁堵時的 140–193s,6–8 倍差距。
DSH 多開 3–4 個 subagent 不用怕——第 3、4 個只在 FIFO 排隊(pending timeout 600s 不會 expire),排到時 frontier 還在 pool 裡,TTFT 很快。
5. 踩過的坑(誠實記錄)
# 坑 現象 正解 1 引擎預設 max_concurrency=1+ pending timeout 30sDSH 多請求並發時全部 expired while waiting for admission--max-concurrency N --pending-timeout-ms 600000;N 按第 4 節規劃2 DSH「緩存命中」永遠 0% 兩層原因疊加:(a) NInfer 的 chat-completions usage 原本不報 cached tokens(Responses API 有報);(b) 即使報了,第 4 節的逐出會令它真的是 0 (a) 小 patch 補 prompt_tokens_details.cached_tokens(~20 行 + schema 測試),端到端驗證 DSH 記錄到非 0 cacheReadTokens;(b) 靠 C=23 用 DSH 顯示速度評估 engine 「51 tok/s 好慢」→ 白排查一圈 decode 路徑 看 server log 的 per-request ttft=/decode=;顯示值含 TTFT+排隊4 KV pool = max_context,不是「越大越好」 262K context 在 32GB 卡上是零餘裕狀態,任何附加分配(vision)都放不進去 按「C × 中位 prompt ≤ pool」反推 context 5 vision 與 262K 不能共存 10.45 GiB KV + 預設 media buffer(1G+2G)> 10.47 GiB 淨餘,啟動直接 reject --max-context 196608 --media-cache-mib 256 --media-live-mib 512→ fit,剩 489 MiB slack6 「C=8 更快」的直覺 3-2 掃描 C=8 已比 C=4 慢 23%;真實負載 8 個並發 = 純排隊 + 逐出加劇 本負載的最優 C 是 2,不是 8 6. 編碼 agent 插件:task-tree 控制系列 + 進行中的 abort signal 工作
動機很具體:本地 27B 跑多 subagent 編程時,任務樹會長得很深很長,上游的任務模型缺「深度控制」和「可靠取消/檢查點」。我在個人 fork 上做了 9 個 PR(5 個核心 + 4 個跟進,全部合併):
類別 內容 深度控制 任務嵌套深度追蹤(cycle-safe backfill)+ schema; maxNestingDepth/autoFlattenOnLimit設定項 round-trip;達深度上限時 subtask 自動 inline flatten取消與恢復 取消時級聯中斷 live children + 歷史樹顯示深度;修跨 interrupt/resume 的 delegation link 遺失 檢查點 手動對話 checkpoint 儲存 + trigger 方法 呈現 i18n 補齊;把深度/parent id 給到 model 看;inline 轉換顯示為獨立 chat banner 目前進行中:abort signal 的端到端 plumbing——由核心任務運行時,經 provider 橋接層(OpenAI provider 整合、pass-through providers),到 prompt 補全(complete-prompt)的取消與 config builder。動機:長本地多 subagent 運行下,取消路徑要真正 reach 住嘅 HTTP 請求同 provider 流,唔係只係將任務狀態標死;呢個系列同上面嘅 task-tree 控制係同一條線(深度限制 + 級聯取消 + 可恢復檢查點)。
這跟第 4 節是配套的:checkpoint + 穩定前綴 → engine 的 prefix reuse 命中率上去 → TTFT 下來。本地模型時代,agent 框架的 context 管理和引擎的 KV 規劃要一起看,不是各管各的。
7. 跟 7900 XTX 那篇的對照(同模型不同環境)
7900 XTX 帖(llama.cpp) 本帖(NInfer) 量化 Q4_K_M(17.1 GiB) NVFP4(20.02 GiB) 顯存頻寬 960 GB/s ~1,792 GB/s 工具調用 decode 73.4 tok/s(n-max 5) 143–166 tok/s(MTP3) MTP 接受率(工具/結構化輸出) 0.71–0.97 90.8%(官方)/ 實測 54–88% 長 prompt prefill 39K 時 437 tok/s 99K 時 4,271 tok/s 結論方向 完全一致:測法決定數字,工作負載類型決定 MTP 收益 同左,且補了一刀:負載 prefill-dominated 時,並發度最優解會翻轉 5090 + NVFP4 + 自寫引擎在 decode 端明顯快過 7900 XTX + Q4_K_M(頻寬 + TensorCore 量化),這不是玄學;但 3.8 的 MTP 接受率天花板也確實比 3.6 低,兩邊抵消後實際體感差距沒有頻寬差距那麼大。
8. 誰適合 / 不適合(開放討論)
適合:
- 想要零邊際成本、代碼不出 LAN 的本地編程 agent。27B 在結構化輸出/工具調用上的 decode 速度(~150–220 tok/s)完全夠 agent loop 用。
- 願意花 20 分鐘做一次「KV 容量規劃」的人——第 4 節那張表就是全部方法,不用魔法數字。
- 有多卡機器:本文只用了一張 5090,其餘卡全程閒置(
--device 0強制)。
不適合 / 要預先接受:
- TTFT 是真實存在的:100K+ prompt 20–190 秒。做長對話 agent 可以接受,拿來當聊天機器人會崩。
- 單 GPU、無搶佔:FIFO admission,長請求會佔住 slot。
- 27B 有質量天花板:複雜多步任務的天花板對不上 Opus 級別。本地環境的正確用法是「大批量、可重試、低價值單步」的工作放本地,關鍵步驟升級雲端(DSH 是 plugin 架構,provider 切換成本低——這點是實話)。
- 安全:本帖環境 auth 是關的,靠家庭 LAN 隔離。別照抄到不可信任網路,別 port-forward。
- WSL 是變數:全部數字在 WSL2 上量,跟 bare-metal 直接比不公平。
如果只帶走三句話:
- agent 工作負荷是 prefill-dominated,先算「C × 中位 prompt ≤ KV pool」,再談並發。
- 別信 harness 顯示的 tok/s,看 server 端 per-request 的 ttft/decode。
- 縮 context 不能救 cache(prompt 跟 window 等比縮),要調的是並發度。
9. 未測項目與已知限制(誠實揭露)
- Qwen3.8-27B
groupwise-intprofile 已支援但未跑發布級 benchmark(本帖只用 nvfp4)。 - 13.7 小時負載的「C=1 估算」用的是實測 solo 速率外推,不是真的重跑一遍(重跑要 12+ 小時,值得做但沒做)。
- vision 只驗證了「放得進 + 能啟動」,影像生成品質/速度沒有正式 benchmark。
- 全部 WSL 數字未做 bare-metal 對照。
- DSH 同該編碼 agent 都係快速迭代項目(developer preview / v3.7x),本文行為基於 2026-08 下旬版本,之後可能有 breaking change。
本帖由本地全棧生成:NInfer(Qwen3.8-27B NVFP4 @ RTX 5090)出 token,DSH 負責 agent 運行(讀 log、跑統計、核對數據、起草與修訂)。數據提取、13.7 小時 log 分析、數字交叉驗證到成文,全部由本地模型完成——它同時也在開發它自己跑在上面嗰套環境。有錯先係佢錯,歡迎打臉。
附圖︰

大部分時間都是(0-1) + 4 subtask 在跑



其中一個subtask

- C=4 和 C=1 總時間差不到 ±10%——因為 98.6% 的工作是 prefill,而 prefill 同一時間只有一個請求在做(log
-
从纯游戏机改成游戏+AI双用机,Qwen 3.6 27B MTP 速度只有 37 t/s,求大神指点怎么升级入手了5090 等有空测就来试试看
5090单卡跑27b忘记q几 现在有6x t/s
最震惊的是跑mtp竟然变慢了3倍只有2X t/s -
从纯游戏机改成游戏+AI双用机,Qwen 3.6 27B MTP 速度只有 37 t/s,求大神指点怎么升级那看来要等等了 我这边5090都$4500了还没货
看上5070TI 因为刚好 $1000就能入手
我不敢淘或是买魔改卡 因为没保养
而且我还要玩游戏 -
从纯游戏机改成游戏+AI双用机,Qwen 3.6 27B MTP 速度只有 37 t/s,求大神指点怎么升级不要对多卡异构抱有翻倍的期待——PCIe 带宽和多卡同步的开销在 consumer 平台上就是瓶颈,尤其是 mix 了 50 系和 30 系的情况。
qwen3.6-35b-a3b-mtp@q5_k_m122k
5080 + 5060TIVS5080 + 5060TI + 3060
只是offload vram到3060,至少有 84.5 / 61.3 = ~ 1.378 倍
3060 loading = 0%
5080 + 5060 TI + 3060






(cpu后补的) 14%

2026-05-26 03:16:27 [DEBUG] LlamaV4::load called with model path: C:\Users\user\.lmstudio\models\unsloth\Qwen3.6-35B-A3B-MTP-GGUF\Qwen3.6-35B-A3B-UD-Q5_K_M.gguf LlamaV4::load config: n_parallel=3 n_ctx=122144 kv_unified=true 2026-05-26 03:16:27 [DEBUG] 0.00.042.077 I srv load_model: loading model 'C:\Users\user\.lmstudio\models\unsloth\Qwen3.6-35B-A3B-MTP-GGUF\Qwen3.6-35B-A3B-UD-Q5_K_M.gguf' 2026-05-26 03:16:37 [DEBUG] 0.09.953.553 W llama_context: n_ctx_seq (122368) < n_ctx_train (262144) -- the full capacity of the model will not be utilized 2026-05-26 03:16:37 [DEBUG] 0.10.207.268 W common_init_from_params: KV cache shifting is not supported for this context, disabling KV cache shifting 0.10.207.283 I common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable) 2026-05-26 03:16:38 [DEBUG] 0.10.801.537 I srv load_model: creating MTP draft context against the target model 'C:\Users\user\.lmstudio\models\unsloth\Qwen3.6-35B-A3B-MTP-GGUF\Qwen3.6-35B-A3B-UD-Q5_K_M.gguf' 0.10.801.591 W llama_context: n_ctx_seq (122368) < n_ctx_train (262144) -- the full capacity of the model will not be utilized 2026-05-26 03:16:38 [DEBUG] 0.11.062.141 W load_hparams: Qwen-VL models require at minimum 1024 image tokens to function correctly on grounding tasks 0.11.062.147 W load_hparams: if you encounter problems with accuracy, try adding --image-min-tokens 1024 0.11.062.148 W load_hparams: more info: https://github.com/ggml-org/llama.cpp/issues/16842 2026-05-26 03:16:39 [DEBUG] 0.12.223.766 I srv load_model: loaded multimodal model, 'C:/Users/user/.lmstudio/models/unsloth/Qwen3.6-35B-A3B-MTP-GGUF/mmproj-F32.gguf' 0.12.223.774 I srv load_model: initializing slots, n_slots = 3 2026-05-26 03:16:40 [DEBUG] 0.12.358.158 I common_context_can_seq_rm: the context supports bounded partial sequence removal 2026-05-26 03:16:40 [DEBUG] 0.12.463.194 I common_speculative_impl_draft_mtp: adding speculative implementation 'draft-mtp' 0.12.463.199 I common_speculative_impl_draft_mtp: - n_max=3, n_min=0, p_min=0.00, n_embd=2048, backend_sampling=1 0.12.463.202 I common_speculative_impl_draft_mtp: - gpu_layers=-1, cache_k=f16, cache_v=f16, ctx_tgt=yes, ctx_dft=yes, devices=[default] 2026-05-26 03:16:40 [DEBUG] 0.12.463.595 I srv load_model: speculative decoding context initialized 0.12.463.598 I slot load_model: id 0 | task -1 | new slot, n_ctx = 122368 0.12.463.602 I slot load_model: id 1 | task -1 | new slot, n_ctx = 122368 0.12.463.602 I slot load_model: id 2 | task -1 | new slot, n_ctx = 122368 0.12.463.948 I srv load_model: prompt cache is enabled, size limit: 8192 MiB 0.12.463.950 I srv load_model: use `--cache-ram 0` to disable the prompt cache 0.12.463.950 I srv load_model: for more info see https://github.com/ggml-org/llama.cpp/pull/16391 0.12.463.967 I srv init: idle slots will be saved to prompt cache and cleared upon starting a new task 2026-05-26 03:16:40 [DEBUG] 0.12.465.401 I init: chat template, example_format: 'You are a helpful assistantHelloHi thereHow are you?' 2026-05-26 03:16:40 [DEBUG] 0.12.465.862 I srv init: init: chat template, thinking = 0 0.12.466.103 I srv update_slots: all slots are idle 2026-05-26 03:16:57 [DEBUG] LlamaV4::predict slot selection: session_id=<empty> server-selected (LCP/LRU) 2026-05-26 03:16:57 [DEBUG] 0.29.629.955 I slot get_availabl: id 2 | task -1 | selected slot by LRU, t_last = -1 0.29.629.960 I srv get_availabl: updating prompt cache 0.29.629.968 I srv load: - looking for better prompt, base f_keep = -1.000, sim = 0.000 0.29.629.972 I srv update: - cache state: 0 prompts, 0.000 MiB (limits: 8192.000 MiB, 122368 tokens, 8589934592 est) 0.29.629.974 I srv get_availabl: prompt cache update took 0.01 ms 0.29.629.994 I slot launch_slot_: id 2 | task 0 | processing task, is_child = 0 0.29.630.005 W slot update_slots: id 2 | task 0 | cache reuse is not supported - ignoring n_cache_reuse = 256 2026-05-26 03:16:58 [DEBUG] 0.30.736.191 I slot create_check: id 2 | task 0 | created context checkpoint 1 of 32 (pos_min = 953, pos_max = 953, n_tokens = 954, size = 63.356 MiB) 2026-05-26 03:16:58 [DEBUG] 0.30.977.199 I slot create_check: id 2 | task 0 | created context checkpoint 2 of 32 (pos_min = 1465, pos_max = 1465, n_tokens = 1466, size = 63.647 MiB) 2026-05-26 03:16:59 [DEBUG] 0.31.967.975 I slot print_timing: id 2 | task 0 | n_decoded = 100, tg = 106.15 t/s 2026-05-26 03:17:02 [DEBUG] 0.34.975.315 I slot print_timing: id 2 | task 0 | n_decoded = 366, tg = 92.67 t/s 2026-05-26 03:17:05 [DEBUG] 0.37.993.364 I slot print_timing: id 2 | task 0 | n_decoded = 622, tg = 89.27 t/s 2026-05-26 03:17:08 [DEBUG] 0.41.012.599 I slot print_timing: id 2 | task 0 | n_decoded = 864, tg = 86.52 t/s 2026-05-26 03:17:11 [DEBUG] 0.44.030.567 I slot print_timing: id 2 | task 0 | n_decoded = 1119, tg = 86.05 t/s 2026-05-26 03:17:14 [DEBUG] 0.47.058.056 I slot print_timing: id 2 | task 0 | n_decoded = 1382, tg = 86.20 t/s 2026-05-26 03:17:17 [DEBUG] 0.50.070.442 I slot print_timing: id 2 | task 0 | n_decoded = 1628, tg = 85.48 t/s 2026-05-26 03:17:20 [DEBUG] 0.53.072.133 I slot print_timing: id 2 | task 0 | n_decoded = 1885, tg = 85.50 t/s 2026-05-26 03:17:23 [DEBUG] 0.56.097.969 I slot print_timing: id 2 | task 0 | n_decoded = 2117, tg = 84.44 t/s 2026-05-26 03:17:26 [DEBUG] 0.59.112.645 I slot print_timing: id 2 | task 0 | n_decoded = 2382, tg = 84.81 t/s 2026-05-26 03:17:29 [DEBUG] 1.02.140.147 I slot print_timing: id 2 | task 0 | n_decoded = 2638, tg = 84.78 t/s 2026-05-26 03:17:32 [DEBUG] 1.05.141.305 I slot print_timing: id 2 | task 0 | n_decoded = 2888, tg = 84.65 t/s 2026-05-26 03:17:34 [DEBUG] 1.06.432.802 I slot print_timing: id 2 | task 0 | prompt eval time = 1395.84 ms / 1470 tokens ( 0.95 ms per token, 1053.13 tokens per second) 1.06.432.809 I slot print_timing: id 2 | task 0 | eval time = 35406.83 ms / 2992 tokens ( 11.83 ms per token, 84.50 tokens per second) 1.06.432.810 I slot print_timing: id 2 | task 0 | total time = 36802.67 ms / 4462 tokens 1.06.432.811 I slot print_timing: id 2 | task 0 | graphs reused = 1150 1.06.432.812 I slot print_timing: id 2 | task 0 | draft acceptance = 0.52496 ( 1830 accepted / 3486 generated) 1.06.432.832 I statistics draft-mtp: #calls(b,g,a) = 1 1162 1162, #gen drafts = 1162, #acc drafts = 873, #gen tokens = 3486, #acc tokens = 1832, dur(b,g,a) = 0.001, 8674.658, 0.563 ms 2026-05-26 03:17:34 [DEBUG] 1.06.432.925 I slot release: id 2 | task 0 | stop processing: n_tokens = 4464, truncated = 0 1.06.432.942 I srv update_slots: all slots are idle 2026-05-26 03:17:34 [DEBUG] LlamaV4: server assigned slot 2 to task 0
5080 + 5060 TI
(cpu后补的) 54%



2026-05-26 03:20:32 [DEBUG] LlamaV4::load called with model path: C:\Users\user\.lmstudio\models\unsloth\Qwen3.6-35B-A3B-MTP-GGUF\Qwen3.6-35B-A3B-UD-Q5_K_M.gguf LlamaV4::load config: n_parallel=3 n_ctx=122144 kv_unified=true 2026-05-26 03:20:33 [DEBUG] 0.00.042.601 I srv load_model: loading model 'C:\Users\user\.lmstudio\models\unsloth\Qwen3.6-35B-A3B-MTP-GGUF\Qwen3.6-35B-A3B-UD-Q5_K_M.gguf' 2026-05-26 03:20:42 [DEBUG] 0.09.165.654 W llama_context: n_ctx_seq (122368) < n_ctx_train (262144) -- the full capacity of the model will not be utilized 2026-05-26 03:20:42 [DEBUG] 0.09.249.067 W sched_reserve: layer 0 is assigned to device CPU but the fused Gated Delta Net tensor is assigned to device CUDA0 (usually due to missing support) 0.09.249.073 W sched_reserve: fused Gated Delta Net (chunked) not supported, set to disabled 2026-05-26 03:20:42 [DEBUG] 0.09.277.167 W common_init_from_params: KV cache shifting is not supported for this context, disabling KV cache shifting 0.09.277.178 I common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable) 2026-05-26 03:20:42 [DEBUG] 0.09.704.231 I srv load_model: creating MTP draft context against the target model 'C:\Users\user\.lmstudio\models\unsloth\Qwen3.6-35B-A3B-MTP-GGUF\Qwen3.6-35B-A3B-UD-Q5_K_M.gguf' 0.09.704.290 W llama_context: n_ctx_seq (122368) < n_ctx_train (262144) -- the full capacity of the model will not be utilized 2026-05-26 03:20:42 [DEBUG] 0.09.826.091 W load_hparams: Qwen-VL models require at minimum 1024 image tokens to function correctly on grounding tasks 0.09.826.098 W load_hparams: if you encounter problems with accuracy, try adding --image-min-tokens 1024 0.09.826.099 W load_hparams: more info: https://github.com/ggml-org/llama.cpp/issues/16842 2026-05-26 03:20:43 [DEBUG] 0.10.771.065 I srv load_model: loaded multimodal model, 'C:/Users/user/.lmstudio/models/unsloth/Qwen3.6-35B-A3B-MTP-GGUF/mmproj-F32.gguf' 0.10.771.074 I srv load_model: initializing slots, n_slots = 3 2026-05-26 03:20:43 [DEBUG] 0.10.893.676 I common_context_can_seq_rm: the context supports bounded partial sequence removal 2026-05-26 03:20:43 [DEBUG] 0.10.978.672 I common_speculative_impl_draft_mtp: adding speculative implementation 'draft-mtp' 0.10.978.679 I common_speculative_impl_draft_mtp: - n_max=3, n_min=0, p_min=0.00, n_embd=2048, backend_sampling=1 0.10.978.684 I common_speculative_impl_draft_mtp: - gpu_layers=-1, cache_k=f16, cache_v=f16, ctx_tgt=yes, ctx_dft=yes, devices=[default] 2026-05-26 03:20:43 [DEBUG] 0.10.979.181 I srv load_model: speculative decoding context initialized 0.10.979.184 I slot load_model: id 0 | task -1 | new slot, n_ctx = 122368 0.10.979.189 I slot load_model: id 1 | task -1 | new slot, n_ctx = 122368 0.10.979.189 I slot load_model: id 2 | task -1 | new slot, n_ctx = 122368 0.10.979.554 I srv load_model: prompt cache is enabled, size limit: 8192 MiB 0.10.979.557 I srv load_model: use `--cache-ram 0` to disable the prompt cache 0.10.979.557 I srv load_model: for more info see https://github.com/ggml-org/llama.cpp/pull/16391 0.10.979.585 I srv init: idle slots will be saved to prompt cache and cleared upon starting a new task 2026-05-26 03:20:43 [DEBUG] 0.10.981.001 I init: chat template, example_format: 'You are a helpful assistantHelloHi thereHow are you?' 2026-05-26 03:20:43 [DEBUG] 0.10.981.453 I srv init: init: chat template, thinking = 0 0.10.981.764 I srv update_slots: all slots are idle 2026-05-26 03:21:14 [DEBUG] LlamaV4::predict slot selection: session_id=<empty> server-selected (LCP/LRU) 2026-05-26 03:21:14 [DEBUG] 0.41.142.122 I slot get_availabl: id 2 | task -1 | selected slot by LRU, t_last = -1 0.41.142.126 I srv get_availabl: updating prompt cache 0.41.142.135 I srv load: - looking for better prompt, base f_keep = -1.000, sim = 0.000 0.41.142.139 I srv update: - cache state: 0 prompts, 0.000 MiB (limits: 8192.000 MiB, 122368 tokens, 8589934592 est) 0.41.142.142 I srv get_availabl: prompt cache update took 0.01 ms 0.41.142.164 I slot launch_slot_: id 2 | task 0 | processing task, is_child = 0 0.41.142.174 W slot update_slots: id 2 | task 0 | cache reuse is not supported - ignoring n_cache_reuse = 256 2026-05-26 03:21:15 [DEBUG] 0.42.203.796 I slot create_check: id 2 | task 0 | created context checkpoint 1 of 32 (pos_min = 953, pos_max = 953, n_tokens = 954, size = 63.356 MiB) 2026-05-26 03:21:15 [DEBUG] 0.42.589.912 I slot create_check: id 2 | task 0 | created context checkpoint 2 of 32 (pos_min = 1465, pos_max = 1465, n_tokens = 1466, size = 63.647 MiB) 2026-05-26 03:21:17 [DEBUG] 0.44.136.037 I slot print_timing: id 2 | task 0 | n_decoded = 101, tg = 68.20 t/s 2026-05-26 03:21:20 [DEBUG] 0.47.179.351 I slot print_timing: id 2 | task 0 | n_decoded = 296, tg = 65.43 t/s 2026-05-26 03:21:23 [DEBUG] 0.50.221.447 I slot print_timing: id 2 | task 0 | n_decoded = 486, tg = 64.23 t/s 2026-05-26 03:21:26 [DEBUG] 0.53.223.641 I slot print_timing: id 2 | task 0 | n_decoded = 673, tg = 63.68 t/s 2026-05-26 03:21:29 [DEBUG] 0.56.268.298 I slot print_timing: id 2 | task 0 | n_decoded = 833, tg = 61.19 t/s 2026-05-26 03:21:32 [DEBUG] 0.59.273.712 I slot print_timing: id 2 | task 0 | n_decoded = 1023, tg = 61.56 t/s 2026-05-26 03:21:35 [DEBUG] 1.02.307.391 I slot print_timing: id 2 | task 0 | n_decoded = 1188, tg = 60.45 t/s 2026-05-26 03:21:38 [DEBUG] 1.05.349.065 I slot print_timing: id 2 | task 0 | n_decoded = 1385, tg = 61.03 t/s 2026-05-26 03:21:41 [DEBUG] 1.08.353.572 I slot print_timing: id 2 | task 0 | n_decoded = 1559, tg = 60.67 t/s 2026-05-26 03:21:44 [DEBUG] 1.11.380.609 I slot print_timing: id 2 | task 0 | n_decoded = 1723, tg = 59.98 t/s 2026-05-26 03:21:47 [DEBUG] 1.14.386.324 I slot print_timing: id 2 | task 0 | n_decoded = 1925, tg = 60.67 t/s 2026-05-26 03:21:50 [DEBUG] 1.17.421.446 I slot print_timing: id 2 | task 0 | n_decoded = 2126, tg = 61.15 t/s 2026-05-26 03:21:53 [DEBUG] 1.20.445.908 I slot print_timing: id 2 | task 0 | n_decoded = 2310, tg = 61.13 t/s 2026-05-26 03:21:56 [DEBUG] 1.23.479.436 I slot print_timing: id 2 | task 0 | n_decoded = 2497, tg = 61.16 t/s 2026-05-26 03:21:59 [DEBUG] 1.26.518.332 I slot print_timing: id 2 | task 0 | n_decoded = 2672, tg = 60.92 t/s 2026-05-26 03:22:02 [DEBUG] 1.29.551.405 I slot print_timing: id 2 | task 0 | n_decoded = 2904, tg = 61.92 t/s 2026-05-26 03:22:05 [DEBUG] 1.32.596.791 I slot print_timing: id 2 | task 0 | n_decoded = 3071, tg = 61.49 t/s 2026-05-26 03:22:06 [DEBUG] 1.33.650.974 I slot print_timing: id 2 | task 0 | prompt eval time = 1512.86 ms / 1470 tokens ( 1.03 ms per token, 971.67 tokens per second) 1.33.650.981 I slot print_timing: id 2 | task 0 | eval time = 50995.81 ms / 3126 tokens ( 16.31 ms per token, 61.30 tokens per second) 1.33.650.982 I slot print_timing: id 2 | task 0 | total time = 52508.67 ms / 4596 tokens 1.33.650.983 I slot print_timing: id 2 | task 0 | graphs reused = 1141 1.33.650.984 I slot print_timing: id 2 | task 0 | draft acceptance = 0.57040 ( 1973 accepted / 3459 generated) 1.33.651.012 I statistics draft-mtp: #calls(b,g,a) = 1 1153 1153, #gen drafts = 1153, #acc drafts = 901, #gen tokens = 3459, #acc tokens = 1974, dur(b,g,a) = 0.000, 7190.776, 0.704 ms 2026-05-26 03:22:06 [DEBUG] 1.33.651.138 I slot release: id 2 | task 0 | stop processing: n_tokens = 4597, truncated = 0 1.33.651.156 I srv update_slots: all slots are idle 2026-05-26 03:22:06 [DEBUG] LlamaV4: server assigned slot 2 to task 0 -
从纯游戏机改成游戏+AI双用机,Qwen 3.6 27B MTP 速度只有 37 t/s,求大神指点怎么升级补一补hermes的log
──────────────────────────────────────── ● search this https://lcz.me/category/7/llm%E8%AE%A8%E8%AE%BA%E5%8C%BA it have more posts ──────────────────────────────────────── ┊ 🌐 preparing browser_navigate… ┊ 🌐 navigate lcz.me 2.8s ┊ 🖥️ preparing browser_console… ┊ ⚡ browser_c 0.2s ┊ 🌐 preparing browser_navigate… ┊ 🌐 navigate lcz.me 1.4s ┊ 🖥️ preparing browser_console… ┊ ⚡ browser_c 0.2s ┊ 🖥️ preparing browser_console… ┊ ⚡ browser_c 0.2s ┊ 🌐 preparing browser_navigate… ┊ 🌐 navigate lcz.me 1.0s ┊ 🖥️ preparing browser_console… ┊ ⚡ browser_c 0.2s ┊ 🌐 preparing browser_navigate… ┊ 🌐 navigate lcz.me 1.1s ┊ 🖥️ preparing browser_console… ┊ ⚡ browser_c 0.2s ╭─ ⚕ Hermes ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ Perfect! Now I have comprehensive data from both categories. Let me compile everything for you: 📊 Forum 完整搜索结果汇总 LLM讨论区关键发现: 1. RTX 4080 (32GB) & RTX 4090 (48GB) 对比测试 (Michael Zhou): - Qwen3.6-27B FP8 + vLLM: 37 t/s - QuantTrio AWQ INT4 + MTP s=3: 81 t/s (单流), 208 t/s (并发3) 2. RTX 5090 实测 (rem): - Qwen3.6-27B-Heretic-W4G128 + vLLM: 平均 43.5 t/s, 日志看到过 86 t/s - TTFT: 第一次 281ms → prefix cache命中后 69ms (快4倍!) 3. 双 7900 XTX (各24GB) MTP 优化记录: - Qwen3.6-27B + llama.cpp ROCm: ~35 t/s - PCIe 4.0 x16 带宽翻倍 = sync延迟缩短约一半 🎯 RTX 5070 Ti vs 你的配置对比表 | GPU | VRAM | Qwen3.6-27B (t/s) | MTP支持 | CP评级 | |-----|------|------------------|---------|--------| | 你现有: RTX 5080 | 16GB | ~49 (IQ4_XS) | ✅ | ⭐⭐⭐ | | RTX 5070 Ti (预估) | ~24GB | 70-80+ | ✅✅ | ⭐⭐⭐⭐⭐ | | RTX 5090 (论坛实测) | 32GB | 43.5~86 | ✅✅ | ⭐⭐⭐⭐ | | AMD 7900XTX x2 (双卡) | 2x24GB | ~35-40 | ❌ | ⭐⭐⭐⭐ | 💡 最终建议:RTX 5070 Ti 是最佳 CP 选择 ✅ 为什么? 1. 显存从 16GB → ~24GB = KV cache + MTP draft model 不再拥挤 2. 带宽提升 = LLM 推理速度直接受益(论坛数据证明) 3. 单卡方案 = 无 TP 同步延迟,无需担心 PCIe 瓶颈 4. 价格优势 ≈ ¥4,500-$6,000 RMB vs 二手 4090 (¥12k-14k) 你现在应该做的: 1. 确认 RTX 5070 Ti 是否已发布/上市(论坛主要讨论的是 AMD 卡和 NVIDIA 高端卡) 2. 如果 5070 Ti 没出 → 考虑二手 RTX 3090 (¥3,500-4k) + 你的 5080 组双卡 3. 或者等论坛更多 5070 Ti 评测帖出现再决定 要我帮你回复帖子继续讨论吗? ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ⚕ qwen3.6-27b-uncensored-... │ 110K/262.1K │ [████░░░░░░] 42% │ 1h 57m │ ⏲ 2m 41s ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ❯ ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
其中一段log 这个好像卡了prompt processing有点慢2026-05-26 01:55:06 [DEBUG] LlamaV4::predict slot selection: session_id=<empty> server-selected (LCP/LRU) 2026-05-26 01:55:06 [DEBUG] 2.49.228.089 I slot get_availabl: id 0 | task -1 | selected slot by LRU, t_last = -1 2.49.228.096 I srv get_availabl: updating prompt cache 2.49.228.100 I srv load: - looking for better prompt, base f_keep = -1.000, sim = 0.000 2.49.228.103 I srv update: - cache state: 0 prompts, 0.000 MiB (limits: 8192.000 MiB, 262144 tokens, 8589934592 est) 2.49.228.104 I srv get_availabl: prompt cache update took 0.01 ms 2.49.228.160 I slot launch_slot_: id 0 | task 823 | processing task, is_child = 0 2.49.228.163 I slot slot_save_an: id 1 | task -1 | saving idle slot to prompt cache 2026-05-26 01:55:06 [DEBUG] 2.49.236.750 W srv prompt_save: - saving prompt with length 111121, total state size = 2229.245 MiB (draft: 124.201 MiB) 2026-05-26 01:55:08 [DEBUG] 2.51.254.262 I slot prompt_clear: id 1 | task -1 | clearing prompt with 111121 tokens 2026-05-26 01:55:08 [DEBUG] 2.51.281.229 I srv update: - cache state: 1 prompts, 9486.766 MiB (limits: 8192.000 MiB, 262144 tokens, 262144 est) 2.51.281.235 I srv update: - prompt 0000040D9D512EF0: 111121 tokens, checkpoints: 30, 9486.766 MiB 2.51.281.247 W slot update_slots: id 0 | task 823 | cache reuse is not supported - ignoring n_cache_reuse = 256 2026-05-26 01:55:08 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 0.0% 2026-05-26 01:55:10 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 4.0% 2026-05-26 01:55:12 [DEBUG] 2.55.238.316 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 8192, progress = 0.08, t = 3.96 s / 2070.22 tokens per second 2026-05-26 01:55:12 [DEBUG] 2.55.238.855 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 0, creating new checkpoint during processing at position 12288 2026-05-26 01:55:12 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 8.0% 2026-05-26 01:55:12 [DEBUG] 2.55.284.543 I slot create_check: id 0 | task 823 | created context checkpoint 1 of 32 (pos_min = 8191, pos_max = 8191, n_tokens = 8192, size = 158.782 MiB) 2026-05-26 01:55:14 [DEBUG] 2.57.358.731 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 12288, progress = 0.12, t = 6.08 s / 2021.89 tokens per second 2026-05-26 01:55:14 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 12.0% 2026-05-26 01:55:17 [DEBUG] 2.59.502.451 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 16384, progress = 0.16, t = 8.22 s / 1992.90 tokens per second 2026-05-26 01:55:17 [DEBUG] 2.59.502.880 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 8192, creating new checkpoint during processing at position 20480 2026-05-26 01:55:17 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 16.0% 2026-05-26 01:55:17 [DEBUG] 2.59.550.933 I slot create_check: id 0 | task 823 | created context checkpoint 2 of 32 (pos_min = 16383, pos_max = 16383, n_tokens = 16384, size = 167.939 MiB) 2026-05-26 01:55:19 [DEBUG] 3.01.774.168 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 20480, progress = 0.20, t = 10.49 s / 1951.79 tokens per second 2026-05-26 01:55:19 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 20.0% 2026-05-26 01:55:21 [DEBUG] 3.04.080.558 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 24576, progress = 0.24, t = 12.80 s / 1920.10 tokens per second 2026-05-26 01:55:21 [DEBUG] 3.04.080.943 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 16384, creating new checkpoint during processing at position 28672 2026-05-26 01:55:21 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 23.9% 2026-05-26 01:55:21 [DEBUG] 3.04.135.630 I slot create_check: id 0 | task 823 | created context checkpoint 3 of 32 (pos_min = 24575, pos_max = 24575, n_tokens = 24576, size = 177.095 MiB) 2026-05-26 01:55:24 [DEBUG] 3.06.529.554 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 28672, progress = 0.28, t = 15.25 s / 1880.34 tokens per second 2026-05-26 01:55:24 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 27.9% 2026-05-26 01:55:26 [DEBUG] 3.09.014.985 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 32768, progress = 0.32, t = 17.73 s / 1847.78 tokens per second 2026-05-26 01:55:26 [DEBUG] 3.09.015.349 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 24576, creating new checkpoint during processing at position 36864 2026-05-26 01:55:26 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 31.9% 2026-05-26 01:55:26 [DEBUG] 3.09.066.771 I slot create_check: id 0 | task 823 | created context checkpoint 4 of 32 (pos_min = 32767, pos_max = 32767, n_tokens = 32768, size = 186.251 MiB) 2026-05-26 01:55:29 [DEBUG] 3.11.626.265 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 36864, progress = 0.36, t = 20.35 s / 1811.94 tokens per second 2026-05-26 01:55:29 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 35.9% 2026-05-26 01:55:31 [DEBUG] 3.14.262.589 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 40960, progress = 0.40, t = 22.98 s / 1782.32 tokens per second 2026-05-26 01:55:31 [DEBUG] 3.14.262.985 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 32768, creating new checkpoint during processing at position 45056 2026-05-26 01:55:31 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 39.9% 2026-05-26 01:55:31 [DEBUG] 3.14.326.857 I slot create_check: id 0 | task 823 | created context checkpoint 5 of 32 (pos_min = 40959, pos_max = 40959, n_tokens = 40960, size = 195.407 MiB) 2026-05-26 01:55:34 [DEBUG] 3.17.054.852 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 45056, progress = 0.44, t = 25.77 s / 1748.15 tokens per second 2026-05-26 01:55:34 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 43.9% 2026-05-26 01:55:37 [DEBUG] 3.19.851.457 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 49152, progress = 0.48, t = 28.57 s / 1720.39 tokens per second 2026-05-26 01:55:37 [DEBUG] 3.19.851.849 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 40960, creating new checkpoint during processing at position 53248 2026-05-26 01:55:37 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 47.9% 2026-05-26 01:55:37 [DEBUG] 3.19.921.417 I slot create_check: id 0 | task 823 | created context checkpoint 6 of 32 (pos_min = 49151, pos_max = 49151, n_tokens = 49152, size = 204.564 MiB) 2026-05-26 01:55:40 [DEBUG] 3.22.797.914 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 53248, progress = 0.52, t = 31.52 s / 1689.52 tokens per second 2026-05-26 01:55:40 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 51.9% 2026-05-26 01:55:43 [DEBUG] 3.25.751.545 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 57344, progress = 0.56, t = 34.47 s / 1663.58 tokens per second 2026-05-26 01:55:43 [DEBUG] 3.25.751.888 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 49152, creating new checkpoint during processing at position 61440 2026-05-26 01:55:43 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 55.9% 2026-05-26 01:55:43 [DEBUG] 3.25.825.218 I slot create_check: id 0 | task 823 | created context checkpoint 7 of 32 (pos_min = 57343, pos_max = 57343, n_tokens = 57344, size = 213.720 MiB) 2026-05-26 01:55:46 [DEBUG] 3.28.859.117 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 61440, progress = 0.60, t = 37.58 s / 1635.01 tokens per second 2026-05-26 01:55:46 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 59.9% 2026-05-26 01:55:49 [DEBUG] 3.31.976.086 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 65536, progress = 0.64, t = 40.69 s / 1610.43 tokens per second 2026-05-26 01:55:49 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 63.9% 2026-05-26 01:55:49 [DEBUG] 3.31.976.461 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 57344, creating new checkpoint during processing at position 69632 2026-05-26 01:55:49 [DEBUG] 3.32.057.800 I slot create_check: id 0 | task 823 | created context checkpoint 8 of 32 (pos_min = 65535, pos_max = 65535, n_tokens = 65536, size = 222.876 MiB) 2026-05-26 01:55:52 [DEBUG] 3.35.255.641 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 69632, progress = 0.68, t = 43.97 s / 1583.47 tokens per second 2026-05-26 01:55:52 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 67.8% 2026-05-26 01:55:56 [DEBUG] 3.38.536.009 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 73728, progress = 0.72, t = 47.25 s / 1560.22 tokens per second 2026-05-26 01:55:56 [DEBUG] 3.38.536.397 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 65536, creating new checkpoint during processing at position 77824 2026-05-26 01:55:56 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 71.8% 2026-05-26 01:55:56 [DEBUG] 3.38.624.601 I slot create_check: id 0 | task 823 | created context checkpoint 9 of 32 (pos_min = 73727, pos_max = 73727, n_tokens = 73728, size = 232.032 MiB) 2026-05-26 01:55:59 [DEBUG] 3.41.998.454 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 77824, progress = 0.76, t = 50.72 s / 1534.47 tokens per second 2026-05-26 01:55:59 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 75.8% 2026-05-26 01:56:03 [DEBUG] 3.45.462.050 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 81920, progress = 0.80, t = 54.18 s / 1511.97 tokens per second 2026-05-26 01:56:03 [DEBUG] 3.45.462.417 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 73728, creating new checkpoint during processing at position 86016 2026-05-26 01:56:03 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 79.8% 2026-05-26 01:56:03 [DEBUG] 3.45.551.951 I slot create_check: id 0 | task 823 | created context checkpoint 10 of 32 (pos_min = 81919, pos_max = 81919, n_tokens = 81920, size = 241.189 MiB) 2026-05-26 01:56:06 [DEBUG] 3.49.105.522 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 86016, progress = 0.84, t = 57.82 s / 1487.54 tokens per second 2026-05-26 01:56:06 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 83.8% 2026-05-26 01:56:10 [DEBUG] 3.52.735.222 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 90112, progress = 0.88, t = 61.45 s / 1466.33 tokens per second 2026-05-26 01:56:10 [DEBUG] 3.52.735.637 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 81920, creating new checkpoint during processing at position 94208 2026-05-26 01:56:10 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 87.8% 2026-05-26 01:56:10 [DEBUG] 3.52.834.750 I slot create_check: id 0 | task 823 | created context checkpoint 11 of 32 (pos_min = 90111, pos_max = 90111, n_tokens = 90112, size = 250.345 MiB) 2026-05-26 01:56:14 [DEBUG] 3.56.551.665 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 94208, progress = 0.92, t = 65.27 s / 1443.35 tokens per second 2026-05-26 01:56:14 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 91.8% 2026-05-26 01:56:17 [DEBUG] 4.00.372.963 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 98304, progress = 0.96, t = 69.09 s / 1422.80 tokens per second 2026-05-26 01:56:17 [DEBUG] 4.00.373.317 I slot update_slots: id 0 | task 823 | 8192 tokens since last checkpoint at 90112, creating new checkpoint during processing at position 102122 2026-05-26 01:56:17 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 95.8% 2026-05-26 01:56:18 [DEBUG] 4.00.470.886 I slot create_check: id 0 | task 823 | created context checkpoint 12 of 32 (pos_min = 98303, pos_max = 98303, n_tokens = 98304, size = 259.501 MiB) 2026-05-26 01:56:21 [DEBUG] 4.04.142.790 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 102122, progress = 0.99, t = 72.86 s / 1401.59 tokens per second 2026-05-26 01:56:21 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 99.5% 2026-05-26 01:56:21 [DEBUG] 4.04.245.109 I slot create_check: id 0 | task 823 | created context checkpoint 13 of 32 (pos_min = 102121, pos_max = 102121, n_tokens = 102122, size = 263.769 MiB) 2026-05-26 01:56:22 [DEBUG] 4.05.069.628 I slot print_timing: id 0 | task 823 | prompt processing, n_tokens = 102634, progress = 1.00, t = 73.79 s / 1390.92 tokens per second 2026-05-26 01:56:22 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 100.0% 2026-05-26 01:56:22 [DEBUG] 4.05.173.737 I slot create_check: id 0 | task 823 | created context checkpoint 14 of 32 (pos_min = 102633, pos_max = 102633, n_tokens = 102634, size = 264.341 MiB) 2026-05-26 01:56:22 [INFO] [qwen3.6-27b-uncensored-abliterated-mtp-i1-smaller] Prompt processing progress: 100.0% 2026-05-26 01:56:26 [DEBUG] 4.08.487.088 I slot print_timing: id 0 | task 823 | n_decoded = 100, tg = 30.87 t/s 2026-05-26 01:56:27 [DEBUG] 4.10.362.290 I slot print_timing: id 0 | task 823 | prompt eval time = 73966.44 ms / 102638 tokens ( 0.72 ms per token, 1387.63 tokens per second) 4.10.362.296 I slot print_timing: id 0 | task 823 | eval time = 5114.39 ms / 155 tokens ( 33.00 ms per token, 30.31 tokens per second) 4.10.362.297 I slot print_timing: id 0 | task 823 | total time = 79080.83 ms / 102793 tokens 4.10.362.298 I slot print_timing: id 0 | task 823 | graphs reused = 806 4.10.362.299 I slot print_timing: id 0 | task 823 | draft acceptance = 0.45641 ( 89 accepted / 195 generated) 4.10.362.319 I statistics draft-mtp: #calls(b,g,a) = 11 827 827, #gen drafts = 827, #acc drafts = 638, #gen tokens = 2481, #acc tokens = 1536, dur(b,g,a) = 0.006, 14288.555, 0.495 ms 2026-05-26 01:56:27 [DEBUG] 4.10.363.793 I slot release: id 0 | task 823 | stop processing: n_tokens = 102792, truncated = 0 4.10.363.804 I srv update_slots: all slots are idle 2026-05-26 01:56:27 [DEBUG] LlamaV4: server assigned slot 0 to task 823另外应该不会卖卡 理论上5080 + 5070 TI + 5060 TI + 3060 应该放得下
之后可能会学comfyUI 但不是刚需 -
从纯游戏机改成游戏+AI双用机,Qwen 3.6 27B MTP 速度只有 37 t/s,求大神指点怎么升级@Xiaote
其實我主要想補一張 5070 Ti,目標是組成 5080 + 5070 Ti + 5060 Ti 三張卡。2026-05-26 00:20:55 [DEBUG] LlamaV4::load called with model path: C:\Users\user\.lmstudio\models\lmstudio-community\Qwen3.6-27B-GGUF\Qwen3.6-27B-Q4_K_M.gguf LlamaV4::load config: n_parallel=1 n_ctx=132144 kv_unified=true 2026-05-26 00:20:55 [DEBUG] 0.00.043.210 I srv load_model: loading model 'C:\Users\user\.lmstudio\models\lmstudio-community\Qwen3.6-27B-GGUF\Qwen3.6-27B-Q4_K_M.gguf' 2026-05-26 00:21:01 [DEBUG] 0.06.171.283 W llama_context: n_ctx_seq (132352) < n_ctx_train (262144) -- the full capacity of the model will not be utilized 2026-05-26 00:21:01 [DEBUG] 0.06.295.851 W common_init_from_params: KV cache shifting is not supported for this context, disabling KV cache shifting 0.06.295.863 I common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable) 2026-05-26 00:21:01 [DEBUG] 0.06.502.458 I srv load_model: initializing slots, n_slots = 1 2026-05-26 00:21:01 [DEBUG] 0.06.562.459 W srv load_model: speculative decoding will use checkpoints 0.06.562.468 W common_speculative_init: no implementations specified for speculative decoding 0.06.562.469 I slot load_model: id 0 | task -1 | new slot, n_ctx = 132352 0.06.562.490 I srv load_model: prompt cache is enabled, size limit: 8192 MiB 0.06.562.491 I srv load_model: use `--cache-ram 0` to disable the prompt cache 0.06.562.491 I srv load_model: for more info see https://github.com/ggml-org/llama.cpp/pull/16391 0.06.562.509 I srv init: idle slots will be saved to prompt cache and cleared upon starting a new task 2026-05-26 00:21:01 [DEBUG] 0.06.563.830 I init: chat template, example_format: 'You are a helpful assistantHelloHi thereHow are you?' 2026-05-26 00:21:01 [DEBUG] 0.06.564.256 I srv init: init: chat template, thinking = 0 0.06.564.497 I srv update_slots: all slots are idle 2026-05-26 00:21:03 [DEBUG] LlamaV4::predict slot selection: session_id=<empty> server-selected (LCP/LRU) 2026-05-26 00:21:03 [DEBUG] 0.08.555.629 I slot get_availabl: id 0 | task -1 | selected slot by LRU, t_last = -1 0.08.555.633 I srv get_availabl: updating prompt cache 0.08.555.643 I srv load: - looking for better prompt, base f_keep = -1.000, sim = 0.000 0.08.555.646 I srv update: - cache state: 0 prompts, 0.000 MiB (limits: 8192.000 MiB, 132352 tokens, 8589934592 est) 0.08.555.648 I srv get_availabl: prompt cache update took 0.01 ms 0.08.555.668 I slot launch_slot_: id 0 | task 0 | processing task, is_child = 0 0.08.555.676 W slot update_slots: id 0 | task 0 | cache reuse is not supported - ignoring n_cache_reuse = 256 2026-05-26 00:21:04 [DEBUG] 0.09.277.868 I slot create_check: id 0 | task 0 | created context checkpoint 1 of 32 (pos_min = 957, pos_max = 957, n_tokens = 958, size = 149.626 MiB) 2026-05-26 00:21:05 [DEBUG] 0.09.716.647 I slot create_check: id 0 | task 0 | created context checkpoint 2 of 32 (pos_min = 1465, pos_max = 1465, n_tokens = 1466, size = 149.626 MiB) 2026-05-26 00:21:07 [DEBUG] 0.12.561.771 I slot print_timing: id 0 | task 0 | n_decoded = 100, tg = 36.14 t/s 2026-05-26 00:21:10 [DEBUG] 0.15.569.755 I slot print_timing: id 0 | task 0 | n_decoded = 209, tg = 36.19 t/s 2026-05-26 00:21:13 [DEBUG] 0.18.572.721 I slot print_timing: id 0 | task 0 | n_decoded = 318, tg = 36.23 t/s 2026-05-26 00:21:16 [DEBUG] 0.21.573.654 I slot print_timing: id 0 | task 0 | n_decoded = 426, tg = 36.17 t/s 2026-05-26 00:21:19 [DEBUG] 0.24.585.790 I slot print_timing: id 0 | task 0 | n_decoded = 535, tg = 36.17 t/s 2026-05-26 00:21:23 [DEBUG] 0.27.611.004 I slot print_timing: id 0 | task 0 | n_decoded = 644, tg = 36.15 t/s 2026-05-26 00:21:26 [DEBUG] 0.30.627.929 I slot print_timing: id 0 | task 0 | n_decoded = 753, tg = 36.14 t/s 2026-05-26 00:21:29 [DEBUG] 0.33.654.559 I slot print_timing: id 0 | task 0 | n_decoded = 862, tg = 36.13 t/s 2026-05-26 00:21:32 [DEBUG] 0.36.673.020 I slot print_timing: id 0 | task 0 | n_decoded = 971, tg = 36.13 t/s 2026-05-26 00:21:35 [DEBUG] 0.39.691.507 I slot print_timing: id 0 | task 0 | n_decoded = 1080, tg = 36.12 t/s 2026-05-26 00:21:38 [DEBUG] 0.42.705.623 I slot print_timing: id 0 | task 0 | n_decoded = 1188, tg = 36.10 t/s 2026-05-26 00:21:41 [DEBUG] 0.45.707.228 I slot print_timing: id 0 | task 0 | n_decoded = 1296, tg = 36.09 t/s 2026-05-26 00:21:44 [DEBUG] 0.48.724.452 I slot print_timing: id 0 | task 0 | n_decoded = 1404, tg = 36.07 t/s 2026-05-26 00:21:47 [DEBUG] 0.51.727.949 I slot print_timing: id 0 | task 0 | n_decoded = 1512, tg = 36.06 t/s 2026-05-26 00:21:50 [DEBUG] 0.54.745.149 I slot print_timing: id 0 | task 0 | n_decoded = 1620, tg = 36.04 t/s 2026-05-26 00:21:53 [DEBUG] 0.57.753.754 I slot print_timing: id 0 | task 0 | n_decoded = 1728, tg = 36.03 t/s 2026-05-26 00:21:56 [DEBUG] 1.00.769.040 I slot print_timing: id 0 | task 0 | n_decoded = 1836, tg = 36.02 t/s 2026-05-26 00:21:59 [DEBUG] 1.03.775.125 I slot print_timing: id 0 | task 0 | n_decoded = 1943, tg = 35.99 t/s 2026-05-26 00:22:02 [DEBUG] 1.06.797.168 I slot print_timing: id 0 | task 0 | n_decoded = 2051, tg = 35.98 t/s 2026-05-26 00:22:05 [DEBUG] 1.09.809.020 I slot print_timing: id 0 | task 0 | n_decoded = 2158, tg = 35.96 t/s 2026-05-26 00:22:08 [DEBUG] 1.12.809.424 I slot print_timing: id 0 | task 0 | n_decoded = 2265, tg = 35.94 t/s 2026-05-26 00:22:11 [DEBUG] 1.15.823.439 I slot print_timing: id 0 | task 0 | n_decoded = 2372, tg = 35.92 t/s 2026-05-26 00:22:14 [DEBUG] 1.18.833.805 I slot print_timing: id 0 | task 0 | n_decoded = 2479, tg = 35.91 t/s 2026-05-26 00:22:17 [DEBUG] 1.21.841.117 I slot print_timing: id 0 | task 0 | n_decoded = 2586, tg = 35.89 t/s 2026-05-26 00:22:20 [DEBUG] 1.24.864.105 I slot print_timing: id 0 | task 0 | n_decoded = 2693, tg = 35.87 t/s 2026-05-26 00:22:23 [DEBUG] 1.27.875.703 I slot print_timing: id 0 | task 0 | n_decoded = 2800, tg = 35.86 t/s 2026-05-26 00:22:26 [DEBUG] 1.30.902.157 I slot print_timing: id 0 | task 0 | n_decoded = 2907, tg = 35.84 t/s 2026-05-26 00:22:29 [DEBUG] 1.33.922.191 I slot print_timing: id 0 | task 0 | n_decoded = 3014, tg = 35.83 t/s 2026-05-26 00:22:32 [DEBUG] 1.36.938.672 I slot print_timing: id 0 | task 0 | n_decoded = 3121, tg = 35.81 t/s 2026-05-26 00:22:35 [DEBUG] 1.39.947.030 I slot print_timing: id 0 | task 0 | n_decoded = 3227, tg = 35.80 t/s 2026-05-26 00:22:38 [DEBUG] 1.42.972.363 I slot print_timing: id 0 | task 0 | n_decoded = 3334, tg = 35.78 t/s 2026-05-26 00:22:41 [DEBUG] 1.45.986.215 I slot print_timing: id 0 | task 0 | n_decoded = 3440, tg = 35.76 t/s 2026-05-26 00:22:44 [DEBUG] 1.48.989.937 I slot print_timing: id 0 | task 0 | n_decoded = 3546, tg = 35.75 t/s 2026-05-26 00:22:44 [DEBUG] 1.49.074.914 I slot print_timing: id 0 | task 0 | prompt eval time = 1239.17 ms / 1470 tokens ( 0.84 ms per token, 1186.28 tokens per second) 1.49.074.917 I slot print_timing: id 0 | task 0 | eval time = 99280.06 ms / 3549 tokens ( 27.97 ms per token, 35.75 tokens per second) 1.49.074.918 I slot print_timing: id 0 | task 0 | total time = 100519.23 ms / 5019 tokens 1.49.074.919 I slot print_timing: id 0 | task 0 | graphs reused = 3534 1.49.074.993 I slot release: id 0 | task 0 | stop processing: n_tokens = 5018, truncated = 0 1.49.075.008 I srv update_slots: all slots are idle 2026-05-26 00:22:44 [DEBUG] LlamaV4: server assigned slot 0 to task 0我目前用 5080 + 5060 Ti 跑普通 Qwen 3.6 27B Q4_K_M(132k context,沒開 MTP)的速度只有 35~36 t/s(log 貼上面了)。 3060 不支援 MTP,而且很容易 checkpoint stuck 或 CUDA error,穩定性很差。
我想要 5070 Ti 的主要原因:
-
三張 Blackwell 卡比較平衡
5080 + 5070 Ti + 5060 Ti 全是 50 系列,架構一樣,llama.cpp 分層會更順,不像現在混 3060 那麼容易出問題。 -
總 VRAM 達到 48GB
目前 32GB 在 132k context 還是會有點吃力,如果能到 48GB,應該能更穩地跑大 context,又不用 offload。 -
想把 27B 速度推到 70-90+ t/s
現在 37 t/s 寫 code 還是會覺得有點慢,如果三張 50 系列卡應該能明顯提升,而且 MTP 也會更穩定。
補一張 5070 Ti 好像比5080更划算,能把現在三張卡都充分利用。
不知道這個思路對不對,還是不加卡比較好。
-