MikroTik CRS812 400G breakout से DGX Spark तक: 200G link 106 Gb/s पर रुक जाता है और NCCL Socket पर fall back कर जाता है
हम चार DGX Spark nodes distributed training के लिए खड़े कर रहे हैं और इन्हें एक MikroTik CRS812-8DS-2DQ-2DDQ से जोड़ा है। Plan यह था कि switch का एक 400G QSFP-DD port दो nodes को 200G-200G पर खिलाए, तो बस दो breakout cables पूरा cluster cover कर लें।
- MikroTik CRS812-8DS-2DQ-2DDQ, breakout mode में use हो रहे QSFP-DD ports
- NADDOD Q2Q56-400G-CU2, QSFP-DD 400G से 2x QSFP56 200G वाली passive DAC
- onboard ConnectX-7 वाले DGX Spark nodes
- iperf3 और nccl-tests all_reduce_perf से validation
दोनों छोर clean 200GbE link report करते हैं, पर throughput उसके आधे से थोड़ा ऊपर टिकी है:
# 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 चारों nodes पर Socket transport और करीब 2 GB/s bus bandwidth report करता है, तो साफ है कि RDMA बिल्कुल भी use नहीं हो रहा।
हम अब तक क्या check कर चुके हैं:
- breakout cable reseat करके switch ports के बीच swap किया, numbers बिल्कुल वैसे ही
- stream count बढ़ाया, aggregate 106 Gb/s के आसपास ही टिका रहता है
- confirm किया कि switch port को 200G report करता है, 100G नहीं
जिस बात पर मैं बार-बार लौट आता हूँ वह यह है कि node पर एक physical QSFP56 port दो logical interfaces के तौर पर दिखता है। क्या breakout हर node को आधी lanes ही दे रहा है, या इस hardware पर 200G port ऐसा ही दिखना चाहिए?
Comments 7
बात बिल्कुल यही है, और breakout cable बेकसूर है। इस platform पर ConnectX-7 port PCIe x4 पर attached है और दो logical halves के तौर पर expose होता है, हर एक करीब 100 Gb/s ले जाता हुआ। पूरा 200G तभी दिखता है जब दोनों halves एक साथ load हों, तो एक ही address से चला iperf3 run 100 Gb/s से थोड़ा ऊपर रुक जाए, यह fault नहीं बल्कि expected result है।
यहाँ किस चीज़ से यह काम कर गया:
दोनों halves पर traffic चलने से आप जोड़ी पर line rate के करीब पहुँच जाना चाहिए, और जैसे ही यह sockets से गुजरना बंद करता है, nccl-tests all_reduce_perf बिल्कुल अलग class की bus bandwidth report करेगा।
Cable को दोष देने से पहले, आप उन दो interfaces को exactly कैसे चला रहे हैं? आपने enp1s0f1np1 और enP2p1s0f1np1 दोनों को UP पेस्ट किया, पर क्या iperf3 दोनों पर जा रहा है, या सिर्फ उस पर जिसके पास address है?
यह भी post करने लायक है: nodes और CRS812 ports पर MTU, क्योंकि इस rate पर 1500 बुरी तरह नुकसान करता है, और /etc/nccl.conf की content। जब NCCL Socket transport चुनता है तो लगभग हमेशा वजह यही होती है कि उस file में कुछ ऐसा था जिसने उसे IB path न छूने को कहा, fabric टूटा होने की वजह से नहीं।
सही सवाल हैं। सिर्फ enp1s0f1np1 के पास address है, enP2p1s0f1np1 वाला half up है पर unconfigured, और अब तक का हर iperf3 run उसी एक address पर गया। Nodes पर MTU 1500 है और switch साइड का L2 MTU भी मैंने नहीं छुआ। और हाँ, वो रही वजह:
यह पहले से ही image में था और मैंने कभी सवाल नहीं उठाया। तो क्या 106 Gb/s शायद port के सिर्फ एक half plus थोड़ा सा headroom है?
अलग stack, हैरानी वैसी ही। मेरी साइड RHEL 8.4 के नीचे एक ConnectX-6 (MT28908) था, MLNX_OFED 5.7, firmware 20.32.2004, MFT 4.21; दूसरी तरफ एक Switch-IB 2 SB7800, और दोनों के बीच एक LinkX MCP7H50-H002R26 splitter जो 200G को 2x100G में उतारता है। Port इस तरह up हुआ:
और न mlxlink -d mlx5_0 -p 1 --speeds edr और न ही --speeds hdr से कुछ बदला। पता चला कि यह config की गलती नहीं बल्कि silicon की एक ceiling थी: EDR gear सिर्फ 1x या 4x चौड़े links बनाता है, और उस तरह का splitter 2x grouping पर टिका है, जो HDR के साथ आई। तो या तो उस switch में plain 4x EDR cable डालो, या अगर split करना ही ज़रूरी है तो HDR पर जाओ।
Breakouts के लिए सामान्य सीख: कुछ भी measure करने से पहले पता कर लो कि हर छोर असल में कौन सी lane grouping बना सकता है।
ऊपर वाली recipe में से एक बात साफ कहने लायक है, क्योंकि यहीं लोग फिर से gains गँवा देते हैं: MTU switch पर भी match होना चाहिए। Hosts पर 9000 set करने से, जबकि ports अब भी 1500-byte frames pass करते हैं, throughput नहीं बल्कि drops मिलते हैं। CRS812 ports पर L2 MTU set करें और कोई भी test फिर से चलाने से पहले large-payload ping से verify कर लें।
IPv6 वाली बात भी वैसी ही है। दोनों halves address होने और IPv6 on रहने पर हर port पर extra GID entries बन जाती हैं, और जो index आपके test को use करने को कहा गया वह ज़रूरी नहीं वही हो जो आप सोचते हैं। CX7 interfaces पर IPv6 बंद रखने से वह table छोटी और reboots के बीच predictable रहती है, जो runs compare करते वक्त लगने से कहीं ज्यादा मायने रखता है।
याद रखने लायक बात है कि जो breakout port down ही रह जाए, वह आपके वाले से बिल्कुल अलग जानवर है। एक second-hand Arista DCS-7060CX-32S (EOS 4.16.8FX-7060X) पर मेरे चारों sub-interfaces में कोई error नहीं था, बस वे link ही नहीं करते थे। Box transceiver qsfp default-mode 4x10G पर बैठा था जबकि far end 25G present कर रहा था, और Et17/1 तब तक errdisabled रहा जब तक rate हाथ से set नहीं की गई:
उसी session में एक Mellanox cable को unqualified transceiver बताकर मना कर दिया गया और उसे Arista-compatible 100GBASE-CR4 QSFP28 DAC से बदलना पड़ा। दूसरे extreme पर, एक colleague को Mellanox switch की तरफ Junos 23.2R1-S1.8-EVO चलाने वाले QFX5220-32CD पर QDD-4X100G-2P5M breakout कभी up नहीं मिला, जबकि port profile को Port Checker ने validate किया था और हर FEC variant try किया जा चुका था। आपका वाला कम से कम negotiate करता है और traffic pass करता है।
Confirm हो गया, port कभी टूटा ही नहीं था। मैंने enP2p1s0f1np1 को अपने अलग interface के तौर पर address किया, nodes और switch ports दोनों पर MTU 9000 set किया, दोनों CX7 interfaces पर IPv6 बंद किया और /etc/nccl.conf से NCCL_IB_DISABLE=1 हटा दिया।
अब दो parallel iperf3 sessions, हर half पर एक, मिलाकर 196-198 Gb/s देते हैं। चारों nodes पर all_reduce_perf 23.76 GB/s bus bandwidth report करता है और NCCL RDMA path पर है, log में अब कोई Socket transport नहीं। NADDOD Q2Q56-400G-CU2 शुरू से अपना काम ठीक से कर रही थी।