RDMA v praxi + návrh uplinků clusteru
Předchozí články v řadě N zdůvodnily nasazení RDMA (N02) a provedly vás volbou topologie (N04, N05). Tento díl je praktický: nainstalovat ovladače, ověřit, že cesta funguje, zapnout GPUDirect, validovat NCCL a poté se povznést o patro výš a promyslet, jak se celý cluster připojuje ke zbytku světa.
Předpokládáme Ubuntu 22.04 nebo 24.04, síťové karty Mellanox/NVIDIA ConnectX-5 nebo ConnectX-6 a buď InfiniBand HDR/NDR, nebo RoCEv2 nad bezeztrátovou ethernetovou sítí. Uvedené příkazy jsou přesně ty, které skutečně píšeme na testovacích stolicích Kentino, než od nás odejde čtyřuzlový cluster Kentino AI.
Ovladače: MLNX_OFED, nebo upstreamový rdma-core?
| Varianta | Co získáte | Kdy ji zvolit |
|---|---|---|
| MLNX_OFED (nyní NVIDIA DOCA-OFED) | Balík ovladačů otestovaný NVIDIÍ, GPUDirect peermem, perftest, mlxconfig | Produkční AI clustery s ConnectX-6/7 a GPUDirect |
Upstreamový rdma-core + in-tree mlx5
|
To, co dodává Ubuntu, bez dalšího repozitáře | Laboratorní stroje, jeden uzel, bez GPUDirect, bez nástrojů pro firmware |
Pro cokoli, co v produkci přenáší provoz NCCL, nainstalujte MLNX_OFED. Upstreamový mlx5 sice funguje, ale přijdete o mlxconfig, o přibalený perftest a — což je nejdůležitější — o modul nvidia-peermem na straně jádra otestovaný proti témuž stromu OFED.
Čistá instalace na Ubuntu 22.04 s jádrem 5.15.x:
tar xf MLNX_OFED_LINUX-*.tgz && cd MLNX_OFED_LINUX-*
sudo ./mlnxofedinstall --add-kernel-support --with-nvmf --force
sudo /etc/init.d/openibd restart && sudo systemctl enable openibd
Přepínač --add-kernel-support je zásadní. Pokud jej na jádře mimo matici OFED vynecháte, sestavení DKMS tiše selže — a vy nakonec provozujete standardní mlx5 a nevíte o tom. Stav user-space stacku ověříte příkazem dpkg -l | grep -E 'libibverbs|rdma-core|mlnx-ofed'.
Nahoďte linku a ověřte, že karta vidí síť
Vše podstatné vám řeknou tři příkazy:
sudo mst start && mst status # firmware tools
ibstat # port state, width, speed
ibv_devinfo -v # GIDs, max_qp, MTU, hw revision
Zdravý port hlásí State: Active, Physical state: LinkUp, očekávanou hodnotu Rate: (např. 200) a správnou Link layer: (InfiniBand, nebo Ethernet). Dvě pole, která se běžně přehlédnou:
-
Link layer: InfiniBandvs.Ethernet. Dvourežimovou kartu ConnectX přepnete příkazemmlxconfig -d /dev/mst/mt4125_pciconf0 set LINK_TYPE_P1=2(1 = IB, 2 = Ethernet). Je nutný restart. -
Rate:odpovídá očekávané rychlosti. Port NDR 200 Gb/s, který naběhl na 100 Gb/s, je nejčastější tichá závada: vadný kabel, nesprávná délka DAC nebo port switche natvrdo omezený na nižší rychlost. Zkontrolujte to dřív, než začnete měřit výkon.
U RoCE navíc ověřte, že je zvolena verze v2 (v1 má ethertype 0x8915, v2 běží na UDP/4791 a používá ji každý moderní stack): sudo cma_roce_mode -d mlx5_0 -p 1 -m 2.
Subnet manager (pouze InfiniBand)
InfiniBand není Ethernet — v síti se nic nesměruje, dokud subnet manager (SM) nepřidělí LID. V laboratorní síti stačí na jednom uzlu spustit sudo apt install opensm && sudo systemctl enable --now opensm. V produkci používejte vestavěný SM na switchi. Dva softwarové SM, které si navzájem konkurují, znamenají odpoledne ladění, které nikdo nepotřebuje. RoCE žádný SM nemá — směrování je úkolem ethernetové sítě, a proto se konfigurace RoCE točí hlavně kolem QoS na switchi, nikoli kolem hostitele.
Ověřte, že RDMA skutečně funguje: perftest
Ještě před jakýmkoli během NCCL nebo frameworku prověřte samotné vedení nástrojem perftest. Dva uzly, nejprve server:
# server (node A) # client (node B)
ib_send_bw -d mlx5_0 -F --report_gbits -D 10
ib_send_bw -d mlx5_0 -F --report_gbits -D 10 10.10.1.1
Očekávané hodnoty na čisté síti:
| Linka |
ib_send_bw (velké zprávy) |
ib_send_lat (2 bajty) |
|---|---|---|
| 100 Gb/s EDR / 100 GbE RoCE | 95–98 Gb/s | 1.0–1.5 µs |
| 200 Gb/s HDR / 200 GbE RoCE | 188–197 Gb/s | 0.9–1.3 µs |
| 400 Gb/s NDR | 370–395 Gb/s | 0.8–1.1 µs |
Jste-li o 20 % pod těmito hodnotami, nezačínejte ladit NCCL. Chyba je v síti. Kontrolujte v tomto pořadí: (1) MTU, (2) PFC u RoCE, (3) dvojici kabel/transceiver, (4) generaci PCIe a počet linek pro síťovou kartu, (5) umístění v rámci NUMA. Latence pod jednu mikrosekundu je u NDR v rámci racku dosažitelná; cokoli nad 5 µs na jednoswitchové síti RoCE je rozbité.
GPUDirect RDMA: zapnutí DMA cesty
Celý smysl RDMA v AI clusteru spočívá v tom, že síťová karta čte a zapisuje přímo do paměti GPU a obchází hostitele. K tomu je potřeba nvidia-peermem (nebo na novějších jádrech DMA-BUF — NVIDIA dnes doporučuje DMA-BUF tam, kde jej jádro podporuje, ale většina produkčních stacků stále dodává peermem).
sudo modprobe nvidia-peermem
lsmod | grep nvidia_peermem
echo nvidia-peermem | sudo tee /etc/modules-load.d/nvidia-peermem.conf
Pokud se modul nepodaří načíst, jádro nebylo sestaveno proti API pro RDMA peer memory se znalostí OFED. Záleží na pořadí instalace: nejprve OFED, pak ovladač NVIDIA a nakonec nvidia-peermem — peermem se při instalaci sestavuje proti hlavičkám OFED.
Celou cestu ověřte zápisem RDMA mezi dvěma GPU:
# server # client
ib_write_bw -d mlx5_0 --use_cuda=0 -F --report_gbits -D 10
ib_write_bw -d mlx5_0 --use_cuda=0 -F --report_gbits -D 10 10.10.1.1
--use_cuda=0 registruje paměť CUDA na GPU 0 jako RDMA buffer. Pokud se výsledek pohybuje v řádu jednotek procent od varianty s hostitelskou pamětí, GPUDirect funguje. Je-li 5× pomalejší, přenos se odehrává přes hostitelskou paměť — obvykle jde o problém s načtením peermem nebo o topologii PCIe, kde karta a GPU leží na opačných uzlech NUMA.
MTU a PFC pro RoCE (právě na tom clustery s RoCE stojí a padají)
RoCEv2 nad bezeztrátovou ethernetovou sítí vyžaduje souhru tří věcí:
- Velké MTU po celé trase. Nastavte 9000 na každé síťové kartě, portu switche i na každém směrovači. RoCE volí největší MTU ve stylu IB, které se vejde do ethernetového MTU — 9000 na Ethernetu dává RoCE MTU 4096 bajtů, a přesně to chcete.
- PFC na prioritě vyhrazené pro RDMA. Pozastavení na linkové vrstvě, které zabrání zahazování paketů ve vybrané třídě provozu. Běžná praxe: RDMA na prioritě 3, vše ostatní na prioritě 0.
- Značkování ECN na switchích a síťových kartách. ECN je dlouhodobý signál zahlcení, PFC krátkodobá záchranná brzda. Většinu práce odvede ECN; PFC se spustí jen tehdy, když ECN nestíhá.
Na straně hostitele pomocí mlnx_qos:
sudo mlnx_qos -i enp1s0f0 --pfc 0,0,0,1,0,0,0,0 # PFC on prio 3
sudo mlnx_qos -i enp1s0f0 --trust dscp
echo 106 | sudo tee /sys/class/infiniband/mlx5_0/tc/1/traffic_class
Hodnota DSCP (26) a priorita PFC (3) se musí shodovat na každém skoku. Síť switchů to musí zrcadlit: zapnuté PFC na prioritě 3, značkování ECN na těchto frontách, bezeztrátová konfigurace bufferů a rezerva na každém portu dimenzovaná na BDP nejdelší linky.
Nákup switche od výrobce s dokumentovanými šablonami pro RoCE (NVIDIA Spectrum, Arista, Cisco Nexus 9000) vám ušetří týden. Ruční konfigurace PFC na obecném whiteboxu s čipem Broadcom je proveditelná, ale je to samostatný projekt. Dělali jsme to. Nedoporučujeme to.
DCQCN (Data Center Quantized Congestion Notification) je regulační smyčka, která PFC a ECN spojuje: ECN označí pakety ve chvíli, kdy se plní fronta, příjemce odešle zpět CNP, odesílatel zpomalí a po vyprázdnění fronty opět zrychlí. PFC je záloha pro případ, že DCQCN nestihne zareagovat. Na moderním firmwaru ConnectX-6/7 je ve výchozím stavu zapnuté a při 4 až 16 uzlech výchozí hodnoty bohatě stačí. Ladění (alpha, cílová rychlost, prahy v bajtech a časovačích) je hrou pro ty, kdo provozují takové měřítko, kde 0,5 % u operace allreduce stojí za dva týdny práce.
NCCL: proměnné, na kterých záleží
NCCL je vrstva, která RDMA využívá pro PyTorch, JAX, DeepSpeed, tenzorově paralelní vLLM a podobné nástroje. Detekuje se automaticky, většinou správně. V každém produkčním spouštěcím skriptu se objeví čtyři proměnné prostředí:
| Proměnná | Co dělá | Kdy ji nastavit |
|---|---|---|
NCCL_IB_DISABLE |
1 vynutí TCP sokety místo IB/RoCE |
Pouze při ladění |
NCCL_SOCKET_IFNAME |
Rozhraní pro bootstrap NCCL (nikoli pro datovou cestu) | Vždy — nasměrujte ji na management kartu, aby se bootstrap nepral o RDMA síť |
NCCL_IB_HCA |
Které HCA používá NCCL pro datovou rovinu | Uzly s více síťovými kartami — explicitní nastavení poráží automatiku |
NCCL_NET_GDR_LEVEL |
Jak agresivně využívat GPUDirect RDMA podle topologie PCIe |
PIX/PHB tam, kde GPU a síťové karty sdílejí PCIe switch nebo uzel NUMA |
Funkční spuštění na clusteru se čtyřmi uzly a čtyřmi GPU na uzel:
export NCCL_SOCKET_IFNAME=eno1 # 1 GbE management network
export NCCL_IB_HCA=mlx5_0,mlx5_1 # both RDMA NICs
export NCCL_IB_GID_INDEX=3 # RoCE v2 GID
export NCCL_NET_GDR_LEVEL=PHB
export NCCL_DEBUG=INFO # one-shot, then drop to WARN
mpirun -np 16 -N 4 --hostfile hosts -x NCCL_SOCKET_IFNAME \
-x NCCL_IB_HCA -x NCCL_IB_GID_INDEX -x NCCL_NET_GDR_LEVEL \
-x NCCL_DEBUG ./build/all_reduce_perf -b 8 -e 8G -f 2 -g 1
Výstup NCCL_DEBUG=INFO je při prvním běhu povinná četba. Řekne vám, jaký transport NCCL zvolilo (Channel ... via NET/IB/0 GDR) pro každý rank a každý kanál. Pokud se kdekoli objeví via NET/Socket, cesta přes RDMA se nepoužívá — netestovali jste to, co si myslíte.
Validace nástrojem nccl-tests
nccl-tests ověřují celý stack — ovladač, OFED, peermem, NCCL i síť — od začátku do konce. Číslo, na kterém záleží, je propustnost sběrnice (busbw), nikoli propustnost algoritmu (algbw). Propustnost sběrnice je normalizovaná na velikost kruhu či stromu a právě ji porovnáváte s rychlostí linky síťové karty.
| Velikost clusteru | Očekávaná busbw u allreduce (velké zprávy) |
|---|---|
| 1 uzel, 4 GPU přes NVLink | 200–400 GB/s |
| 1 uzel, 8 GPU přes NVLink | 250–500 GB/s |
| 2 uzly, po 4 GPU, 200 GbE RDMA | 20–24 GB/s |
| 4 uzly, po 4 GPU, 200 GbE RDMA + GDR | 20–22 GB/s |
Allreduce mezi uzly je stropem omezen zhruba na polovinu linkové rychlosti karty (allreduce každý bajt jednou odešle a jednou přijme na každý rank). 200 Gb/s ≈ strop 25 GB/s; naměřených 22 GB/s je zdravá hodnota. Pokud hodnota při přechodu z jednoho uzlu na dva klesne 5×, pro přenos mezi uzly se RDMA nepoužívá. Přečtěte si výstup NCCL_DEBUG=INFO.
A teď o patro výš: návrh uplinku clusteru
Všechno výše se týká datové roviny — sítě, přes kterou spolu GPU komunikují. Druhou polovinou použitelného clusteru je uplink: způsob, jakým se tato síť připojuje k okolnímu světu. Špatně navržený uplink potkáváme neustále.
Čtyřuzlový tréninkový cluster Kentino AI má tři vazby na okolí:
- Firemní síť / WAN — registry modelů, úložiště datasetů (S3, NFS, MinIO), Git, registry kontejnerů, telemetrie.
- Workstationy vývojářů — inženýři se připojují přes SSH, spouštějí úlohy, kopírují checkpointy ven, provozují Jupyter.
- Další clustery — druhý tréninkový cluster, inferenční cluster, cluster pro CI a evaluace.
Výpočet propustnosti
Pokud 4 uzly provádějí allreduce rychlostí zhruba 22 GB/s každý, přenese interní síť v souhrnu asi 700 Gb/s provozu mezi uzly. Samotný uplink tomu odpovídat nemusí. Musí odpovídat rychlosti načítání dat:
- 4 uzly × 4 GPU × zhruba 1 GB/s na GPU (obrazový či video model) = 16 GB/s ≈ 128 Gb/s trvalého čtení z objektového úložiště.
- Předtrénování LLM nad tokenizovaným textem je mnohem skromnější — 1–4 Gb/s, protože tokeny jsou husté a jedna dávka vydrží dlouho.
- Doladění, které často znovu načítá checkpointy, vyskočí na pár sekund na 40 Gb/s a pak spadne téměř na nulu.
| Workload | Trvalé načítání | Špička | Uplink |
|---|---|---|---|
| Předtrénování LLM (tokenizovaný text) | 1–4 Gb/s | 20 Gb/s | 25 GbE |
| Trénink obrazových a video modelů | 50–150 Gb/s | 200 Gb/s | 2× 100 GbE v LAG nebo 1× 200 GbE |
| Doladění / RLHF s přehazováním checkpointů | 5–20 Gb/s | 50 Gb/s | 25–100 GbE |
| Inferenční cluster za load balancerem | 5–50 Gb/s | závisí na modelu | 25–100 GbE |
Častá chyba: utratit 40 000 € za uplink 400 GbE jen proto, že interní síť má 400 GbE. Špatné měřítko. Správným měřítkem je rychlost čtení datasetu. Postavili jsme čtyřuzlové clustery s uplinkem 25 GbE, které týdny jely naplno na tokenizovaných datech pro LLM.
Souhrnná versus přidělená propustnost
Uzel se čtyřmi kartami 100 GbE má souhrnnou kapacitu linek 400 Gb/s. Tato kapacita se ale přiděluje po tocích, nesdílí se v jednom fondu. Jediné TCP spojení mezi dvěma IP adresami využije jednu kartu — tedy nejvýše 100 Gb/s. ECMP a hashování po tocích rozprostírají mezi čtyři karty různé toky.
-
Allreduce představuje mnoho paralelních toků — jeden na kanál a protistranu. NCCL je nativně rozkládá na více karet (
NCCL_IB_HCAs oběma uvedenými). Pro NCCL se 4× 100 GbE prakticky blíží 400 Gb/s. - Jediný datový proud datasetu (jeden HTTP GET stahující 1TB shard) je jeden tok. 4× 100 GbE mu dá 100 Gb/s, nikoli 400. Aby se využil souhrn, musí dataloader otevřít paralelní proudy — což DALI, WebDataset i Streaming od MosaicML dělají už z principu.
Oddělení sítí
- 100/200/400 GbE RoCE nebo InfiniBand HDR/NDR
- NCCL, čtení datasetů, zápisy checkpointů
- Bezeztrátová, PFC/ECN, vyhrazené switche
- Sterilní — žádný provoz mimo AI
- 1 GbE nebo 10 GbE
- SSH, Prometheus, NTP, syslog, IPMI/BMC
- Levné switche, standardní L2/L3, žádné zvláštní QoS
- Funguje vždy, i když datová síť leží
Provozujte vždy dvě sítě. Management rovina nesmí být ve své funkci závislá na datové rovině — přístup přes SSH potřebujete právě ve chvíli, kdy je RDMA síť rozbitá.
Management rovina není volitelná. Když datová síť selže — vadný transceiver, špatně nastavené PFC, pád switche — potřebujete cestu přes SSH, která na rozbité síti nezávisí. Ladit bouři v RoCE přes linku, která právě bouří, je chyba, kterou uděláte přesně jednou. Patří sem i IPMI/BMC a NTP; rozjetí hodin je neviditelné do chvíle, než váš distribuovaný framework začne počítat špatné gradienty.
BGP unnumbered pro směrovanou Clos topologii
Nad zhruba 8 uzly začíná být leaf-spine na L2 bolestivý — limity spanning tree, škálování MAC tabulek, broadcastové bouře a žádné nativní multi-path. Moderní odpovědí je směrovaná Clos topologie na L3: každá linka leaf–spine je unnumbered, BGP nese trasy a ECMP rozprostírá toky přes spine prvky.
BGP unnumbered navazuje relace přes link-local adresy IPv6, které jádro přiděluje samo, takže evidenci sítí /31 pro každou linku zcela odpadá. Leaf s FRRouting na Linuxu vypadá zhruba takto:
router bgp 65001
neighbor swp1 interface remote-as external
neighbor swp2 interface remote-as external
address-family ipv4 unicast
network 10.1.1.0/24
redistribute connected
Každý leaf i každý spine je vlastní AS, eBGP inzeruje loopbacky a ECMP přes spine prvky je zadarmo. Vzor popisuje RFC 7938; unnumbered BGP dnes podporují Cumulus/NVIDIA, Arista, Cisco i Juniper. U 4 uzlů stačí jediný switch. U 8 až 16 uzlů se dvěma spine prvky se směrovaná Clos topologie začíná vyplácet. Nad 16 uzlů je jedinou rozumnou odpovědí.
Propojení s dalšími clustery
Nedávejte tréninkový a inferenční cluster na tutéž RDMA síť. Trénink znamená obrovské nárazové operace allreduce, inference ustálený tok malých zpráv; požadavky na QoS se rozcházejí a nevydařený tréninkový běh inferenční cestu vyhladoví. Správnou odpovědí jsou dvě oddělené sítě, které se potkávají na L3 směrovači s běžným IP routingem. Řídicí provoz mezi clustery — fronty úloh, odesílání logů, přenos artefaktů — jede po management rovině nebo po vyhrazené ethernetové lince mezi clustery. Soubor s vahami modelu o 70B parametrech má zhruba 140 GB, checkpoint dvojnásobek. Při 25 GbE to trvá asi 90 sekund, při 100 GbE asi 22 sekund. Počítejte s tou větší variantou.
Co dělat dál
Rozumný postup při zprovoznění RDMA na novém clusteru:
-
Nejprve vše zapojte a zkontrolujte linkovou vrstvu. Spusťte
ibstatna každém uzlu. Stejná rychlost, stejné MTU, stejná linková vrstva. Fyzickou vrstvu dejte do pořádku dřív, než sáhnete na software. -
Nainstalujte MLNX_OFED, nejen
rdma-core, pokud je ve hře GPUDirect nebo NCCL. Sestavení OFED musí odpovídat běžícímu jádru. -
Spusťte
perftestmezi každou dvojicí uzlů ještě předtím, než sáhnete na frameworky. Hodnoty do 5 % od teoretického maxima = zdravý stav. Cokoli pod tím = zastavte a opravte. -
Načtěte
nvidia-peermema ověřte jej pomocíib_write_bw --use_cuda=0. Výsledek by měl odpovídat variantě s hostitelskou pamětí. - Nakonfigurujte PFC, ECN a DCQCN, pokud jste na RoCE. Na InfiniBandu tento krok vůbec neexistuje; to je polovina důvodu, proč lidé volí IB.
-
Spusťte
nccl-testsallreduce na 2 uzlech, pak na 4 a pak na 8. Při prvním běhu každé velikosti clusteru si projděte výstupNCCL_DEBUG=INFO. Ověřte, že se objevíNET/IB ... GDR. - Oddělte sítě. Management na levném 1/10 GbE. Data na RDMA síti. Nesdílejte je.
- Uplink dimenzujte podle rychlosti načítání datasetu, nikoli podle rychlosti interní sítě. Většina clusterů potřebuje podstatně méně externí propustnosti, než má.
- Nad 8 uzlů plánujte směrovanou Clos topologii s BGP unnumbered. Pod 8 uzly stačí jediný switch.
Navazující články v řadě N rozebírají latenci (N06) a složitost směrování (N07) — právě tam najdete ladění DCQCN a patologie hashování v ECMP. Řada K navazuje distribuovaným tréninkem (K02), inferenčními clustery (K03) a úložišti (K04) — a všechny předpokládají, že RDMA stack popsaný na této stránce už funguje.
Toto je součást Kentino Wiki, referenční série o výpočetním výkonu pro AI a o systémech, které jej propojují. Opravy uvítáme na info@kentino.com.