Skip to main content

Run large LLMs across two NVIDIA DGX Sparks with vLLM — model picker, one-command start/stop, and an Anthropic-compatible endpoint for Claude Code.

Project description

dgxllm

Run large LLMs across two NVIDIA DGX Sparks with vLLM — pick a model from a menu, start it with one command, and use it from Claude Code.

$ dgxllm start

? 使用するモデルを選択してください:
❯ deepseek-v4-flash-0731  (TP=2, 1M ctx, KV fp8_ds_mla, spec k=5)
  qwen3.6-27b-nvfp4       (TP=2, 32K ctx)
  gemma-4-31b-it-nvfp4    (TP=2, 32K ctx)

deepseek-v4-flash-0731 を 2 ノードで起動します...
$ dgxllm claude      # Claude Code をこのモデルで起動

なぜ必要か

DGX Spark を 2 台つないで大きなモデルを動かすのは、やってみると設定の落とし穴が多い。 dgxllm は実機で踏んだ落とし穴を最初から回避する。

落とし穴 dgxllm の対処
1 つの物理 QSFP ポートが 2 つの論理 IF に見える。 片方だけ NCCL_IB_HCA に渡すと約 100 Gbit/s で頭打ち phys_port_name で同一物理ポートのレールを全部集めて渡す
RoCEv2 の GID index はノードごとに違い、再起動でずれる。 固定値を共有すると NCCL が初期化時に固まる IPv4 が埋まった GID を sysfs から毎回解決する
--master-addr を渡さないと 127.0.0.1 になりワーカーが繋がらない 常に明示的に渡す
ヘッドを先に起動すると mp 初期化のレースで掴み損ねる ワーカーを先に起動する
API キーを渡し忘れると LAN 上の誰でもアクセスできる キーを自動生成し、起動後に「キー無しで 401 か」を検証する
ログインシェルが fish だと ssh host "bash構文" が壊れる スクリプトを常に stdin から渡す (ssh host bash -ls)
GB10 は GPUDirect RDMA 非対応。 ログに GDRDMA が出なくても正常 NCCL_NET_GDR_LEVEL=0 を明示
同梱の NCCL プラグインが GB10 で RoCE を使っているように見えて性能が出ない NCCL_NET_PLUGIN=none

インストール

uv tool install dgxllm

試すだけなら:

uvx dgxllm --help

Mac / Linux のどちらからでも使える。ノード側に入れる必要はない — SSH 経由で操作する。


セットアップ

1. クラスタを登録する

dgxllm init

SSH ホストとノード間リンクの IP を訊かれる。実機を見に行って GPU・メモリ・ ファブリック構成(物理ポートと論理 IF の対応、RoCE デバイス、MTU)を検出し、 API キーを生成する。

前提: 各ノードへパスワードなし SSH が通り、docker が使えること。

2. モデルを登録する

dgxllm model add deepseek-ai/DeepSeek-V4-Flash-0731 \
  --name deepseek-v4-flash-0731 \
  --max-model-len 1048576 \
  --kv-cache-dtype fp8_ds_mla \
  --speculative-tokens 5

引数を省略すると対話的に訊かれる。

モデル名にスラッシュは使えない。 vLLM の served model name がそのまま Claude Code の model picker に出るため。

3. 起動する

dgxllm start          # 選択画面が出る
dgxllm start <name>   # 直接指定

起動前に「SSH で届くか」「イメージがあるか」「モデルがキャッシュにあるか」を 全ノードで確認してから始める。

モデルを切り替える

dgxllm switch         # 選択画面。起動中のモデルには [起動中] と出る
dgxllm switch <name>

動いているモデルを止めてから新しいモデルを起動する。 2 台の合計メモリに 1 モデルしか載らないため、同時起動はできない。

Claude Code を開いている場合は、モデル名が変わるので dgxllm claude で 起動し直す必要がある。


コマンド

コマンド 説明
dgxllm init クラスタを対話的に設定する
dgxllm start [name] 起動する。名前を省略すると選択画面
dgxllm switch [name] 動いているモデルを止めて別のモデルに切り替える
dgxllm stop 停止し、メモリと GPU 電力を表示する
dgxllm status ノード状態と API の疎通・認証を確認する
dgxllm logs [-f] ヘッドノードのログ
dgxllm claude Claude Code をこの endpoint で起動する
dgxllm model list 登録済みモデル一覧
dgxllm model add モデルを追加する
dgxllm model remove モデルを削除する

Claude Code から使う

dgxllm claude

vLLM は v0.11.1 から Anthropic 互換の /v1/messages を持つので、 LiteLLM や claude-code-router のような変換プロキシは要らない。

dgxllm claude は「その起動だけ」に環境変数を効かせるため、 別ターミナルで動いている通常の claude.ai セッションには影響しない。

制約

  • 動作中のセッションを /model で切り替えることはできない。 ANTHROPIC_BASE_URL は プロセス起動時に一度だけ読まれる
  • Anthropic モデルとの同一セッション併用は不可。 ANTHROPIC_BASE_URL を設定すると Anthropic モデルは無効になる
  • Anthropic は非 Claude モデルを gateway 経由で使う構成を公式にはサポートしていない

設定ファイル

~/.config/dgxllm/config.yaml

nodes:
  - ssh_host: dgx-spark-1
    fabric_ip: 192.168.100.10
  - ssh_host: dgx-spark-2
    fabric_ip: 192.168.100.11
models:
  - name: deepseek-v4-flash-0731
    hf_repo: deepseek-ai/DeepSeek-V4-Flash-0731
    tensor_parallel: 2
    max_model_len: 1048576
    kv_cache_dtype: fp8_ds_mla
    speculative_tokens: 5
default_image: ghcr.io/anemll/dspark-vllm-gx10:0.1.1
port: 8888

API キーは ~/.config/dgxllm/api-key (mode 600) に分離してある。 設定ファイルをそのまま共有しても鍵は漏れない。


セキュリティ

  • API キーは自動生成され、起動後に「キー無しアクセスが 401 になるか」を必ず検証する。 ならなければエラーで終了する
  • 既定の bind は 0.0.0.0。LAN 内から使う想定
  • ルーターでポートを開けないこと。 vLLM は単一の静的キーしか持たず、 レート制限も監査ログもない。外から使うなら Tailscale か SSH トンネルを使う

動作確認済みの構成

  • 2× DGX Spark (GB10, sm_121, ARM64, Ubuntu 24.04)
  • 1 本の 200GbE ConnectX-7 QSFP DAC 直結
  • deepseek-ai/DeepSeek-V4-Flash-0731 を TP=2、1M コンテキスト

実測 (64K コンテキスト): TTFT 34.05 秒 / prefill 1,926 tok/s / decode 61.8 tok/s

ベンチマークを取るときは 必ず 2 回以上回して 2 回目以降を採用すること。 vLLM は初回リクエストで Triton カーネルを JIT コンパイルすることがあり、 TTFT が 8 倍以上変わる。ログの jit_monitor 警告で確認できる。


謝辞

2 ノード DGX Spark で DeepSeek-V4-Flash を動かす方法は、以下の先行事例に多くを負っている。

dgxllm はこれらのレシピを、モデルを差し替えられる形の CLI にまとめ直したもの。

ライセンス

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dgxllm-0.1.0.tar.gz (60.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dgxllm-0.1.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file dgxllm-0.1.0.tar.gz.

File metadata

  • Download URL: dgxllm-0.1.0.tar.gz
  • Upload date:
  • Size: 60.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for dgxllm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a228f8b3394802c01d64198f4423c0cf5e6a9d0b2ebb48ea291cd05e853dbac2
MD5 d446ea5fdca10b44ff5ff81d7dfae153
BLAKE2b-256 87f9d9df72b9d8c345df9eb6c463f049daff55beab14556022048dc2e9b955a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for dgxllm-0.1.0.tar.gz:

Publisher: publish.yml on javasparrows/dgxllm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dgxllm-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dgxllm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for dgxllm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a19403c6a2b9a47f4b758c9097dc1167b8fba6661d373434ee17ad1cddeea7d5
MD5 52ba4f0d34d7a6d8dd88c474693c51f3
BLAKE2b-256 828f01fc0cf09cd140a281be693874687e19b7317a20b4b4d5bdb41d02695794

See more details on using hashes here.

Provenance

The following attestation bundles were made for dgxllm-0.1.0-py3-none-any.whl:

Publisher: publish.yml on javasparrows/dgxllm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page