Choix du système de fichiers pour les serveurs d'IA : XFS, ZFS, ext4 et pourquoi Btrfs n'est pas dans la liste

Si vous venez d'investir 40 000 € dans des GPU, le choix du système de fichiers sur lequel vous stockez vos données mérite une réflexion approfondie. L'installateur d'Ubuntu installe systématiquement ext4 ; si c'est la solution idéale pour de nombreuses charges de travail d'IA, ce n'est pas le cas pour toutes. Choisir un système de fichiers inadapté pour un volume de données de 50 To peut entraîner une perte de débit, une perte de données, ou encore l'immobilisation de votre DataLoader, bloqué par un goulot d'étranglement lié aux métadonnées.

Ce document décrit le choix du système de fichiers et son emplacement sur un serveur d'IA de type Kentino (4 à 8 GPU, disque de démarrage NVMe, disque de travail NVMe, couche de stockage plus lente). Ubuntu 22.04 / 24.04, noyau 6.x.

La version courte

Point de montage Charge de travail Système de fichiers Pourquoi
/ (démarrage, racine) Système d'exploitation, paquets, journaux ext4 Ennuyeux, éprouvé, récupérable
/scratch (NVMe RAID0) Fragments d'entraînement actifs, écrits éphémères XFS Débit, E/S de répertoire parallèles
/data (RAID10) ensembles de données d'entraînement, points de contrôle du modèle XFS ou ZFS XFS pour une vitesse brute ; ZFS si vous souhaitez des instantanés et des sommes de contrôle.
/archive (RAID-Z2/6) Exécutions terminées, stockage à froid des données ZFS Compression, sommes de contrôle, instantanés
/home Maisons des utilisateurs, ordinateurs portables ext4 Fichiers de petite taille, faible contention

Version en un paragraphe : ext4 pour le système d’exploitation, XFS pour le stockage temporaire à chaud, ZFS là où l’intégrité compte plus que les 10 % de débit restants, pas de Btrfs en production.

ext4 — le système de fichiers par défaut, certes ennuyeux, mais généralement judicieux.

ext4 est le système de fichiers par défaut sur Ubuntu, Debian, Fedora et RHEL depuis plus de dix ans. Bien connu et récupérable avec fsck16 To par fichier, 1 Eo par volume. Rien d'extraordinaire — c'est le but.

Utilisez ext4 pour la racine (toutes les clés USB live Ubuntu savent comment résoudre ce problème ; beaucoup moins savent comment importer un zpool), pour /homeet pour les magasins d'images de machines virtuelles à petite et moyenne échelle.

Là où ext4 cesse d'avoir raison : E/S parallèles larges (son journal sérialise les mises à jour des métadonnées — vingt processus DataLoader sur un seul volume ext4 goulot d'étranglement sur le journal bien avant de saturer NVMe) ; fichiers uniques et énormes (géré, mais l'allocation d'étendue est moins conviviale que XFS pour les fichiers séquentiels de plus de 100 Go — fragments d'entraînement, points de contrôle, corpus vidéo) ; des instantanés (aucune nativement ; les snapshots légers LVM fonctionnent mais sont maladroits).

mkfs.ext4 -L root /dev/nvme0n1p2

Si vous vous retrouvez à effectuer des réglages complexes sur ext4 pour une charge de travail d'IA, c'est que vous avez choisi le mauvais système de fichiers.

XFS — la solution idéale pour les données de test et d'entraînement à chaud

XFS était un système de fichiers SGI conçu pour les E/S séquentielles à haut débit sur de grandes baies de stockage. Cet héritage correspond presque parfaitement aux charges de travail d'IA : fichiers volumineux (partitions d'entraînement, Parquet, archives tar de jeux de données Web, points de contrôle), lectures séquentielles, nombreux lecteurs parallèles et tolérance à la régénération des données par la charge de travail.

Ce que XFS fait que ext4 ne fait pas : groupes d'allocation — le volume se divise en 4 à 32 groupes indépendants qui lisent et écrivent en parallèle sans verrou de journal global, exactement ce que souhaite un DataLoader multi-travailleurs ; préallocation différée et spéculative ainsi les grandes écritures séquentielles obtiennent des étendues contiguës ; aucune limite pratique de taille de fichier (8 EB); et xfs_growfs pour une extension fiable en une seule ligne après la croissance RAID.

Ce qu'il ne fait pas : pas de snapshots natifs, pas de sommes de contrôle des données de fichiers (métadonnées protégées par CRC depuis 2014), pas de réduction — uniquement une extension.

Un raisonnable mkfs.xfs pour un volume temporaire RAID0 NVMe 8×, bloc de 64 KiB :

# su = stripe unit = chunk size; sw = number of data disks
mkfs.xfs -f -d su=64k,sw=8 -l size=512m -L scratch /dev/md0

# largeio + swalloc: behave for >1 MB I/O
# allocsize=1g: preallocate aggressively for big sequential writes
# noatime: save a write per read under heavy DataLoader load
mount -o noatime,largeio,swalloc,allocsize=1g /dev/md0 /scratch

noatime et largeio L'essentiel est là. XFS est acceptable pour les petits fichiers, mais ce n'est pas son point fort ; pour des centaines de millions d'images de moins de 16 Ko, il est préférable de les reconditionner dans webdataset/parquet/lmdb plutôt que de changer de système de fichiers (voir ci-dessous).

ZFS — la solution idéale lorsque l’intégrité, les instantanés ou la compression sont essentiels.

ZFS est un système de fichiers, un gestionnaire de volumes et une couche RAID logicielle, le tout en un seul élément :

  • Somme de contrôle de bout en bout. Détection de corruption de données en lecture, corrigée silencieusement grâce à la redondance. Pour un ensemble de données de 50 To stocké sur un disque dur classique pendant deux ans, cela a une importance ; pour des données éphémères sur un disque NVMe pendant six semaines, cela n'en a pas.
  • Instantanés et clones. Atomique, COW, et quasiment gratuit. Capture d'instantané avant exécution, duplication du système de fichiers, restauration : ZFS est conçu pour ce type de flux de travail.
  • Compression intégrée. lz4 activé par défaut ; zstd pour de meilleurs ratios. Sur texte / JSON / parquet, la compression est généralement des augmentations Débit effectif car le coût du processeur est inférieur aux économies réalisées sur les E/S.
  • ARC — son propre cache de lecture en RAM, distinct du cache de pages Linux. Le fameux piège.
  • RAID-Z natif — pas de madame.

Ce qu'il ne fait pas bien pour l'IA : consomme de la RAM (l'ARC par défaut représente environ 50 % de la mémoire système — sur un serveur de 512 Go, le noyau ne dispose soudainement plus de 256 Go, et les tâches d'entraînement qui s'attendent à un cache de pages ou à des pages volumineuses sont interrompues par manque de mémoire ; limitez l'ARC) ; pas le plus rapide pour les lectures séquentielles brutes (XFS bien réglé sur NVMe RAID0 surpasse ZFS de 15 à 30 % — le calcul de la somme de contrôle et le COW coûtent des cycles réels) ; ne tient pas compte O_DIRECT (Toutes les E/S passent par ARC par conception — convient à la plupart des charges de travail, mais présente une incompatibilité majeure avec GPUDirect Storage).

Réglage ARC — le seul bouton que vous devez régler

Sur une installation fraîche d'Ubuntu + ZFS sur un boîtier de 512 Go, ZFS alloue 256 Go à ARC. zfs_arc_max lors de l'installation, et non après la première erreur de mémoire insuffisante.

# Cap ARC at 64 GB. Bytes, not 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   # apply now
sudo update-initramfs -u                                             # persist

Règle générale : limiter ARC à 10 à 20 % de la RAM système Sur un serveur d'IA, le dimensionnement classique « 2 Gio de base + 1 Gio par Tio » est destiné aux systèmes de stockage ; sur un système d'IA, la majeure partie de la RAM est réservée aux poids des modèles, aux activations et au cache de pages du framework.

Une configuration ZFS cohérente pour la couche de données d'un serveur d'IA

# 8 × 16 TB SAS in two RAID-Z2 vdevs (6+2 each) — two vdevs give 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]

# Datasets sized for their workload
zfs create -o recordsize=1M   data/datasets       # large training shards
zfs create -o recordsize=128k data/checkpoints    # mixed size
zfs create -o recordsize=16k  data/metadata       # small files (json, yaml)

zfs snapshot data/datasets@pre-run-2026-05-14
zfs rollback data/datasets@pre-run-2026-05-14

ashift=12 = 4 blocs de KiB — si vous vous trompez à ce niveau lors de la création du pool, vous ne pourrez pas le corriger sans détruire le pool. recordsize=1M pour les charges de travail de fichiers volumineux (la valeur par défaut de 128 KiB est trop faible pour les partitions de plusieurs Go). xattr=sa Stocke les attributs étendus en ligne, beaucoup plus rapidement que par défaut.

Btrfs — généralement à éviter pour l'IA en production

Btrfs partage les mêmes caractéristiques conceptuelles que ZFS : copie sur écriture (COW), instantanés, sommes de contrôle et RAID intégré. Sur le papier, c’est parfait ; en pratique, nous le déconseillons sur les serveurs Kentino. Les RAID 5 et 6 présentent des failles connues de perte de données, que le projet lui-même considère comme non prêtes pour la production (les RAID 1 et 10 sont stables, contrairement aux modes de parité) ; les performances se dégradent fortement avec la fragmentation générée par les charges de travail d’IA (points de contrôle de gradient, caches) ; les performances des instantanés chutent brutalement au-delà de quelques centaines, seuil atteint en moins d’un trimestre par expérience ; et les outils de réplication, de surveillance et de planification du nettoyage sont moins aboutis que ceux de ZFS ou XFS. Cela convient pour un ordinateur portable. Pour un serveur multi-GPU avec des dizaines de téraoctets de données d’entraînement, privilégiez XFS ou ZFS.

Configurations RAID — avec quel système de fichiers associer ?

Niveau RAID Cas d'utilisation Redondance Remarques
RAID0 Rayure (éphémère, régénérable) Aucun Uniquement pour les données que vous pouvez reconstruire
RAID10 ensembles de données d'entraînement, points de contrôle 1 par miroir Vitesse et sécurité optimales pour les données sensibles
RAID-Z1 / RAID5 À éviter pour les nouvelles constructions 1 disque Les temps de reconstruction sur les disques de plus de 16 To rendent le Z1 risqué.
RAID-Z2 / RAID6 Archivage, stockage de données froides 2 disques Le choix idéal pour les achats en gros
RAID-Z3 Baies larges (12 disques et plus) 3 disques Uniquement lorsque la largeur du tableau l'impose

Sur les disques de plus de 16 To, la reconstruction d'un seul disque peut prendre entre 24 et 72 heures, et une seconde panne sur un disque du même lot pendant ce laps de temps n'est pas négligeable. La parité simple n'est plus la solution par défaut la plus sûre. Utilisez Z2/RAID6 ou des miroirs.

fichiers de petite taille versus fichiers volumineux

La question qui piège les gens plus que n'importe quel choix de système de fichiers : Comment votre système de fichiers se comporte-t-il avec 50 millions d'images de 4 Ko dans une arborescence de répertoires ? Réponse pour chaque système de fichiers : mal.

Les métadonnées par fichier (inode, dentry, horodatages, xattrs) occupent entre 200 et 500 octets, quelle que soit la taille du fichier ; 50 millions de petits fichiers consomment entre 10 et 25 Go de métadonnées avant même de stocker un seul octet de données de pixels. Le cycle d'ouverture/lecture/fermeture sature la gestion des métadonnées et ralentit les processus DataLoader.

La solution ne réside pas dans le système de fichiers. Ne stockez pas les petits fichiers en tant que fichiers. Empaqueter dans webdataset / tar / parquet / lmdb / hdf5 / safetensors et diffuser séquentiellement — PyTorch WebDataset NVIDIA DALI et ZFS s'attendent tous deux à cela. Le système de fichiers gère alors un petit nombre de fichiers volumineux, ce que tous les systèmes de fichiers présentés ici savent faire. Si vous devez conserver des fichiers individuels à grande échelle, ZFS avec recordsize=16k et xattr=sa est la moins mauvaise option, mais la vraie solution est de refaire ses emballages.

E/S directes, cache de pages et O_DIRECT

PyTorch s'appuie sur le cache de pages Linux pour les itérations répétées des jeux de données : l'itération 1 est chargée sur disque, les itérations 2 à N sur la RAM. Certaines charges de travail utilisent O_DIRECT Pour contourner le cache lors des lectures volumineuses où les données ne sont traitées qu'une seule fois, la technologie GPUDirect Storage de NVIDIA va plus loin en effectuant un accès direct (DMA) entre le NVMe et le GPU.

ext4 et XFS honorent O_DIRECT Correctement alignées — E/S directes, sans cache de pages. ZFS ignore O_DIRECT (Toutes les E/S transitent par ARC, par conception) : convient à la plupart des charges de travail, mais présente une incompatibilité majeure avec GPUDirect Storage. L’alignement est crucial : la taille du tampon et le décalage doivent correspondre à la taille des blocs du périphérique (généralement 4 Ko).

Si vous prévoyez d'utiliser GPUDirect Storage pour alimenter un système à 8 GPU à pleine bande passante, /data Il doit s'agir de XFS sur NVMe. Si vous ne savez pas ce qu'est GPUDirect Storage et que l'entraînement est limité par la puissance de calcul, vous n'en avez pas encore besoin.

multipath NVMe

Le double port U.2 / E1.S NVMe est présenté comme deux chemins PCIe chacun. Le pilote NVMe Linux gère le multipath natif (nvme_core.multipath=Y(Par défaut dans les noyaux modernes), assurant la tolérance aux pannes et l'équilibrage de charge. Invisible au niveau du système de fichiers, il est pourtant crucial pour la tolérance aux pannes (sans lui, une défaillance de chemin ou de HBA entraîne la disparition du disque et le plantage du système de fichiers) et la bande passante (un disque U.2 multipath atteint environ 14 Go/s contre 7 Go/s pour un disque monopath).

cat /sys/module/nvme_core/parameters/multipath   # expect: Y
nvme list-subsys

Pour les SSD M.2 NVMe grand public (configurations de bureau de type 5090), le multipath n'est pas pertinent : un seul chemin suffit. Pour les configurations EPYC à 8 GPU avec interface U.2/E1.S professionnelle sur une carte mère à double contrôleur, laissez cette option activée.

Surcharge de calcul de somme de contrôle

Opération Coût du processeur par Go, un cœur Remarques
ZFS fletcher4 (par défaut) ~50–100 ms somme de contrôle par défaut des blocs de données
Compression ZFS lz4 ~150–250 ms Le retour sur investissement se fait généralement par la réduction des E/S.
Compression ZFS zstd ~400–800 ms Meilleur ratio, coût plus élevé
XFS / ext4 (pas de somme de contrôle des données) 0 Métadonnées uniquement

Sur un hôte EPYC à 64 cœurs, le coût est imperceptible. Sur un Xeon à 16 cœurs sous charge soutenue, ZFS peut consommer 5 à 10 % de la puissance CPU effective ; l’importance de ce coût dépend de la dépendance de l’entraînement au CPU lors du prétraitement (souvent le cas pour la vision) ou au GPU (souvent le cas pour les grands modèles linéaires).

Le cadrage honnête : ZFS détecte les erreurs de bits que vous ne remarqueriez jamais autrement, jusqu'à ce que votre modèle soit entraîné sur des données subtilement corrompues. Pour un jeu de données que vous avez mis six mois à constituer, un gain de 5 à 10 % est justifié. Pour des données temporaires éphémères que vous régénérez chaque semaine, ce n'est pas le cas.

NFS pour les ensembles de données partagés entre les nœuds du cluster

Dès lors que vous disposez de plusieurs serveurs, la question de l'emplacement des données devient intéressante. Trois schémas se dégagent :

  1. Copier sur chaque nœud. Simple, mais gaspille de la capacité. Convient pour <1 To et ≤4 nœuds.
  2. NFS depuis un serveur de stockage dédié. Une seule copie canonique. Le réseau constitue le facteur limitant : 25 GbE minimum, 100 GbE pour l’entraînement multi-nœuds.
  3. Système de fichiers parallèle (BeeGFS, Lustre, WekaFS). Un projet plus ambitieux, qui dépasse les limites de NFS.

Pour 1 à 4 nœuds, NFS est la solution idéale. Serveur : XFS sur RAID 10 NVMe, exporté via NFSv4. Client : montage avec nconnect=8 paralléliser sur plusieurs connexions TCP.

# Server /etc/exports
/data/shared 10.0.10.0/24(rw,async,no_subtree_check,no_root_squash)

# Client
mount -t nfs -o vers=4.2,nconnect=8,proto=tcp,rsize=1048576,wsize=1048576 \
  storage01:/data/shared /mnt/shared

NFS sur 100 GbE avec nconnect=8 Il offre un débit soutenu de 8 à 10 Go/s, suffisant pour 16 GPU lors d'entraînements classiques de vision ou de modèles linéaires. Au-delà, BeeGFS/Lustre feront l'objet d'un autre article.

Exemple complet : EPYC 8 GPU, 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 of 512 GB RAM. NVMe multipath: on. NFS export: /data over 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

Débit NVMe brut là où vous en avez besoin, redondance là où les données sont irremplaçables, stockage en masse compressé avec somme de contrôle pour tout le reste.

Que faire ensuite

Avant toute mise en forme, répondez :

  1. Le plus grand ensemble de données, en téraoctets ? Formats /data et vous indique si vous avez besoin d'un niveau d'archivage.
  2. Les données d'entraînement sont-elles régénérables à partir d'une source de vérité ? Si oui, un RAID 0 scratch convient. Sinon, RAID 10 minimum, envisagez ZFS. /data.
  3. Combien de GPU lisent simultanément le même volume ? Au-delà d'environ 8 processus DataLoader parallèles, les groupes d'allocation XFS sont plus rentables que ext4.
  4. Avez-vous besoin de captures d'écran ? « Créer une copie d'un jeu de données et revenir en arrière » → ZFS. Sinon, XFS est plus rapide et plus simple.
  5. Budget RAM et quelle quantité ZFS peut-il prendre en charge ? Décidez avant l'installation, pas après la première erreur de mémoire insuffisante.

Le choix du système de fichiers n'est pas la décision la plus passionnante à prendre concernant un serveur d'IA, mais c'est l'une des rares qu'il est vraiment difficile de revenir en arrière. Choisissez-le avec soin, formatez-le une fois pour toutes, et passez à autre chose.


Ceci fait partie du Kentino Wiki, une série de référence sur le calcul, le stockage et les systèmes de connexion en IA. Commentaires et corrections bienvenus. info@kentino.com.