マルチノードの GPU トレーニングでは、ネットワーク通信のレイテンシーが主なボトルネックになることがよくあります。elastic Remote Direct Memory Access (eRDMA) は、カーネルバイパスによるノード間の低レイテンシーなデータ転送を提供し、勾配同期の速度と全体的なトレーニングのスループットを直接的に向上させます。
このトピックでは、eRDMA コントローラーのインストール、GPU ノードでの eRDMA の有効化、Arena を介した PyTorch 分散トレーニングジョブの送信、そして eRDMA による高速化が有効になっていることの確認方法について説明します。
前提条件
開始する前に、以下が準備されていることを確認してください。
ACK マネージドクラスター。eRDMA は専用クラスターではサポートされていません。
eRDMA 互換のインスタンスタイプを使用するノード:
gn8is、ebmgn8is、gn8v、またはebmgn8vクラスターにインストールされたCloud-native AI Suite の Arena コンポーネント
ローカルマシンに設定済みの Arena クライアント
インストール済みで、kubeconfig を介してクラスターに接続されている kubectl
ステップ 1:ACK eRDMA Controller アドオンのインストール
クラスターで Terway ネットワークプラグインを使用している場合は、このアドオンをインストールする前に Terway のホワイトリストを設定してください。これにより、Terway が eRDMA NIC を変更するのを防ぐことができます。詳細については、「ENI のホワイトリストを設定する」をご参照ください。
[クラスター] ページで、クラスター名を クリックします。左側の ナビゲーションウィンドウで、[アドオン] を クリックします。
[コンポーネント管理] ページの [ネットワーク] タブをクリックし、ACK eRDMA Controller を見つけて、プロンプトに従って設定およびインストールします。
ノードに複数の NIC が存在する場合、ACK eRDMA コントローラー は、eRDMA NIC のルートに対して、同一 CIDR ブロック内の他の NIC よりも低いルート優先度(デフォルトでは
200)を割り当てます。インストール後に NIC を手動で設定する場合は、ルートの競合を回避してください。設定項目 説明 preferDriver (ドライバータイプ) ノードの eRDMA ドライバーモード。オプション: default(デフォルトモード)、compat(RoCE 互換モード)、ofed(OFED ベースのモード、GPU インスタンスに推奨)。詳細については、「eRDMA を有効にする」をご参照ください。ノード上のすべての eRDMA デバイスを Pod に割り当てる True: ノード上のすべての eRDMA デバイスを Pod に割り当てます。False: NUMA トポロジーに基づいて、Pod ごとに 1 つの eRDMA デバイスを割り当てます。ノードで CPU Static ポリシーが有効になっている必要があります。詳細については、「ノードプールを作成および管理する」をご参照ください。インストールが完了したら、[ワークロード] > [Pod] に移動し、名前空間を
ack-erdma-controllerに設定し、コントローラー Pod が 実行中 の状態であることを確認します。
ステップ 2:ノードでの eRDMA の有効化と検証
eRDMA デバイスがアクティブであることを確認します。[クラスター] ページで、対象のクラスター名をクリックし、[ワークロード] > [Pod] に移動し、eRDMA が有効なノードでターミナルを開きます。以下を実行します。
ibv_devinfo出力で、
port_state: PORT_ACTIVEを持つerdma_0デバイスを探します。これにより、ノードで eRDMA が有効になっていることが確認できます。ノードが eRDMA をスケジューリング可能なリソースとして公開していることを確認します。
"nvidia.com/gpu":"1"— ノードにはスケジューリング可能な GPU が 1 つあります"aliyun/erdma":"200"— このノード上の最大 200 の Pod が eRDMA リソースをリクエストできます
kubectl get node <node-name> -o jsonpath='{.status.allocatable}'期待される出力:
{"aliyun/erdma":"200","cpu":"15890m","ephemeral-storage":"243149919035","hugepages-1Gi":"0","hugepages-2Mi":"0","memory":"128290128Ki","nvidia.com/gpu":"1","pods":"64"}2 つのフィールドを確認します。
ステップ 3:PyTorch 分散トレーニングジョブの送信
以下の例では、迅速な評価のために事前ビルド済みのイメージを使用します。本番環境で使用する場合は、必要な RDMA ユーザーモードライブラリを含む独自のイメージをビルドしてください。詳細については、「eRDMA をサポートする本番環境用コンテナイメージのビルド」をご参照ください。
arena submit pytorch \
--name=pytorch-mnist \
--namespace=default \
--workers=2 \
--gpus=1 \
--device=aliyun/erdma=1 \
--nproc-per-node=1 \
--env NCCL_NET_GDR_LEVEL=1 \
--env NCCL_P2P_LEVEL=5 \
--env NCCL_DEBUG=INFO \
--env NCCL_SOCKET_IFNAME=eth0 \
--env NCCL_ALGO=Ring \
--clean-task-policy=None \
--working-dir=/root \
--image=kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/pytorch:mnist-example \
--image-pull-policy=Always \
--tensorboard \
--logdir=/workspace/logs \
"torchrun /workspace/arena/examples/pytorch/mnist/main.py \
--epochs 10000 \
--backend nccl \
--data /workspace \
--dir /workspace/logs"重要なパラメーターは --device=aliyun/erdma=1 です。これにより、ワーカーごとに 1 つの eRDMA リソースがリクエストされ、コンテナ内で利用可能になります。このパラメーターがないと、ノードが eRDMA をサポートしていても NCCL は eRDMA を使用しません。
完全なパラメーターリファレンスについては、「Arena ジョブパラメーター」および「NCCL 環境変数」をご参照ください。
ステップ 4:トレーニングジョブの検証
マスター Pod のログにトレーニングの進捗が表示されていることを確認します。
kubectl logs pytorch-mnist-master-0 | head -n 50ログに
Train Epochが含まれていれば、ジョブは正しく実行されています。NCCL 通信パスで eRDMA がアクティブであることを確認します。マスター Pod のログで次の行を探します。
NCCL が eRDMA NIC (
erdma_0) を検出しました通信には RoCE (RDMA over Converged Ethernet) を使用します
ノード間の勾配同期は eRDMA 高速化を使用しています
NET/IB : Using [0]erdma_0:1/RoCEこの行は以下を確認します。
ステップ 5:eRDMA NIC トラフィックの監視
トレーニングノードでターミナルを開き ([ワークロード] > [Pod] > [操作] > [ターミナル])、以下を実行します。
eadm stat -d erdma_0 -lアクティブなトレーニング中、出力には次のような継続的な双方向トラフィックが表示されます。
rx (download): 914.89 MiB/s 150423 p/s; tx (upload): 914.66 MiB/s 147128 p/sこのレベルでの持続的なアップロードおよびダウンロードトラフィックは、ノード間の勾配同期が eRDMA を経由して流れていることを示します。
Torch、Python、および CUDA カーネルレベルでトレーニングパフォーマンスを分析するには、ACK の AI プロファイリング機能を使用します。AI プロファイリングは、トレーニングジョブにおけるコンピュート、通信、およびメモリのボトルネックを特定します。
リソースのクリーンアップ
トレーニングが完了したら、ジョブを削除します。
arena delete pytorch-mnist -n default期待される出力:
INFO[0001] The training job pytorch-mnist has been deleted successfullyこれにより、ジョブによって作成されたすべての Pod と Kubernetes リソースが削除されます。永続ストレージ内の TensorBoard ログは削除されません。
Arena ジョブパラメーター
| パラメーター | 説明 | 推奨値 |
|---|---|---|
--name | ジョブ名。クラスター内で一意である必要があります。 | タスクやチームのコンテキストを反映した名前を使用します。 |
--namespace | ジョブの Kubernetes 名前空間。 | チームまたはプロジェクトごとに分離します。 |
--workers | マスターを含むワーカーの総数。 | 2(マスター 1 台とワーカー 1 台) |
--gpus | ワーカーあたりの GPU 数。 | モデルサイズと GPU メモリ要件に基づいて設定します。 |
--device=aliyun/erdma=1 | eRDMA を有効にするために必須です。ワーカーごとに 1 つの eRDMA リソースをリクエストします。 | eRDMA を使用する場合は常に 1 に設定します。 |
--nproc-per-node | ノードあたりのトレーニングプロセス数。 | --gpus に合わせます。 |
--clean-task-policy | ジョブ完了後の Pod クリーンアップポリシー。 | None を指定すると、ログの検査のために Pod を保持します。 |
--env | トレーニングコンテナに渡される環境変数。 | 必要に応じて NCCL パラメーターを設定します。 |
NCCL 環境変数
NCCL 環境変数は、本番スクリプトに安全に保持できるシステム構成パラメーターと、本番環境では削除または削減すべきデバッグパラメーターの 2 つのカテゴリに分類されます。
システム構成 (本番環境で安全):
| 変数 | 説明 | 推奨値 |
|---|---|---|
NCCL_SOCKET_IFNAME | NCCL 調整トラフィック用のネットワークインターフェイス。 | eth0 (ACK クラスターのデフォルト NIC) |
NCCL_NET_GDR_LEVEL | GPU Direct RDMA ポリシーレベル (0–5)。 | 1 (PIX レベル) - eRDMA 用 |
NCCL_P2P_LEVEL | P2P 通信ポリシー (0–5)。 | 5 (SYS レベル) ノード間通信用 |
NCCL_ALGO | 集団通信アルゴリズム。 | Ring または Tree(ネットワークトポロジーに応じて) |
NCCL_IB_HCA | 使用する RDMA NIC の名前。 | ibstat を実行して利用可能な NIC 名をリストします。 |
デバッグ (トラブルシューティング時にのみ使用し、本番環境では削除):
| 変数 | 説明 | 推奨値 |
|---|---|---|
NCCL_DEBUG | ログの詳細度レベル。 | INFO。本番環境では WARN に切り替えます。 |
NCCL_IB_TIMEOUT | InfiniBand 通信タイムアウト。デフォルト:22。 | NCCL タイムアウトエラーが発生した場合は 23 に増やします。 |
NCCL_IB_RETRY_CNT | 失敗した InfiniBand 操作のリトライ回数。 | 不安定なネットワークの場合は 10 に設定します。 |
完全な NCCL 環境変数リファレンスについては、NCCL ドキュメントをご参照ください。
よくある質問
ログに NET/IB : Using erdma_0 が表示されない
これはほとんどの場合、eRDMA がコンテナにマウントされていないことを意味します。最も一般的な原因は、submit コマンドに --device=aliyun/erdma=1 がないことです。これを追加して再送信してください。
パラメーターが存在する場合、ノードレベルで確認します。
ノードが eRDMA リソースを公開していることを確認します。
kubectl get node <node-name> -o jsonpath='{.status.allocatable}'出力には
"aliyun/erdma"が含まれている必要があります。含まれていない場合、ACK eRDMA Controller が正しく実行されていません。ack-erdma-controller名前空間で Pod のステータスを確認してください。ノード上の eRDMA デバイスが正常であることを確認します。
ibv_devinfoport_state: PORT_ACTIVEを持つerdma_0を探します。コンテナイメージに必要な RDMA ユーザーモードライブラリ (
libibverbs1、ibverbs-providers、およびlibrdmacm1) が含まれていることを確認します。含まれていない場合は、新しいイメージをビルドします。「eRDMA をサポートする本番環境用コンテナイメージのビルド」をご参照ください。
トレーニング中に NCCL タイムアウトエラーが発生する
タイムアウトエラーは通常、ネットワークの不安定性、またはデフォルトのタイムアウトがクラスターに対して短すぎることを意味します。タイムアウトとリトライ制限を増やしてください。
--env NCCL_IB_TIMEOUT=23 \
--env NCCL_IB_RETRY_CNT=10エラーが続く場合は、ノード間のネットワーク接続を確認し、ibv_devinfo で eRDMA デバイスのステータスを検証してください。
eRDMA が実際にトレーニングパフォーマンスを向上させるかどうかを測定する方法
他は同一の 2 つのジョブ (--device=aliyun/erdma=1 を使用するものと使用しないもの) を送信し、同じトレーニングステップ数での総完了時間を比較します。より詳細な分析には、AI プロファイリングツールを使用して、通信とコンピュートに費やされた時間の割合を測定します。
eRDMA は、大規模モデル (数十億パラメーター以上) を使用するマルチノードシナリオ (2 ノード以上) で最も顕著なパフォーマンス向上をもたらします。
ジョブの送信時に Arena がリソース不足を報告する
kubectl get nodes を実行して、ノードのステータスと利用可能なリソースを確認します。ノードに aliyun/erdma または nvidia.com/gpu の容量が不足している場合は、ノードを追加するか、リソースリクエストを減らしてください。
リソースが利用可能に見えても Pod がスケジューリングに失敗する場合は、以下を実行します。
kubectl describe pod <pod-name>Events セクションには、Toleration の欠落やノードセレクターの不満など、特定のスケジューリング失敗理由が表示されます。
eRDMA をサポートする本番環境用コンテナイメージのビルド
本番環境では、Alibaba Cloud eRDMA APT リポジトリから RDMA ユーザーモードライブラリをインストールするコンテナイメージをビルドします。以下の Dockerfile は、公式の PyTorch イメージをベースにビルドされ、eRDMA ドライバーと MNIST トレーニングの例が含まれています。
詳細については、「コンテナ (Docker) で eRDMA を有効にする」をご参照ください。
ARG PYTORCH_IMAGE=docker.io/pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime
FROM docker.io/library/alpine:3.22.1 AS downloader
WORKDIR /workspace
RUN apk add git wget gzip
RUN mkdir -p /workspace/MNIST/raw && \
cat <<EOF > /workspace/MNIST/raw/checksums.md5
f68b3c2dcbeaaa9fbdd348bbdeb94873 train-images-idx3-ubyte.gz
d53e105ee54ea40749a09fcbcd1e9432 train-labels-idx1-ubyte.gz
9fb629c4189551a2d022fa330f9573f3 t10k-images-idx3-ubyte.gz
ec29112dd5afa0611ce80d1b7f02629c t10k-labels-idx1-ubyte.gz
EOF
RUN cd /workspace/MNIST/raw && \
wget https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz && \
wget https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz && \
wget https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz && \
wget https://ossci-datasets.s3.amazonaws.com/mnist/t10k-labels-idx1-ubyte.gz && \
md5sum -c checksums.md5 && \
rm checksums.md5 && \
gzip -d *.gz
RUN git clone https://github.com/kubeflow/arena.git -b v0.15.2
FROM ${PYTORCH_IMAGE}
WORKDIR /workspace
COPY --from=downloader /workspace .
RUN set -eux && \
apt update && \
apt install -y wget gpg && \
wget -qO - https://mirrors.aliyun.com/erdma/GPGKEY | gpg --dearmour -o /etc/apt/trusted.gpg.d/erdma.gpg && \
echo "deb [ ] https://mirrors.aliyun.com/erdma/apt/ubuntu jammy/erdma main" > /etc/apt/sources.list.d/erdma.list && \
apt update && \
apt install -y libibverbs1 ibverbs-providers ibverbs-utils librdmacm1 && \
pip install --no-cache-dir -r /workspace/arena/examples/pytorch/mnist/requirements.txt && \
rm -rf /var/lib/apt/lists/*