自宅PCでもAIしたい！ChatRWKVでLLMをはじめよう

# 自宅PCでも動くLLM、ChatRWKV
ChatRWKVは100% RNNで実装されたRWKVという言語モデルを使ったチャットボットの実装です。
RWKVは高速でありながら省VRAMであることが特徴で、Transformerに匹敵する品質とスケーラビリティを持つRNNとしては、今のところ唯一のものであるそうです。
https://github.com/BlinkDL/ChatRWKV

このChatRWKVを、一般のご家庭にあるようなゲーミングPCで、それなりに高速に動作させることができたので、導入方法を紹介します。
- GPU: Nvidia GTX1070(VRAM 8G)
- メモリ: 16G
- CPU: Intel Core i7-7820HK
- OS: Windows11

<iframe width="560" height="315" src="https://www.youtube.com/embed/BcV2tTBjC4U" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

本手順のポイントは、pytorchのCUDA対応版を入れることと、環境変数RWKV_CUDA_ON=1を設定してGPUで動作するRWKVのCUDAカーネルをビルドすることです。両方CUDA使った方がよいです。
NVIDIAのグラボの乗ったPCへインストールすることを想定しています。

GPU付きのクラウドPCをPaperspace COREで借りて、ChatRWKVを動かすまでの手順を動画にしました。

<iframe width="560" height="315" src="https://www.youtube.com/embed/NSHS5iJrlyI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

Paperspace COREを使うと16GBのVRAMを搭載したA4000インスタンスが1時間あたり約0.76ドル(約100円少々)で使えて、Ravenの7Bモデルまでは動作させることができました。  
Paperspaceのアカウントを新しく作る方は、こちらの紹介コードを使うと10ドル分お得になります。
https://console.paperspace.com/signup?R=2VKCZ4L

# セットアップ手順

1. Pythonのインストール
私は3.10.4を入れていたのでそれを使いましたが、3.10系であれば動くと思います。
https://www.python.org/downloads/windows/

1. CUDA Toolkitのインストール
PytorchのCUDA対応版を使うため、またRWKV_CUDA_ONにするために必要です。最新の12系ではなく[RWKV](https://github.com/BlinkDL/ChatRWKV)公式の手順に記載された11.7を入れます。
https://developer.nvidia.com/cuda-11-7-0-download-archive?target_os=Windows&target_arch=x86_64&target_version=11&target_type=exe_local

1. VS2022 build toolsで「C++によるデスクトップ開発」をインストール
RWKV_CUDA_ON=1でCUDAカーネルをビルドするために必要です。
https://aka.ms/vs/17/release/vs_BuildTools.exe
MSVC v143と、Windows 11 SDKと、Windows用C++ CMakeツールを入れます。
![スクリーンショット_20230406_000715_m.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536213/e26b1a2d-9bd8-e13b-4ddb-05f9ea7b2366.png)

1. ChatRWKVのインストール
Git for windowsを入れている方は `git clone https://github.com/BlinkDL/ChatRWKV` を実行します。
Gitを入れてない方はChatRWKVのGithubページ右上の「Code」から「Download ZIP」して展開してもよいでしょう。
https://github.com/BlinkDL/ChatRWKV
ChatRWKVフォルダを置く場所は任意ですが、私は「C:\Users\私のユーザ名\usr\ChatRWKV」にしました。

1. Python仮想環境の作成
・スタートメニューの検索で「x64 Native Tools Command Prompt for VS 2022」を探して開き、コマンドプロンプトを準備します。
・cdコマンドでChatRWKVのフォルダに移動して、以下を実行して `.venv` フォルダ以下にPythonの仮想環境をつくります。
`py -m venv .venv`<br>
・python310.dllを準備します。
`C:\Users\自分のユーザ名\AppData\Local\Programs\Python\Python310\python310.dll` を `.venv\Scripts` フォルダにコピーしておきます。コピー元のファイルがなかったらCドライブでpython310.dllを探してコピってください。<br>
・python310.libを準備します。
`.venv\Scripts` フォルダの中に `libs` フォルダを作ります。
`C:\Users\自分のユーザ名\AppData\Local\Programs\Python\Python310\libs\python310.lib` を `.venv\Scripts\libs` フォルダにコピーしておきます。コピー元のファイルがなかったらCドライブでpython310.libを探してコピってください。<br>
・RWKVでCUDAを使うための環境変数もactivate.bat(ChatRWKVフォルダの.venv/Scripts/activate.bat)に書いておきます。
```set RWKV_CUDA_ON=1```

1. Python仮想環境の有効化
コマンドプロンプトでChatRWKVのフォルダで以下を実行して、Pythonの仮想環境を有効化します。この操作は、セットアップが終わった後も、コマンドプロンプトを新しく開いてChatRWKVを実行するたびに必要です。
```.venv\Scripts\activate.bat```

1. Pipで必要なパッケージを入れていく
普通にpipでtorchをインストールするとCUDA非対応版が入ってしまいます。入れたCUDA Toolkitのバージョンに対応したものをPytorchのアーカイブから探してバージョン指定して入れましょう。
https://download.pytorch.org/whl/torch_stable.html
```pip install torch==2.0.0+cu117 -f https://download.pytorch.org/whl/torch_stable.html```
```pip install rwkv```
```pip install ninja```
```pip install numpy```
```pip install -r requirements.txt```

1. モデルの入手
RWKV-4で使える適当なモデルを入手します。RavenはRWKV-4-PileモデルをAlpaca, CodeAlpaca, Guanaco, GPT4All, ShareGPT等でファインチューンしたものです。
今の時点では、日本語中国語を1.5%含む、RWKV-4-Raven-EngAndMoreの新しいバージョンを使うのが日本語では使いやすいのではと思います。
https://huggingface.co/BlinkDL/rwkv-4-raven/tree/main
1B,3B,7B,14B等はモデルのパラメータ数(B=10億)で、大きいほど賢い回答が生成できますが、それだけメモリも占有し計算も重くなるので、まずは小さめのモデルから試していくのがよいのではと思います。
モデルはChatRWKVのフォルダに置きます。私はいったんRWKV-4-Raven-7B-v6-EngChnJpn-20230331-ctx4096.pthを使いました。

1. 実行スクリプト`v2/chat.py`の修正
・RWKV_CUDA_ONの修正
`os.environ["RWKV_CUDA_ON"] = '0'`
↓
`os.environ["RWKV_CUDA_ON"] = '1'`<br>
・モデルファイル名の修正(拡張子pthを除いたファイル名を設定する)
`args.MODEL_NAME = '/fsx/BlinkDL/HF-MODEL/rwkv-4-raven/RWKV-4-Raven-14B-v6-Eng-20230401-ctx4096' # try +i for "Alpaca instruct"`
↓
`args.MODEL_NAME = 'RWKV-4-Raven-7B-v6-EngChnJpn-20230331-ctx4096'`

1. チャットスクリプトを実行
`python v2\chat.py`

# VRAMが足りない場合
チャットスクリプト実行後、VRAMが足りない場合は `RuntimeError: CUDA out of memory. Tried to allocate 394.00 MiB (GPU 0; 8.00 GiB total capacity; 7.22 GiB already allocated; 0 bytes free; 7.34 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF` みたいなエラーが出ます。

この場合、より小さいモデルを使うか、使いたいモデルの一部をGPUのVRAMでなく普通のRAMに載せてCPUに処理させるよう変換するstrategyを採用することで、VRAMの使用量を減らすことができます。
どういったstratergyでどの程度VRAMの使用量を減らせるかについては、PyPIのrwkvのページが参考になります。
https://pypi.org/project/rwkv/<br>
基本的にはGPUで処理させる方が速いので、各自の環境でVRAMにできるだけ多くモデルを載せられるようなstrategyを探るのがよいと思います。
私の環境(VRAM8G)では、下記の7Bのモデルは `'cuda fp16i8 -> cpu fp32 *1'` のstrategyで、ぎりぎりVRAMに載りました。
```python .\v2\convert_model.py --in .\RWKV-4-Raven-7B-v6-EngChnJpn-20230331-ctx4096.pth --out .\cudafp16i8_cpufp32x1.pth --strategy "cuda fp16i8 -> cpu fp32 *1"```


モデルをstrategyで変換したら、それに合わせてv2\chat.pyを編集して、再度チャットスクリプトを実行します。
・strategyの編集
`args.strategy = 'cuda fp16'`
↓
`args.strategy = 'cuda fp16i8 -> cpu fp32 *1'`<br>

・モデルファイル名の編集
`args.MODEL_NAME = 'RWKV-4-Raven-7B-v6-EngChnJpn-20230331-ctx4096'`
↓
`args.MODEL_NAME = 'cudafp16i8_cpufp32x1'`

# VRAMの使用量
nvidia-smi.exeコマンドで確認できます。この場合、8192MiB中7996MiB(97%)が使用中です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536213/7cdc5884-a747-ff87-882c-0e6798cc3c67.png)

# 参考
以下のサイトが参考になりました。RWKV開発者のPENG Bo様、LLMで研究開発や情報発信してくださっている皆様、ありがとうございます。

[ChatRWKVを日本語で試す\(Windows11, VRAM 11GB環境）｜松xRのnote｜note](https://note.com/eurekachan/n/na87bd5319dfc)

[RWKVの7Bや14Bを遊ぶ\(NVIDIA RTX A5000 16GB\)](https://zenn.dev/octu0/scraps/ae1eaaff866f3a)

[VRAM8GBのRTX3080Laptop \+ Window11 で、今話題の RWKV\(ルワクフ\)を動かしてみた \| ryuuriの日記 \| スラド](https://srad.jp/~ryuuri/journal/660962/)