macOSでtext-generation-webuiを使って生成モデルを動作させてみた

# はじめに

Apple Silicon を搭載した Mac を使って LLM 生成モデルを動作させる手順を紹介します。正確にいうと[ローカル環境で大規模言語モデルをAPIサーバを動作させる text-generation-webui編](https://qiita.com/vfuji/items/d1ba564eb8590ea1a271)をmacOSで実行してみました、という内容です。

# 前提条件

- Apple Silicon を搭載した Mac であること
- 16GB 程度のシステムメモリを有していること (8GB だと動かせるモデルがかなり少なくなります)
- セットアップ作業時にインターネットへアクセス可能なこと (*1)

*1 GitHub や Hugging Face へのアクセスが必要となります。

# 手順

これらの手順は、macOS にて実行するための手順となります。OS によって実行するスクリプトが違います。

- [github/oobabooga/text-generation-webui](https://github.com/oobabooga/text-generation-webui) のリポジトリをクローンもしくはダウンロードする
- クローンもしくはダウンロードしたファイルを展開したディレクトリに移動し、`start_macos.sh`を実行する
- 適切なモデルをWeb UIよりダウンロードする

## セットアップ

git clone します。もしくは[ダウンロード](https://github.com/oobabooga/text-generation-webui/archive/refs/heads/main.zip)して下さい。git がインストールされていない場合は、

```sh
git clone https://github.com/oobabooga/text-generation-webui.git
```

git clone もしくは、ダウンロードしたディレクトリに移動し、セットアップを実行します。

```sh
cd text-generation-webui
./start_macos.sh
```

自動的にセットアップが行われますが、次のように、途中で質問が出てきます。Apple M SeriesなのでCを入力しエンターを押下します。

```sh
What is your GPU?

A) NVIDIA
B) AMD (Linux/MacOS only. Requires ROCm SDK 5.6 on Linux)
C) Apple M Series
D) Intel Arc (IPEX)
N) None (I want to run models in CPU mode)

Input> C
```

しばらく待つと次のような出力があり、起動が完了します。この状態でmacOS から URL にアクセスすると Web UI にアクセスできます。ただし、モデルは何もロードされていませんので、Chat など機能しません。

```sh
Running on local URL:  http://127.0.0.1:7860
```

## モデルをダウンロード

はじめにモデルをダウンロードする必要があります。モデル rinna/nekomata-7b.Q4_K_M.gguf を例として紹介します。

1. Web UI 画面上部の Model タブをクリック
2. Download model or LoRA に「rinna/nekomata-7b-gguf」を入力する
3. Getfile list を押下し、 nekomata-7b.Q4_K_M.gguf というファイルが表示されることを確認する
4. Download を押下して待ちます (ネットワークの状況に依存しますが、モデルのダウンロードには時間がかかります)
5. "Model successfully saved to models/"が表示されることを確認します
6. 同じ画面左上にある Model の項目のリロードアイコンボタンをクリックします
7. ボタンの左にあるModel選択のプルダウンメニューから`nekomata-7b.Q4_K_M.gguf`を選択します (しばらくすると Model loader が自動で選択されます)
8. Load をクリックし、モデルが正常にロードされることを確認します (モデルサイズが大きすぎたりサポートしていないモデルの場合、ここでエラーが出力されます)
9. Successfully loaded `nekomata-7b.Q4_K_M.gguf` と表示されれば成功です

あとは、Chat UI から会話を試すなり、API を有効にして利用するなど、色々な使い方があります。API として動作させる場合は、こちらの[ローカル環境で大規模言語モデルをAPIサーバを動作させる text-generation-webui編](https://qiita.com/vfuji/items/d1ba564eb8590ea1a271)をご確認ください。


# 注意事項

## 利用できるモデルのサイズについて

ロードするモデルサイズによって、回答に長時間かかる(1分を超える)ことが起きます。いくつか試した感じだと、16GB のシステムメモリの場合、モデルサイズが5GB 程度のものでないとメモリに乗り切れないようです。私の環境はM1 mac miniです。他にアプリを起動していない状態で、5GB程度のモデルを動かしたところ、残り1GB程度でした。

## llama.cppのn-gpu-layersについて

(追記 2024/06/16)

私の手元にあるM1 mac mini では、n-gpu-layers を適切に設定する場合と設定しない場合でパフォーマンスが大きく違います。レイヤーが全て GPU に載る場合、具体的には`llm_load_tensors: offloaded 33/33 layers to GPU` となる場合、ベストな結果がでました。モデルサイズによって、layer はことなりますが、とりあえず `--n-gpu-layers 64`でも動作します。13B モデルだと、M1 16GB メモリ構成では動作しませんでした。`ggml_metal_graph_compute: command buffer 0 failed with status 5`が連続して出力されます。その場合は、`--n-gpu-layers` を設定しなければ、GPU オフロードがなくなり、CPU　で動作します。遅いですが、レスポンスは返りました。

```sh
./start_macos.sh --model llama-2-7b.Q4_K_M.gguf --chat --share --loader llama.cpp --api --listen --nowebui --auto-devices --n-gpu-layers 64
```

# 参考

- [github.com/oobabooga/text-generation-webui](https://github.com/oobabooga/text-generation-webui)
- [github.com/oobabooga/text-generation-webui/12 - OpenAI API](https://github.com/oobabooga/text-generation-webui/wiki/12-%E2%80%90-OpenAI-API#examples)