# GPUを忙しくするだけでは速くならない — M4で測ったDFlashと有効tokenの最適点 測定日:2026-09-07。公開時点の運用者自身による探索報告。 ## 結論:単一要求では幅8〜10が有望だった Apple M4・Qwen3-4B BF16で162件の主測定を行った。今回の単一課題では、DFlashのblock幅8〜10が有効出力の速い領域だった。参考rooflineに合わせて幅40へ増やすと、演算量は増えても出力速度は低下した。これは共有Macでの探索結果であり、GPUの理論上限や全課題に共通の最適値ではない。 ## 何を成功と数えたか 主指標は最終的に出力されたtokens / GPU-second。1 GPU上のdecode wall-clock時間で計算し、prefillと最初のtokenは測定区間から除いた。GPU active-time counterではない。利用率80%そのものは成功条件にせず、採用token当たりの計算量と待ち時間も併記した。 ## ハードウェアと測定条件 M4、10 GPU cores、32 GiB unified memory、MLX 0.32.2、mlx-lm 0.31.3。Apple公称メモリ帯域は120 GB/s。今回の再校正ではBF16 4096角の行列積が2.712 TFLOP/s、配列加算の論理帯域が56.18 GB/sだった。この比48.28 FLOP/byteは参考値であり、DRAMカウンタから求めたridge pointではない。前回は約2.91 TFLOP/s・75 GB/sで、共有負荷による変動もある。 ## 単一要求:投機幅を増やしても有効出力は増えない 二分探索を説明する同じpromptからgreedyで256 tokensを生成し、255 tokens分のdecodeを計測した。広域探索の中央値はAR 6.66、幅8が14.05、幅16が8.88、幅40が5.06、幅64が4.59 tokens/GPU秒。幅40では出力1 tokenにつきtarget位置を13.56個処理し、幅8の2.34個を大きく上回った。幅16を超える条件はdraftの学習block幅外である。 ## 幅8と10の差を最適値と断定しない 別の2反復ではAR 7.99、幅8が15.15、幅10が15.25、幅12が13.00 tokens/GPU秒だった。8と10の差は約0.6%で、反復差より小さい。さらに別の2反復で幅5/10/15を比較し、11.06/14.26/9.92、対照ARは6.06だった。幅10のAR比は比較群により約1.9〜2.35倍。異なる時点の値を混ぜて唯一の最適幅を選んでいない。 ## 出力一致と無駄な計算 投機生成26回すべてで256 token全体が同じ反復のARに一致した。これは今回の1課題についての一致であり、一般的な品質保証ではない。幅を増やすほどtargetの推定演算速度が上がる一方、有効出力は下がった。余剰FLOPsは単純ARに対するtarget密行列演算の増分で、draftやattentionを含む全GPU FLOPsではない。 ## 実モデルの行列形状が重要 実BF16 weightを使った4形状・M=1〜1024の測定では、M=40で0.31〜0.90 TFLOP/sだった。測定範囲内の最大値はLM headがM=128、MLP gateが256、MLP downが512、q_projが1024に分かれた。各呼出しの同期・launch費用も含むため、モデル全体の非同期実行とは異なる。AI≈Mという単純近似だけで最適幅を決められない。 ## 実装の境界を仮説に使う MLX v0.32.2のgemv_wide_configには、条件を満たす行列について最大5 vectors/pass・3 passesの経路があり、M=16から対象外になる。この公開ソースを手掛かりに5/10/15を追加した。ただし実際に選択されたkernel名は追跡しておらず、減速原因をこの分岐だけに帰していない。 ## 複数要求:本当に必要なtokensをbatchへまとめる 異なる配列の例題を複数要求として与えた同期ARでは、batch 40で95.11、batch 64で128.34 tokens/GPU秒だった。各要求64出力のうち63出力を測定した。先頭要求は元の2反復18条件でbatch 1と一致したが、全要求の回答品質は評価していない。DFlash試験とは長さとruntimeが異なり、両者の数字を直接speedupとして比べない。 ## 待ち時間を含む条件付きの候補 観測した全反復でp95 stepが200 ms以内だった条件の最高throughputはbatch 4の30.62、500 ms以内ではbatch 40の95.11、1秒以内ではbatch 64の128.34 tokens/GPU秒。batch 40のp95は499.6 msで境界に近い。batch 64のp95は629.8 ms、prefill+最初のtokenは中央値29.69秒。これは到着済みfull batchの容量試験で、要求が揃うまでのqueue待ちは含まない。 ## 動的制御は採用数と所要時間から選ぶ 簡単なbatch=1 simulationでは、独立で一定の採用確率pを仮定し、期待排出数sum(p^i, i=0..K-1)を実測1ラウンド時間で割って幅を選んだ。広域探索のcostではp=0.2でAR、0.4〜0.9で幅8、0.95以上で幅64。ただし高幅でその採用率を実現した測定ではなく、pを変えてもcost一定という仮定がある。queueやlatency制約を備えた実運用schedulerは未実装。 ## 測定の限界と再現資料 主データはGEMM 64件、target forward 38件、decode 32件、AR batch 28件。メモリ保持設定の差を見つけ、初期のunwired測定を参考扱いに隔離し、本文のGEMM・target・ARは公式生成と同じwired_limitで測り直した。他の作業は停止せず、load averageが100を超えた観測もある。実DRAM帯域、Tensor/SM利用率、実MFU、50/70/80%到達のM、dLLM/treeとの実測比較は未取得。この結果をMurakumo本番サービスの速度保証やNVIDIA GPUの結果とは扱わない。 ## 図とデータ - [gemm-roofline.png](https://murakumo.cloud/research/m4-roofline-2026-09-07/gemm-roofline.png) - [decode-tradeoff.png](https://murakumo.cloud/research/m4-roofline-2026-09-07/decode-tradeoff.png) - [ar-throughput-latency.png](https://murakumo.cloud/research/m4-roofline-2026-09-07/ar-throughput-latency.png) - [gemm.csv](https://murakumo.cloud/research/m4-roofline-2026-09-07/gemm.csv) - [target.csv](https://murakumo.cloud/research/m4-roofline-2026-09-07/target.csv) - [decode.csv](https://murakumo.cloud/research/m4-roofline-2026-09-07/decode.csv) - [ar-batch.csv](https://murakumo.cloud/research/m4-roofline-2026-09-07/ar-batch.csv) - [calibration.json](https://murakumo.cloud/research/m4-roofline-2026-09-07/calibration.json) - [method.json](https://murakumo.cloud/research/m4-roofline-2026-09-07/method.json) - [validation.json](https://murakumo.cloud/research/m4-roofline-2026-09-07/validation.json) - [scheduler-simulation.csv](https://murakumo.cloud/research/m4-roofline-2026-09-07/scheduler-simulation.csv) ## 出典 - [Apple M4 Air仕様](https://support.apple.com/en-us/122209) - [MLX v0.32.2 Metal matmul](https://github.com/ml-explore/mlx/blob/v0.32.2/mlx/backend/metal/matmul.cpp) - [DFlash](https://github.com/z-lab/dflash) - [Draft block 16](https://huggingface.co/z-lab/Qwen3-4B-DFlash-b16)