Volba souborového systému pro AI servery: XFS, ZFS, ext4 a proč tu Btrfs chybí
Pokud jste právě utratili €40k za GPU, zaslouží si souborový systém, do kterého svá data nalijete, víc než pět minut přemýšlení. Instalátor Ubuntu vesele rozprostře ext4 přes všechno; pro řadu AI workloadů je to správná odpověď, pro některé není. Zvolte pro 50TB datový svazek špatný souborový systém a přijdete o propustnost, o data, nebo budete sledovat, jak váš DataLoader zahálí za metadatovým úzkým hrdlem.
Tento text řeší, který souborový systém kam nasadit na AI serveru třídy Kentino (4–8 GPU, NVMe boot, NVMe scratch, pomalejší kapacitní vrstva). Ubuntu 22.04 / 24.04, jádro řady 6.x.
Krátká verze
| Přípojný bod | Workload | Souborový systém | Proč |
|---|---|---|---|
/ (boot, root) |
OS, balíčky, logy | ext4 | Nudný, prověřený, obnovitelný |
/scratch (NVMe RAID0) |
Aktivní trénovací shardy, dočasné zápisy | XFS | Propustnost, paralelní I/O v adresářích |
/data (RAID10) |
Trénovací datasety, checkpointy modelů | XFS nebo ZFS | XFS pro čistou rychlost; ZFS, když chcete snapshoty + kontrolní součty |
/archive (RAID-Z2/6) |
Dokončené běhy, studené uložení datasetů | ZFS | Komprese, kontrolní součty, snapshoty |
/home |
Domovské adresáře, notebooky | ext4 | Malé soubory, nízká souběžnost |
Jednou větou: ext4 pro OS, XFS pro horký scratch, ZFS tam, kde je integrita důležitější než posledních 10 % propustnosti, a žádný Btrfs v produkci.
ext4 — nudná výchozí volba, která je obvykle správná
ext4 je už přes deset let výchozí volbou na Ubuntu, Debianu, Fedoře i RHEL. Dobře popsaný, obnovitelný pomocí fsck, 16 TB na soubor, 1 EB na svazek. Nic vzrušujícího — a to je právě ono.
Použijte ext4 pro root (každé živé Ubuntu USB ho umí opravit; zdaleka ne každé umí importovat zpool), pro /home a pro úložiště obrazů VM v malém až středním měřítku.
Kde ext4 přestává být správnou volbou: široké paralelní I/O (jeho žurnál serializuje aktualizace metadat — dvacet workerů DataLoaderu nad jedním ext4 svazkem narazí na žurnál dávno předtím, než nasytí NVMe); jednotlivé obří soubory (zvládne je, ale alokace extentů je pro sekvenční soubory >100 GB méně přívětivá než u XFS — trénovací shardy, checkpointy, videokorpusy); snapshoty (nativně žádné; tenké snapshoty LVM fungují, ale jsou nemotorné).
mkfs.ext4 -L root /dev/nvme0n1p2
Pokud se přistihnete při exotickém ladění ext4 kvůli AI workloadu, vybrali jste špatný souborový systém.
XFS — správná odpověď pro horký scratch a trénovací data
XFS vznikl v SGI jako souborový systém pro vysokopropustné sekvenční I/O nad velkými poli. Tento rodokmen sedí AI workloadům téměř dokonale: velké soubory (trénovací shardy, parquet, webdataset tary, checkpointy), sekvenční čtení, mnoho paralelních čtenářů a tolerance k tomu, že „workload si data vygeneruje znovu“.
Co XFS umí a ext4 ne: alokační skupiny — svazek se dělí na 4–32 nezávislých skupin, které čtou a zapisují paralelně bez globálního zámku žurnálu, přesně jak to potřebuje vícevláknový DataLoader; odloženou a spekulativní předalokaci díky níž velké sekvenční zápisy dostanou souvislé extenty; žádný praktický limit velikosti souboru (8 EB); a xfs_growfs pro spolehlivé rozšíření jedním příkazem po zvětšení RAID pole.
Co neumí: žádné nativní snapshoty, žádné kontrolní součty dat souborů (metadata chrání CRC od roku 2014), žádné zmenšení — jen růst.
Rozumný mkfs.xfs pro scratch svazek z 8× NVMe v RAID0 s chunkem 64 KiB:
# su = stripe unit = velikost chunku; sw = počet datových disků
mkfs.xfs -f -d su=64k,sw=8 -l size=512m -L scratch /dev/md0
# largeio + swalloc: chování pro I/O >1 MB
# allocsize=1g: agresivní předalokace pro velké sekvenční zápisy
# noatime: ušetří jeden zápis na každé čtení při silné zátěži DataLoaderu
mount -o noatime,largeio,swalloc,allocsize=1g /dev/md0 /scratch
noatime a largeio jsou nejdůležitější. XFS na malých souborech je přijatelný, ale není to jeho silná stránka — u stovek milionů obrázků <16 KB raději přebalte do webdataset / parquet / lmdb, než abyste měnili souborový systém (viz níže).
ZFS — správná odpověď, když jde o integritu, snapshoty nebo kompresi
ZFS je souborový systém, správce svazků a softwarová RAID vrstva v jednom:
- Kontrolní součty od konce ke konci. Bit rot se odhalí při čtení a s redundancí se tiše opraví. U 50TB datasetu na rotačních discích po dva roky na tom záleží; u dočasného NVMe scratche na šest týdnů ne.
- Snapshoty a klony. Atomické, COW, prakticky zdarma. Snapshot před během, odbočka v podobě klonu, návrat zpět — přesně ten workflow, kvůli kterému ZFS existuje.
-
Vestavěná komprese.
lz4je zapnutý ve výchozím stavu;zstddává lepší poměry. U textu / JSONu / parquetu komprese obvykle efektivní propustnost zvyšuje, protože náklad na CPU je menší než ušetřené I/O. - ARC — vlastní čtecí cache v RAM, oddělená od linuxové page cache. Proslulá past.
- Nativní RAID-Z — bez mdadm.
V čem je pro AI slabý: žere RAM (výchozí ARC je ~50 % systémové paměti — na serveru s 512 GB jde o 256 GB, které najednou jádru chybí, a trénovací úlohy počítající s page cache nebo huge pages skončí na OOM; ARC omezte); není nejrychlejší v čistém sekvenčním čtení (dobře vyladěný XFS na NVMe RAID0 překonává ZFS o 15–30 % — kontrolní součty a COW stojí reálné takty); ignoruje O_DIRECT (veškeré I/O jde záměrně přes ARC — pro většinu workloadů v pořádku, ale tvrdá nekompatibilita s GPUDirect Storage).
Ladění ARC — jediný knoflík, který musíte nastavit
Na čerstvé instalaci Ubuntu + ZFS na stroji s 512 GB si ZFS vezme 256 GB pro ARC. Nastavte zfs_arc_max už při instalaci, ne až po prvním OOM.
# Omezení ARC na 64 GB. V bajtech, ne v GB. 64 * 1024^3 = 68719476736
echo "options zfs zfs_arc_max=68719476736" | sudo tee /etc/modprobe.d/zfs.conf
echo 68719476736 | sudo tee /sys/module/zfs/parameters/zfs_arc_max # aplikovat ihned
sudo update-initramfs -u # zachovat po restartu
Orientační pravidlo: omezte ARC na 10–20 % systémové RAM na AI serveru. Klasické dimenzování „2 GiB základ + 1 GiB na TiB“ platí pro úložné stroje; na AI stroji je většina RAM rezervovaná pro váhy modelu, aktivace a page cache frameworku.
Rozumné rozložení ZFS pro datovou vrstvu AI serveru
# 8 × 16 TB SAS ve dvou RAID-Z2 vdev (6+2 každý) — dva vdevy dají 2× IOPS
zpool create -o ashift=12 \
-O compression=zstd -O atime=off -O xattr=sa -O recordsize=1M \
data \
raidz2 /dev/sd[a-h] \
raidz2 /dev/sd[i-p]
# Datasety dimenzované podle workloadu
zfs create -o recordsize=1M data/datasets # velké trénovací shardy
zfs create -o recordsize=128k data/checkpoints # smíšená velikost
zfs create -o recordsize=16k data/metadata # malé soubory (json, yaml)
zfs snapshot data/datasets@pre-run-2026-05-14
zfs rollback data/datasets@pre-run-2026-05-14
ashift=12 = bloky 4 KiB — když to při vytváření poolu pokazíte, nespravíte to bez jeho zničení. recordsize=1M pro workloady s velkými soubory (výchozích 128 KiB je pro shardy o velikosti několika GB příliš málo). xattr=sa ukládá xattr inline, což je výrazně rychlejší než výchozí nastavení.
Btrfs — pro produkční AI se mu raději vyhněte
Btrfs má koncepčně stejnou sadu funkcí jako ZFS — COW, snapshoty, kontrolní součty, vestavěný RAID. Na papíře tedy sedí; v praxi ho na serverech Kentino nedoporučujeme. RAID5/6 má známé chyby vedoucí ke ztrátě dat, které sám projekt označuje za nevhodné pro produkci (RAID1/10 jsou stabilní, paritní režimy nikoli); výkon výrazně klesá při fragmentaci, kterou AI workloady vytvářejí (gradientní checkpointy, cache); výkon snapshotů se propadá nad několika stovkami snapshotů, čehož workflow s jedním snapshotem na experiment dosáhne během čtvrtletí; a nástroje pro replikaci, monitoring a plánování scrubů jsou méně vyzrálé než u ZFS nebo XFS. Na notebooku v pohodě. Pro server s více GPU a desítkami TB trénovacích dat zvolte XFS nebo ZFS.
Rozložení RAID — s čím souborový systém párovat
| Úroveň RAID | Použití | Redundance | Poznámky |
|---|---|---|---|
| RAID0 | Scratch (dočasný, znovu vytvořitelný) | Žádná | Jen pro data, která umíte obnovit |
| RAID10 | Trénovací datasety, checkpointy | 1 na zrcadlo | Nejlepší poměr rychlosti a bezpečí pro horká data |
| RAID-Z1 / RAID5 | Pro nové sestavy nedoporučeno | 1 disk | Doby obnovy u disků 16 TB+ dělají ze Z1 riziko |
| RAID-Z2 / RAID6 | Archiv, studené uložení datasetů | 2 disky | Správná volba pro kapacitu |
| RAID-Z3 | Široká pole (12+ disků) | 3 disky | Jen když si to vynutí šířka pole |
U disků 16 TB+ může obnova jednoho disku trvat 24–72 hodin a druhé selhání u disků ze stejné výrobní dávky v tomto okně není zanedbatelné. Jednoduchá parita už není bezpečná výchozí volba. Použijte Z2/RAID6 nebo zrcadla.
Malé soubory versus velké soubory
Otázka, která lidi nachytá častěji než volba souborového systému: jak se váš souborový systém chová při 50 milionech 4KB obrázků ve stromu adresářů? Odpověď pro každý zdejší souborový systém: špatně.
Metadata na soubor (inode, dentry, časová razítka, xattr) zabírají 200–500 bajtů bez ohledu na velikost souboru — 50 milionů drobných souborů spálí 10–25 GB metadat, než uloží jediný bajt obrazových dat. Vzor open/read/close zahltí metadatovou stranu a zastavuje workery DataLoaderu.
Řešením není souborový systém. Neukládejte malé soubory jako soubory. Zabalte je do webdataset / tar / parquet / lmdb / hdf5 / safetensors a streamujte sekvenčně — WebDataset v PyTorchi i NVIDIA DALI to očekávají. Souborový systém pak vidí malý počet velkých souborů, v čemž je každý zdejší systém dobrý. Pokud musíte jednotlivé soubory ve velkém zachovat, nejméně špatnou volbou je ZFS s recordsize=16k a xattr=sa, ale skutečnou odpovědí je přebalení.
Přímé I/O, page cache a O_DIRECT
PyTorch se u opakovaných epoch nad datasetem spoléhá na linuxovou page cache — epocha 1 z disku, epochy 2..N z RAM. Některé workloady používají O_DIRECT k obejití cache u velkých čtení, kde se data dotknete jen jednou. GPUDirect Storage od NVIDIA jde ještě dál a přenáší data přes DMA přímo z NVMe do GPU.
ext4 a XFS respektují O_DIRECT správně — zarovnané přímé I/O, žádná page cache. ZFS O_DIRECT ignoruje (veškeré I/O jde záměrně přes ARC): pro většinu workloadů v pořádku, ale tvrdá nekompatibilita s GPUDirect Storage. Záleží na zarovnání — buffer i offset musí být zarovnané na velikost bloku zařízení (typicky 4 KB).
Pokud plánujete použít GPUDirect Storage k sycení stroje s 8 GPU na plnou propustnost, /data musí být XFS na NVMe. Pokud nevíte, co GPUDirect Storage je, a váš trénink je omezený výpočetním výkonem, zatím ho nepotřebujete.
NVMe multipath
Dvouportové NVMe U.2 / E1.S se hlásí jako dvě PCIe cesty. Linuxový NVMe ovladač zvládá nativní multipath (nvme_core.multipath=Y, výchozí v moderních jádrech) a dává failover i round-robin rozložení zátěže. Na úrovni souborového systému je neviditelný, ale záleží na něm při výpadku (bez něj disk při selhání cesty nebo HBA zmizí a souborový systém zpanikaří) i u propustnosti (disk U.2 s multipath dosáhne ~14 GB/s oproti 7 GB/s po jedné cestě).
cat /sys/module/nvme_core/parameters/multipath # očekávejte: Y
nvme list-subsys
U spotřebitelských M.2 NVMe (desktopové sestavy s 5090) multipath roli nehraje — je jen jedna cesta. U sestav s 8 GPU na EPYC a enterprise U.2 / E1.S v backplane se dvěma řadiči ho nechte zapnutý.
Režie kontrolních součtů
| Operace | Náklad CPU na GB, jedno jádro | Poznámky |
|---|---|---|
| ZFS fletcher4 (výchozí) | ~50–100 ms | Výchozí kontrolní součet datového bloku |
| Komprese ZFS lz4 | ~150–250 ms | Obvykle se vrátí díky nižšímu I/O |
| Komprese ZFS zstd | ~400–800 ms | Lepší poměr, vyšší náklad |
| XFS / ext4 (bez kontrolního součtu dat) | 0 | Jen metadata |
Na hostiteli s 64jádrovým EPYC je tento náklad neviditelný. Na 16jádrovém Xeonu pod trvalou zátěží dokáže ZFS ukrojit 5–10 % efektivního výkonu CPU — jestli na tom záleží, závisí na tom, zda je trénink omezený CPU při předzpracování (u počítačového vidění často ano), nebo GPU (u velkých LLM často ano).
Poctivé shrnutí: ZFS odhalí bit rot, kterého byste si jinak nevšimli, dokud by se váš model nezačal učit na nenápadně poškozených datech. U datasetu, který jste stavěli půl roku, 5–10 % stojí za to. U dočasného scratche, který každý týden vytvoříte znovu, ne.
NFS pro sdílené datasety mezi uzly clusteru
Jakmile máte víc než jeden server, začíná být zajímavé, kde dataset vlastně žije. Tři vzorce:
- Kopie na každém uzlu. Jednoduché, plýtvá kapacitou. Použitelné do <1 TB a ≤4 uzlů.
- NFS z vyhrazeného úložného serveru. Jedna kanonická kopie. Úzkým hrdlem je síť — minimálně 25 GbE, pro vícouzlový trénink 100 GbE.
- Paralelní souborový systém (BeeGFS, Lustre, WekaFS). Větší zásah, ale škáluje za hranici, kde NFS končí.
Pro 1–4 uzly je NFS správná volba. Server: XFS na RAID10 z NVMe, export přes NFSv4. Klient: připojení s nconnect=8 pro paralelizaci přes více TCP spojení.
# Server /etc/exports
/data/shared 10.0.10.0/24(rw,async,no_subtree_check,no_root_squash)
# Klient
mount -t nfs -o vers=4.2,nconnect=8,proto=tcp,rsize=1048576,wsize=1048576 \
storage01:/data/shared /mnt/shared
NFS přes 100 GbE s nconnect=8 doručí trvalých 8–10 GB/s — dost pro 16 GPU při typickém trénování v počítačovém vidění nebo u LLM. Nad tím přicházejí BeeGFS / Lustre — a to je na jiný článek.
Kompletní příklad: 8 GPU na EPYC, 24 NVMe + 8 SAS
2× 480 GB NVMe (boot) → md RAID1 → ext4 → /
8× 7.68 TB NVMe (scratch) → md RAID0 → XFS → /scratch
8× 7.68 TB NVMe (data) → md RAID10 → XFS → /data
8× 16 TB SAS (archive) → 2× RAID-Z2 → ZFS → /archive
ZFS ARC: 64 GB z 512 GB RAM. NVMe multipath: zapnutý. NFS export: /data přes 100 GbE.
mkfs.ext4 -L root /dev/md0
mkfs.xfs -f -d su=64k,sw=8 -l size=512m -L scratch /dev/md1
mkfs.xfs -f -d su=64k,sw=4 -l size=512m -L data /dev/md2
zpool create -o ashift=12 \
-O compression=zstd -O atime=off -O xattr=sa -O recordsize=1M \
archive raidz2 /dev/sd[a-h]
echo "options zfs zfs_arc_max=68719476736" > /etc/modprobe.d/zfs.conf
update-initramfs -u
Surová propustnost NVMe tam, kde ji potřebujete, redundance tam, kde jsou data nenahraditelná, a komprimovaná kapacita s kontrolními součty pro všechno ostatní.
Co dělat dál
Než cokoli naformátujete, odpovězte si:
-
Jak velký je největší dataset v TB? Dimenzuje
/dataa řekne vám, jestli potřebujete archivní vrstvu. -
Jsou trénovací data znovu vytvořitelná ze zdroje pravdy? Pokud ano, RAID0 scratch stačí. Pokud ne, minimálně RAID10 a zvažte ZFS na
/data. - Kolik GPU čte stejný svazek současně? Nad zhruba 8 paralelními procesy DataLoaderu se alokační skupiny XFS oproti ext4 vyplatí.
- Potřebujete snapshoty? „Odbočit dataset a vrátit se zpět“ → ZFS. Jinak je XFS rychlejší a jednodušší.
- Rozpočet RAM — a kolik z něj může sebrat ZFS? Rozhodněte se před instalací, ne po prvním OOM.
Volba souborového systému není nejzajímavější rozhodnutí, které o AI serveru uděláte, ale je jedním z mála skutečně těžko vratných. Rozhodněte se vědomě, naformátujte jednou a jděte dál.
Toto je součást Kentino Wiki, referenční série o AI výpočtech, úložištích a systémech, které je propojují. Komentáře a opravy uvítáme na info@kentino.com.