はじめに
流行りに乗ってNVIDIA DGX SparkベースのASUS GX10を購入してしまった。
これまでは、RAM32GBのM4のMac miniを使って、軽量LLMモデルによるバッチ的な処理を試し、ローカルLLM楽しいなあとその恩恵に少しあずかれていたが、どうしてもコーディング支援となると力不足を感じていた。RAMも少ないし、CUDAのパワーも試したい。なので、お手軽に手に入るASUSのGX10を導入して一か月ほど使ってみた。買えばすぐ使える(実際に使えた)が、使えるのと安定して運用するのは少し観点が違うので、立ち上げ、運用に回せるまでどのように各課題を解決していったのか残しておく。
現在の構築済み環境
- LiteLLMとvLLMとモデル別の設定をIaCとして1コンテナ単位で管理し、モデルを簡易に切り替え、かつ再現性良く立ち上げられるようにした
- GX10へはLiteLLMを通してアクセスできるようにし、モデルに寄らずすべてLiteLLMへ接続すればクライアント側の設定は不要な構成とした
- GPUの状態監視は物理的なモニタ(T-Ddisplay S3)で常に監視できる状態にした
- LLMモデルのダウンロードはHagging FaceでLikeしたモデルをPoling&Pullする仕組みを作った
- LLMモデルはイメージに含ませず、モデルディレクトリをマウントする形でイメージサイズを低減させた
LiteLLMであればVSCodeのプラグインを使ってCopilotChatから使うこともできる(下図)。ただ、なんとなくOpenCodeのほうがCopilotChatよりコンテキストを少なく軽快に使える感覚があり、OpenCodeを主に使っている。まだ試してはいないが、Cloudflare Tunnelを使えば、インターネットから宅内ローカルLLMに接続することもできるだろう。
課題1 モデルのダウンロード
一般的な家庭のインターネット環境において100GB以上のモデルをダウンロードしてくること自体が大変だ。特に楽天モバイルを固定回線化して使っている我が家は下り40Mpbs程度しか出ないので、理論値でも100GBなら6時間程度かかることになる。いざ「このモデルを使おう」と思ってもすぐには試せない。
でもよく考えてみると、「このモデルを使ってみたいなあ」と思うのは大体の場合、通勤中にスマホで見た情報きっかけである。モデル吟味の際にHagging Faceまで行って、Model cardを見ているので、気になったモデルはその場でLikeしておき、GX10側からLike状態を定期ポーリングし、Like状態や対象モデルの更新差分があれば、ダウンロードさせるサービスhf-syncを稼働させることにした。家に帰ったらモデルがダウンロードが完了している上、Likeを解除すればRemoveする仕掛けも入れたので、現在使えるモデルの一元管理がHagging Face上でできていることになる。
課題2 GB10の冷却状態の監視
ASUSのGX10は、ほかのDGX Sparkシリーズと比較しても冷却に優れる個体であるそうだが、連続して酷使すると時にはGPU温度が75℃近くなっていることもある。トークンスピードが遅くなったなあと思ったとき、要因を探るために毎度SSHでnvidia-smiコマンドを打つのも面倒であるので、物理的な独立モニタをデスクに備え付けることとした。LILYGO T-Display-S3、安価な液晶付きのESP32である。AliExpressで1200円ぐらいで買えた。GX10にて5秒間隔でnvidia-smiをしFastAPI経由でjsonを吐かせ、5秒毎にESP32側からHTTPで直接参照して可視化させている。

T-Display-S3は1.9インチで画面も大きく横長なので文字が配置しやすい
課題3 モデル別のカスタマイズ・再現性
モデル別のカスタムは、以下を構成をテンプレートとして管理することにした。利用においてはLiteLLMのモデルの情報を記載したopencode.jsonをモデル毎に準備して、これを利用側のクライアントPCへ配布する。どんなモデルであってもLiteLLMが唯一のエンドポイントとなり、OpenCodeから何も気にせず接続できる。vLLMでなくllama.cppだとか違う推論エンジンを使う場合も同じ構成で作れるだろう、と思う。

config.yaml、.env、docker-compose.ymlをモデル別・カスタム設定別に用意
QwenとかNemotronだとか、いろいろモデルを触ってみたが、各モデルには性能を左右する設定パラメータがある。モデルプロバイダが推奨値を出していたり、いろんなレシピが公開されていたりするが、パラメータの数が多く組み合わせは無限に取り得うるのでIaCを意識していないと、二度と同じ構成が再現できなくなる。ベースラインを1つ作り、gitで逐次チェックポイントを作って立ち戻れるようにして起動検証やカスタマイズを進めた。

Qwen3.8-27Bでいえば、3つパラメータの組み合わせ違いでトークン速度に差が発生
最後に
いろいろ弄り倒した結果、Qwen3.8-27Bが普通に使えるスピードでトークンを吐いてくれるようになった。GitHub CopilotのプランもMax→Planに下げても9月は乗り切ることができた。変な感じがするが、SasSとしてLLMを使っているときは、如何にトークン数を抑えてコーディングをしてもらおうかとケチった使い方を常に考えていたが、ローカルLLMだと、使わないともったいない、使えるだけ使おうと制約なし、予算度外視でものづくりができるようになった。自由度の幅が増え非常に楽しい。



