SB C&Sの最新技術情報 発信サイト

C&S ENGINEER VOICE

SB C&S

2台のDGX Sparkを束ねる:物理構成・ソフトウェア設定について

AI
2025.11.10

皆様こんにちは。SB C&Sの下山です。

前回の記事の最後で、今後の連載では実際のアプリケーションやベンチマークの紹介に進む予定であることをお伝えしました。
その前段として、今回は2台の DGX Spark をスタック構成で運用する際に必要となる準備作業について整理しておきます。

なお、本記事の内容は、以下の NVIDIA 公式ドキュメントを参考に作成しました。

目次

  1. 物理的な接続手順
  2. NICについて
  3. NWセットアップ手順
  4. NCCLセットアップ手順
  5. NCCLテスト手順
  6. まとめ

物理的な接続手順

NVIDIA社が認定しているスタック構成用ケーブルは限られており、そのうち弊社にて利用しているAmphenol社製のNJAAKK-N911はケーブル長が 40 cm です。

cable_1_r.jpg

このため、2台のSparkは物理的に近い位置に配置する必要があります。

before_cabling_r.jpg

Sparkおよびスタック構成用ケーブルはホットプラグに対応しているため、接続時にSparkをシャットダウンする必要はありません。また、各Sparkには2つのポートが搭載されていますが、どちらのポートにケーブルを接続しても問題ありません。

cabling_1_r.jpgcabling_2_r.jpg

NICについて

スタック接続に使用するQSFPポートを制御するコントローラーにはConnectX-7が採用されており、Sparkに搭載されているConnectX-7は単一ポートあたり最大200 Gbit/sのイーサネット接続に対応可能です。

本来、ConnectX-7Ethernetに加えてInfiniBandプロトコルにも対応していますが、現時点ではEthernet通信のみがサポートされていることが確認されています。
以下はデバイスの情報をコマンドで表示した情報です。

lspci | grep Ether
 
## 出力例
0000:01:00.0 Ethernet controller: Mellanox Technologies MT2910 Family [ConnectX-7]
0000:01:00.1 Ethernet controller: Mellanox Technologies MT2910 Family [ConnectX-7]
0002:01:00.0 Ethernet controller: Mellanox Technologies MT2910 Family [ConnectX-7]
0002:01:00.1 Ethernet controller: Mellanox Technologies MT2910 Family [ConnectX-7]

0007:01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. Device 8127 (rev 05)

sudo ibdev2netdev -v
 
## 出力例
/usr/sbin/ibdev2netdev: line 165: warning: command substitution: ignored null byte in input
0000:01:00.0 rocep1s0f0 (MT4129 - P4242-0000 ) NVIDIA DGX Spark, P4242-0000, 2-port QSFP up to 200G, Ethernet, PCIe5                                                                                                                  fw 28.45.4028 port 1 (ACTIVE) ==> enp1s0f0np0 (Up)
~一部省略~

NWセットアップ手順

ここまでのステップで物理的な接続は完了していますが、実際に通信を行うために必要なIPアドレスなどの設定はまだ行われていません。このセクションでは公式のドキュメントに則ってそれらの設定を2台のDGX Sparkに行っていきます。

スタック接続通信のセットアップ

スタック接続通信にIPアドレスを割り当てる方法として以下2つがあります。
・netplanを使用した自動割り当て(NVIDIAが提供するYAMLファイルを利用)
・手動での設定

ここではnetplanを用いた自動でIPアドレスを設定する方法を記載します。
※手動での設定方法は以下ユーザーガイド内「Option 2: Manual IP assignment (advanced)」をご参照ください
https://docs.nvidia.com/dgx/dgx-spark/spark-clustering.html#option-2-manual-ip-assignment-advanced

①netplan設定ファイルのダウンロード

sudo wget -O /etc/netplan/40-cx7.yaml https://github.com/NVIDIA/dgx-spark-playbooks/raw/main/nvidia/connect-two-sparks/assets/cx7-netplan.yaml

②設定ファイルへ適切な権限を設定

sudo chmod 600 /etc/netplan/40-cx7.yaml

③Netplan設定の適用

sudo netplan apply

以下は上記手順を実際に実行した際の様子となります。
ここまでの設定にて2台のSparkは互いに通信可能な状態となりました。

auto_ip_1_r.jpg

DGX Spark Discovery Scriptの実行

続いて、各Sparkへパスワード不要のSSH認証とノード識別の設定を行います。
本設定はNVIDIA社にてDiscovery Scriptというスクリプトが提供されており、そちらをダウンロードし実行します。
※Discovery Scriptもそれぞれのホストで実行が必要です。

①Discovery scriptのダウンロード

wget https://github.com/NVIDIA/dgx-spark-playbooks/raw/refs/heads/main/nvidia/connect-two-sparks/assets/discover-sparks

②スクリプトへ実行権限を付与

chmod +x discover-sparks

③スクリプトの実行

./discover-sparks

以下は上記手順を実際に実行した際の様子となります。
ここまでの設定にて2台のSparkはノードの識別が出来るようになりました。

discover_2_2_r.jpg

NCCLセットアップ手順

続いて、2台のSpark間で高速なGPU間通信を実現するために必要なNCCLと呼ばれる通信ライブラリを入手します。

■NCCLとは
NVIDIA Collective Communication Libraryの略称であり、ニッケルもしくはエヌシーシエルと読みます。

ディープラーニングなどの分散学習では、GPU間でデータをやり取りする際に、All-Reduce・Scatter・Gatherなどの「コレクティブ通信」と呼ばれるさまざまな通信が発生します。
NCCLは、これらの通信方式やNVLink、InfiniBand、EthernetといったGPU接続トポロジーを自動的に判別し、ユーザーへ意識させることなく高効率な通信を実現します。さらに、NCCLはGPUDirect RDMAに対応しており、これを利用することで、従来のCPU経由の通信と比較して、より低レイテンシかつ高スループットな通信を可能にします。

通信経路のイメージ:
【アプリケーション層】
  CUDA / PyTorch / TensorFlow etc...
      ↓   ↑
【通信ライブラリ層】
  NCCL(通信制御・集約演算)
      ↓   ↑
【データ転送層】
  GPUDirect RDMA(GPUメモリ直接通信)
      ↓   ↑
【ネットワーク層】
RoCEv2(Ethernet上のRDMA通信)

模式図_枠あり.jpg

画像引用元:NVIDIA GPUDirect

NCCLの構築

NCCLを利用するための準備を進めていきます。
このステップも双方のSparkで実行してください。

まず、BlackwellアーキテクチャをサポートするソースからNCCLをビルドします。
なお、ビルドにあたり一部依存関係のインストールも実施しています。

# 依存関係をインストールしてNCCLをビルド
sudo apt-get update && sudo apt-get install -y libopenmpi-dev
git clone -b v2.28.3-1 https://github.com/NVIDIA/nccl.git ~/nccl/
cd ~/nccl/
make -j src.build NVCC_GENCODE="-gencode=arch=compute_121,code=sm_121"

続いて、必要なパラメータを環境変数に格納しておきます。
この環境変数は実際にNCCLを利用する際に用います。

# 環境変数の設定
export CUDA_HOME="/usr/local/cuda"
export MPI_HOME="/usr/lib/aarch64-linux-gnu/openmpi"
export NCCL_HOME="$HOME/nccl/build/"
export LD_LIBRARY_PATH="$NCCL_HOME/lib:$CUDA_HOME/lib64/:$MPI_HOME/lib:$LD_LIBRARY_PATH"

NCCLテスト手順

それではNCCLの準備ができましたので、NCCLの動作確認を行います。
NVIDIA社のリポジトリにてテスト用ツールが提供されていますため、そちらを利用します。
https://github.com/NVIDIA/nccl-tests

なお、本手順も双方のSparkで実施してください。

①NCCLテストスイートの構築

# テストスイートのソースクローンとビルド
git clone https://github.com/NVIDIA/nccl-tests.git ~/nccl-tests/
cd ~/nccl-tests/
make MPI=1

②有効なNW I/FとIPアドレスの特定

NCCLのテストに用いる有効なI/FIPアドレスを確認します。

# NWポートステータスの確認
ibdev2netdev
# IPアドレス情報の確認
ip -brief link show

以下画像の実行例ではibdev2netdevの実行結果から、黄枠内のenp1s0f0np0enP2p1s0f0np0UPしていることが確認できます。続いてipコマンドを実行すると、enp1s0f0np0にのみアドレスがアサインされていることがわかりました。

これらの点から、テストではenp1s0f0np0を用いることとします。

find_nic_add_1_mod_r.jpg

③NCCLテストの実行

テストを実行するには、両ノードで以下のコマンドを実行します。IPアドレスとインターフェース名は、前の手順で確認したものに置き換えてください。

# NW I/F名を環境変数へ設定する (前のステップで確認したI/F)
export UCX_NET_DEVICES=<interface name>
export NCCL_SOCKET_IFNAME=<interface name>
export OMPI_MCA_btl_tcp_if_include=<interface name>

# 2台のSparkにまたがるall_gatherパフォーマンステストの実行 (コマンド例のIPアドレスは前のステップで確認したものを用いる)
mpirun -np 2 -H <Node1のIPアドレス>:1,<Node2のIPアドレス>:1 \
  --mca plm_rsh_agent "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
  -x LD_LIBRARY_PATH=$LD_LIBRARY_PATH \
  $HOME/nccl-tests/build/all_gather_perf

このテストを私たちの環境で実行した場合次のような結果が得られました。

Node1:nccl_test_1_r.jpg

Node2:
nccl_test_2_r.jpg出力結果より、今回のテストでは片方向あたり15.415.8GB/sの通信速度が確認されました。この値は約126Gbit/sに換算され、Connect-X7として十分に高い性能が発揮されています。

まとめ

この連載では、公式ドキュメントをもとに、2台の Spark をスタック構成で接続し、実際に GPU 間通信のテストを行う手順をご紹介しました。これらの手順を通じて、2台の Spark は互いに連携し、分散学習における GPU 間通信を高速に処理できるようになります。

次回以降の連載では、2台のノードにまたがってアプリケーションを実行する実践的な検証を進めていく予定です。ぜひ今後の掲載を楽しみにお待ちください。

著者紹介

SB C&S株式会社
ICT事業本部 技術本部 技術統括部 第2技術部 1課
下山 翔也 - Shoya Shimoyama -

NVIDIA社製品のプリセールス・エンジニア業務を担当。
GPUのほか、クラウドサービスやサーバー、ネットワーク機器についても取り扱う。