Joshua Guo

デザインエンジニア · V2SPACE 創設者

技術ノート

LM Studio と Pi で、20GB VRAM の Qwen3.8-27B を動かす

RX 7900 XT で Qwen3.8-27B を 128K コンテキスト、全 64 層 GPU offload に設定し、Mac の Pi につないで試した記録。

本文

やりたいことは単純でした。Pi は Mac に置いて手元のファイルのそばで動かし、推論は RX 7900 XT(VRAM 20GB)を積んだ PC の LM Studio に任せる、という分担です。

Qwen3.8-27B は 128K コンテキストで、64 層すべてを GPU offload に設定した状態でロードできました。これを Pi から使って、React と ECharts の可視化をつくりました。以下は動いた設定と、まだ測っていないことのメモです。

構成

LM Studio は ROCm ではなく Vulkan でモデルを動かし、ローカルネットワークに OpenAI 互換の API を公開しています。

Pi on Mac
  -> LM Studio API on PC (Vulkan runtime)
  -> Qwen3.8-27B
  -> RX 7900 XT 20GB

LM Studio の設定値はこうなっています。

設定値
モデルQwen3.8-27B
GGUFQwen3.8-27B-UD-Q3_K_XL.gguf
モデルの配布元unsloth/Qwen3.8-27B-GGUF
ランタイムVulkan
コンテキスト長128,000
GPU offload64 層中 64 層
Flash Attention有効
K キャッシュQ4_0、GPU 上
V キャッシュQ4_0、GPU 上
CPU スレッドプールサイズ4
評価バッチサイズ512
物理バッチサイズ1024
同時推論数1
RoPEデフォルト
投機的デコード無効
MTP無効

Qwen3.8-27B の公式モデルカードによると、パラメーターは 270 億、層は 64、ネイティブのコンテキスト長は 262,144 トークンです。私は 128K で止めました。普段のコーディングにはそれで十分すぎるくらいですし、収まるからです。

Q3_K_XL を選んだ理由

Unsloth は Qwen3.8-27B の GGUF 量子化版をいくつか出しています。検討したのは次のものです。

量子化ファイルサイズ
UD-IQ3_S12GB
UD-Q3_K_XL13.1GB
UD-IQ4_XS14.3GB
UD-Q4_K_M16.5GB
UD-Q5_K_XL20.9GB

サイズは Unsloth の GGUF リポジトリの値です。選んだのは UD-Q3_K_XL です。13.1GB なら 4-bit 版より余裕が残り、しかも最小クラスの 3-bit まで落とさずに済みます。

選んだ理由は収まるかどうかで、品質がいちばんいいからではありません。UD-Q3_K_XL と UD-IQ3_S を同じタスクで比べていないので、コーディングやツールの利用でどちらが上かは分かりません。

LM Studio でロードする

ランタイムは Vulkan にしました。ロードする前に、メモリの見積もりを確認しています。

lms load --estimate-only <model-key> --gpu max --context-length 128000

モデルキーは lms ls で調べます。GGUF のファイル名と同じとは限りません。LM Studio のロードコマンドのドキュメントによると、この見積もりはコンテキスト長、Flash Attention、ビジョン対応を考慮しています。

13.1GB のファイルは、VRAM の使い道の一部にすぎません。実行時のバッファー、ビジョン関連のコンポーネント、KV キャッシュにもメモリが要りますし、128K のキャッシュは 8K や 16K よりずっと大きくなります。Q4_0 の K と V のキャッシュはどちらも GPU に置き、モデルの層と同じ 20GB を分け合わせました。

LM Studio のモデルロード API では、offload_kv_cache_to_gpu で KV キャッシュをシステム RAM に移せます。コンテキストを伸ばせる可能性はありますが遅くなり、一部の計算用バッファーはどのみち VRAM に残ります。システム RAM を増やせば、CPU 側に置いたキャッシュや層の助けにはなります。それで 20GB のカードが大きなカードになるわけではありません。

見積もりは最終的な答えとしては扱いません。コンテキスト長、キャッシュの置き場所、バッチサイズで、実際に何がロードできるかは変わります。記録しておくべきなのは、ロードしたあとの LM Studio のパネルの値です。

PC の LM Studio を Mac の Pi に接続する

Pi は Mac でファイルを読み書きし、LM Studio は PC で推論します。LM Studio のローカルサーバーはデフォルトで 1234 番ポートを使うので、Pi は PC の LAN アドレスに向けます。

http://<PC-LAN-IP>:1234/v1

Pi の設定をいじる前に、LM Studio にモデル ID を問い合わせました。

curl http://<PC-LAN-IP>:1234/v1/models

このエンドポイントは LM Studio の OpenAI 互換モデル API のドキュメントに載っています。有効になっていた ID は qwen3.8-27b でした。最初に qwen/qwen3.8-27b だろうと当て推量して、外しています。

Pi はカスタムプロバイダーを ~/.pi/agent/models.json から読み込みます。

{
  "providers": {
    "lmstudio": {
      "baseUrl": "http://<PC-LAN-IP>:1234/v1",
      "api": "openai-completions",
      "apiKey": "lm-studio",
      "models": [
        {
          "id": "qwen3.8-27b",
          "name": "Qwen3.8-27B",
          "reasoning": true,
          "input": ["text"],
          "contextWindow": 128000,
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          },
          "compat": {
            "maxTokensField": "max_tokens",
            "supportsDeveloperRole": false,
            "thinkingFormat": "qwen-chat-template"
          }
        }
      ]
    }
  }
}

models.json の形式と openai-completions プロバイダータイプについては、Pi のカスタムモデルのドキュメントに説明があります。上の apiKey は、認証なしのサーバー用のただのプレースホルダーです。認証を有効にしたら、本物のトークンはローカルに置き、Git には入れないでください。

pi --list-models | grep qwen3.8-27b

表示されたのは lmstudio qwen3.8-27b 128K でした。LM Studio が localhost 以外でも待ち受けるなら、認証を有効にして、インターネットには公開しないようにします。

コーディングで試したもの:モノクロのインターネットグラフ

チャットの返事ひとつでは試したことにならないと思い、Pi に React と Apache ECharts でモノクロのネットワーク可視化をつくってもらいました。

できあがったデモは、17,184 ノード、29,340 エッジ、31 クラスのインターネットトポロジーのデータを描きます。ECharts GL、ForceAtlas2 レイアウト、グレースケールの配色、小さな HUD を使っています。ノードは最初三角形の中にまとまっていて、力学シミュレーションでグラフの形に広がっていきます。

モデルは既存の Vite プロジェクトの中で作業し、外部のデータファイルを読み込みました。後からの修正でも WebGL のインタラクションを壊さないようにする必要がありました。デモはちゃんと動いています。ただ、ツール呼び出し、失敗した修正、やり直しの回数は記録していません。実際のプロジェクトであって、条件をそろえた AI エージェントのベンチマークではありません。

測っていないこと

1 秒あたりのトークン数、プロンプト処理速度、RAM のピーク、ロード時間は記録していませんし、64K と 128K の条件をそろえた比較もしていません。なので、この構成は動きますが、ほかの量子化版と比べて速いのか、質がいいのかについては、何も確かなことは言えません。

次は 64K から始めて、同じテストを 128K で繰り返すつもりです。ロードのたびに、次のことを記録します。

  1. 最終的に GPU へ offload された層数。
  2. モデルのロード時間。
  3. 同じ長いプロンプトを使った処理速度。
  4. 同じ出力上限での生成速度。
  5. VRAM とシステム RAM のピーク使用量。
  6. 決めておいた複数ステップの Pi タスクが、手動の復旧なしで完了するか。

UD-Q3_K_XL と UD-IQ3_S も比べてみたいと思っています。小さいファイルなら、コンテキストや GPU の層に回せる余裕が増えるかもしれません。分からないのは、それでコーディングやツール利用の安定性が落ちるかどうかです。

結果

このプロジェクトでは、Pi は Mac、推論は PC という分担がうまくいきました。速いと言えるか、長時間の作業を任せられるかは、きちんと条件をそろえて試してからでないと判断できません。

参考資料