J'ai eu l'occasion de développer un petit logiciel open-source pour mon travail, donc j'en profite pour partager ici.
Motivation
Sur les grappes de calculs (clusters) dédiés à l'intelligence artificielle, il y a un problème assez récurrent lié au stockage et à l'accès aux données.
Dans ces installations, on trouve généralement d'un côté une baie de stockage avec des jeux de données composés de millions de petits fichiers, et de l'autre côté les nœuds de calcul qui lisent ces fichiers.
La baie est montée sur tous les noeuds (ex: nfs, gpfs, lustre, etc.).
Quelques ordres de grandeurs et précisions :
- Une expérience (un job) travaille pendant quelques jours, et sur un jeu de données à la fois.
- Plusieurs expériences de différents utilisateurs peuvent se partager un nœud de calcul (c'est très bien géré par slurm avec des cgroups).
- Les fichiers sont assez petits (entre 100ko et 10mo), chaque jeu de données pèse entre une centaine de giga et un téra.
- Les fichiers sont lus aléatoirement, autour d'une centaine de fois chacun.
En termes de stockage, ces millions de fichiers sont déjà un problème en soi pour le système de fichier.
Pour la charge de travail, les centres de calculs adoptent plusieurs politiques avec leurs avantages et inconvénients :
Option 1: Obliger les utilisateurs à copier les données sur un disque local du nœud au début de l'expérience, puis à nettoyer à la fin. L'ennui, c'est qu'il faut répéter l'opération à chaque expérience, hors elles peuvent s’enchaîner assez fréquemment en phase de mise au point d'un modèle. D'autre part, si l'expérience plante, le nettoyage des fichiers n'est pas garanti. Enfin, différentes expériences sur un même nœud ne partagent pas le cache, on pourrait donc se retrouver avec le même jeu de données en doublon.
Option 2: Opter pour une solution de mise en cache matérielle ou logicielle, ce qui est coûteux mais transparent pour l'utilisateur.
Option 3: Imposer l'utilisation d'une base de données spécifiquement étudiée pour ce type d'usage (ex: S3 avec minio), ce qui oblige les utilisateurs à modifier leur code de chargement des données et à convertir les données.
Approche
Pour scratch_manager, la liste des objectifs était donc la suivante :
- Regrouper les fichiers dans des archives pour que le nombre de fichiers sur la baie reste faible.
- Garder un accès aux données via une API de filesystem posix.
- Pas de délai pour démarrer une expérience.
- Mise en cache transparente pour l'utilisateur.
- Mutualiser le cache entre les expériences et aussi entre les utilisateurs.
Pour 1 et 2, l'astuce consiste à utiliser des images disques qui rassemblent les fichiers d'un jeu de données. J'ai opté pour squashfs mais de l'ext4 en lecture seule fonctionnerait aussi.
Pour 3, on monte les images stockées sur la baie afin que le contenu soit immédiatement accessibles. Bien sûr, toutes les lectures occasionnent alors de la charge de travail sur la baie de stockage.
Pour 4, on utilise un démon qui copie les images localement sur les nœuds et les monte par-dessus le premier montage. Linux gère ça très bien à chaud même s'il y a des fichiers ouverts. Après ça, les nouveaux accès pointent vers les disques locaux.
5 est résolu par le fait qu'un démon système gère ça pour tout le monde.
Voilà la nimage qui récapitule le bazar :
Détails d'implémentation
Mesure du traffic: Du fait que l'on travaille avec des images disques, le débit sur chaque jeu de donnée est accessible en consultant /proc/diskstats. Il faut juste faire le lien entre les /dev/loop*
et les images.
Allocation du cache: L'optimisation des images à mettre en cache est un problème de Knapsack, j'ai honteusement copié-collé le code qui résout ça.
Démontage et suppression des images: Pour appeler umount, il faut penser à passer le flag --lazy
pour attendre la fermeture des fichiers encore ouvert. Étonnamment, la suppression d'une image montée ne pose pas de problème, le fichier disparaît quand on fait un ls, mais subsiste en fait jusqu'au démontage.
Conclusion
Le projet est en ligne: https://github.com/CEA-LIST/scratch_manager
On ne va pas se mentir, c'est encore expérimental donc attention à votre hamster.
Je suis preneur de retours et de signalements de bugs bien sûr.
# Alternative ?
Posté par mzf (site web personnel) . Évalué à 2.
Bravo pour ce logiciel et pour ce journal de qualité qui explique très clairement les problèmes récurrents d'accès aux données sur HPC !
Du coup je me demande quelles sont les références/alternatives du domaine (libre ou non-libre) ? Car les motivations ont l'air d'être assez générales, et donc je suis étonné qu'il n'existe pas déjà des solutions ?
Je pense par exemple au format de fichier HDF5 qui cherche à répondre à la problématique du grand nombre de petit fichiers en les regroupant dans un conteneur rapide d'accès.
Et est-ce que les systèmes de fichiers tels que Lustre, GPFS ou VAST (tirés de ce lien) ne résolvent pas déjà ces soucis ? ou peut être que en partie ?
Merci d'avance pour les réponses !
[^] # Re: Alternative ?
Posté par nlgranger . Évalué à 3.
Merci!
Il y a effectivement des solutions logicielles apportées par les filesystems distribués tels que ceph, Lustre, et probablement GPFS aussi. Ça demande des compétences pointues sur ces filesystems (ou plutôt des frais de support en dehors des grands centres avec une équipe dédiée), ça ajoute du travail de maintenance et des risques de panne donc je n'ai pas approfondi cette piste.
Il me semble que sur des centres comme Jean Zay il y a une solution matérielle et logicielle ad-hoc, c'est top mais on n'est pas sur les même tarifs.
J'avais regardé HDF5, niveau fonctionnalités c'est pas mal. Mais ça oblige à convertir les datasets au format HDF5. Pareil pour apache Arrow. La simplicité d'utilisation et la qualité des docs ne m'ont pas semblé suffisantes aussi. Si sur un stage de recherche de 6 mois on perd 15 jours à convertir des données, à écrire et à déboguer du code de chargement, c'est embêtant.
[^] # Re: Alternative ?
Posté par oau . Évalué à 1. Dernière modification le 17 décembre 2022 à 19:11.
Ceph , cephfs et S3 c'est excellent pour faire ça. J'ai le même genre de problèmatique que j'ai résolu avec une stack ceph + k8s + kafka.
Effectivement ça demande des compétences mais quand il faut passer en production un pipeline de traitement de données il faut des compétences.
[^] # Re: Alternative ?
Posté par freejeff . Évalué à 2.
Attention avec HDF5, un fichier mal fermé et c'est toute la base de données qui est corrompue et ce n'est pas trivial (j'ai essayé de longues heures) à récupérer. Un fichier mal fermé ça arrive vite avec du code de chercheur, il suffit que ça plante et que l'exception ne soit pas chopée là où il faut et c'est mort, des gigas de données perdues et une expérience de plusieurs heures, voir jours, fichue … A réfléchir avec cette perspective.
Au passage, si quelqu'un a un outil pour ça, je suis preneur …
[^] # Re: Alternative ?
Posté par nlgranger . Évalué à 2. Dernière modification le 19 décembre 2022 à 00:13.
Pour mon cas il n'y a que du read only.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.