ASUS Ascent GX10 を購入しました。NVIDIA GB10 Grace Blackwell Superchip を載せた、いわゆる NVIDIA DGX Spark 系の小型AIワークステーションです。
まずは難しいことをせず、「この箱でローカルLLMサーバを立てて、手元の端末からOpenAI互換APIとして叩ける」状態を目標にしました。今回は vLLM
で Qwen/Qwen3.6-27B-FP8 を起動し、通常のチャットAPIと簡単なベンチマークまで確認した記録です。
なぜGX10を買ったのか
ここ数年、ローカルLLMはかなり現実的になってきました。小さめのモデルならノートPCでも動きますし、量子化モデルを使えば手元で試せる範囲も広がっています。以前書いた CanIRun.aiの記事 でも、「このGPUでどのLLMが動くか」を見積もるツールを紹介しました。
ただ、実際に日常的に使おうとすると、単に「動く」だけでは足りません。
- ある程度大きいモデルを載せたい
- 長めのコンテキストを扱いたい
- 推論サーバとして常時起動したい
- 手元のツールや自作アプリからOpenAI互換APIで呼びたい
- GPUメモリやランタイムの挙動を自分で見ながら調整したい
このあたりを自宅・手元環境で試すための機械として、GX10はかなり面白い立ち位置にあります。Mac Studioクラスタや exo の方向も魅力的ですが、単体のNVIDIA系ワークステーションとしてvLLMを素直に動かせる環境も欲しかった、というのが購入理由です。
複数台Macで分散する方向については、以前 macOS 26.2のRDMA over Thunderbolt記事 や exo 1.0の記事 で書きました。今回はその対極として、単体のDGX Spark機をローカル推論APIサーバにする話です。
今回できたこと
今回の到達点は次の通りです。
- GX10側でGPUとCUDAの基本確認
spark-vllm-dockerを使ったvLLM環境の準備Qwen/Qwen3.6-27B-FP8の起動http://gx10-3cd9:8000/v1でOpenAI互換APIを公開/v1/modelsと/v1/chat/completionsの疎通確認vllm bench serveによる簡単な性能確認
確認した範囲では、Qwen/Qwen3.6-27B-FP8 はGX10上でかなり素直に扱えました。35B MoE系も試していますが、まず日常的に立てておくローカルAPIとしては、27B Denseのほうが見通しがよさそうです。
構成
今回の構成は次の通りです。
- ホスト:
gx10-3cd9 - 機種扱い: DGX Spark / NVIDIA GB10
- API:
http://gx10-3cd9:8000/v1 - 起動方式: spark-vllm-docker
の
launch-cluster.sh - モデル:
Qwen/Qwen3.6-27B-FP8
構成図にすると、こんな感じです。
flowchart LR
client[手元の端末 / アプリ] -->|OpenAI互換API| api[http://gx10-3cd9:8000/v1]
api --> vllm[vLLM]
vllm --> qwen[Qwen3.6-27B-FP8]
qwen --> gb10[NVIDIA GB10 / DGX Spark]
ポイントは、GX10を「LLMが入った作業端末」としてではなく、LAN内の推論APIサーバとして扱うことです。こうしておくと、手元のMacや別マシンから curl でもアプリでも同じAPIを叩けます。
事前確認
ここからのコマンドは、基本的に GX10上のターミナルで直接実行する 前提です。別マシンから遠隔操作してもよいのですが、記事としてはローカル作業の形で書いたほうが見通しがよいので、以降はGX10上でそのまま打てるコマンドとして載せます。
まず、GPUとPython環境が見えるか確認します。
|
|
GB10環境では、nvidia-smi --query-gpu=memory.total が [N/A] になることがあります。通常のディスクリートGPUのようなVRAM表示とは少し違うので、ここだけで失敗と判断しないほうがよさそうです。
PyTorchからCUDAが見えているかも確認します。
|
|
GPU名が返り、PyTorchでCUDAが使えるなら、まずは次に進めます。
spark-vllm-dockerを準備する
今回は eugr/spark-vllm-docker を使いました。DGX Spark / GB10向けにvLLMをDocker経由で立ち上げるための構成です。
|
|
ビルド後、vllm-node イメージができているか確認します。
|
|
Qwen3.6-27B-FP8を起動する
起動スクリプトは gx10 側に置きました。
モデルはHugging Faceから取得するため、vLLMを起動するコンテナにもHugging Faceのアクセストークンを渡します。ここでは、あらかじめGX10上で huggingface-cli login などを済ませておき、/home/tumf/.cache/huggingface/token に保存されているトークンを読む形にしています。
トークンの値そのものは表示しないようにします。スクリプトでもファイルから読み込んで HF_TOKEN 環境変数としてコンテナに渡すだけです。
|
|
ポイントはこのあたりです。
--max-model-len 262144: Qwen3.6-27Bの長いコンテキストを活かすため--gpu-memory-utilization 0.65: まずは余裕を持たせた設定から開始--kv-cache-dtype fp8: 長いcontextを確保するために使用--default-chat-template-kwargs '{"enable_thinking": false}': まずは通常応答を安定させるためthinkingを切る
Qwen3.6 系は thinking mode が有効になり得ます。最初のセットアップでは、thinkingを切って「普通に聞いたら普通に返る」状態を作るほうが切り分けしやすいです。
なお、起動にはそれなりに時間がかかります。私の環境では、safetensors 66 shard の読み込み、torch.compile、CUDA graph capture を含めて約6〜7分ほど待ちました。ready前の /health は connection reset になることがあります。
疎通確認
モデル一覧を確認します。
|
|
通常チャットも確認します。
|
|
疎通確認だけなら、max_tokens や temperature は指定しなくても十分です。短く・決定的に返したい場合だけ、リクエスト側で追加します。
ready待ちは、次のようなループにしておくと楽です。
|
|
LAN内の別マシンから使う場合は、base URL を次のように見ます。
|
|
OpenAI互換APIなので、自作アプリ、CLIツール、各種LLMクライアントから流用しやすいのがvLLMの便利なところです。
ベンチマーク
稼働中の qwen3.6-27b-fp8 に対して、vllm bench serve も軽く実行しました。
|
|
結果は次の通りです。
| 条件 | Output tok/s | Peak output tok/s | Total tok/s | TTFT mean | TPOT mean | 成功/失敗 |
|---|---|---|---|---|---|---|
| 16 prompts / max concurrency 4 | 25.57 | 34.00 | 129.07 | 1911.70 ms | 149.38 ms | 16 / 0 |
| 50 prompts / max concurrency 8 | 43.85 | 64.00 | 221.37 | 2849.90 ms | 156.66 ms | 50 / 0 |
この数字だけを見ると、クラウド上の大型GPUサーバのような爆速環境ではありません。ただ、手元の小型機で27Bクラスのモデルを長めのcontext付きで常時立てられる、という意味ではかなり実用的です。
注意点として、--model qwen3.6-27b-fp8 だけだと、ベンチ側が Hugging Face repo として qwen3.6-27b-fp8 を探して404になることがありました。--tokenizer Qwen/Qwen3.6-27B-FP8 を明示すると通りました。
また、vllm bench serve はデフォルトでtemperature 0を送らないため、再現性を重視してgreedy固定したい場合は --temperature=0 を付けます。単なる疎通確認では不要です。
27B Denseを先に選んだ理由
最初は、より大きい Qwen3.6-35B-A3B-FP8 や DFlash 構成も試しました。通常チャットや速度実験としては、こちらも面白いです。
ここでいう Dense は、MoE(Mixture of Experts)のように一部のexpertを選んで使う構成ではなく、基本的に一枚岩のモデルとして動く、という意味です。ざっくり言えば、Denseは普通のモデル、MoEは複数の専門家を持つモデルです。
ただ、初期セットアップで重要なのは「一番大きいモデルを載せること」より、安定して起動し、APIとして素直に返ることです。モデル重みだけでなく、KV cache、chat template、thinking mode、ランタイム側の対応状況が絡みます。
その意味で、今回のGX10では Qwen/Qwen3.6-27B-FP8 が最初の常用候補として扱いやすいと感じました。27B Denseなので挙動が読みやすく、262k context構成も試しやすいです。
停止方法と運用メモ
停止は launch-cluster.sh から行えます。
|
|
雑に pkill -f "vllm serve" すると、実行中のシェルや関連プロセスまで巻き込むことがあります。PIDを確認するなら、まずLISTENしているプロセスを見るほうが安全です。
|
|
おまけ:GPUモニター用にnvtopをビルドする
vLLMを立ち上げると、モデル読み込み中やCUDA graph capture中にGPU側で何が起きているか見たくなります。通常なら nvtop を入れて見るところですが、2026年6月時点では、配布版の nvtop がGX10のunified memory表示にうまく対応していませんでした。
そのため、私は nvtop をGitHubから取得してビルドしました。
|
|
これで ~/.local/bin/nvtop として使えます。~/.local/bin が PATH に入っていない場合は、フルパスで実行します。
|
|
まとめ
ASUS Ascent GX10 / DGX Spark 相当機で、Qwen/Qwen3.6-27B-FP8 を vLLM から起動し、LAN内のOpenAI互換APIとして使えるところまで確認しました。
今回の実感としては、GX10は「LLMを試すための高価な箱」というより、自宅や開発環境に置けるローカル推論サーバとして見ると魅力が出ます。クラウドGPUを借りるほどではない日常的な検証、長めのcontextを使った実験、自作ツールからのAPI呼び出しなどに使いやすいです。
まずは27B Denseで安定した土台を作り、そこから35B MoE、DFlash、SGLang、複数モデル切り替えへ広げていくのがよさそうです。