MikroTik CRS812の400GブレイクアウトでDGX Sparkに接続、200Gリンクが106Gb/sで頭打ちになりNCCLがSocketにフォールバック
分散学習用に4台のDGX Sparkノードを立ち上げ、MikroTik CRS812-8DS-2DQ-2DDQにぶら下げています。計画では、スイッチの1つの400G QSFP-DDポートから200Gずつで2ノードに給電し、2、3本のブレイクアウトケーブルでクラスタ全体をカバーするというものでした。
- MikroTik CRS812-8DS-2DQ-2DDQ、QSFP-DDポートをブレイクアウトモードで使用
- NADDOD Q2Q56-400G-CU2、QSFP-DD 400Gから2x QSFP56 200Gへのパッシブ DAC
- オンボードConnectX-7を積んだDGX Sparkノード
- iperf3とnccl-testsのall_reduce_perfで検証
両端とも200GbEのきれいなリンクを報告していますが、スループットはその半分をわずかに超える程度で止まっています。
# iperf3 -c <peer> -P 8
[SUM] 0.00-10.00 sec ... 106 Gbits/sec
single stream: ~30 Gbits/sec
# ip -br link
enp1s0f1np1 UP
enP2p1s0f1np1 UP
NCCLはそれよりさらに悪く、all_reduce_perfはSocketトランスポートを報告していて、4ノード間のバスバンド幅は2GB/s程度しかありません。つまりRDMAはまったく使われていないことが明らかです。
すでに確認したこと:
- ブレイクアウトケーブルを挿し直し、スイッチのポート間で入れ替えたが数字は変わらない
- ストリーム数を増やしたが、合計は106Gb/s付近に張り付いたまま
- スイッチがポートを100Gではなく200Gと報告していることは確認済み
何度も引っかかるのは、1つの物理QSFP56ポートがノード側では2つの論理インターフェースとして見えることです。ブレイクアウトが各ノードにレーンの半分しか届けていないのか、それともこのハードウェアの200Gポートはそもそもそういう見え方をするものなのでしょうか。
Comments 7
まさにその通りで、ブレイクアウトケーブルは無罪です。このプラットフォームでは、ConnectX-7のポートはPCIe x4で接続されていて、それぞれ約100Gb/sを運ぶ2つの論理的な半分として見えます。フルの200Gが出るのは両方の半分に同時に負荷をかけたときだけなので、単一アドレスでのiperf3実行が100Gb/sをわずかに超えたところで止まるのは、故障ではなく想定通りの結果です。
ここで効果があったのは:
両方の半分にトラフィックを流せば、そのペアではほぼラインレートに近い数字になるはずですし、nccl-testsのall_reduce_perfもSocket経由でなくなった時点でまったく違う次元のバスバンド幅を報告するようになります。
ケーブルを疑う前に、その2つのインターフェースを具体的にどう使っていますか。enp1s0f1np1とenP2p1s0f1np1が両方ともUPだと貼っていますが、iperf3は両方に対して実行されていますか、それともアドレスを持っているほうだけですか。
併せて貼ってほしいのは、ノード側とCRS812ポート側のMTUです。このレートで1500だとかなり痛手になります。それと/etc/nccl.confの中身も。NCCLがSocketトランスポートを選ぶのは、ほとんどの場合ファブリックが壊れているからではなく、そのファイル内の何かがIBパスに触るなと指示しているからです。
もっともな質問です。アドレスを持っているのはenp1s0f1np1だけで、enP2p1s0f1np1側はupですが未設定のままです。これまでのiperf3実行はすべてその1つのアドレスに対して行っていました。MTUはノード側で1500で、スイッチ側のL2 MTUも触っていません。そして、ありました。
これはイメージに最初から入っていて、疑ったことがありませんでした。つまり106Gb/sというのは、ポートの半分にちょっとした余裕を足しただけの数字だった可能性があるということでしょうか。
スタックは違いますが、驚きの形は同じです。こちらはRHEL 8.4上のConnectX-6(MT28908)、MLNX_OFED 5.7、ファームウェア20.32.2004、MFT 4.21で、対向はSwitch-IB 2 SB7800、その間に200Gを2x100Gに分けるLinkX MCP7H50-H002R26スプリッタを挟んでいました。ポートは次のように上がりました。
mlxlink -d mlx5_0 -p 1 --speeds edrも--speeds hdrも何も変わりませんでした。結局これは設定ミスではなくシリコン自体の天井でした。EDR機器は1xか4x幅のリンクしか作れないのに、この種のスプリッタは2xグルーピングに依存していて、それはHDRから導入されたものです。なのでそのスイッチには素の4x EDRケーブルを挿すか、分割がどうしても必要ならHDRに移行するかのどちらかです。
ブレイクアウト全般についての教訓としては、何かを測定する前に、両端が実際にどのレーングルーピングを形成できるのかを確認しておくことです。
上の手順の中で1点、はっきり言っておく価値があります。ここでまたせっかくの改善を失う人が多いからです。MTUはスイッチ側も合わせる必要があります。ポートが1500バイトのフレームしか通さないままホスト側だけ9000にすると、スループットではなくドロップを買うことになります。CRS812のポートでL2 MTUを設定し、テストをやり直す前に大きめのペイロードのpingで確認してください。
IPv6の話も同じです。両方の半分にアドレスを振った状態でIPv6を有効なままにしておくと、ポートごとに余分なGIDエントリが増え、テストに指定したインデックスが思っているものと違う可能性があります。CX7インターフェースでIPv6をオフにしておけば、そのテーブルは小さく、再起動をまたいでも予測可能なままになります。これは実行結果を比較するときに、見た目以上に効いてきます。
覚えておく価値があるのは、リンクすら上がらないブレイクアウトポートは、あなたのケースとはまったく別物だということです。中古のArista DCS-7060CX-32S(EOS 4.16.8FX-7060X)では、4つのサブインターフェースがエラーは一切出さないまま、単純にリンクしませんでした。機器はtransceiver qsfp default-mode 4x10Gのままだったのに対向側は25Gを提示していて、Et17/1はレートを手動で設定するまでerrdisabledのままでした。
同じ作業の中で、Mellanoxのケーブルは未認定のトランシーバとして拒否され、Arista互換の100GBASE-CR4 QSFP28 DACに交換する羽目になりました。もう一つの極端な例では、同僚がJunos 23.2R1-S1.8-EVO動作のQFX5220-32CDでMellanoxスイッチに向けたQDD-4X100G-2P5Mブレイクアウトを、Port Checkerが検証済みのポートプロファイルとあらゆるFECのバリエーションを試しても、一度も上げられませんでした。あなたのケースは少なくともネゴシエートしてトラフィックも通っています。
確認できました、ポートは一度も壊れていませんでした。enP2p1s0f1np1を独立したインターフェースとしてアドレス設定し、ノードとスイッチポートの両方でMTUを9000にし、両方のCX7インターフェースでIPv6をオフにして、/etc/nccl.confからNCCL_IB_DISABLE=1を取り除きました。
半分ごとに1つずつ、並列で2つのiperf3セッションを走らせると、今では合計196-198Gb/sになります。4ノード間のall_reduce_perfは23.76GB/sのバスバンド幅を報告していて、NCCLはRDMAパスに乗っており、ログにはもうSocketトランスポートは出てきません。NADDOD Q2Q56-400G-CU2はずっと仕事をきちんとこなしていたわけです。