MikroTik CRS812 400G 브레이크아웃으로 DGX Spark 연결: 200G 링크가 106Gb/s에서 막히고 NCCL이 Socket으로 폴백
분산 학습용으로 DGX Spark 노드 네 대를 세팅해서 MikroTik CRS812-8DS-2DQ-2DDQ에 걸었습니다. 계획은 스위치의 400G QSFP-DD 포트 하나가 노드 두 개에 각각 200G씩 먹이는 거였고, 그러면 브레이크아웃 케이블 몇 개로 클러스터 전체를 커버합니다.
- MikroTik CRS812-8DS-2DQ-2DDQ, QSFP-DD 포트를 브레이크아웃 모드로 사용
- NADDOD Q2Q56-400G-CU2, QSFP-DD 400G에서 QSFP56 200G 2개로 나가는 패시브 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 transport를 보고하고 노드 네 개에 걸쳐 대략 2GB/s bus bandwidth가 나오니까, RDMA가 확실히 전혀 안 쓰이고 있는 겁니다.
이미 확인한 것:
- 브레이크아웃 케이블을 스위치 포트 사이에서 재장착하고 교체, 숫자는 동일
- 스트림 수를 늘림, 합계는 106Gb/s 근처에 계속 고정됨
- 스위치가 포트를 100G가 아니라 200G로 보고하는 것 확인
계속 다시 돌아오게 되는 부분은 물리적인 QSFP56 포트 하나가 노드에서 논리 인터페이스 두 개로 보인다는 겁니다. 브레이크아웃이 각 노드에 레인을 절반만 전달하고 있는 건가요, 아니면 이 하드웨어의 200G 포트는 원래 그렇게 보여야 하는 건가요?
Comments 7
정확히 그겁니다, 브레이크아웃 케이블은 무죄고요. 이 플랫폼에서는 ConnectX-7 포트가 PCIe x4로 붙어있고 논리적으로 절반씩 두 개로 노출됩니다. 각각 대략 100Gb/s를 나릅니다. 전체 200G는 두 절반이 동시에 부하를 받을 때만 나타나니까, 단일 주소 iperf3 실행이 100Gb/s를 살짝 넘는 데서 멈추는 건 고장이 아니라 예상된 결과입니다.
여기서 통했던 방법입니다.
양쪽 절반 다 트래픽을 나르게 되면 그 페어에서 라인 레이트에 가깝게 나올 거고, nccl-tests all_reduce_perf도 소켓을 더 이상 거치지 않게 되면 완전히 다른 수준의 bus bandwidth를 보고할 겁니다.
케이블 탓하기 전에, 그 두 인터페이스를 정확히 어떻게 돌리고 계신가요? enp1s0f1np1이랑 enP2p1s0f1np1이 둘 다 UP이라고 붙여주셨는데, iperf3가 둘 다를 치고 있나요, 아니면 주소를 가진 쪽 하나만인가요?
이것도 올려주시면 좋겠습니다. 노드랑 CRS812 포트의 MTU요, 이 속도에서는 1500이 크게 발목을 잡거든요. 그리고 /etc/nccl.conf 내용도요. NCCL이 Socket transport를 고르는 건 거의 항상 그 파일 안의 뭔가가 IB 경로를 건드리지 말라고 시켰기 때문이지, 패브릭이 고장나서가 아닙니다.
좋은 질문이네요. enp1s0f1np1만 주소가 있고, enP2p1s0f1np1 절반은 up인데 설정이 안 돼 있고, 지금까지 iperf3 실행은 전부 그 주소 하나로 갔습니다. MTU는 노드에서 1500이고 스위치 쪽 L2 MTU도 안 건드렸습니다. 그리고 맞습니다, 여기 있네요.
이건 이미지에 원래 들어있던 거라 한 번도 의심을 안 해봤습니다. 그러면 106Gb/s는 어쩌면 포트 절반에 약간의 여유가 더해진 것뿐일 수도 있겠네요?
다른 스택인데 놀란 모양새는 똑같습니다. 제 쪽은 RHEL 8.4에 MLNX_OFED 5.7, 펌웨어 20.32.2004, MFT 4.21의 ConnectX-6(MT28908)이었고, 반대편은 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로 옮기는 수밖에 없습니다.
브레이크아웃 전반에 대한 교훈은, 뭘 측정하기 전에 양쪽 끝이 실제로 형성할 수 있는 레인 그룹핑이 뭔지부터 파악하라는 겁니다.
위 레시피에서 한 가지는 짚고 넘어갈 만합니다. 사람들이 다시 이득을 놓치는 지점이거든요. MTU는 스위치에서도 맞아야 합니다. 포트가 여전히 1500바이트 프레임을 통과시키는데 호스트에 9000을 설정하면 처리량이 아니라 드롭을 얻게 됩니다. CRS812 포트에 L2 MTU를 설정하고 큰 페이로드 ping으로 확인한 뒤에 테스트를 다시 돌리세요.
IPv6 얘기도 마찬가지입니다. 양쪽 절반 다 주소가 있고 IPv6를 켜둔 채로 두면 포트마다 GID 엔트리가 추가로 생기고, 테스트가 쓰라고 지시받은 인덱스가 반드시 생각하시는 그 인덱스는 아닙니다. CX7 인터페이스에서 IPv6를 꺼두면 그 테이블이 작고 재부팅해도 예측 가능하게 유지되는데, 실행 결과를 비교할 때 겉보기보다 중요합니다.
계속 down으로 남는 브레이크아웃 포트는 님 경우랑은 완전히 다른 종류라는 걸 알아두시면 좋겠습니다. 중고 Arista DCS-7060CX-32S(EOS 4.16.8FX-7060X)에서는 제 서브인터페이스 네 개가 에러도 전혀 없이 그냥 링크가 영영 안 됐습니다. 박스는 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 변형을 다 시도했는데도요. 님 경우는 적어도 negotiate도 되고 트래픽도 지나가네요.
확인했습니다, 포트는 애초에 고장난 적이 없었네요. enP2p1s0f1np1을 독립된 인터페이스로 주소를 줬고, 노드랑 스위치 포트 다 MTU 9000으로 설정했고, CX7 인터페이스 둘 다 IPv6를 껐고, /etc/nccl.conf에서 NCCL_IB_DISABLE=1을 뺐습니다.
절반마다 하나씩 병렬 iperf3 세션 두 개를 돌리니 이제 합계 196-198Gb/s가 나옵니다. 노드 네 개에 걸친 all_reduce_perf는 23.76GB/s bus bandwidth를 보고하고 NCCL은 RDMA 경로에 있고, 로그에 더 이상 Socket transport는 없습니다. NADDOD Q2Q56-400G-CU2는 내내 제 할 일을 하고 있었던 거네요.