西川和久の不定期コラム

初心者も簡単!ついにPCで104BのLLMも動かせるようになった!そして巷を騒がせるマルチモーダルも試した

 これまでローカルPCでは、ビデオカードのVRAM(ビデオメモリ)容量の関係から本連載で試せたのは34Bクラスまでだった。ところが最近、遅くなるものの、不足分はメインメモリを使って補うことによって、104BクラスのCommand R+が動くようになったので、2つの環境でご紹介する。

 加えて、MicrosoftがマルチモーダルLLM「Phi-3-Vision-128K-Instruct」をリリースしたので、それについても触れてみたい。

LM Studio

 ローカルPCでLLMを試す時、二の足を踏むのは、gitやpythonをインストールして、環境を構築しなければならないことだろう。慣れている人であれば大したことないのだが、一般ユーザー的には難しい部分となる。

 以前ご紹介したNVIDIAの「Chat with RTX」(現在はChatRTXという名前に変更)はこの点が良くできており、同社のGPUさえ動いていればセットアップ一発で動く優れものだった。

 とは言え、対応しているLLMの言語モデルが限られているほか、実用的だが面白みには欠けるのは否めなかった。

 そこに登場したのが「LM Studio」だ。Windows、macOS(M1/M2/M3)、そしてLinux(Beta)にも対応。しかもWindowsの場合、setup.exeを実行して、試したいモデルをダウンロードすれば、即チャットができる環境ができあがる。

 さらに、動作しているPCのGPU、VRAM、メモリ容量で、モデルが使えるかどうか、一覧にグリーン=OK、ブルー=使えるがVRAMも使用するため遅い、レッド=使えない……と、パッと見て分かるようになっている点も親切だ。

 今回は、少し前に規模的にGoogle Colab ProでもダメそうでAPIを使用した104BなCommand R+を手元のPCで動かしてみたい。

 とは言え、今回筆者が試すのは巨大なモデルなので、VRAM 24GB、メモリ32GBが最低ライン(つまり超ハイエンドPC)となることをあらかじめご了承頂きたい。ここでは前回記事にした、Core i9-12900(64GB/1TB+1TB)+OCuLink接続GeForce RTX 3090を使用している。

 もちろん、もっと規模の小さいモデルも数多くあり、お手持ちのPCでLM Studioを動かしてみて、グリーンかブルーのモデルなら利用可能だ。手順的には同じなので、本記事を参考にしてほしい。手順は以下の通り。

  1. setup.exeをここからダウンロードする
  2. LM-Studio-xxx-setup.exeを実行(xxxはversion)。即起動する
  3. 2回目以降は、デスクトップのLM Studioショートカットをクリックし起動
LM Studioのホームページ。[Download LM Studio for Windows]をクリックして、LM-Studio-xxx-setup.exeをダウンロード
LM-Studio-xxx-setup.exeを実行すると、即、起動する

 たったこれだけ。あとは目当てのCommand R+をキーワード検索で探せばよいが、どれもファイルサイズが30GB級なのでダウンロードは時間がかかる。また、ダウンロードする前に、My Modelsフォルダが.cache的になっているので、ほかのプログラムなどからモデルにアクセスする予定があるなら、一般的な場所に変えておくといいかもしれない。

これはブルーなので行けそうだ
ダウンロードフォルダは.cache的になっているので、ほかのプログラムからアクセスしやすいよう、場所を変えておく
Command R+起動! 早速チャットしてみる
LM StudioのOpenAI API互換サーバー機能

 タスクマネージャーからも分かるように、メインメモリを42GBほど使用し、CPUの使用率は平均28%(Core i9-12900)と、かなり重い処理というのが分かる。そして動くには動くものの、1 token/sあるかないかで、かなり遅い。7BのLlama2だとすべてVRAMに乗りサクサク動くので、この点は仕方ないところか。

VScodeにcontinue拡張機能を使いLM Studio Serverへ接続し使用中(右側。codellama-13b-instruct.Q8_0.gguf)
Dockerが必要だが、Open WebUIを使えば、ChatGPTそっくりのWebUIで使用可能

 LM Studioはサーバー機能もあり、OpenAI API相当を利用可能だ。従ってクライアント側でOpenAI API対応のものを使うと(endpointをLM Studioが動作しているIPアドレスに変える)、LM Studioのモデルをそのまま利用できる。VSCodeでは画面キャプチャのように、continue拡張機能を使えばOKだ。

 WebUIで使いたい時は、Dockerが必要だが、Open WebUIがChatGPTそっくり。ダミーなのにアカウントを作らないと入れないのも面白い。Docker起動後、

docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main

として、localhost:3000で表示する。後はアカウントを作りログイン、設定→接続でendpoint=http://[LM Studioが動作しているIPアドレス]:1234/v1を入力(この時API Keyはダミーなので何でも良い)。チャット画面に戻り、モデルを選択すればチャットが可能になる。

 画面キャプチャは実験的機能の画像(AUTOMATIC1111, ComfyUI, Dail-E対応)を有効にし、日本語で軽く指示、具体的なイメージを英語で作ってもらい、[image]ボタンを押し生成したものだ。「こんな使い方もある」と言うことで(笑)。

gradio_llm.py

 次は「sd-scripts」でお馴染みKohya Tech氏によるWebUI、gradio_llm.pyを紹介したい。

 いつものminicondaやpip installが必要となるが、command-rやmistral-instruct、llama-3などのチャット形式に対応。またLAN上に接続しているほかのPCからもWebUIにアクセスできるのが特徴だ。

 LM StudioとOpen WebUIの組み合わせでもいいのだが、チャットするだけのためには大袈裟なので筆者は普段こちらを使っている。

 インストールはそれほど難しくない。

  1. もしCUDA Toolkitが入っていなければここからダウンロード/インストール
  2. Minicondaをダウンロード/インストール
  3. 環境構築
    conda create -n llm python=3.11
    conda activate llm
    pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
    pip install -U llama_cpp_python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121
    pip install transformers gradio
  4. コードをここからダウンロード

 そして使用するモデルだが、LM Studioでモデルのフォルダを一般的な場所に……と書いたのは、こちらと併用するため。モデルの検索はネットでもできるが、LM Studioで探した方が楽! ということもある。

ファイル構造
gradio_llm.py
└models/ (LM StudioでここをModel保存場所にする)
 └dranger003/ (モデルをダウンロードすると勝手に作られる)
  └c4ai-command-r-plus-iMat.GGUF/ (〃)
   └ggml-c4ai-command-r-plus-q2_k_s.gguf (上記のモデル)
   └ggml-c4ai-command-r-plus-iq2_xxs.gguf (新規にダウンロードしたモデル)
起動方法
python gradio_llm.py -m ./models/dranger003/c4ai-command-r-plus-iMat.GGUF/ggml-c4ai-command-r-plus-iq2_xxs.gguf -ngl 50 -c 4096 --chat --listen
※ -ngl 50はRAM/VRAMの割合を決める。--listenはLAN上のほかのPCからアクセスOK。他のオプションなどはGitHubのドキュメント参照(日本語)
AIサーバーで起動し、--listenを使い、macOS上で動作する動作中のgradio_llm.py

 筆者の環境だと、ggml-c4ai-command-r-plus-q2_k_s.ggufは0.88 tokens/sと実用に耐えず、もう1つ小さいggml-c4ai-command-r-plus-iq2_xxs.ggufだと2.31/tokens/sと出るので、遅いながらも使える範囲。日頃これで翻訳やプログラミングなどを聞いている。

マルチモーダルなPhi-3-Vision-128K-Instruct

 LLMは上記のようなチャットで楽む(もちろんいろいろ教えてくれる)のはもちろんだが、マルチモーダルになると、画像を与え、そのこに何があるのか? を答えてくれる。最近出た手軽で優秀なのが、MicrosoftのPhi-3-Vision-128K-Instruct(4.15B)。VRAMは10GBほどあれば行けるので、12GBクラス以上でOKだ。手順は以下の通り。

  1. 環境構築

    conda create -n phi3vision python=3.10
    conda activate  phi3vision
    pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
    pip install flash_attn numpy Pillow Requests transformers pip install accelerate
    pip install https://github.com/dillfrescott/flash-attn-windows-wheels/releases/download/2.5.8/flash_attn-2.5.8-cp310-cp310-win_amd64.whl

  2. コードを用意
    ここにあるサンプルコードを気持ち手直し。すべて記載したのでコピペして、test.pyといったファイルに入れればOK。

    from PIL import Image
    import requests
    from transformers import AutoModelForCausalLM
    from transformers import AutoProcessor

    model_id = "microsoft/Phi-3-vision-128k-instruct"
    model = AutoModelForCausalLM.from_pretrained(model_id, device_map="cuda", trust_remote_code=True, torch_dtype="auto")
    processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)

    # 質問: What is shown in this image of a woman?
    messages = [
        {"role": "user", "content": "<|image_1|>\nWhat is shown in this image of a woman?"},
    ]

    # URLから画像読み込み
    url = "https://asset.watch.impress.co.jp/img/pcw/docs/1587/613/F02_o.jpg"
    # url = "https://asset.watch.impress.co.jp/img/pcw/docs/1577/939/T11_o.jpg"
    image = Image.open(requests.get(url, stream=True).raw)

    # ローカルファイルから画像を読み込み
    # image = Image.open("ここへpathを入力")

    prompt = processor.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
    inputs = processor(prompt, [image], return_tensors="pt").to("cuda:0")
    generation_args = {
        "max_new_tokens": 500,
        "temperature": 0.0,
        "do_sample": False,
    }
    generate_ids = model.generate(**inputs, eos_token_id=processor.tokenizer.eos_token_id, **generation_args)

    # remove input tokens
    generate_ids = generate_ids[:, inputs['input_ids'].shape[1]:]
    response = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
    print(response)

  3. 実行

    python test.py
実行中。モデルのファイルサイズが約8.3GBほどある

 初期起動時は約8.3GBほどあるモデルをダウンロードするので少し時間がかかる。今回参照した画像は過去記事この2つ。後者はかなり詳細に書かれているのが分かる。日本語訳は先のggml-c4ai-command-r-plus-iq2_xxs.ggufを使用した。

The image shows a woman standing by a window, wearing a floral dress with a sheer overlay.
女性が窓のそばに立っています。花柄ワンピースの上から透明なオーバーレイを着ています
The image shows a woman standing in front of a tree with pink cherry blossoms. She is wearing a light-colored, sleeveless top and a pair of pants. The background features a train track and a train, suggesting that the photo was taken at a train station.
写真は、ピンクの桜の木の前でポーズをとる女性を示しています。彼女は袖なしの明るい色のトップスとパンツを着ていて、背景には線路や列車があります。これは写真が鉄道駅で撮影されたことを示唆します。

 ここではURLから画像を得ているが、ローカルファイルの場合は、URL関連の部分をコメントアウトして、ローカルファイルから画像を読み込みの部分のコメントを外し、画像へのpathを書けば読み込める。

 筆者はコードにもう少し手を加え、フォルダ内にある全画像を対象とし、同じファイル名で拡張子を.caption、それに保存。以前ご紹介した、SDXL FineTuneのキャプション付けに利用している。従来のBLIP-2よりかなり詳細に出てくるので、嬉しい限り。

 ちょっと残念なのは女性で肌露出が多かったり、グラビア的なポーズをしていると、出るには出るが、前置きとして“Sorry, it may be inappropriate to answer this question. ”とイチイチ入ること。米国企業のセンシティブ病もここまで来たか……という感じだ。分かっててローカル環境で画像を入れているのだから、(generation_argsにオプションがあるかもだが)黙ってそのまま出してほしいところ。いらぬおせっかいと言えよう。

 次はお馴染み、ミニPCの内部写真。これはpromptを少し変更して“What is shown in this image detail?”としている。結果がなかなか凄まじい。翻訳はPhi-3-medium-128k-instruct-Q8_0.gguf(14B)を使用。このモデルも14Bの割に高性能で最近巷を騒がせているものだ。

The image details a computer case that has been opened, revealing its internal components. The case is predominantly white with a blue circuit board inside. The circuit board is labeled with the word "crucial", indicating the brand of the motherboard.

The case also contains a black fan, which is likely used for cooling the internal components. The fan is connected to the circuit board via a series of wires.

In addition to the fan and circuit board, the case also has a small storage compartment. This compartment appears to be empty in the image.

The image does not contain any text or other objects. The relative positions of the objects are such that the fan is located on the left side of the case, the circuit board is in the center, and the storage compartment is on the right side.

This image provides a clear view of the internal components of a computer case, which could be useful for someone interested in computer hardware or DIY computer building.

画像は、開いたコンピュータケースの内部を描写しており、そこに含まれるコンポーネントが明らかになっています。ケースは主に白色であり、青色の回路基板が中心に配置されています。回路基板には「crucial」という単語が記載されており、それがマザーボードのブランドを示していることを意味します。

ケース内部には黒色のファンも見られ、コンポーネントの冷却用である可能性が高いです。ファンは回路基板へと接続されており、そのために複数のワイヤーを介して結ばれています。

加えて、ケース内部に小さな保管用コンパートメントも存在しているようです。このコンパートメントは画像において空っぽと見受けられます。

テキストや他のオブジェクトが画像内に存在しないため、ファンはケースの左側に位置し、回路基板は中心部分に配置されており、保管用コンパートメントは右側にあると考えられます。

この画像は、コンピュータハードウェアやDIYコンピュータ構築に関心を持つ人々にとって有用な情報を提供している可能性があります。


 以上、dGPU搭載のハイエンドなPCが必要にはなるものの、104BなCommand R+と、画像に何が書かれているのかを答えるマルチモーダルLLMのPhi-3-Vision-128K-InstructをクラウドGPUではなく、ローカルPCのみで動作させる方法をご紹介した。

 本連載で初めてLLMを扱ってからまだ1年とちょっとだが、ここに来てギアが一段上がった感じだ。ここまでローカルPCで動き出すとかなり楽しく、そして実用的になる。

 また、つい先日、Copilot+ PC=AI機能標準搭載PCが発表された。現在40TOPS以上のAI処理能力を持つのがSnapdragon X Elite/Plusのみだが(例のDevelopper Kit PCを購入するか悩み中)、追ってIntel/AMDからも出てくるだろう。今回のような超ハイエンドPCを使わず、同じことができるようになるのか!? 今後に期待大♪