Add: DGX Spark デュアル構成ガイド
All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 23s
All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 23s
This commit is contained in:
parent
27cb274105
commit
7141ad7f5a
444
docs/dgx-spark-dual/index.md
Normal file
444
docs/dgx-spark-dual/index.md
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
title: DGX Spark デュアル構成ガイド
|
||||||
|
description: 2台のDGX Sparkを接続して256GBメモリ環境を構築する方法を初心者向けに解説
|
||||||
|
---
|
||||||
|
|
||||||
|
# DGX Spark デュアル構成ガイド
|
||||||
|
|
||||||
|
2台のDGX Sparkを接続して、**256GBの巨大メモリ環境**を構築する方法を解説します。
|
||||||
|
|
||||||
|
## はじめに
|
||||||
|
|
||||||
|
### この記事で学べること
|
||||||
|
|
||||||
|
- 2台のDGX Sparkを接続する方法
|
||||||
|
- ネットワーク設定の仕組み
|
||||||
|
- vLLMクラスターの起動方法
|
||||||
|
|
||||||
|
### 対象読者
|
||||||
|
|
||||||
|
- DGX Sparkを2台持っている方
|
||||||
|
- 70B〜405Bの大規模モデルを動かしたい方
|
||||||
|
- Linuxの基本操作ができる方
|
||||||
|
|
||||||
|
### 前提条件
|
||||||
|
|
||||||
|
- DGX Spark × 2台
|
||||||
|
- QSFPケーブル × 1本
|
||||||
|
- 両方のマシンに同じユーザー名でログインできる
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## なぜデュアル構成が必要?
|
||||||
|
|
||||||
|
DGX Spark 1台のメモリは **128GB** です。
|
||||||
|
|
||||||
|
| 構成 | メモリ | 動かせるモデル |
|
||||||
|
|------|--------|---------------|
|
||||||
|
| 単体 | 128GB | 〜70B(量子化時) |
|
||||||
|
| **デュアル** | **256GB** | 〜405B |
|
||||||
|
|
||||||
|
**Llama-3.3-70B** や **MiniMax-M2.5-172B** など、大きなモデルを動かすにはデュアル構成が必要です。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 全体像
|
||||||
|
|
||||||
|
まず、完成形のイメージを掴みましょう。
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────┐ ┌─────────────────────┐
|
||||||
|
│ │ │ │
|
||||||
|
│ DGX Spark 1 │ │ DGX Spark 2 │
|
||||||
|
│ (ヘッドノード) │ │ (ワーカーノード) │
|
||||||
|
│ │ │ │
|
||||||
|
│ ┌───────────────┐ │ QSFPケーブル │ ┌───────────────┐ │
|
||||||
|
│ │ 192.168.100.10│◄─┼─────────────────────────┼─►│ 192.168.100.11│ │
|
||||||
|
│ │ (QSFP) │ │ 200Gbps │ │ (QSFP) │ │
|
||||||
|
│ └───────────────┘ │ │ └───────────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ┌───────────────┐ │ │ ┌───────────────┐ │
|
||||||
|
│ │ 10.0.0.10 │ │ 通常のLAN │ │ 10.0.0.11 │ │
|
||||||
|
│ │ (eth0) │◄─┼─────────────────────────┼─►│ (eth0) │ │
|
||||||
|
│ └───────────────┘ │ │ └───────────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
└─────────────────────┘ └─────────────────────┘
|
||||||
|
│
|
||||||
|
│ API (ポート8000)
|
||||||
|
▼
|
||||||
|
クライアント
|
||||||
|
```
|
||||||
|
|
||||||
|
**ポイント**:
|
||||||
|
- **QSFPケーブル**:2台のSparkを直接つなぐ超高速回線(200Gbps)
|
||||||
|
- **通常LAN**:普段使っているネットワーク(SSH接続、API公開用)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 手順1:物理接続
|
||||||
|
|
||||||
|
### ケーブルを差す
|
||||||
|
|
||||||
|
両方のDGX Sparkの **QSFPポート** にケーブルを差すだけ!
|
||||||
|
|
||||||
|
```
|
||||||
|
DGX Spark 1 DGX Spark 2
|
||||||
|
┌───────────┐ ┌───────────┐
|
||||||
|
│ [QSFP]───┼──────────────┼───[QSFP] │
|
||||||
|
│ │ ケーブル1本 │ │
|
||||||
|
└───────────┘ └───────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip QSFPポートの場所
|
||||||
|
背面にある大きめのポートです。LANケーブルより太いケーブルが刺さります。
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 接続確認
|
||||||
|
|
||||||
|
どちらかのマシンで以下を実行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ibdev2netdev
|
||||||
|
```
|
||||||
|
|
||||||
|
出力例:
|
||||||
|
```
|
||||||
|
mlx5_0 port 1 ==> enp1s0f1np1 (Up) ← ✅ Upになっていれば接続OK
|
||||||
|
mlx5_1 port 1 ==> enp1s0f0np0 (Down)
|
||||||
|
```
|
||||||
|
|
||||||
|
:::warning Upにならない場合
|
||||||
|
- ケーブルがしっかり刺さっているか確認
|
||||||
|
- 両方のマシンでコマンドを実行して確認
|
||||||
|
:::
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 手順2:ネットワーク設定
|
||||||
|
|
||||||
|
QSFPポートには **IPアドレスが自動で割り当てられません**。手動で設定が必要です。
|
||||||
|
|
||||||
|
### 設計を決める
|
||||||
|
|
||||||
|
| マシン | QSFPのIP | 役割 |
|
||||||
|
|--------|---------|------|
|
||||||
|
| Spark 1 | 192.168.100.10 | ヘッドノード |
|
||||||
|
| Spark 2 | 192.168.100.11 | ワーカーノード |
|
||||||
|
|
||||||
|
:::tip IPアドレスの決め方
|
||||||
|
`192.168.100.x` は例です。既存のネットワークと被らなければOK。
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Spark 1 で設定
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 一時的に設定(再起動で消える)
|
||||||
|
sudo ip addr add 192.168.100.10/24 dev enp1s0f1np1
|
||||||
|
sudo ip link set enp1s0f1np1 up
|
||||||
|
```
|
||||||
|
|
||||||
|
### Spark 2 で設定
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 一時的に設定(再起動で消える)
|
||||||
|
sudo ip addr add 192.168.100.11/24 dev enp1s0f1np1
|
||||||
|
sudo ip link set enp1s0f1np1 up
|
||||||
|
```
|
||||||
|
|
||||||
|
### 疎通確認
|
||||||
|
|
||||||
|
Spark 1 から Spark 2 に ping:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ping 192.168.100.11
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
PING 192.168.100.11 (192.168.100.11) 56(84) bytes of data.
|
||||||
|
64 bytes from 192.168.100.11: icmp_seq=1 ttl=64 time=0.123 ms ← ✅ 成功!
|
||||||
|
```
|
||||||
|
|
||||||
|
### 永続化(再起動しても消えないように)
|
||||||
|
|
||||||
|
設定を永続化するには、netplanファイルを作成します。
|
||||||
|
|
||||||
|
**Spark 1:**
|
||||||
|
```bash
|
||||||
|
sudo tee /etc/netplan/99-qsfp.yaml << 'EOF'
|
||||||
|
network:
|
||||||
|
version: 2
|
||||||
|
ethernets:
|
||||||
|
enp1s0f1np1:
|
||||||
|
addresses:
|
||||||
|
- 192.168.100.10/24
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo netplan apply
|
||||||
|
```
|
||||||
|
|
||||||
|
**Spark 2:**
|
||||||
|
```bash
|
||||||
|
sudo tee /etc/netplan/99-qsfp.yaml << 'EOF'
|
||||||
|
network:
|
||||||
|
version: 2
|
||||||
|
ethernets:
|
||||||
|
enp1s0f1np1:
|
||||||
|
addresses:
|
||||||
|
- 192.168.100.11/24
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo netplan apply
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 手順3:SSH設定
|
||||||
|
|
||||||
|
2台のマシン間で **パスワードなしでSSH接続** できるようにします。
|
||||||
|
|
||||||
|
### なぜ必要?
|
||||||
|
|
||||||
|
vLLMクラスターが内部で自動的にSSH接続を使うためです。
|
||||||
|
|
||||||
|
### Spark 1 → Spark 2
|
||||||
|
|
||||||
|
Spark 1 で実行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 鍵がなければ作成
|
||||||
|
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
|
||||||
|
|
||||||
|
# Spark 2 に公開鍵をコピー
|
||||||
|
ssh-copy-id $USER@192.168.100.11
|
||||||
|
```
|
||||||
|
|
||||||
|
確認:
|
||||||
|
```bash
|
||||||
|
ssh 192.168.100.11 "hostname"
|
||||||
|
```
|
||||||
|
パスワードなしで `spark2`(ホスト名)が表示されればOK!
|
||||||
|
|
||||||
|
### Spark 2 → Spark 1
|
||||||
|
|
||||||
|
Spark 2 で実行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
|
||||||
|
ssh-copy-id $USER@192.168.100.10
|
||||||
|
```
|
||||||
|
|
||||||
|
確認:
|
||||||
|
```bash
|
||||||
|
ssh 192.168.100.10 "hostname"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 手順4:vLLMクラスター起動
|
||||||
|
|
||||||
|
いよいよ本番!2台を1つのクラスターとして動かします。
|
||||||
|
|
||||||
|
### 4-1. 両方のマシンで準備
|
||||||
|
|
||||||
|
**両方のマシンで実行:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# vLLMイメージを取得
|
||||||
|
docker pull nvcr.io/nvidia/vllm:25.11-py3
|
||||||
|
|
||||||
|
# クラスター起動スクリプトを取得
|
||||||
|
wget https://raw.githubusercontent.com/vllm-project/vllm/refs/heads/main/examples/online_serving/run_cluster.sh
|
||||||
|
chmod +x run_cluster.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4-2. ヘッドノード起動(Spark 1)
|
||||||
|
|
||||||
|
Spark 1 で実行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 環境変数を設定
|
||||||
|
export VLLM_IMAGE=nvcr.io/nvidia/vllm:25.11-py3
|
||||||
|
export MN_IF_NAME=enp1s0f1np1
|
||||||
|
export VLLM_HOST_IP=192.168.100.10
|
||||||
|
|
||||||
|
# ヘッドノードとして起動
|
||||||
|
bash run_cluster.sh $VLLM_IMAGE $VLLM_HOST_IP --head ~/.cache/huggingface \
|
||||||
|
-e VLLM_HOST_IP=$VLLM_HOST_IP \
|
||||||
|
-e NCCL_SOCKET_IFNAME=$MN_IF_NAME \
|
||||||
|
-e GLOO_SOCKET_IFNAME=$MN_IF_NAME \
|
||||||
|
-e RAY_memory_monitor_refresh_ms=0
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip 起動を待つ
|
||||||
|
`Ray runtime started.` と表示されるまで待ちます(1〜2分)
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 4-3. ワーカーノード起動(Spark 2)
|
||||||
|
|
||||||
|
Spark 2 で実行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 環境変数を設定
|
||||||
|
export VLLM_IMAGE=nvcr.io/nvidia/vllm:25.11-py3
|
||||||
|
export MN_IF_NAME=enp1s0f1np1
|
||||||
|
export VLLM_HOST_IP=192.168.100.11
|
||||||
|
export HEAD_NODE_IP=192.168.100.10 # ← Spark 1 のIP
|
||||||
|
|
||||||
|
# ワーカーノードとして起動
|
||||||
|
bash run_cluster.sh $VLLM_IMAGE $HEAD_NODE_IP --worker ~/.cache/huggingface \
|
||||||
|
-e VLLM_HOST_IP=$VLLM_HOST_IP \
|
||||||
|
-e NCCL_SOCKET_IFNAME=$MN_IF_NAME \
|
||||||
|
-e GLOO_SOCKET_IFNAME=$MN_IF_NAME \
|
||||||
|
-e RAY_memory_monitor_refresh_ms=0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4-4. クラスター確認
|
||||||
|
|
||||||
|
Spark 1 で実行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# コンテナ名を取得
|
||||||
|
export VLLM_CONTAINER=$(docker ps --format '{{.Names}}' | grep -E '^node-[0-9]+$')
|
||||||
|
|
||||||
|
# Rayクラスターの状態を確認
|
||||||
|
docker exec $VLLM_CONTAINER ray status
|
||||||
|
```
|
||||||
|
|
||||||
|
期待する出力:
|
||||||
|
```
|
||||||
|
Healthy:
|
||||||
|
2 node(s) ← ✅ 2ノードになっていれば成功!
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 手順5:モデルを起動
|
||||||
|
|
||||||
|
クラスターができたら、大規模モデルを起動します。
|
||||||
|
|
||||||
|
### MiniMax-M2.5-172B を起動する例
|
||||||
|
|
||||||
|
Spark 1(ヘッドノード)で実行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it $VLLM_CONTAINER /bin/bash -c '
|
||||||
|
vllm serve MiniMax-AI/MiniMax-M2.5-REAP-172B-A10B \
|
||||||
|
--tensor-parallel-size 2 \
|
||||||
|
--trust-remote-code \
|
||||||
|
--max-model-len 8192 \
|
||||||
|
--host 0.0.0.0 \
|
||||||
|
--port 8000'
|
||||||
|
```
|
||||||
|
|
||||||
|
| オプション | 意味 |
|
||||||
|
|-----------|------|
|
||||||
|
| `--tensor-parallel-size 2` | 2台のGPUに分散 |
|
||||||
|
| `--host 0.0.0.0` | 外部からアクセス可能に |
|
||||||
|
| `--max-model-len 8192` | 最大コンテキスト長 |
|
||||||
|
|
||||||
|
:::warning 起動に時間がかかります
|
||||||
|
モデルのダウンロード(初回のみ)と読み込みで **10〜30分** かかることがあります。
|
||||||
|
:::
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 手順6:動作確認
|
||||||
|
|
||||||
|
### APIにリクエストを送る
|
||||||
|
|
||||||
|
別のターミナル(または別のPC)から:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://<Spark1のIP>:8000/v1/chat/completions \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"model": "MiniMax-AI/MiniMax-M2.5-REAP-172B-A10B",
|
||||||
|
"messages": [{"role": "user", "content": "こんにちは!"}]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
レスポンスが返ってくれば成功!🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ワンライナーで簡単セットアップ
|
||||||
|
|
||||||
|
上記の手順を自動化するスクリプトを用意しています。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# フルセットアップ
|
||||||
|
curl -sL https://docs.techswan.online/scripts/dgx-spark-setup.sh | bash -s -- all
|
||||||
|
```
|
||||||
|
|
||||||
|
| コマンド | 内容 |
|
||||||
|
|----------|------|
|
||||||
|
| `network` | QSFPのIP設定 |
|
||||||
|
| `ssh` | SSH鍵配布 |
|
||||||
|
| `docker` | Docker権限設定 |
|
||||||
|
| `vllm-pull` | vLLMイメージ取得 |
|
||||||
|
| `cluster` | クラスター起動 |
|
||||||
|
| `all` | 全部実行 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## トラブルシューティング
|
||||||
|
|
||||||
|
### pingが通らない
|
||||||
|
|
||||||
|
**症状**:`ping 192.168.100.11` がタイムアウト
|
||||||
|
|
||||||
|
**対処**:
|
||||||
|
1. ケーブルが正しく接続されているか確認
|
||||||
|
2. `ibdev2netdev` で `Up` になっているか確認
|
||||||
|
3. IPアドレスが正しく設定されているか確認:
|
||||||
|
```bash
|
||||||
|
ip addr show enp1s0f1np1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rayクラスターが1ノードのまま
|
||||||
|
|
||||||
|
**症状**:`ray status` で `1 node(s)` と表示される
|
||||||
|
|
||||||
|
**対処**:
|
||||||
|
1. ワーカーノードでSSH接続テスト
|
||||||
|
2. ワーカー側のコンテナログを確認:
|
||||||
|
```bash
|
||||||
|
docker logs $(docker ps -q)
|
||||||
|
```
|
||||||
|
|
||||||
|
### vLLMがOOMで落ちる
|
||||||
|
|
||||||
|
**症状**:Out of Memory エラー
|
||||||
|
|
||||||
|
**対処**:
|
||||||
|
```bash
|
||||||
|
# max-model-len を小さくする
|
||||||
|
vllm serve <model> --tensor-parallel-size 2 --max-model-len 4096
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## まとめ
|
||||||
|
|
||||||
|
| 手順 | 内容 |
|
||||||
|
|------|------|
|
||||||
|
| 1 | QSFPケーブルで2台を接続 |
|
||||||
|
| 2 | QSFPポートにIPアドレスを設定 |
|
||||||
|
| 3 | パスワードなしSSHを設定 |
|
||||||
|
| 4 | vLLMクラスターを起動 |
|
||||||
|
| 5 | 大規模モデルを起動 |
|
||||||
|
|
||||||
|
これで **256GB環境** が手に入りました!🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 参考リンク
|
||||||
|
|
||||||
|
- [NVIDIA DGX Spark Playbooks](https://build.nvidia.com/spark/)
|
||||||
|
- [vLLM ドキュメント](https://docs.vllm.ai/)
|
||||||
|
- [DGX SparkでMiniMax-M2.5を動かす](/dgx-spark-minimax/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*この記事は2026年2月時点の情報です。最新情報は公式ドキュメントをご確認ください。*
|
||||||
@ -13,14 +13,18 @@ AI・インフラ・開発の技術メモ
|
|||||||
### DGX Spark
|
### DGX Spark
|
||||||
|
|
||||||
- [DGX SparkでMiniMax-M2.5-REAP-172Bを動かす](/dgx-spark-minimax/)
|
- [DGX SparkでMiniMax-M2.5-REAP-172Bを動かす](/dgx-spark-minimax/)
|
||||||
|
- [DGX Spark デュアル構成ガイド](/dgx-spark-dual/) 🆕
|
||||||
|
|
||||||
## スクリプト
|
## スクリプト
|
||||||
|
|
||||||
記事で紹介しているスクリプトはダウンロードして使用できます。
|
記事で紹介しているスクリプトはダウンロードして使用できます。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# DGX Spark セットアップ
|
# DGX Spark セットアップ(デュアル構成)
|
||||||
curl -sL https://docs.techswan.online/scripts/dgx-spark-setup.sh | bash -s -- all
|
curl -sL https://docs.techswan.online/scripts/dgx-spark-setup.sh | bash -s -- all
|
||||||
|
|
||||||
|
# モデル起動
|
||||||
|
curl -sL https://docs.techswan.online/scripts/dgx-spark-serve.sh | bash -s -- minimax-m25
|
||||||
```
|
```
|
||||||
|
|
||||||
## リンク
|
## リンク
|
||||||
|
|||||||
@ -7,6 +7,7 @@ const sidebars: SidebarsConfig = {
|
|||||||
label: 'DGX Spark',
|
label: 'DGX Spark',
|
||||||
items: [
|
items: [
|
||||||
'dgx-spark-minimax/index',
|
'dgx-spark-minimax/index',
|
||||||
|
'dgx-spark-dual/index',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user