Text Generation
llama-cpp-python
GGUF
llama.cpp
Mixture of Experts
ssd-offload
smallthinker
expert-paging
low-ram
Instructions to use HelloSun/SmallThinker4b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use HelloSun/SmallThinker4b with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="HelloSun/SmallThinker4b", filename="{{GGUF_FILE}}", )output = llm( "Once upon a time,", max_tokens=512, echo=True ) print(output)
- Notebooks
- Google Colab
- Kaggle
Auto Upload Agent commited on
Commit ·
833ef4d
1
Parent(s): 84fbb3b
v9: STATUS/README 補上 SSD 讀取能力與實測成果
Browse files
README.md
CHANGED
|
@@ -14,6 +14,16 @@ ST_RAM_BUDGET_MB=512 ./llama_server.sh # 手動壓低 RAM 預算做實驗
|
|
| 14 |
|
| 15 |
進度真相來源:[STATUS.md](STATUS.md)。續作指引:[AGENTS.md](AGENTS.md)。
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
## 檔案
|
| 18 |
|
| 19 |
| 檔案 | 用途 |
|
|
|
|
| 14 |
|
| 15 |
進度真相來源:[STATUS.md](STATUS.md)。續作指引:[AGENTS.md](AGENTS.md)。
|
| 16 |
|
| 17 |
+
## 實測成果
|
| 18 |
+
|
| 19 |
+
| 設定 | peak 總 RSS | swap | 冷權重 SSD 重讀 | 輸出 |
|
| 20 |
+
| --- | --- | --- | --- | --- |
|
| 21 |
+
| 上游行為(`ST_PAGER=0`) | 2.564 GiB | 0 | — | 基準 |
|
| 22 |
+
| 預算 512 MiB | **0.833 GiB** | 0 | 2315 MiB | **逐字相同** |
|
| 23 |
+
| 預算 256 MiB | **0.601 GiB** | 0 | 2320 MiB | **逐字相同** |
|
| 24 |
+
|
| 25 |
+
證據:`validate/ab-test.json`(`all_passed: true`)與 `validate/last-run.json`。
|
| 26 |
+
|
| 27 |
## 檔案
|
| 28 |
|
| 29 |
| 檔案 | 用途 |
|
STATUS.md
CHANGED
|
@@ -96,6 +96,16 @@ expert 維度是最外層):
|
|
| 96 |
取捨很清楚:**放棄 I/O 預取,換取「計算路徑完全沒動過」的保證。**
|
| 97 |
模型只有 2.45 GiB、SSD 讀取 300+ MB/s,demand paging 的penalty 可接受。
|
| 98 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
## 踩過的坑(全部有實測證據,不要重蹈)
|
| 100 |
|
| 101 |
| 坑 | 真相 | 怎麼知道的 |
|
|
@@ -110,11 +120,13 @@ expert 維度是最外層):
|
|
| 110 |
| **`nb[2] != ne[0]*nb[0]` 檢查會誤判量化張量** | 量化張量 `nb[0]` 是**一個 block** 的位元組數,不是 1。只要檢查 `nb[2] == ne[1]*nb[1]` | 「layer 0 不連續」誤報 |
|
| 111 |
| **第一輪 sweep 永遠什麼都不做** | 條件寫成 `last_used < now - hot_tokens`,第一輪時門檻是 0 而 `last_used` 也是 0,`0 < 0` 為假 | sweep 計數有跳、但 resident 不降 |
|
| 112 |
| **拿 layer 0 的 `nb[2]` 當全模型常數** | `down_exps` 逐層量化型別不同(實測 layer 4 是 Q4_K、layer 0 是 Q6_K) | 「layer 4 part 2 形狀不一致」 |
|
|
|
|
| 113 |
| **外部取樣 RSS 抓不到 decode 階段** | 一次 generation 的樣本數太少。改由**行程自己**在 sweep 裡讀 `/proc/self/status` | 兩邊數字對不起來時才發現 |
|
| 114 |
|
| 115 |
-
(本專案被「量測方式/語意/時序」教訓共
|
| 116 |
② 讀 `/proc/self/io` 的格式錯 ③ 在行程退出後才讀它 ④ 把 prefetch 語意寫反
|
| 117 |
-
⑤ 分層時把「有打算分頁」和「已註冊分頁」混為一談
|
|
|
|
| 118 |
共同特徵都是「看起來有在做事,但量錯了地方」。每次都是靠實測抓到的。)
|
| 119 |
|
| 120 |
,不要重蹈)
|
|
|
|
| 96 |
取捨很清楚:**放棄 I/O 預取,換取「計算路徑完全沒動過」的保證。**
|
| 97 |
模型只有 2.45 GiB、SSD 讀取 300+ MB/s,demand paging 的penalty 可接受。
|
| 98 |
|
| 99 |
+
## 本機 SSD 讀取能力(實測,`validate/io-probe.json`)
|
| 100 |
+
|
| 101 |
+
| threads | 1 | 2 | 4 | 8 |
|
| 102 |
+
| --- | --- | --- | --- | --- |
|
| 103 |
+
| 循序讀取 | 337 MB/s | 667 MB/s | 1328 MB/s | 2558 MB/s |
|
| 104 |
+
|
| 105 |
+
4K 隨機讀 ≈ 1767 IOPS。檔案系統是 **overlayfs**。
|
| 106 |
+
單執行緒 337 MB/s 是「每個 decode step 重讀 4 experts × 32 層」這個負載的基準,
|
| 107 |
+
SSD 讀取頻寬是本模型 decode 速度的主要上限。
|
| 108 |
+
|
| 109 |
## 踩過的坑(全部有實測證據,不要重蹈)
|
| 110 |
|
| 111 |
| 坑 | 真相 | 怎麼知道的 |
|
|
|
|
| 120 |
| **`nb[2] != ne[0]*nb[0]` 檢查會誤判量化張量** | 量化張量 `nb[0]` 是**一個 block** 的位元組數,不是 1。只要檢查 `nb[2] == ne[1]*nb[1]` | 「layer 0 不連續」誤報 |
|
| 121 |
| **第一輪 sweep 永遠什麼都不做** | 條件寫成 `last_used < now - hot_tokens`,第一輪時門檻是 0 而 `last_used` 也是 0,`0 < 0` 為假 | sweep 計數有跳、但 resident 不降 |
|
| 122 |
| **拿 layer 0 的 `nb[2]` 當全模型常數** | `down_exps` 逐層量化型別不同(實測 layer 4 是 Q4_K、layer 0 是 Q6_K) | 「layer 4 part 2 形狀不一致」 |
|
| 123 |
+
| **`os.pread()` 回傳資料本身,不是讀到的位元組數** | 寫成 `got += n` 會得到 `TypeError: int + bytes`,而**執行緒裡的例外不會讓主程式失敗** → `io_probe` 印出 `bytes: 0、0.015 秒、0.0 MB/s`,看起來像「SSD 完全沒速度」 | `bytes: 0` 搭配「只花 15 ms」這個不合理組合才察覺 |
|
| 124 |
| **外部取樣 RSS 抓不到 decode 階段** | 一次 generation 的樣本數太少。改由**行程自己**在 sweep 裡讀 `/proc/self/status` | 兩邊數字對不起來時才發現 |
|
| 125 |
|
| 126 |
+
(本專案被「量測方式/語意/時序」教訓共 6 次:① 只看外部取樣的 RSS
|
| 127 |
② 讀 `/proc/self/io` 的格式錯 ③ 在行程退出後才讀它 ④ 把 prefetch 語意寫反
|
| 128 |
+
⑤ 分層時把「有打算分頁」和「已註冊分頁」混為一談 ⑥ 在執行緒裡把 `pread` 的
|
| 129 |
+
回傳值當成位元組數,例外被吞掉後看起來像「量到 0」。
|
| 130 |
共同特徵都是「看起來有在做事,但量錯了地方」。每次都是靠實測抓到的。)
|
| 131 |
|
| 132 |
,不要重蹈)
|