Lagring til AI-klynger: NFS, BeeGFS, Lustre og spørgsmålet om objektlagring

Delt lagring er den del af en distribueret træningsklynge, som ingen tænker over, før det bliver årsagen til, at GPU'erne har en udnyttelsesgrad på 40 %. På det tidspunkt er det smertefuldt at udskifte den – hvert træningsscript har indbyggede antagelser, hvert checkpoint er i et format, der måske eller måske ikke migrerer problemfrit, og klyngen er i produktion. Det rette tidspunkt at beslutte sig for lagring er, før den anden træningsnode er i rack.

Dette er lagerdelen af ​​K-serien. Det er en køber-og-arkitekt-visning, ikke en systemadministrator-gennemgang – målet er at foretage valget mellem NFS, BeeGFS, Lustre og objektlagre med åbne øjne og at være ærlig om, hvilken de fleste Kentino-kunder rent faktisk har brug for.

Hvorfor delt lagring er den stille flaskehals

En enkeltnode-træner læser sit datasæt fra lokal NVMe og skriver checkpoints til samme sted. Intet at diskutere. I det øjeblik en anden node tilslutter sig, ændrer to ting sig:

  1. Hver node læser det samme datasæt. Bytesene er identiske på hver worker og skal være synlige fra hver node.
  2. Hver node skriver checkpoints, og foreningen skal overleve. Med FSDP eller DeepSpeed ​​sharding skriver hver rank sit eget slice; med DDP skriver ranks redundant. Uanset hvad ser filsystemet en række store skrivninger med få minutters eller få timers mellemrum.

Disse adgangsmønstre er modsatte. Adgang til datasæt er vedvarende, sekventiel, læsetung og latenstolerant. Checkpoint-adgang er bursty, store blokke, skrivetung og kræver træningsblokke. Et lagringssystem, der er godt til det ene, er ofte middelmådigt til det andet.

Derudover gør moderne ML-datasæt en tredje ting: metadatastormeEt datasæt på 50 millioner 4-12 KB JPEG'er er, set fra filsystemets perspektiv, 50 millioner åbne/stat/læse/lukke-cyklusser. Metadataserveren, ikke datastien, falder først. Derfor er "vi har masser af båndbredde" ikke et tilstrækkeligt svar.

arbejdsbyrde Mønster Hvad den har brug for
Datasæt blandet/læst Vedvarende sekventielle aflæsninger, TB-skala Samlet læsebåndbredde
Lille fildatasæt Tilfældige metadata + læsning af små filer Metadata-IOPS, lav driftslatens
Skrivning af kontrolpunkt Storsprængninger i store mængder, alle noder på én gang Burst-skrivebåndbredde, ingen head-of-line
Indlæsning af inferensmodel Stor aflæsning i én omgang ved opstart Tolerant overfor alt rimeligt

NFS — standarden, og den varer længere end du tror

NFS (NFSv3 eller v4) er den mindste modstands vej. Alle Linux-distributioner leverer det, alle schedulere forstår det, og en "storage node" er bare en Linux-boks med en masse disk, en /etc/exports linje og et hurtigt NIC.

Hvad en fornuftigt bygget NFS-server giver dig:

  • Et navnerum monteret identisk på hver beregningsnode.
  • Anstændig sekventiel læsehastighed, især med nconnect på moderne kerner (multipleksing af én montering over flere TCP-forbindelser — single-stream-loftet har været væk i årevis).
  • Driftsmæssigt kedeligt. Fejl er velforståede, og gendannelsesprocedurer findes i alle sysadmin-bøger, der nogensinde er skrevet.

Hvad du giver afkald på:

  • Én server, én flaskehals. Den samlede klyngekapacitet er begrænset til det, som den ene boks betjener.
  • Låsning og serialisering af metadata. Arbejdsbelastninger med små filer rammer metadatagrænser før båndbreddegrænser.
  • Ingen yndefuld udskalering. Når kassen er fuld, bygger du en anden med et andet monteringspunkt, og dine scripts lærer om det.

Det urimelige ry, som NFS har i HPC-kredse, handler primært om det gamle loft over enkeltforbindelser og metadataproblemer på bittesmå filer. Til træning af datasæt i størrelsesordenen 100 GB til 1-2 TB på 4-8 GPU-noder er en korrekt bygget NFS-server helt fin. Vi har set kunder træne Qwen2.5-VL-finjusteringer på NFS-baserede datasæt uden at klage.

NFS begynder at gøre ondt når:

  • Datasættene overstiger ~2 TB, og blandede filer forårsager cache-thrash på serveren.
  • Mere end ~8-12 computernoder rammer den samme montering under belastning.
  • Ti millioner af små filer dominerer arbejdsbyrden.
  • Størrelsen på kontrolpunkter pr. rang overstiger 50-100 GB, der skrives samtidigt.

Under alle fire tærskler er NFS næsten helt sikkert det rigtige svar, og et parallelt filsystem er overdreven engineering.

BeeGFS — den praktiske middelvej

BeeGFS er det parallelle filsystem, som folk rent faktisk implementerer, når NFS ikke længere er nok. Det opdeler data på tværs af flere lagringsmål (diske på flere servere) og metadatamål (separate NVMe-servere). Klienter ser ét navnerum; læser og skriver Stripe på tværs af storage-mål parallelt.

Hvorfor det optræder i mellemstore klynger:

  • Opsætningen tager dage, ikke uger. En kompetent Linux-ingeniør kan klare en installation med to storage-noder og én MDS på en eftermiddag. Lustre er ikke i den liga.
  • Samlet båndbredde skaleres lineært med lagermål. Tre noder på 100 GbE leverer tæt på 3 gange læsegennemstrømningen af ​​én.
  • Native RDMA på InfiniBand eller RoCE — undgår TCP/IP-overhead.
  • Open source, ingen licensfælde per-TB. Kommerciel support fra ThinkParQ er valgfri.

Hvad den ærligt talt er mindre god til:

  • Metadata for arbejdsbelastninger med meget mange små filer. En enkelt MDS bliver flaskehalsen under fildominans på under 4 KB. Du kan tilføje metadatamål, men arkitekturen er ikke så aggressiv som Lustres DNE.
  • Ingen indbygget lagdeling. Styr selv varmt/koldt.
  • HA er boltet på, ikke native. Spejling fungerer, men er ikke så gennemsigtig som Lustres failover.

Sødt punkt: 4-32 træningsnoder, 10-100 TB datasæt, filer i området 1 MB til 1 GB. Hvor de fleste Kentino-lande med flere noder bygger.

En baseline BeeGFS-implementering for en Kentino-klasse 4-node klynge:

Component Spec
Lagernode 1 2U, EPYC 24-core, 256 GB RAM, 12× 7.68 TB NVMe, 2× 100 GbE
Lagernode 2 Identisk
Metadata-node 1U, EPYC 16-kernet, 192 GB RAM, 2× 3.84 TB NVMe (RAID-1), 2× 100 GbE
Netværk 100 GbE leaf-spine eller single switch (RoCE-kompatibel)
Klienter 4× K-AI træningsnoder, hver med 1× 100 GbE

Vedvarende samlet læsning i de fire trænere lander typisk i området 30-60 GB/s, nok til at forsyne 32 GPU'er med det meste vision- og LLM-træning. Dette stopper skalering, når metadataserveren mættes – tilføj et andet metadatamål eller begynd at tænke på Lustre.

Glans — guldstandard, ægte kompleksitet

Lustre kører lagringsniveauet for stort set alle top-500 supercomputere, der har brug for POSIX, og skalerer til hundredvis af petabytes og en samlet gennemløbshastighed på flere TB/s. Arkitekturen har tre roller: MGS/MDS (administration + metadata), OSS (objektlagringsservere, der indeholder OST'er) og klienter. Klienter kommunikerer med MDS'en for navneområdeoperationer og kommunikerer derefter direkte med den OSS, der indeholder dataene - datastien omgår metadataserveren fuldstændigt. Denne adskillelse er grunden til, at Lustre skalerer, og DNE (Distributed Namespace) også tillader metadata at skalere horisontalt.

Omkostningerne er operationelle: stejlere indlæringskurve end BeeGFS, strenge kerne-/driverkrav, snesevis af tuning-knapper (standard ydeevne er normalt ikke, hvad hardwaren kan levere), og gendannelsesprocedurer, der kræver en kompetent storage-ingeniør.

Tærsklen, hvor Lustre giver mening, er omtrent 16-32+ træningsnoder eller PB-klasse datasæt. Derunder mætter BeeGFS netværket længe før Lustres arkitektoniske fordele betyder noget. Kentinos udvalg når for det meste ikke tærsklen - vi bygger en Lustre-klynge, hvis vi bliver bedt om det, men vi fortæller dig først, at BeeGFS plus en kraftig MDS får dig 80% af vejen med 20% af den operationelle smerte.

Objektlagring — MinIO og Ceph til ML-datasøer

De parallelle filsystemer ovenfor er korrekte, når frameworket forventer filer. En voksende andel af moderne ML-pipelines gør ikke det — datasæt lever som S3-objekter, dataloaderen henter dem over HTTP, og det lokale filsystem er transient scratch.

MinIO er et S3-kompatibelt objektlager med ét formål. Distribueret tilstand kører på 4-32+ noder med sletningskodning. Open source, operationelt enklere end noget parallelt filsystem og moderne dataindlæsere (PyTorch med fsspec/s3fs, WebDataset, NVIDIA DALI) læser det direkte.

ceph er bredere — blok (RBD), fil (CephFS), objekt (RGW) på det samme RADOS-lag. Ceph vinder, når du ønsker ét lagringssystem til flere arbejdsbelastninger (VM'er, fildelinger, ML-objekter). Det taber på driftsmæssig enkelhed — Ceph er et system, du forpligter dig til, med sin egen overvågning, tuning og on-call-disciplin.

Hvad objektlagring giver dig til ML: billig kapacitet (tætte HDD-noder med erasure-kodning giver €/TB-tal, som flash ikke kan røre), operationelt simpel skalering, sharded by design (ingen metadata-flaskehals) og et godt match til shard-baserede dataloadere. Hvad du giver afkald på: latenstid på titusindvis af ms per-op (ikke mikrosekunder), ingen direkte POSIX (omskriv loaderen eller accepter en FUSE-straf) og ingen in-place-skrivninger (objekter er uforanderlige - fint til checkpoints, dårligt til alt, der muterer).

Arkitekturen der fungerer i praksis: objektlagring som den holdbare, store og billige datasø; et parallelt eller NFS-filsystem som det hurtigt fungerende sæt, der er iscenesat til den aktuelle kørsel. Datasættet findes i MinIO. Et job overfører relevante shards til BeeGFS eller lokal NVMe fra bunden ved start. De endelige kontrolpunkter sendes tilbage til MinIO til arkivering.

WekaIO og VAST — virksomhedsniveauet (kort fortalt)

WekaIO og VAST Data er det specialbyggede, prisvenlige svar til virksomheder: ekstremt små metadatafiler, meget høj samlet båndbredde, native S3 og POSIX, integreret tiering, GPU-direkte stier. Disse giver fremragende mening for 100+ GPU-klynger, hvor lagerplads skal holde trit med GPU-udgifterne. De er ikke det rigtige valg til en 4-GPU eller 8-GPU server, eller en klynge på fire sådanne - lageromkostningerne ville dominere build'et. Nævnt her for ærlighedens skyld om den høje ende, ikke som en anbefaling til den køber, som denne serie er skrevet til.

Adgangsmønstre for datasæt og hvorfor de er vigtige

To mønstre dominerer ML-træning. Mønster A — store skår: Datasæt præpakket i WebDataset tarballs, parquet eller LMDB, 100 MB til 10 GB pr. shard, læst sekventielt og blandet indeni. Alle lagringssystemer er gode til dette. Mønster B — mange små filer: millioner af JPEG'er/PNG'er/JSON'er, én pr. sample, der hamrer metadatastien. Dette straffer NFS, skader BeeGFS i stor skala, og det er derfor, Weka og VAST eksisterer.

Den enkeltstående beslutning med den højeste gearing i træningslagring er at flytte mønster B til mønster A. Hvis dit datasæt er små filer, skal du pakke det om til shards før træning. Omkostningerne er én forbehandlingsproces; fordelen er, at ethvert lagringssystem bliver tilstrækkeligt. Vi har set pipelines øge hastigheden med 3-5 gange uden ændring af lagringshardware, blot ved at pakke om.

Hvis du ikke kan genpakke – datasættet ændrer sig konstant, kræver frameworket virkelig filer pr. sample – så skal lagringspladsen være omkring metadata-IOPS, ikke båndbredde. Det skubber dig i retning af BeeGFS med flere MDS-mål, Weka/VAST eller Lustre med DNE.

Checkpoint-strategi — skriv hurtigt, skriv senere, skriv mindre

Checkpoint-skrivninger er det værst tænkelige mønster: hver rang skriver samtidigt, skrivningerne er store, træningsblokke er holdbare. Et naivt synkront checkpoint på en 100 B parametermodel kan stoppe træningen i ti minutter.

Nuværende bedste praksis er en tretrinsmetode, der er indbygget i PyTorchs torch.distributed.checkpoint (DCP), NVIDIA NeMo og de fleste moderne frameworks:

  1. Hver rang skriver sin shard til den lokale NVMe-database. Den samlede klyngeskrivebåndbredde er summen af ​​NVMe-hastigheder pr. node (5-50 GB/s hver). Træning ophæver blokeringer inden for få sekunder.
  2. En asynkron baggrundsproces kopierer til delt lager. Træningen er nu genoptaget.
  3. Ældre kontrolpunkter beskæres eller flyttes til objektlager efter en tidsplan. Behold de sidste 2-3 på hurtig lagring, resten på MinIO/Ceph.

Implikationen: Delt lagring behøver ikke at absorbere alle kontrolpunkter med fuld hastighed. Den skal indtage den asynkrone kopi uden at falde bagud i forhold til kadencen. For en 70 B-model med kontrolposter hvert 30. minut er vedvarende skrivning på et lavt encifret GB/s tilstrækkeligt – inden for et kompetent BeeGFS- eller en god NFS-server.

Fejlen man skal undgå: synkrone, ikke-shardede kontrolpunkter skrevet direkte til NFS. Det var normalt i 2022. Det er det ikke længere. Hvis din pipeline gør dette, er det mere fordelagtigt at rette checkpoint-koden end at opgradere lagerpladsen.

Spørgsmålet om klynge-uplink

Deler lagertrafikken strukturen med træning, eller får den en separat?

Delt stof
En 100/200 GbE eller IB har både all-reduce og storage. Billigere, enklere. Risiko: checkpoint burst kan konkurrere med NCCL og stall-træning.
Splitstof
To NIC'er pr. node — en til computerstrukturen (IB), en til lagringsstrukturen (Ethernet). Uafhængige overbelastningsdomæner. ~2× netværksudstyret.

Delt fabric er fint til klynger med 4-8 noder med asynkron checkpointing; delt fabric er berettiget over 8 noder eller tung synkron I/O.

For Kentino-klasse 4-8 node-klynger er delt fabric fint, når asynkron checkpointing er i brug, og lagerbelastningen primært består af læsning - vedvarende læsning sameksisterer med NCCL-kollektiver uden alvorlig skade. Split fabric er berettiget til stor LLM-træning med FSDP ved høj TP/PP-grad, tung synkron lagertrafik eller når budgettet tillader det. Den praktiske standard: delt 100 GbE op til 8 noder med et lager-VLAN som blød isolation.

Ærlige anbefalinger efter skala

Scale datasæt Lagerniveau Noter
1 node Enhver Lokal NVMe Spring delt lagerplads helt over.
2–3 træningsnoder < 1 TB NFS på en kraftig lagernode nconnect, rigelig RAM til sidecache.
4–8 træningsnoder 1–10 TB NFS eller første BeeGFS-implementering BeeGFS hvis datasættet har en lille filtung størrelse.
4–16 træningsnoder 10–100 TB BeeGFS, 2-3 lagringsmål, dedikeret MDS Perfekt punkt. Tilføj MinIO til kold arkivering.
16–32+ træningsnoder 100 TB–1 PB BeeGFS presset hårdt, eller Luster Beslutningspunkt for glans.
32+ noder, PB-skala, 24/7 PB+ Lustre eller Weka/VAST hvis budgettet tillader det Forbi den typiske Kentino-bygning.
Stor datasø, episodisk træning PB+ kold MinIO/Ceph, fase til hurtigniveau pr. job "Masser af data, lejlighedsvis træning."

De fleste Kentino-kunder lander i række to og tre. Vi bygger resten, hvis du bliver bedt om det, men vi fortæller dig, når det er overspecificeret.

Hvad går i stykker

Fejltilstande vi har set, sorteret efter hvor ofte de bider:

  • Metadatamangel under indlæsning af små filer. Symptom: GPU'er på 30-50%, netværksinaktiv, lagrings-CPU inaktiv, hver open() langsom. Rettelse: ompak til shards, eller skaler MDS-mål.
  • Synkrone kontrolpunkter sætter træningen i stå. Rettelse: asynkrone shardede checkpoints (PyTorch DCP eller NeMo).
  • En langsom disk tanker klyngen. En SSD, der ikke fungerer, fejler ikke helt – den bliver bare langsom. Rettelse: overvåg latenstid pr. enhed, alarm ved > 2× baseline.
  • Sidecache-thrash på lagernoden. Datasættet passer ikke i RAM'en, hver epoch fjerner den forrige. Rettelse: mere RAM.
  • nconnect ikke aktiveret på NFS-klienter. Standard NFS for enkeltstreamsgrænser ligger langt under NIC-linjehastigheden. nconnect=8 or =16 giver 4–8× gennemløb på den samme hardware.
  • MinIO i skala uden EC-tuning. Standardværdier prioriterer holdbarhed frem for latenstid; latenstid for små objekter lider. Accepter ikke standardværdier blindt.

Ingen af ​​disse er eksotiske. Alle er forudsigelige, når de først er set én gang.

Hvad skal jeg gøre næste

Hvis du specificerer lagerplads til en ny eller voksende træningsklynge, skal du besvare disse, før du underskriver for hardware:

  1. Datasætform — store shards eller mange små filer? Den største enkeltstående faktor for, hvilket opbevaringssystem der passer.
  2. Aktivt arbejdssæt, ikke datasøstørrelse. Lagringsbudgettet går til arbejdssættet; søen lever af billigere og langsommere objektlagring.
  3. Kontrolpunktskadence, størrelse, tolerance for stalls. Størrelser angiver burst-skrivekapacitet og fortæller dig, om asynkrone sharded-kontrolpunkter er obligatoriske (normalt over ~13 B-parametre, ja).
  4. Træningsnoder i dag og realistisk 12-måneders prognose. Hvis du skal bruge 4 noder i et år, så byg til 4 noder. Køb ikke Lustre på forhånd.
  5. Opbevaring på træningsstof eller delt? Beslut dig før du trækker kabler, ikke bagefter.
  6. Plan for koldt arkiv. Modeller, datasætversioner, artefakter fra gennemførte kørsel – disse hører til et billigt sted. MinIO eller Ceph er normalt svaret.

Lagerplads belønner fremsynethed mere end næsten nogen anden del af en AI-klynge, fordi omkostningerne ved at gøre det forkert betales ved hver træningskørsel i systemets levetid. Det ærlige mål er ikke "den hurtigste lagerplads, vi kan købe" - det er "den enkleste lagerplads, der ikke flaskehalser de GPU'er, vi allerede har", og for de fleste Kentino-skala builds er det meget mindre eksotisk, end leverandørens markedsføring antyder.

Tilstødende artikler: K01 (enkeltnode vs. flernode) K02 (distribueret træningsmekanik), K03 (inferensklynger), N08 (RDMA + klynge-uplink), W06 (lagerniveauer inden for en enkelt server).


Dette er en del af Kentino Wiki, en referenceserie om AI-beregning, robotteknologi og de systemer, der forbinder dem. Kommentarer og rettelser er velkomne på info@kentino.com.