All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 26s
454 lines
14 KiB
Markdown
454 lines
14 KiB
Markdown
# DGX Sparkで最新LLM「MiniMax-M2.5-REAP-172B」を動かしてみた
|
||
|
||
## はじめに
|
||
|
||
NVIDIA DGX Sparkは、デスクトップサイズでありながら最大200Bパラメータ(デュアル構成で405B)のAIモデルを動かせる小型AIワークステーションです。今回は、2026年2月にリリースされたばかりの最新モデル「**MiniMax-M2.5-REAP-172B-A10B**」をDGX Sparkデュアル構成(256GB統合メモリ)で動かす手順を紹介します。
|
||
|
||
---
|
||
|
||
## MiniMax-M2.5-REAP-172Bとは?
|
||
|
||
MiniMax-M2.5は、中国MiniMax社が開発したコーディング・エージェント特化のMixture-of-Experts(MoE)モデルです。Cerebras社がREAP(Router-weighted Expert Activation Pruning)技術を適用し、オリジナルの230Bパラメータから172Bに軽量化したものが本モデルです。
|
||
|
||
### スペック
|
||
|
||
| 項目 | 値 |
|
||
|------|-----|
|
||
| 総パラメータ数 | 172B |
|
||
| アクティブパラメータ数 | 10B/トークン |
|
||
| レイヤー数 | 62 |
|
||
| エキスパート数 | 192(256から25%削減)|
|
||
| コンテキスト長 | 196,608トークン |
|
||
| ライセンス | Modified MIT |
|
||
|
||
### なぜREAP版がおすすめ?
|
||
|
||
- **ほぼ無劣化で25%軽量化**: HumanEval等のベンチマークでオリジナルと同等性能
|
||
- **vLLMネイティブ対応**: パッチ不要でそのまま動く
|
||
- **256GBメモリで十分動作**: オリジナル230B版では厳しいVRAM要件をクリア
|
||
|
||
---
|
||
|
||
## 動作環境
|
||
|
||
### DGX Spark デュアル構成
|
||
|
||
| 項目 | スペック |
|
||
|------|----------|
|
||
| アーキテクチャ | NVIDIA Grace Blackwell (GB10) |
|
||
| GPU | Blackwell GPU × 2 |
|
||
| メモリ | 256GB統合メモリ(LPDDR5x)|
|
||
| ストレージ | 4TB NVMe × 2 |
|
||
| ネットワーク | ConnectX-7 (QSFP接続) |
|
||
|
||
---
|
||
|
||
## 事前準備:ネットワーク構成
|
||
|
||
デュアルSpark構成では、2台のノードをQSFPケーブルで物理接続する必要があります。
|
||
|
||
詳細な手順は公式ドキュメントを参照してください:
|
||
👉 [Connect two Sparks](https://build.nvidia.com/spark/connect-two-sparks)
|
||
|
||
### ネットワーク構成の理解(重要)
|
||
|
||
DGX Sparkデュアル構成では、**2種類のネットワーク**を使い分けます。公式ドキュメントではこの点が分かりにくいため、詳しく解説します。
|
||
|
||
```
|
||
┌─────────────────────┐ QSFP (200GbE) ┌─────────────────────┐
|
||
│ DGX Spark 1 │◄────────────────────────────►│ DGX Spark 2 │
|
||
│ │ 192.168.100.10/11 │ │
|
||
│ enp1s0f1np1 │ (クラスター通信) │ enp1s0f1np1 │
|
||
│ ┌───────────────┐ │ │ ┌───────────────┐ │
|
||
│ │ NCCL/Ray通信 │ │ │ │ NCCL/Ray通信 │ │
|
||
│ └───────────────┘ │ │ └───────────────┘ │
|
||
├─────────────────────┤ ├─────────────────────┤
|
||
│ eth0 (10.0.0.10) │◄──── 通常LAN ──────────────►│ eth0 (10.0.0.11) │
|
||
│ ┌───────────────┐ │ │ ┌───────────────┐ │
|
||
│ │ 管理/API公開 │ │ │ │ 管理のみ │ │
|
||
│ └───────────────┘ │ │ └───────────────┘ │
|
||
└─────────────────────┘ └─────────────────────┘
|
||
│
|
||
▼
|
||
クライアントからの
|
||
APIリクエスト
|
||
http://10.0.0.10:8000
|
||
```
|
||
|
||
| ネットワーク | 用途 | インターフェース例 | IP例 |
|
||
|-------------|------|-------------------|------|
|
||
| **クラスター通信** | NCCL、Ray、テンソル並列 | enp1s0f1np1 (QSFP) | 192.168.100.x |
|
||
| **管理/API公開** | SSH、APIエンドポイント | eth0 (通常LAN) | 10.0.0.x |
|
||
|
||
### なぜ分離が必要?
|
||
|
||
1. **セキュリティ**: クラスター通信は暗号化されていないため、プライベートネットワーク推奨
|
||
2. **パフォーマンス**: NCCL通信は200GbE QSFPを使用し、APIトラフィックと分離
|
||
3. **柔軟性**: APIエンドポイントを外部公開しつつ、クラスター通信は内部に閉じる
|
||
|
||
### QSFPインターフェースへのIP割り当て(手動)
|
||
|
||
**重要**: QSFPインターフェースにはIPアドレスが自動で割り当てられません。手動設定が必要です。
|
||
|
||
```bash
|
||
# 両ノードで実行
|
||
|
||
# 1. インターフェース確認
|
||
ibdev2netdev
|
||
# 出力例: mlx5_0 port 1 ==> enp1s0f1np1 (Up)
|
||
# mlx5_1 port 1 ==> enp1s0f0np0 (Down)
|
||
# "(Up)" と表示されるインターフェースを使用
|
||
|
||
# 2. IPアドレス設定
|
||
# Node 1
|
||
sudo ip addr add 192.168.100.10/24 dev enp1s0f1np1
|
||
sudo ip link set enp1s0f1np1 up
|
||
|
||
# Node 2
|
||
sudo ip addr add 192.168.100.11/24 dev enp1s0f1np1
|
||
sudo ip link set enp1s0f1np1 up
|
||
|
||
# 3. 疎通確認(Node 1から)
|
||
ping 192.168.100.11
|
||
```
|
||
|
||
### 永続化(netplan使用)
|
||
|
||
再起動後もIPを維持するには、netplanで設定します。
|
||
|
||
```bash
|
||
# /etc/netplan/99-qsfp.yaml を作成
|
||
sudo tee /etc/netplan/99-qsfp.yaml << 'EOF'
|
||
network:
|
||
version: 2
|
||
ethernets:
|
||
enp1s0f1np1:
|
||
addresses:
|
||
- 192.168.100.10/24 # Node 2は192.168.100.11/24
|
||
EOF
|
||
|
||
sudo netplan apply
|
||
```
|
||
|
||
### パスワードなしSSHの設定
|
||
|
||
```bash
|
||
# Node 1で
|
||
ssh-keygen -t ed25519 -N ""
|
||
ssh-copy-id user@192.168.100.11
|
||
|
||
# Node 2でも同様に設定(逆方向)
|
||
```
|
||
|
||
---
|
||
|
||
## 環境構築
|
||
|
||
### 1. Dockerグループの設定(初回のみ)
|
||
|
||
```bash
|
||
sudo groupadd docker
|
||
sudo usermod -aG docker $USER
|
||
newgrp docker
|
||
```
|
||
|
||
### 2. NGC公式vLLMイメージの取得
|
||
|
||
DGX Sparkではドライバー互換性の関係で、**必ずNGC公式イメージを使用**してください。
|
||
|
||
```bash
|
||
# 両方のノードで実行
|
||
docker pull nvcr.io/nvidia/vllm:25.11-py3
|
||
export VLLM_IMAGE=nvcr.io/nvidia/vllm:25.11-py3
|
||
```
|
||
|
||
### 3. クラスターデプロイスクリプトの取得
|
||
|
||
```bash
|
||
# 両方のノードで実行
|
||
wget https://raw.githubusercontent.com/vllm-project/vllm/refs/heads/main/examples/online_serving/run_cluster.sh
|
||
chmod +x run_cluster.sh
|
||
```
|
||
|
||
---
|
||
|
||
## Rayクラスターの起動
|
||
|
||
### Node 1(ヘッドノード)の起動
|
||
|
||
```bash
|
||
# Node 1で実行
|
||
|
||
# 高速インターフェースのIPアドレスを取得
|
||
# ibdev2netdev で "(Up)" と表示されるインターフェースを使用
|
||
export MN_IF_NAME=enp1s0f1np1
|
||
export VLLM_HOST_IP=$(ip -4 addr show $MN_IF_NAME | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
|
||
|
||
echo "Using interface $MN_IF_NAME with IP $VLLM_HOST_IP"
|
||
|
||
bash run_cluster.sh $VLLM_IMAGE $VLLM_HOST_IP --head ~/.cache/huggingface \
|
||
-e VLLM_HOST_IP=$VLLM_HOST_IP \
|
||
-e UCX_NET_DEVICES=$MN_IF_NAME \
|
||
-e NCCL_SOCKET_IFNAME=$MN_IF_NAME \
|
||
-e OMPI_MCA_btl_tcp_if_include=$MN_IF_NAME \
|
||
-e GLOO_SOCKET_IFNAME=$MN_IF_NAME \
|
||
-e TP_SOCKET_IFNAME=$MN_IF_NAME \
|
||
-e RAY_memory_monitor_refresh_ms=0 \
|
||
-e MASTER_ADDR=$VLLM_HOST_IP
|
||
```
|
||
|
||
### Node 2(ワーカーノード)の起動
|
||
|
||
```bash
|
||
# Node 2で実行
|
||
|
||
export MN_IF_NAME=enp1s0f1np1
|
||
export VLLM_HOST_IP=$(ip -4 addr show $MN_IF_NAME | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
|
||
|
||
# 重要:Node 1のIPアドレスを設定
|
||
# Node 1で `echo $VLLM_HOST_IP` を実行して確認
|
||
export HEAD_NODE_IP=<NODE_1_IP_ADDRESS>
|
||
|
||
echo "Worker IP: $VLLM_HOST_IP, connecting to head node at: $HEAD_NODE_IP"
|
||
|
||
bash run_cluster.sh $VLLM_IMAGE $HEAD_NODE_IP --worker ~/.cache/huggingface \
|
||
-e VLLM_HOST_IP=$VLLM_HOST_IP \
|
||
-e UCX_NET_DEVICES=$MN_IF_NAME \
|
||
-e NCCL_SOCKET_IFNAME=$MN_IF_NAME \
|
||
-e OMPI_MCA_btl_tcp_if_include=$MN_IF_NAME \
|
||
-e GLOO_SOCKET_IFNAME=$MN_IF_NAME \
|
||
-e TP_SOCKET_IFNAME=$MN_IF_NAME \
|
||
-e RAY_memory_monitor_refresh_ms=0 \
|
||
-e MASTER_ADDR=$HEAD_NODE_IP
|
||
```
|
||
|
||
### クラスター状態の確認
|
||
|
||
```bash
|
||
# Node 1で実行
|
||
export VLLM_CONTAINER=$(docker ps --format '{{.Names}}' | grep -E '^node-[0-9]+$')
|
||
echo "Found container: $VLLM_CONTAINER"
|
||
|
||
docker exec $VLLM_CONTAINER ray status
|
||
```
|
||
|
||
2ノードが認識され、GPUリソースが利用可能と表示されればOKです。
|
||
|
||
---
|
||
|
||
## モデルのダウンロード
|
||
|
||
### Hugging Faceへのログイン
|
||
|
||
```bash
|
||
# Node 1のコンテナ内で実行
|
||
export VLLM_CONTAINER=$(docker ps --format '{{.Names}}' | grep -E '^node-[0-9]+$')
|
||
docker exec -it $VLLM_CONTAINER /bin/bash
|
||
|
||
# コンテナ内で
|
||
huggingface-cli login
|
||
```
|
||
|
||
### MiniMax-M2.5-REAP-172Bのダウンロード
|
||
|
||
```bash
|
||
# コンテナ内で(約330GB、時間がかかります)
|
||
huggingface-cli download cerebras/MiniMax-M2.5-REAP-172B-A10B
|
||
```
|
||
|
||
---
|
||
|
||
## 推論サーバーの起動
|
||
|
||
### MiniMax-M2.5-REAP-172B用の起動コマンド
|
||
|
||
```bash
|
||
# Node 1で実行
|
||
export VLLM_CONTAINER=$(docker ps --format '{{.Names}}' | grep -E '^node-[0-9]+$')
|
||
|
||
docker exec -it $VLLM_CONTAINER /bin/bash -c '
|
||
vllm serve cerebras/MiniMax-M2.5-REAP-172B-A10B \
|
||
--tensor-parallel-size 2 \
|
||
--tool-call-parser minimax_m2 \
|
||
--reasoning-parser minimax_m2_append_think \
|
||
--trust-remote-code \
|
||
--enable-auto-tool-choice \
|
||
--max-model-len 65536 \
|
||
--gpu-memory-utilization 0.90'
|
||
```
|
||
|
||
### パラメータ解説
|
||
|
||
| パラメータ | 説明 |
|
||
|-----------|------|
|
||
| `--tensor-parallel-size 2` | 2台のSparkでテンソル並列 |
|
||
| `--tool-call-parser minimax_m2` | MiniMax専用ツールコールパーサー |
|
||
| `--reasoning-parser minimax_m2_append_think` | thinking出力を履歴に保持 |
|
||
| `--max-model-len 65536` | 最大コンテキスト長(64K)|
|
||
| `--gpu-memory-utilization 0.90` | メモリ使用率上限 |
|
||
|
||
### メモリ節約版(長文不要な場合)
|
||
|
||
```bash
|
||
docker exec -it $VLLM_CONTAINER /bin/bash -c '
|
||
vllm serve cerebras/MiniMax-M2.5-REAP-172B-A10B \
|
||
--tensor-parallel-size 2 \
|
||
--tool-call-parser minimax_m2 \
|
||
--reasoning-parser minimax_m2_append_think \
|
||
--trust-remote-code \
|
||
--enable-auto-tool-choice \
|
||
--max-model-len 16384 \
|
||
--max-num-seqs 32 \
|
||
--gpu-memory-utilization 0.85'
|
||
```
|
||
|
||
### APIエンドポイントを別IPで公開する
|
||
|
||
クラスター通信(QSFP)とAPIエンドポイント(通常LAN)を分離したい場合:
|
||
|
||
```bash
|
||
docker exec -it $VLLM_CONTAINER /bin/bash -c '
|
||
vllm serve cerebras/MiniMax-M2.5-REAP-172B-A10B \
|
||
--tensor-parallel-size 2 \
|
||
--host 0.0.0.0 \
|
||
--port 8000 \
|
||
...'
|
||
```
|
||
|
||
| オプション | 説明 |
|
||
|-----------|------|
|
||
| `--host 0.0.0.0` | 全インターフェースでリッスン(推奨) |
|
||
| `--host 10.0.0.10` | 特定IPのみでリッスン |
|
||
| `--port 8000` | APIポート番号 |
|
||
|
||
**ポイント**: `VLLM_HOST_IP`環境変数はクラスター内部通信用であり、`--host`オプションはAPIエンドポイント用です。これらは独立して設定できます。
|
||
|
||
---
|
||
|
||
## 動作確認
|
||
|
||
### OpenAI互換APIでテスト
|
||
|
||
```bash
|
||
curl http://localhost:8000/v1/chat/completions \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "cerebras/MiniMax-M2.5-REAP-172B-A10B",
|
||
"messages": [
|
||
{"role": "user", "content": "Pythonでフィボナッチ数列を生成する関数を書いて"}
|
||
],
|
||
"temperature": 1.0,
|
||
"top_p": 0.95,
|
||
"top_k": 40
|
||
}'
|
||
```
|
||
|
||
### ヘルスチェック
|
||
|
||
```bash
|
||
curl http://localhost:8000/health
|
||
```
|
||
|
||
---
|
||
|
||
## 監視とデバッグ
|
||
|
||
### Rayダッシュボード
|
||
|
||
```
|
||
http://<head-node-ip>:8265
|
||
```
|
||
|
||
### GPU使用状況の確認
|
||
|
||
```bash
|
||
# 両ノードで
|
||
nvidia-smi
|
||
|
||
# コンテナ内から
|
||
export VLLM_CONTAINER=$(docker ps --format '{{.Names}}' | grep -E '^node-[0-9]+$')
|
||
docker exec $VLLM_CONTAINER nvidia-smi --query-gpu=memory.used,memory.total --format=csv
|
||
```
|
||
|
||
---
|
||
|
||
## トラブルシューティング
|
||
|
||
### OOM(メモリ不足)エラー
|
||
|
||
```bash
|
||
# 対策1: シーケンス数を減らす
|
||
--max-num-seqs 32
|
||
|
||
# 対策2: コンテキスト長を短く
|
||
--max-model-len 16384
|
||
|
||
# 対策3: メモリ使用率を下げる
|
||
--gpu-memory-utilization 0.80
|
||
```
|
||
|
||
### CUDA illegal memory access エラー
|
||
|
||
```bash
|
||
# CUDAグラフモードを変更
|
||
--compilation-config "{\"cudagraph_mode\": \"PIECEWISE\"}"
|
||
```
|
||
|
||
### Rayクラスターに接続できない
|
||
|
||
```bash
|
||
# ネットワークインターフェースの確認
|
||
ibdev2netdev
|
||
|
||
# ファイアウォールの確認
|
||
sudo ufw status
|
||
|
||
# Rayポートの開放(必要な場合)
|
||
sudo ufw allow 6379
|
||
sudo ufw allow 8265
|
||
```
|
||
|
||
---
|
||
|
||
## 重要な注意点
|
||
|
||
### Thinkingトークンの扱い
|
||
|
||
MiniMax-M2.5は **interleaved thinking model** です。出力に含まれる `<think>...</think>` タグは、履歴として次のリクエストに含める必要があります。
|
||
|
||
```python
|
||
# ❌ NGパターン:thinkingを削除
|
||
content = response.replace(r'<think>.*?</think>', '')
|
||
|
||
# ✅ OKパターン:そのまま保持
|
||
history.append({"role": "assistant", "content": response})
|
||
```
|
||
|
||
### 推奨推論パラメータ
|
||
|
||
```json
|
||
{
|
||
"temperature": 1.0,
|
||
"top_p": 0.95,
|
||
"top_k": 40
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## まとめ
|
||
|
||
DGX Sparkデュアル構成(256GB)とNGC公式vLLMイメージを使えば、最新のMiniMax-M2.5-REAP-172Bが快適に動作します。オープンソースモデルとしてはトップクラスのコーディング・エージェント性能を持つこのモデル、ぜひ試してみてください。
|
||
|
||
### 参考リンク
|
||
|
||
- [MiniMax-M2.5-REAP-172B (Hugging Face)](https://huggingface.co/cerebras/MiniMax-M2.5-REAP-172B-A10B)
|
||
- [DGX Spark vLLM公式ガイド](https://build.nvidia.com/spark/vllm/stacked-sparks)
|
||
- [MiniMax-M2 公式リポジトリ (GitHub)](https://github.com/MiniMax-AI/MiniMax-M2)
|
||
- [vLLM MiniMax-M2 デプロイガイド](https://docs.vllm.ai/projects/recipes/en/latest/MiniMax/MiniMax-M2.html)
|
||
- [REAP論文 (arXiv)](https://arxiv.org/abs/2510.13999)
|
||
|
||
---
|
||
|
||
*この記事は2026年2月時点の情報です。最新情報は各公式ドキュメントをご確認ください。*
|