月別アーカイブ: 2025年3月

APU 内蔵 GPU でもローカル LLM を走らせてみる

以前 ROCm 非対応の Radeon RX 6400 でも、環境変数の設定だけで ROCm 版の ollama を走らせることができました。同じ方法で APU の内蔵 GPU でもローカル LLM を実行できるので実際に試してみました。

今回使用した CPU 内蔵 GPU は以下の 2つです。いずれも DDR5-5600 を使用しています。

CPU (APU)内蔵 GPUアーキテクチャCUspfp32 FLOPS
Ryzen 7 9700XRadeon 610M RDNA2 gfx10372 CU128 sp486.4 GFLOPS
Ryzen 7 7840HSRadeon 780MRDNA3 gfx110312 CU768 sp8294.4 GFLOPS

インストール方法など

事前に UEFI (BIOS) 設定で、内蔵 GPU のフレームバッファの割当をできるだけ増やしておいてください。今回は Ryzen 7 9700X では 16GB、Ryzen 7 7840HS では 8GB に設定しています。

  1. OS は Linux を直接インストールしています
    • Ubuntu 24.04LTS (Desktop 版最小構成)
  2. ollama をインストールします
    • 公式手順どおりです
    • curl -fsSL https://ollama.com/install.sh | sh
  3. ollama の起動設定ファイルを開きます
    • sudo systemctl edit ollama.service
  4. エディタが起動したら 3行目からの空行に以下の 2行を挿入します
    • Ryzen 7 9700X (RDNA2) の場合
      • [Service]
        Environment="HSA_OVERRIDE_GFX_VERSION=10.3.0"
    • Ryzen 7 7840HS (RDNA3) の場合
      • [Service]
        Environment="HSA_OVERRIDE_GFX_VERSION=11.0.2"
  5. 保存して終了したら以下のコマンドを実行します
    • sudo systemctl daemon-reload
    • sudo systemctl restart ollama

実行方法

  1. コマンドラインから直接モデル名を指定して実行します
    • ollama run gemma2:9b
  2. あとは質問などをコンソールから入力できます

もし詳細 (token/s など) を表示させたい場合は質問の前に「/set verbose [ENTER]」を入力しておきます。終了は Ctrl-D です。

実行中に別のターミナルを開いて、コマンドラインから ollama ps を実行することで GPU への割当状況を確認することができます。100% GPU になっていれば OK です。

oga@ub24llm:~$ ollama ps
NAME         ID              SIZE      PROCESSOR    UNTIL
gemma2:9b    ff02c3702f32    9.4 GB    100% GPU     4 minutes from now

実行結果

実際に試した結果は以下のとおりです。CPU のみの場合と比べています。

9b model (gemma2:9b) の場合

CPUGPUGPU割合使用メモリtoken/s
Ryzen 7 9700Xなし0%7.7 GB8.71 tps
Ryzen 7 9700XRadeon 610M100%7.3 GB5.88 tps
Ryzen 7 7840HSなし0%9.0 GB9.02 tps
Ryzen 7 7840HSRadeon 780M100%7.3 GB12.89 tps

Ryzen 7 9700X では GPU Radeon 610M を使用した方が速度が落ちているのは予想通りです。この GPU は 2CU 128sp しかなく CPU よりも演算性能が劣ります。Ryzen 7 9700X の Zen5 は AVX512 命令が同時に 2命令走るため 8 core でも 256sp 相当、クロック差を考慮すると CPU の方が 4倍以上演算能力が高いことになります。

逆に Ryzen 7 7840HS の場合は 768sp × 2ALU の GPU を搭載しており、GPU の方が何倍も演算能力が高いことになります。ですが LLM の場合は演算能力だけでなくメモリ速度の影響を強く受けます。APU ではメモリ帯域で頭打ちになるため、あまりパフォーマンスが変わらないのではないかと思ってましたが少々予想外でした。この結果だけ見るとGPU の方が 40% ほど速くなっています。なお NPU は未使用です。

以下他のモデルでの結果です

14b model (phi4:14b)

CPUGPUGPU割合使用メモリtoken/s
Ryzen 7 9700Xなし0%10 GB5.73 tps
Ryzen 7 9700XRadeon 610M100%12 GB1.96 tps
Ryzen 7 7840HSなし0%11 GB6.22 tps
Ryzen 7 7840HSRadeon 780M80%10 GB6.59 tps

14b のモデルではフレームバッファ割当 8GB の Radeon 780M では VRAM 領域にすべて載りませんでした。そのため 20% は CPU が用いられており CPU と GPU の差は小さくなっています。

他のモデルや他の GPU 利用時の結果は↓こちらのページにまとめています。Wiki なので逐次更新しています。

CPU の速度差

上の結果を見ると CPU 利用時は Ryzen 7 9700X よりも Ryzen 7 7840HS の方がパフォーマンスが高いように見えます。でも実際は演算性能は Zen5 の 9700X の方が上で、Desktop 向けなので電力&冷却も 9700X の方が有利です。

これまでの表の結果を見ると動作時の使用メモリ容量が 7.7GB と 9.0GB で異なっているので、走っている ollama の runner が異なっている可能性があります。runnner によって使用する CPU 命令に違いがあり、最適化方法が異なっている可能性があります。また動作プラットフォームを変えると逆転することがあるため、計測環境の不一致も考えられます。どちらが速い、等の結論を出すにはまだ早いようです。

以下は異なる OS 下での ollama による違い調べたものです。token/s が大きい順に並べています。WSL2 の結果を見ると 9700X の方が速くなっています。

9b (gemma2:9b) CPUのみ

OSCPU使用メモリtoken/s
Windows11 + WSL2Ryzen 7 9700X7.7 GB9.46 tps
LinuxRyzen 7 7840HS9.0 GB9.02 tps
LinuxRyzen 7 9700X7.7 GB8.71 tps
Windows11Ryzen 7 9700X7.7 GB8.66 tps
Windows 11 + WSL2Ryzen 7 7840HS9.0 GB8.59 tps

演算能力で大きく異なるはずの 9700X と 7840HS でも結果としてはあまり違いが生じない結果となっています。使用している RAM の速度が同一なので、メモリ帯域による限界ではないかと思われます。

まとめなど

さまざまな GPU で試した結果を見ても、やはりメモリ速度が非常に重要であることがわかります。CPU 内蔵 GPU (APU) ではメモリ帯域に制限があるため、いくら演算能力が高くても外付け GPU ほどの大幅な高速化は期待できません。それでも Ryzen 7 7840HS は GPU の方が速度が出ていますので、使えるケースでは活用していきたいところです。

関連ページ

ローカル LLM と VRAM メモリ速度

パラメータ数とメモリ帯域

LLM はパラメータ数が多い方が性能が高いですがその分多くの RAM を必要とします。例えばパラメータ数が 32b の LLM モデルの場合、単純に考えるとパラメータだけでも fp32 で 128GB、fp16 でも 64GB の規模感です。4bit に量子化できたと仮定しても最低 16GB 以上、実際には 18GB 程度のメモリが必要です。

これらのパラメータは演算を行うたびに毎回メモリから読み込まれます。そのため LLM の推論にはパラメータを格納するメモリ容量に応じたメモリの転送速度 (メモリ帯域) が必要になることがわかります。

例えば PC 用メモリの DDR4-3200 2ch (128bit) の転送レートはピークで 51.2GB/s です。この場合 4bit 量子化した 18GB のパラメータを最大レートで読み込めたとしても秒間 2.8回しか読み込むことができません。1 Token 生成するたびに全パラメータが 1回だけロードされると仮定しても、最大で 2.8 token/s の速度しか期待できないことになります。実際に DDR4-3200 を搭載した CPU Ryzen 9 3950X での 32b モデルの推論結果は 2.16 token/s で、この数値を下回っていました。

もちろん実際にはもっと多くの帯域が必要になるかもしれませんし、逆に MoE のようにモデル構造によっては推論に必要なメモリが少なく済む可能性があります。

GPU と VRAM 速度

GPU は並列演算に特化しており、同時に大量のデータを扱うことができます。そのため高性能な GPU には、性能に見合うだけのより高速な専用メモリが VRAM として搭載されています。

一般的に CPU よりも GPU の方が演算能力が高く VRAM 速度も速いので、パラメータをできるだけ VRAM に載せ、GPU 上で動作させることが高速化に繋がります。

例えば GeForce RTX 2080Ti はメモリ帯域は 616 GB/s と高速です。CPU (DDR4-3200) と比べると 12倍も速く、仮に 18GB のモデルがすべて VRAM に収まったと仮定すると 1秒に 34回読み出せる計算になります。ただし実際は VRAM 容量が 11GB と少ないため残念ながら 18GB のパラメータは VRAM から溢れます。PC 向けのビデオカードでは VRAM 容量が小さいことが多く、大きな制限となっています。

ollama のマルチ GPU 推論と VRAM

ollama では複数のビデオカードを併用することで、大きなモデルも分割して VRAM に載せることができるようになります。1台では入り切らない大きなモデルも複数台集めれば高速な VRAM 上で走らせられるようになるわけです。ですが残念ながらすべての GPU が同時に動いているわけではありません。パラメータはレイヤー毎に分割されるので、前段レイヤーの出力を受け取ってから次のレイヤーの演算が走ります。GPU も前の GPU の結果が出るまで待つことになります。

よって現時点では、ビデオカードを複数台接続しても時間あたりの演算能力が増えるわけでは無いようです。将来的には別の方法が登場するかもしれませんが、今のところビデオカード複数台使う目的は GPU の並列化や演算能力の増強ではなく、あくまでトータルの VRAM 容量を増やすことにあります。

  • 1台分の VRAM に収まる小さいモデルはビデオカードを増やしても速度が変わらない
  • 直列動作なので異なる性能のビデオカードでも組み合わせられる
  • 台数が増えればそれだけ GPU が休んでいる時間が増え稼働率は下がる

そのため家に眠っていた旧世代のビデオカードを再利用することができますし、ビデオカードを 5台つないだからといって必ずしも消費電力が 5倍になるわけではありません。

メモリ速度からの推論速度の上限を大雑把に計算してみる

少々乱暴ですが、GPU のメモリ速度とメモリ使用量から推論の限界速度がどれくらいなのか割り出してみました。あくまでメモリ速度への依存度が高いことが前提となっています。

先程も例に上げた GeForce RTX 2080Ti の場合 616 GB/s で、かつ 14b (phi4:14b) 実行時の使用メモリ容量は 10GB となっています。よって 1秒間に 61.6 回読み込める計算なので、メモリ速度から見た推論速度の予測上限値は 61.6 になります。実際の推論速度は 51.33 tps でした。

GPUメモリ速度メモリ使用量token/s予測上限値
RTX 2080Ti616 GB/s10GB51.33 tps61.60

複数台の GPU に分散される場合は、それぞれの GPU に割り当てられるメモリ容量から個別に求めて加算します。

予測上限値 = ( 1 / ∑ (GPU毎の使用メモリサイズ / GPU のメモリ速度) )

VRAM に乗らず GPU にも分散される場合は、CPU の割合からメモリ使用量を求めてから同じように加算しています。

予測上限値 = (1/( (CPUの使用メモリサイズ / CPU メモリ速度) + ∑ (GPU毎の使用メモリサイズ / GPU のメモリ速度)))

今まで集めたケースそれぞれで予測値を計算して、まとめページの表に追加してみました。こちらのページで右端にある「mpr」がメモリ速度から求めた予測上限値となります。

以下の表は上のページからの抜粋です。複数 GPU のケースがわかりやすいように 70b (llama3.3:70b) のデータを選びました。

GPUVRAM合計メモリ使用量GPU割合token/s予測上限値
RTX4060Ti16GB46GB35%1.65 tps2.57
RTX4060Ti
RTX2080Ti
27GB48GB57%2.22 tps3.28
RTX4060Ti x2
RTX2070S
40GB49GB83%3.08 tps3.40
RTX4060Ti x2
RTX2070S
GTX1080
48GB51GB94%4.25 tps4.68
RTX4060Ti x2
RTX2070S
GTX1080
GTX1070
56GB55GB100%5.10 tps5.50

GPU が複数台接続されている場合は、それぞれの VRAM 容量に応じて均等にメモリが割り当てられているものとみなしています。実際の VRAM 割り当てを見ているわけではないのでモデルサイズが小さい場合は誤差が生じます。例えば小さいモデルが速い GPU の VRAM にすべて収まるような場合でも、遅い VRAM の GPU と平均化されてしまうため予測値が実測値よりも低くなることがあります。

以下の表はシングル GPU (+CPU) のケースで 14b (phi4:14b) の結果です。

GPUVRAM合計メモリ使用量GPU割合token/s予測上限値
RX76008GB10GB80%11.43 tps15.72
RTX2070S8GB10GB76%14.67 tps22.86
RTX4060Ti16GB12GB100%27.92 tps24.00
RTX2080Ti11GB10GB100%51.33 tps61.60

大半は token/s として予測未満の値が出ているように見えますが、GeForce RTX 4060 Ti では予測した上限値よりも高いスコアが出ています。RTX 3000 のデータがないのでわかりませんが、RTX 4000/5000 などの新しい世代では必ずしも計算が合わないかもしれません。おそらく使用メモリには必ずしも毎回ロードされないパラメータ領域があるか、またはキャッシュが効きやすい短時間に何度も参照される領域も含まれているのだと考えられます。

まとめなど

ビデオカードを追加する場合にどの程度の速度向上が見込めるかをある程度予想できるので、無駄な投資をしなくて済むのではないかと思って計算してみました。ただし新しい世代の GPU では予想よりも速くなる可能性があるため、必ずしもこの通りの結果にはならないようです。 RTX の 4000 世代ではキャッシュメモリが増加しているので、もっとモデルの構造やアルゴリズムも考慮しないといけなかったのかもしれません。

関連ページ