みなさんこんにちは、ユニファの赤沼です。 この記事は Unifa Advent Calendar 2023 の24日目の記事です。
最近 ChatGPT をはじめとした LLM をAPIで利用することは多い一方で、ローカル環境でモデルを動かしたことはなかったのですが、先日ブラックフライデーのセールでゲーミングPCが安くなっていて、 ただゲームやりたさに AI関連のことに使いたいなと思い Windows PC を買ったこともあり、何もわからないところから最低限ひとまずモデルを動かしてみました。
ローカルに直接各種ライブラリなどをインストールして環境を作るのは後々依存関係など面倒なので Docker で動かしたいと思い、手探りでいろんなサイトを拝見してやり方を調べましたが、 WSL2 の Ubuntu の上で環境を構築するケースが多そうだったものの、WindowsもローカルLLMも初心者なので、今回はまずはシンプルに Windows 上の Docker で動かす方法でやってみます。
NVIDIA ドライバの確認
まずは NVIDIA のドライバが入っているかを確認します。 nvidia-msi
コマンドを実行すると下記のように GPU の情報が確認できたので、ドライバは問題なさそうです。これは既に GeForce Experience からドライバーをインストールしてあったことによるものかと思います。
Docker・Windows環境
Docker は Docker Desktop を使っていて、バージョンは下記のとおりです。
> docker version Client: Cloud integration: v1.0.35+desktop.5 Version: 24.0.7 API version: 1.43 Go version: go1.20.10 Git commit: afdd53b Built: Thu Oct 26 09:08:44 2023 OS/Arch: windows/amd64 Context: default Server: Docker Desktop 4.26.1 (131620) Engine: Version: 24.0.7 API version: 1.43 (minimum version 1.12) Go version: go1.20.10 Git commit: 311b9ff Built: Thu Oct 26 09:08:02 2023 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.25 GitCommit: d8f198a4ed8892c764191ef7b3b06d8a2eeb5c7f runc: Version: 1.1.10 GitCommit: v1.1.10-0-g18a0cb0 docker-init: Version: 0.19.0 GitCommit: de40ad0
Windowsやデバイスのスペックは下記の通り。
- エディション Windows 11 Home
- バージョン 23H2
- プロセッサ AMD Ryzen 7 6800H with Radeon Graphics 3.20 GHz
- 実装 RAM 16.0 GB (15.2 GB 使用可能)
CPU で Llama のクイックデモを動かす
まずは Docker が公開している下記のチュートリアル的な記事に沿ってLlamaのモデルを動かしてみます。
Llamaモデルへのアクセスリクエストが必要ということなので Hugging Face の下記ページの案内に従って Submit しておきます。
私の場合は一時間以内ぐらいで Access granted のメールが来たと思います。
また、 Hugging Face のアカウントの設定ページからアクセストークンを作成しておきます。
では下記コマンドを実行してモデルを動かしてみます。 HUGGING_FACE_HUB_TOKEN
には Hugging Face のアクセストークンを設定します。
初回実行時はイメージのダウンロードに時間がかかります。2回目以降でもモデルのファイル取得が発生するので、私の環境だと起動までに2分ぐらいかかりました。
PS C:\Users\hiroa> docker run -it -p 7860:7860 --platform=linux/amd64 -e HUGGING_FACE_HUB_TOKEN="XXXXXXXXXXXXXXXXXXXX" registry.hf.space/harsh-manvar-llama-2-7b-chat-test:latest python app.py Unable to find image 'registry.hf.space/harsh-manvar-llama-2-7b-chat-test:latest' locally latest: Pulling from harsh-manvar-llama-2-7b-chat-test 0a9573503463: Pull complete 1ccc26d841b4: Pull complete 800d84653581: Pull complete 7c632e57ea62: Pull complete f9a1922eee8a: Pull complete b0fef9d6962c: Pull complete a8d4dcc5b913: Pull complete ffdc35a04c11: Pull complete 0472b8c3ae5c: Pull complete a788554e043e: Pull complete 03098cd05c8d: Pull complete 98b5990936af: Pull complete 46995db4b389: Pull complete 8b97359802d5: Pull complete a39f01aaecff: Pull complete fd856e75ffe3: Pull complete 3ef947ccedda: Pull complete Digest: sha256:d0db0be9521a717a108a722f73087acf6c64b707695d76c15afa137df8c96439 Status: Downloaded newer image for registry.hf.space/harsh-manvar-llama-2-7b-chat-test:latest config.json: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████| 29.0/29.0 [00:00<00:00, 91.8kB/s] Fetching 1 files: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 2.23it/s] llama-2-7b-chat.ggmlv3.q2_K.bin: 100%|████████████████████████████████████████████████████████████████████████████████████| 2.87G/2.87G [01:58<00:00, 24.3MB/s] Fetching 1 files: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [01:59<00:00, 119.86s/it] Generate config GenerationConfig { "_from_model_config": true, "bos_token_id": 1, "eos_token_id": 2, "pad_token_id": 2, "transformers_version": "4.31.0" } tokenizer_config.json: 100%|██████████████████████████████████████████████████████████████████████████████████████████████| 1.62k/1.62k [00:00<00:00, 4.54MB/s] tokenizer.model: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████| 500k/500k [00:00<00:00, 11.2MB/s] tokenizer.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████| 1.84M/1.84M [00:00<00:00, 2.70MB/s] special_tokens_map.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████| 414/414 [00:00<00:00, 1.29MB/s] loading file tokenizer.model from cache at /home/user/.cache/huggingface/hub/models--meta-llama--Llama-2-7b-chat-hf/snapshots/c1b0db933684edbfe29a06fa47eb19cc48025e93/tokenizer.model loading file tokenizer.json from cache at /home/user/.cache/huggingface/hub/models--meta-llama--Llama-2-7b-chat-hf/snapshots/c1b0db933684edbfe29a06fa47eb19cc48025e93/tokenizer.json loading file added_tokens.json from cache at None loading file special_tokens_map.json from cache at /home/user/.cache/huggingface/hub/models--meta-llama--Llama-2-7b-chat-hf/snapshots/c1b0db933684edbfe29a06fa47eb19cc48025e93/special_tokens_map.json loading file tokenizer_config.json from cache at /home/user/.cache/huggingface/hub/models--meta-llama--Llama-2-7b-chat-hf/snapshots/c1b0db933684edbfe29a06fa47eb19cc48025e93/tokenizer_config.json Starting Running on local URL: http://0.0.0.0:7860 To create a public link, set `share=True` in `launch()`.
起動が完了したら http://localhost:7860
にアクセスすると下記のようなデモ用のチャットのUIが表示されます。
英語で入力すると普通に対話ができそうです。日本語も解釈してくれているようですが、そのまま日本語で会話できるという感じではなさそうです。
UI下部の Advanced options
を開くと システムプロンプトや各種パラメータの設定もできるようです。
docker コマンドを実行したターミナルには下記のように入力についてのログが表示されます。
display_input=Hello Generate config GenerationConfig { "_from_model_config": true, "bos_token_id": 1, "eos_token_id": 2, "pad_token_id": 2, "transformers_version": "4.31.0" } display_input=日本語も話せますか? Generate config GenerationConfig { "_from_model_config": true, "bos_token_id": 1, "eos_token_id": 2, "pad_token_id": 2, "transformers_version": "4.31.0" }
とりあえずこれでローカルでモデルを動かすこと自体はできましたが、ここまでの内容では GPU は使われておらず、すべて CPU で処理されているようです。
GPU でモデルを動かす
GPUが使われないとゲーミングPCでやってる意味もないということで、先程のデモの内容を少し変更して動かそうとしてみたのですがすんなりはうまく行かなかったので方法を探したところ、 @karaage0703 さんが下記の記事を公開されていたのでこれをもとに動かしてみます。
記事では Linux環境、もしくは WSL2 の環境をベースとされていますが、今回は Windows から直接 Docker を使います。
まずは下記コマンドでリポジトリを clone してからイメージをビルドします。
> git clone https://github.com/karaage0703/ChatLLM > cd ChatLLM > docker build -t ubuntu:ChatLLM .
ビルドが終わったら下記コマンドでコンテナを起動します。
--gpus
は NVIDIA の GPU を使うためのオプションで、 all
を指定することで全ての GPU が使われることになります。
> docker run -it -v C:\Users\hiroa\workspaces\ChatLLM:/root --gpus all ubuntu:ChatLLM
コンテナ内でプロンプトが表示されたら用意されている Python のスクリプトを動かします。下記では サイバーエージェントによって開発されたモデルである CALM を使っています。
# cd /root # python3 chat_calm.py
プロンプトが表示されたら文を入力してみます。
> こんにちは CALM: こんにちは! 今回は、3月生まれのお誕生日会を行いました。 今回は、3月生まれのお友達のお祝いということで、 4名のお友達をお祝いしました。 とってもかわいい、3月生まれのお友達です。 お名前を言ってもらって、みんなでお祝いしました。 3月生まれのお友達、お誕生日おめでとうございます
> 今日の東京の天気は
CALM: 今日の東京の天気は雨・・・
「台風」で気圧変化が大きいと、自律神経のバランスが乱れ、頭痛、めまい、耳鳴り、吐き気・・・
などの症状を引き起こします。
また、
台風が通過する地域の方は、台風の風や雨で体調を崩さないよう
くれぐれもご注意を!
「台風」
このモデルはチャット用のモデルではないため、入力した文の続きを推測して出力するような内容になっています。
上記実行中は下記のように GPU の使用率が上がったため、ちゃんと GPU が活用されたようです。
CALM以外にも りんな などを使うためのスクリプトも用意されていますが、自分の環境で動かした際にはエラーになってしまい、CALMしか実際の動きは試せませんでした。この原因調査はまた別途してみたいと思います。
まとめ
今回は他の方が用意されたスクリプトを動かしただけの形ではありましたが、ともかくローカル環境のDockerでLLMのモデルをGPUを使って動かすことができました。やはり実際に動かしてみるとうまく行かないことを調べたりしながら少しずつでもイメージが掴めてきて良いですね。私のPCのスペックは GeForce を積んではいても高いスペックではないので実質的に使い物になるかは微妙なところですが、面白そうなのでもっと色々と触ってみようと思います。
ユニファではGPUがあったらLLMを動かしてみたくなっちゃうような仲間も募集中です!少しでも興味をお持ちいただけた方は、ぜひ一度カジュアルにお話しましょう!