minicpm47woek_EPQ / docs /NEGATIVE_RESULTS.md
HelloSun's picture
EPM: expert paging CPU inference for MiniCPM-V-4.7-35B-A3B Q4_K_M
12eb3a5 verified
|
Raw History Blame Contribute Delete
2.97 kB
# 負結果:試過但沒留下的最佳化
記錄在 8 GiB 上**量過、放棄**的選項。每一項都有原始資料在
`bench/results/strict_prefetch.json` 與 `bench/results/strict_threads.json`。
## 1. 預取(關閉)
pager 可以從上一個 token 的路由預測下一層會用到哪些 expert,在本層計算的時候
先把資料讀好。三種設定各 6 輪,交錯執行:
| 設定 | 平均 tok/s | 單輪標準差 | 單輪全距 |
| --- | ---: | ---: | --- |
| **關閉(預設)** | **6.03 ± 0.44** | 0.44 | 5.55 – 6.68 |
| 跨層預取 `SDQ_PREFETCH_LAYER_AHEAD=1` | 5.95 ± 0.37 | 0.37 | 5.38 – 6.29 |
| 僅 end_token `SDQ_PREFETCH=1` | 5.78 ± 0.33 | 0.33 | 5.45 – 6.27 |
**三者差異遠小於單輪抖動,統計上無法分辨。** 而且預取開著時 SSD 讀取量
在多數輪次是上升的(預測不夠準,多讀的全是白讀)。
更嚴重的是正確性問題:預取佔用的槽位(busy)會讓 `acquire()` 偶爾拿不到槽位,
而舊版的失敗處理是**靜默跳過一個 expert**。預測率不到 1% 的最佳化不應該
承擔這個風險。
**預設關閉。** 程式碼保留(`SDQ_PREFETCH_LAYER_AHEAD=1` 可以重現),
免得後人重新發明。
## 2. 執行緒數(預設 8,但 12 更好)
| threads | 平均 tok/s | 單輪標準差 |
| ---: | ---: | ---: |
| 4 | 4.65 ± 0.22 | 0.22 |
| 8 | 5.96 ± 0.45 | 0.45 |
| 10 | 6.16 ± 0.48 | 0.48 |
| **12** | **6.35 ± 0.51** | 0.51 |
| 16 | 6.27 ± 0.35 | 0.35 |
**這個結論與參考實作相反。** 參考的 Qwen3.6-35B-A3B 是純 transformer,
每層每 token 只有 8 個 expert 可以平行,加執行緒只是在搶同一批 CPU,
實測 8 → 12 → 16 是下降的。
MiniCPM-V-4.7-35B-A3B 是**混合架構**:40 層裡只有 10 層是全注意力,
其餘 30 層是 SSM 層(見 `DESIGN.md` §1)。SSM 層的計算不受序列維度限制,
可以吃滿更多執行緒,所以 12 執行緒比 8 快約 6.5%。
**這是本模型與參考實作最實際的一個行為差異,也說明「執行緒數」這種設定
不能從上一個模型照抄。** 8 保留為預設(與標配量測一致),12 是建議值。
> 4 → 8 是真實且顯著的提升(4.65 → 5.96,+28%)。8 之後的差異(8/10/12/16)
> 都在單輪抖動之內,不足以支撐更細的宣稱。
## 3. 單一尺寸槽位(放棄)
把所有槽位都配成最大的那種(`SDQ_FORCE_UNIFORM_SLOT=1`)最簡單,代價是
同樣的 arena 少掉約 18% 的槽位。本模型兩種 expert 大小相差 15%
(2,039,808 vs 1,769,472 B),所以分級槽位的收益比參考實作小,但仍然是免費的。
驗證用的 `prefetch_stress_check` 兩種配置都跑,確保分級槽位的配置器正確。
## 4. 端到端 A/B 對照(做不到)
需要把整個 21.17 GB 模型常駐 RAM 作為對照組。在 8 GiB 上不可能,
這正是本專案存在的理由。見 `STRICT_8GIB.md` §3。