Apple Siliconを使ってローカルLLMを実現する際のコストとパフォーマンスの比較

# はじめに

大規模言語モデル (LLM) をクラウドサービスの一部として使う、ではなく`ローカル環境で動作させること`を目的に調査及び検証を行った内容です。ローカル LLM を実現する上でポイントとなる GPU を選択する上で、Apple Silicon のコスト面と現実的な速度の比較ができると良いなと考え調査してみました。

LLM をローカル環境で実行しようとすると、一般的には NVIDIA の GPU を使うことになるかと思います。しかし、コンシュマーモデルで VRAM 24GB を用意しようとすると GPU カードだけで 30万円コースとなります。80GB のエンタープライズ クラスのカードの場合、一枚でも100万円を超えるのではないでしょうか。

Apple Silicon は CPU とメモリ、GPU とメモリを一つのチップに統合した SoC であり、ユニファイドメモリアーキテクチャを採用しています。CPU と GPU が効率的にメモリ上のデータにアクセスできる、ということです。このことは、[WWDC2020](https://developer.apple.com/videos/play/wwdc2020/10686/) にて解説されています。このユニファイドメモリアーキテクチャがローカル LLM の実現に効果を発揮するのではないか、ということで、比較してみました。といっても、GPU メモリが大きなマシンを何台も用意できるわけではないので、コンパクトなモデルで比較しています。大規模な環境の結果については、検索した内容を紹介します。

# 前提条件

## Apple Silicon

- Mac Mini M1 2020
- 16GB メモリ

環境は次の[macOSでtext-generation-webuiを使って生成モデルを動作させてみた](https://qiita.com/vfuji/items/a1f4b5c79b034e264d77)に記載している手順で用意しました。

次の表が現実的な選択肢でしょうか。2024/06/17 時点での調査となるので、変更があった場合は、適宜読み替えてください。

私の環境は M1 16GB メモリですが、4ビット量子化した 7B/8B モデルは GPU で動作しましたが、13B/14B クラスは GPU では動作せず、CPU での動作となりました。

||CPU/GPU|Memory|Price|GB/Yen|
|---|---|---|---|---|
|Apple Mac mini|M2 Pro: 10 CPU core, 16 GPU Core|32|244,800|7,650.0|
|Apple Mac Studio|M2 Max: 12 CPU core, 30 GPU Core|64|358,800|5,606.3|
|Apple Mac Studio|M2 Max: 12 CPU core, 38 GPU Core|96|448,800|4,675.0|
|Apple Mac Studio|M2 Ultra: 24 CPU core, 60 GPU Core|128|718,800|5,615.6|
|Apple Mac Studio|M2 Ultra: 24 CPU core, 60 GPU Core|192|838,800|4,368.8|

## NVIDIA GPU マシン

- NVIDIA GeForce RTX 4060 8GB (ラップトップ)
- 32GB メモリ
- WSL2 Ubuntu

環境は次の[ローカル環境で大規模言語モデルをAPIサーバを動作させる text-generation-webui編](https://qiita.com/vfuji/items/d1ba564eb8590ea1a271)に記載している手順で用意しました。

# 比較結果

秒間トークン数 (tokens/s) を記録すると次のようになりました。ノート PC に搭載された NVIDIA GPU の方が 3.5 倍ほど高速なようです。

|llama-3-8b|Q1|Q2|Q3|Average|
|---|---|---|---|---|
|RTX 4060|29.24|29.06|28.92|29.07|
|M1|8.11|9.00|8.95|8.69|

|llama-2-7b|Q1|Q2|Q3|Average|
|---|---|---|---|---|
|RTX 4060|39.59|25.97|39.65|35.07|
|M1|5.76|10.99|11.08|9.28|

様々なハードウェア環境での比較が[こちらのページ](https://github.com/XiongjieDai/GPU-Benchmarks-on-LLM-Inference)に記載されています。

蛇足ですが、OpenAI API と比較すると面白いかと思います。[OpenAI API's Token Generation Speeds](https://fabienroger.github.io/trackoai/) というページに計測結果が掲載されています。GPT-3.5-Turbo と GPT-4o が 60 tokens/s から 90 tokens/s 程度となっており、GPT-4-Turbo が 25 tokens/s から 40 tokens/s の間という感じです。皆様の体感と同じような感じでしょうか。


# 比較の手順

## 質問文

次のような形で実行しました。system role は設定していません。

```sh
curl "http://{IP_Address}:5000/v1/chat/completions" \
-H 'Content-Type: application/json' \
-d '{"messages":
   [
    {"role":"user",
    "content":"{QUESTION}"} 
    ],
     "temperature":0.9
    }'
```

QUESTION には1回目から3回目まで次のような質問を入力しています。

1. Please tell me US GDP share by industry.
2. Which is the best place to go in Japan west area?
3. Show me top 3 list of automotive manufacturer in Europe.

## text-generation-webui を実行

WSL2 Ubuntu では次のように実行しています。

```sh
./start_linux.sh --model {MODEL_NAME} --chat --share --auto-devices --loader llama.cpp --api --listen --n-gpu-layers 128 --nowebui
```

macOS では次のように実行しています。`-n-gpu-layers` はモデルサイズに依存するようです。7B/8B では 33 でした。

```sh
./start_macos.sh --model {MODEL_NAME} --chat --share --auto-devices --loader llama.cpp --api --listen --n-gpu-layers 33 --nowebui
```


# 参考

- [github.com/oobabooga/text-generation-webui](https://github.com/oobabooga/text-generation-webui)
- [github.com/XiongjieDai/GPU-Benchmarks-on-LLM-Inference](https://github.com/XiongjieDai/GPU-Benchmarks-on-LLM-Inference)
- [github.com/FabienRoger/trackoai](https://github.com/FabienRoger/trackoai)
- [Optimizing your LLM in production](https://huggingface.co/blog/optimize-llm?_fsi=OWh5oBFR&_fsi=HKcbqROu#:~:text=Loading%20the%20weights%20of%20a,requirement%20to%20load%20the%20weights)