koide 8c109a1d9a
All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 28s
Add: OGPバナー画像自動生成 (node-canvas) + 全記事一括生成
2026-02-28 01:03:39 +00:00

447 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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
```
---
## 手順3SSH設定
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"
```
---
## 手順4vLLMクラスター起動
いよいよ本番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月時点の情報です。最新情報は公式ドキュメントをご確認ください。*