概要
- Flash-MoE は3970億パラメータのMixture-of-Expertsモデルを MacBook Pro で高速動作させる技術
- C/Metal のみで実装、フレームワークやPython未使用
- SSDから専門家重みを ストリーミング し、4.4トークン/秒を達成
- 生産品質の出力 とツールコールを実現
- OSキャッシュ 活用によるシンプルかつ効率的なパイプライン設計
Flash-MoE: 397Bパラメータモデルをラップトップで実行
- Qwen3.5-397B-A17B (3970億パラメータMixture-of-Expertsモデル)を MacBook Pro (48GB RAM)で動作
- 4.4トークン/秒 以上の生成速度、 ツールコール対応 の高品質出力
- モデル全体(209GB)は SSDからストリーミング、Metalカスタムパイプラインで処理
- C/Objective-C/Metal のみで構築、Pythonや機械学習フレームワークは不使用
実験結果・構成
| 設定 | tok/s | 品質 | 備考 | |----------------------------|-------|-----------|----------------------------------------------| | 4bitエキスパート + FMA | 4.36 | 優秀 | 現行ベスト、209GB、ツールコール可 | | 4bitエキスパート | 3.90 | 優秀 | FMA最適化前 | | 2bitエキスパート | 5.74 | 良い* | 120GB、JSON/ツールコール不可 | | 2bitピーク | 7.05 | 良い* | キャッシュバースト、ツール用途不可 | | *2bitはJSON出力に不具合発生、4bitが本番推奨 |
ハードウェア構成
- MacBook Pro (Apple M3 Max, 16-core CPU, 40-core GPU, 48GB unified memory)
- SSD: 1TB, 17.5GB/sシーケンシャルリード
- macOS: 26.2 (Darwin 25.2.0)
モデルアーキテクチャ
- 60層トランスフォーマー: 45 GatedDeltaNet(線形アテンション)+ 15標準フルアテンション
- 各層 512エキスパート、トークン毎にK=4のみ活性化(+共有エキスパート)
- 隠れ次元4096
主要技術
-
SSDエキスパートストリーミング
- エキスパート重み(209GB/4bit)を NVMe SSD から 必要分のみ並列読み込み
- K=4のみロード(1層あたり約6.75MB)、OSページキャッシュに完全依存
- Apple "LLM in a Flash" 論文に着想
-
FMA最適化デクオンカーネル
- 4bitデクオン+行列積を FMA(積和演算) で1命令化、12%高速化
-
Metal手書きカーネル
- 4bit/2bitデクオン行列積、SwiGLU活性化、RMS正規化、GPUアテンション、RoPE、MoE合成等を GPUで融合処理
-
Deferred GPUエキスパート計算
- エキスパート前向き計算を 非同期送信、CPUは次層準備と並行
- 合成・正規化もGPUで完結し、次層アテンションへ直接渡す
-
Accelerate BLASによる線形アテンション
- GatedDeltaNetの状態更新を cblas_sscal/sgemv/sger で64%高速化
-
OSキャッシュ信頼設計
- カスタムキャッシュ不要、 OSページキャッシュ(約35GB) に一任
- 独自キャッシュは GPUメモリ圧迫やオーバーヘッドで逆効果
パイプライン概要(1層平均4.28ms/4bit)
- CMD3(prev) → CMD1 (アテンション投影+デルタネット, 1.22ms GPU)
- → CPU: 結果フラッシュ(0.01ms)
- → CMD2 (o_proj+正規化+ルーティング+共有, 0.55ms GPU)
- → CPU: softmax/topKルーティング(0.003ms)
- → I/O: K=4エキスパート並列pread(2.41ms SSD)
- → CMD3 (エキスパート前向き+合成+正規化, 0.04ms, Deferred)
Apple Siliconにおけるメモリ制約
- SSD DMAとGPU計算は同一メモリコントローラ を共有し、並列化は逆効果
- GPUのデクオンカーネルは帯域飽和 (418GiB/s)
- SSD DMAの背景動作でも GPUレイテンシ急増、直列パイプラインが最適
クイックスタート
cd metal_infer && make- 4bit推論:
./infer --prompt "Explain quantum computing" --tokens 100 - 2bit推論(高速/ツール不可):
./infer --prompt "Explain quantum computing" --tokens 100 --2bit - インタラクティブチャット:
./chat - 層ごとのタイミング計測:
./infer --prompt "Hello" --tokens 20 --timing
プロジェクト構成
metal_infer/infer.m:推論エンジン本体(約7000行)shaders.metal:Metalカーネル(約1200行)chat.m:チャットTUI/ツールコールtokenizer.h:C BPEトークナイザ(449行)main.m:MoEベンチマークMakefile:ビルドextract_weights.py:重み抽出repack_experts_2bit.py:2bit化train_predictor.py:ルーティング分析model_weights.bin:非エキスパート重み(5.5GB)model_weights.json:テンソルマニフェストvocab.bin:語彙tokenizer.bin:BPEトークナイザrepack_experts.py:4bitパッキングprogress.py:可視化results.tsv:実験ログ
試行錯誤と最適化
-
維持した手法
- FMAデクオンカーネル:トークン生成速度+12%
- OSページキャッシュ信頼:独自キャッシュより38%高速
- GPU合成+正規化融合:CPUラウンドトリップ排除
- BLASデルタネット:アテンション64%高速化
- Deferred CMD3:GPU/CPU重複
- 小型Cトークナイザ:起動20倍高速化
- 2bit用F_NOCACHE:ページスラッシング回避で+3%
- GPU融合アテンション(RoPE):フルアテンション層+2%
-
破棄した手法(抜粋)
- LZ4圧縮:デコードオーバーヘッドで-13%
- F_RDADVISEプリフェッチ:SSD DMAでGPU-73%
- 時系列予測ルーティング:SSD帯域浪費で-18%
- MLPルーティング予測:精度31%、時系列未満
- GPU LUTデクオン:間接参照で-2%
- プライベートバッファ圧縮:パイプライン-20%
- mmapエキスパートファイル:ページフォルトで5倍遅延
- 早期投機ルーティング:キャッシュ汚染で-38%
- その他:NVMeの7MB粒度、dispatch_io/dispatch_dataのオーバーヘッド等
セーフティ設計
- 開発端末での安全性重視
- 非エキスパート重みは 5.5GBのみmmap (読み取り専用)
- Metalバッファ約200MB、合計6GB以下
- 残り42GBは OS+ページキャッシュ 専用
- OOMリスクなし、エキスパート重みはSSDからオンデマンドストリーム
- 独自キャッシュなし、OS信頼方針
この技術により、 巨大言語モデル の 省リソース・高効率推論 が個人端末でも現実的になりつつある。