Show HN: 遅いコンピュータで GLM 5.2 を実行する
(github.com/JustVugg)- colibrì は GLM-5.2 744B MoE をコンシューマ向けマシンの約 25GB RAM で実行するために作られた純 C エンジンで、ルーティングされた expert をディスクからストリーミングし、GPU なしで動作する
- 中核構造は dense 部分の約 17B パラメータを int4 で RAM に常駐させて 9.9GB を使い、21,504 個のルーティング expert は約 370GB のディスクに置いて必要時に読み込む方式
- 実装には GLM-5.2 forward、MLA attention と 圧縮 KV-cache、DeepSeek-V3 スタイル router、MTP speculative decoding、int8/int4/int2 量子化 kernel、byte-level BPE tokenizer が含まれる
- WSL2 12 コア・25GB RAM・NVMe VHDX 環境でのロード時間は約 30 秒、チャット中の peak RSS は約 20GB、cold decode はトークンあたり約 11GB のディスク読み込みで 0.05〜0.1 tok/s 程度
- 高速な NVMe とより大きな RAM では cache と pinning が重要で、実際のコミュニティ測定では Apple M5 Max 128GB 環境が MTP off 基準で 1.06 tok/s を記録
colibrì が解決しようとする問題
- colibrì は “Tiny engine, immense model” を掲げ、GLM-5.2 744B-parameter MoE モデルを約 25GB RAM のコンシューマ向けマシンで実行するエンジン
- ランタイムは 純 C で、Python、BLAS、GPU への依存がない
- エンジンは
c/glm.cという単一 C ファイル約 1,300 行と小さなヘッダ群で構成される - 実行例は
./coli chatで、出力例はcolibrì v1.0 — GLM-5.2 · 744B MoE · int4 · streaming CPUと約 32 秒の準備時間、9.9GB の resident メモリを示している
ディスクストリーミングベースの MoE 実行方式
- GLM-5.2 の 744B Mixture-of-Experts モデルでは、トークンあたり約 40B パラメータ だけがアクティブになる
- トークンごとに変わるルーティング expert は約 11GB に相当する
- dense 部分は RAM に常駐する
- attention、shared experts、embeddings を含む
- 約 17B パラメータ
- int4 基準で約 9.9GB RAM を使用
- ルーティング expert はディスクに保存される
- 75 個の MoE layer × 256 experts と MTP head を含む
- 合計 21,504 個の routed experts
- expert あたり int4 基準で約 19MB
- 全体のディスク使用量は約 370GB
- expert のロードには per-layer LRU cache、optional pinned hot-store、OS page cache を使う
実装済みの主な機能
- GLM-5.2 forward は
glm_moe_dsa構造に合わせて実装され、transformersoracle 基準で token-exact に検証済み- tiny-random モデルで teacher-forcing 32/32
- greedy generation 20/20
- MLA attention は q/kv-LoRA と interleaved partial RoPE を含む
- 圧縮 KV-cache はトークンあたり 576 floats を使用
- 従来の 32,768 floats/token に比べて 57 倍小さい
- GLM-5.2 は 64 heads で GQA はない
- DeepSeek-V3 スタイルの sigmoid router を実装
noaux_tcrouted_scaling_factor- shared expert
- first-3-dense layers
- Native MTP speculative decoding は GLM-5.2 の multi-token-prediction head(layer 78) が draft token を作り、main model が batched forward で検証する
- MTP head は int8 である必要がある
- int4 では draft acceptance が 0〜4% に落ち、speculation が機能しない
- int8 では acceptance が 39〜59%、2.2〜2.8 tokens/forward と測定された
- rejection sampling により sampling 中も lossless に維持される
- cold cache では verified draft が追加 expert をルーティングし、expert-loads/token が約 660 から約 1100 に増える場合がある
- この場合、cache と pin が warm-up されるまでは時間が長くなる可能性があるため、adaptive guard と
DRAFT=0オプションがある
- True sampling は temperature と nucleus をサポート
- デフォルトは 0.7 / 0.90
- 公式の 1.0 / 0.95 設定は、int4 環境では tail の量子化ノイズをサンプリングすると説明している
- integer-dot kernel は Q8_0-style int8 activations と AVX2
maddubsを使用- int8 matmul は 1.4〜2.5 倍高速
- 測定性能は 119 GFLOP/s
- int4 は batch で 1.8 倍高速
- int4 single-row は測定上より遅く、f32 のまま維持
- MLA weight absorption は decode で per-token k/v reconstruction を避ける
- query が
kv_bを吸収し、context は attention 後に projection される - forced absorption 環境でも TF 32/32 と generation 20/20 で検証済み
- query が
- expert readahead は、ある expert block を掛けている間に次の block を
WILLNEEDで読み込む - 量子化 kernel は int8、packed int4、packed int2、per-row scales、AVX2、dequant-on-use をサポート
- DSA sparse attention は進行中
- lightning-indexer weights は FP8 repo から約 108GB を抽出する形
- indexer forward は次の段階として予定
- それまでは attention は context ≤ 2048 tokens で dense かつ exact
- prefill と MTP verification では Batch-union MoE が batch 内の unique expert を一度だけ読み込み、その expert にルーティングされたすべての position に適用する
- tokenizer は C で実装された byte-level BPE tokenizer で、GPT-2 スタイルの Unicode-property regex と 320k merges を使用
- RAM 安全装置は起動時に
MemAvailableを基準に expert cache を自動でサイズ調整する- working set、KV、MTP row、reconstruction buffer の peak projection を反映
- kernel OOM-killer が動作しないように設計
- offline converter は
c/convert_fp8_to_int4.pyとして提供- GLM-5.2 FP8 shard を一度に 1 つずつダウンロード
- 128×128 block scales で dequant した後、エンジン container に requantize
- shard を削除しながら進むため、756GB の FP8 checkpoint 全体が同時にディスク上に存在する必要はない
- 変換は再開可能
測定された基本性能と制約
- 開発環境は WSL2、12 コア、25GB RAM、NVMe via VHDX
- 測定値は以下の通り
- int4 container モデルサイズ: 約 370GB
- resident RAM: 9.9GB
- load time: 約 30 秒
- チャット中の peak RSS: 約 20GB、auto-capped
- cold decode cost: トークンあたり約 11GB disk reads
- VHDX random disk ceiling: 約 1GB/s
- cold decode 速度: 約 0.05〜0.1 tok/s
- MTP speculation: int8 head 基準で 2.2〜2.8 tok/forward
- 高速なシステムではないことを明記し、warm cache、pinned hot experts、MTP が useful-response latency を短縮すると説明している
- SSD に関する注意点は 2 つ
- colibrì streaming は read-only なので、読み込み自体は SSD の摩耗に意味のある影響を与えない
- RAM 不足で swap traffic が発生すると write が発生し、ドライブを摩耗させる可能性がある
- 長時間の full read duty cycle は低価格ドライブを加熱する可能性があるため、温度と health monitoring が必要
モデルのダウンロードと実行
- 事前変換済みの GLM-5.2 int4 モデルは Hugging Face で提供されている
- 事前変換モデルを取得すれば、FP8 → int4 変換ステップを省略できる
- 実行時は
COLI_MODELをモデルディレクトリに指定する
COLI_MODEL=/path/to/GLM-5.2-colibri-int4 ./coli chat
- quick start は
cディレクトリで./setup.shにより gcc/OpenMP の確認、ビルド、self-test を行う - 自分で変換するには
./coli convert --model /nvme/glm52_i4を使う- 約 400GB の空き容量がある ext4/NVMe パスが必要
- 変換には Python と
torch、safetensors、huggingface_hub、numpyが必要 - ランタイムエンジン自体は純 C で、Python は 1 回限りの converter にのみ使われる
- 有用なオプションは以下の通り
--temp T: sampling temperature、デフォルト 0.7 と nucleus 0.90、0 は greedy--topp 0.7: adaptive expert top-p、disk 使用量を 30〜40% 削減--ngen N: 回答あたりの最大トークン数AUTOPIN=0: learning cache auto-pin を無効化THINK=1: GLM-5.2 reasoning block を有効化DRAFT=n: MTP draft depthTF=1: teacher-forcing validation
Learning cache とハードウェア別の期待値
- Learning cache は実利用でルーティングされた expert をモデル横の
.coli_usageに記録する - 起動時に spare RAM へ最も hot な expert を自動 pin する
- プロジェクト説明では、使用量が蓄積するほど colibrì は速くなるとしている
- 必要環境は Linux または WSL2、OpenMP 対応 gcc、AVX2、最低 16GB RAM、約 370GB の int4 モデルがある local NVMe
- ext4 パスを推奨
- network/9p mount は使わないよう案内している
- テスト順序は、ビルドと self-test、
iobenchによるディスク測定、chat で tok/s・expert hit-rate・RSS 確認、expert usage 記録後の pinning、品質 benchmark 実行 - ハードウェア別の予想値は測定ではなく推定値
- 開発マシン WSL2 VHDX、約 1GB/s、25GB RAM: 0.05〜0.1 tok/s cold
- native Linux、PCIe4 NVMe 3〜5GB/s random、32GB: 0.5〜1 tok/s
- PCIe5 NVMe または 2×NVMe RAID0 8〜12GB/s、64GB、PIN 約 40GB: 2〜4 tok/s
- 128〜256GB RAM、12 コア、hot experts cached: 2〜4 tok/s
- 同じ RAM で 24〜32 コアまたは AVX-512/VNNI kernels: 5〜15 tok/s
コミュニティベンチマーク
- Intel Core Ultra 7 270K Plus、24 threads、WSL2、24GB RAM、NVMe VHDX 環境で、基本設定は 0.07 tok/s を記録
- disk iobench: 1.96GB/s buffered、2.74GB/s O_DIRECT
- expert hit: 3〜4%
- RSS: 14.1GB
- 同じ環境で
--topp 0.7は 0.11 tok/s を記録- expert hit: 11%
- RSS: 14.7GB
- end-to-end 速度は 1.6 倍に向上
- Apple M5 Max、18 cores、macOS、128GB unified memory、internal SSD 環境は 1.06 tok/s を記録
- disk iobench: 14.2GB/s O_DIRECT
- default、MTP off
- expert hit: 23%
- RSS: 21.8GB
- 24GB RAM マシンでは expert cache が layer あたり 2 slot に auto-cap されるため、開発マシンよりディスクが 2〜2.7 倍速くても decode が cold 状態に留まる
- 小容量 RAM マシンではディスクより RAM cap がボトルネックになる
- M5 Max の測定値は、744B モデルが laptop SSD で約 1 tok/s を出す事例であり、14GB/s ディスクはボトルネックを再び RAM budget と kernel に移す
品質ベンチマークと残る測定
- int4 量子化が精度に与えるコストはまだ測定されていない
- benchmark harness は実装済みだが、開発マシンの約 1GB/s ディスクでは全体実行に 1 日のかなりの部分がかかる
- 提供される benchmark コマンドは
hellaswag、arc_challenge、mmluを実行する
cd c
./coli bench
./coli bench hellaswag --limit 200
./coli bench mmlu arc_challenge --ram 100
- 出力は task 別 accuracy で、log-likelihood scoring と EleutherAI-harness スタイルを使用
- full-precision GLM-5.2 の公開スコアは、該当 task で約 85〜95% と書かれている
- int4 container が数点差以内に入れば量子化が検証され、そうでなければ mixed または grouped-scale quantization に投資する根拠になる
リポジトリ構成とライセンス
- 主なファイル構成は以下の通り
c/glm.c: GLM-5.2 forward、streaming MoE、MTP、serve mode を含むエンジンc/st.h:preadとfadviseベースの safetensors reader、mmapは未使用c/tok.h: C byte-level BPE tokenizerc/coli: chat、run、bench、convert、info CLIc/iobench.c: エンジンが体感する parallel disk microbenchmarkc/convert_fp8_to_int4.py: disk-safe FP8 → int4 converterc/make_glm_oracle.py: validation 用 tiny-random oracle generatorc/olmoe.c: Stage-A engine で最初の validation target
- colibrì という名前は、ハチドリが軽い体でホバリングし、1 日に多くの花を訪れることに由来する
- プロジェクトのライセンスは Apache 2.0 で、GLM-5.2 weights は Z.ai が MIT で公開している
1件のコメント
Hacker Newsの意見
実際に使うときにトークン/秒で測れるレベルなのか、それとも1分に1トークンに近いのかが一番気になる
ローカルLLMが1トークン/秒くらい遅くても、一晩プロジェクトを任せておいて6〜8時間後に結果を確認する形ならかなり有用だった
一方で、リンク先にある最低スペックのハードウェアでの0.05〜0.1トークン/秒は、使いどころがほとんどなさそうに見える
それでも全体のコンセプトは素晴らしいし、一般の人が手の届くハードウェアで350B〜900B級モデルをローカルに、たとえ1トークン/秒でも動かせるようにする試みがもっと増えることを期待している
「読み取り性能の速いNVMe SSDがあり、ローカルディスクに巨大なモデルがあるのだから、全体を載せずに必要なときだけ11GB/トークンずつ読もう」という方向性が気に入っている
今では遅くとも2028年ごろにはローカルで動かしているだろうと思っている
予算は1万ドル以下にして、今日の最高水準モデルに匹敵するモデルを動かしたい
Mac StudioやGPUにお金を使う前に、今あるハードウェアでこのアイデアを検証する方法を決めたので、今週中に概念実証くらいは作れそうだ
新しいアイデアではなく、自分の作業スタイルに合うように動かす時間が必要なだけだ
さらに改善し続けようとしている
1分に1トークンは、無料利用枠と比べてもあまりに小さい数字だ
Apple SiliconのmacOS向けに似たものを作っている
Unsloth split GGUF、統合メモリ内で圧縮部分を常駐させる方式、ネイティブMetalカーネル、RAM専用のネイティブ圧縮KVを使う方向だ
自分の64GBより128GBのほうが筋がよさそうで、準備できたらGitHubに上げるつもりだ
画像/動画生成のほうでもhttps://github.com/cretz/thinferで似た戦略を使ってみた
videoブランチにかなり作業が入っている
必要なタイミングで重みをLRU方式で出し入れできる推論エンジンがずっと必要だったので、結局
--vram-budgetを受け取り、その範囲内に収まるツールをバイブコーディングで作ったmmapされたバイト列をVRAMの内外へ移動するコストは計算に比べればかなり安いことが分かり、パイプライニングとダブルバッファリングを組み合わせると、ほぼ常にメモリ律速ではなく計算律速になる
もちろん、使っているのはずっと小さいモデルではある
すべて実行できる共通ハーネスを作ったのか気になる
どのモデルがVRAM予算内により一貫して収まるのかも気になる
llama.cppはさまざまな4ビット以下の量子化をサポートしていて、デフォルトでモデルをmmapするので、重み全体をメモリに保持する必要がない
OSが必要なときにストレージから持ってきてくれる
依存関係なしに非常に少ないコードで実装しているのは見事だが、実際に性能上の利点があるのかは気になる
かなり格好いい
今週GLM 5.2を触ってみたが、同じく印象的だった
会社では次のプロジェクトを始める前に、ものすごく高価なハードウェアでローカル実行をテストしているところなので、この巨大なオープンソースモデルのリリースを平均的なマシンで動かしている人たちがいるのは良いことだ
まだ実用性は大きくないとしても、良い仕事だ
LLMの内部構造をよく知っているわけではないが、「層」を持つほかのモデルにも似た構造を使えるのか気になる
ある層が処理を終えたらその層をRAMから取り除き、次の層をディスクからロードしてから、最初の層の結果に対して有効化する、といったことは可能なのだろうか
RAM 64GBとVRAM 24GBがあるマシンなので、これをより多くのRAMを使うように調整できるのか気になる
あるいはGPUでGemma/Qwenを動かし、GLM-5.2がより小さな作業をそこに委任することもできそうだ
GLM-5.2をある程度再学習する必要があるかもしれない
複数のディスクを並列に使って帯域幅を増やせば高速化できるのかも気になる
SSD摩耗警告には、コールドスタートはランダム読み取り約11GB/トークンと重く、読み取り自体は安全だがOSのページキャッシュが書き込みを発生させる可能性があり、過度な使用は安価なSSDの摩耗を早める可能性がある、と書かれている
安全な方法としては、モデル重み用に別パーティションを作って読み取り専用に設定することが可能かもしれない
ページキャッシュがパーティション単位なのかディスク単位なのか分からないが、ディスク単位なら読み取り専用の
data.isoをパーティションのようにフォーマットしてディスクとしてマウントする方法もあり得るディスクがもっとあれば実際にテストできるだろう
ベンチマークが出たらプルリクエストやIssueで上げてくれれば、一緒に取り組める
何を見落としているのだろう? なぜ大量読み取りが書き込みを生むのか?
ページにSSD摩耗警告がある https://github.com/JustVugg/colibri#ssd-wear-warning
自分で部品を組んだデスクトップPCならSSDを交換できるが、はんだ付けされたSSDを使っているユーザーはどうすればいいのか?
こういうアプリケーションを避けるべきなのか、それともストレージが早く壊れる可能性を受け入れて突き進むべきなのか?
外部ストレージを消耗品のSSDのように使う必要がありそうだ
はんだ付けSSDが入ったノートPCでは使用量をしっかり監視し、注意する必要がある
このプロジェクトは誰もが動かすものというより実験に近そうだが、それでもかなり格好いい
ここで迷信的に考える必要はない
ディスク活動、特に書き込みは測定できる
例えばLinuxでは
iostatやvmstatを使えばいいアプリケーションは書き込みを行わないので、実際にはアプリケーション自体がSSDを摩耗させるわけではない
残りはアプリケーションとは無関係な一般的な管理上の注意に近い
技術的には印象的だが、実際に実用的に使えるのかが気になる
私も実は同じものを作っていたが、追加のRAM使用を避けるためにモデル全体をメモリにmmapする方向にした
さらにClaudeにモデルへMedusahttps://arxiv.org/abs/2401.10774を実装させ、追加モデルをメモリに載せずにマルチトークン予測の利点を得ようとした
いま帰宅したので補足すると、すべての変更はllama.cppに対して行っており、最終目標はNVMeでmmapファイルを処理するシングルボードコンピュータのようなものに載せることだ
以前のテストでは、現在の構成の理論上の上限は約1.8トークン/秒に見えるが、追加のMedusaヘッドが完全に学習済みというわけではなく、生成されたトークンとして計算されるのかも正直よく分からない
結局アイデアは似ているようだが、私はまだLLMパーサー/ランナーを一から書けないので、何をメモリに残すかを指定する代わりにLinuxカーネルに任せた
最後に、llama.cppの使用量を自分の32GBのうち16GBに制限したので、さらに下げることも可能かもしれない