---
hide_table_of_contents: false
displayed_sidebar: null
sidebar_position: 3
title: DGX Spark デュアル構成ガイド
description: 2台のDGX Sparkを接続して256GBメモリ環境を構築する方法を初心者向けに解説
image: ./banner.png
---
# 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を動かす](/tech/dgx-spark-minimax/)

---

*この記事は2026年2月時点の情報です。最新情報は公式ドキュメントをご確認ください。*
