ブログ

10年前のXeonで最新LLMを動かす技術:メモリ帯域の制約をどう乗り越えるか

今回は、A 10 year old Xeon is all you need という記事を参考に、一見すると最新AIの動作には不向きに思える古いハードウェアで、いかにしてLLM(大規模言語モデル)を実用的な速度で動かすかという試みについて紹介します。

この記事はめちゃめちゃハートに刺さりました。ik_llama.cppを熟読したくなりました。ちゃんと読んで理解しよ!!


最新のAIモデルを動かすには、高価なハイエンドGPUが必要だと思われがちです。しかし、適切なソフトウェアの最適化と設定を組み合わせれば、2016年頃の古いサーバー機でも「Gemma 4」のようなモデルを動作させることができるかもしれません。

検証環境のスペック

今回対象とするのは、約10年前の設計となる以下のような構成の再生サーバーです。

コンポーネント スペック 備考
CPU Intel Xeon E5-2620 v4 (2.10 GHz) 2016年製、8コア/16スレッド
命令セット AVX2 AVX-512やBF16等の最新命令は非搭載
メモリ 128 GB DDR3 容量は十分ですが、最新規格より5〜6倍低速
GPU なし 内蔵GPUも非搭載

この構成での最大の弱点は、演算能力そのものよりも「メモリ帯域幅」にあります。DDR3メモリは現代の基準で見ると非常に低速であり、これがLLMの推論において決定的なボトルネックとなります。

なぜ古いPCではAIが遅いのか:メモリの壁

LLMがテキストを1単語(トークン)ずつ生成する際、プロセッサはモデルの「重み」と呼ばれる膨大なデータを、メモリ(RAM)から計算ユニットへ絶えず転送し続ける必要があります。

このとき、プロセッサが計算を行う速さよりも、メモリからデータを読み出す速さの方が遅いため、プロセッサが待ち状態になってしまいます。これを「メモリの壁(Memory Wall)」と呼びます。

flowchart TD
    subgraph Storage [メモリ上のデータ]
        Weights[モデルの重み: 数GB〜数十GB]
    end

    subgraph Processor [CPU内部]
        Cache[L3/L2キャッシュ]
        ALU[演算コア]
    end

    Weights -- "低速なDDR3バス (ボトルネック)" --> Cache
    Cache -- "高速転送" --> ALU
    ALU -- "次の単語を計算" --> Output[生成テキスト]

    style Weights fill:#f9f,stroke:#333,stroke-width:2px
    style Processor fill:#e1f5fe,stroke:#01579b

たとえば、ChatGPTのように文字がさらさらと流れてくる「デコーダーパス」のフェーズでは、システムは演算依存(Compute-bound)ではなく、完全にメモリ帯域依存(Memory-bound)な状態にあります。

最適化の「魔法の呪文」:ik_llama.cppの活用

Ollamaのような使いやすさを重視したツールは、内部で多くの設定を自動化していますが、古いハードウェアの性能を限界まで引き出すための細かな調整(ノブ)が隠されてしまっています。

そこで、llama-cli(あるいは最適化を施した ik_llama.cpp)を使い、コマンドラインから詳細なフラグを指定する方法が有効です。以下は、Gemma 4を動作させるための設定例です。

llama-cli \
  --model gemma-4-26B-A4B-it-Q8_0.gguf \
  --model-draft gemma-4-26B-A4B-it-assistant-Q8_0.gguf \
  --spec-type mtp --draft-max 3 --draft-p-min 0.0 --spec-autotune \
  -cnv --color --jinja --special \
  -sm graph -smgs -sas -mea 256 --split-mode-f32 \
  --temp 0.7 -t 8 --parallel 8 \
  --cpu-moe --merge-up-gate-experts \
  --flash-attn on --mla-use 3 \
  --mlock --run-time-repack --no-kv-offload

これらのフラグは、古いCPUのキャッシュ構造や命令セットを考慮し、無駄なデータ転送を極限まで減らすためのものです。

投機的デコード(Speculative Decoding)の重要性

この設定の中で特に重要なのが「投機的デコード(Speculative Decoding)」、ここでは特にMTP(Multi-Token Prediction)ドラフターの使用です。

これは、小さなモデル(ドラフトモデル)に「次の単語」をいくつか予測させ、大きなモデル(検証モデル)がそれをまとめてチェックする手法です。

  1. 下書き(ドラフト): 軽量で高速なモデルが、あらかじめ3〜4単語ほど予測します。
  2. 検証(ベリファイ): 本体の大きなモデルが、その予測が正しいか一度に計算します。

この手法の利点は、メモリから重みを読み出す回数を減らせる点にあります。1回の読み出しで複数の単語を確定できれば、低速なDDR3メモリの制約を実質的に緩和できるわけです。

まとめ

10年前のXeonであっても、適切な最適化技術を組み合わせることで、最新のAIモデルを動作させることは不可能ではありません。

もちろん、最新のH100やDDR5環境には及びませんが、ハードウェアの特性を理解し、メモリ帯域というボトルネックをソフトウェア側で工夫(投機的デコードなど)して回避するアプローチは、エンジニアリングとして非常に面白い領域かと思います。

手元に古いサーバーやPCが眠っている方は、最新の llama.cpp の機能をフルに活用して、どこまで動くか試してみるのも一つの楽しみかもしれません。

参照記事