Hub documentation
Déduplication
Déduplication
Les dépôts activés pour Xet utilisent le fractionnement défini par le contenu (CDC) pour dédupliquer au niveau des octets (environ 64 Ko de données, également appelés « chunk »). Chaque chunk est identifié par un hachage glissant qui détermine les limites des chunks en fonction du contenu réel du fichier, ce qui le rend résistant aux insertions ou suppressions n'importe où dans le fichier. Lorsqu'un fichier est téléversé dans un dépôt basé sur Xet à l'aide d'un client compatible Xet, son contenu est découpé en ces chunks de taille variable. Seuls les nouveaux chunks qui ne sont pas déjà présents dans le stockage Xet sont conservés après le fractionnement, tout le reste est supprimé.
La déduplication au niveau des chunks est également ce qui rend les copies côté serveur instantanées :
hf buckets cpentre dépôts et buckets ne migre que les hachages de contenu, sans ré-upload de données. Voir Copier des fichiers entre dépôts et buckets.
Fonctionnement du fractionnement défini par le contenu
Pour comprendre le fractionnement défini par le contenu, imaginez un fichier comme un long passage de texte. Le système analyse les données à l'aide d'un hachage glissant — une petite fonction mathématique qui se déplace sur les octets. Chaque fois que le hachage atteint un motif particulier, une limite de fragment est placée à cette position. Comme les limites sont déterminées par le contenu lui-même (et non par des positions fixes), les régions de données identiques produisent toujours les mêmes fragments, même si le contenu environnant change.
Pourquoi ne pas utiliser des blocs de taille fixe ?
Considérez ce qui se passe lorsque vous insérez une petite quantité de données au milieu d’un fichier. Avec un découpage en blocs de taille fixe, toutes les limites de blocs situées après l’insertion se décalent, invalidant ainsi tous les blocs en aval — même si la plupart des données restent inchangées :
Original file, fixed 6-byte chunks:
|The qu|ick br|own fo|x jump|s over| the l|azy do|g |
chunk1 chunk2 chunk3 chunk4 chunk5 chunk6 chunk7 chunk8
Insert "very " before "lazy":
|The qu|ick br|own fo|x jump|s over| the v|ery la|zy dog|
chunk1 chunk2 chunk3 chunk4 chunk5 chunk6 chunk7 chunk8
~~~~~~ ~~~~~~ ~~~~~~
3 chunks changed!Bien que seules 5 octets aient été insérés, 3 des 8 blocs ont changé car toutes les limites après la modification ont été décalées de 5 positions. Dans des fichiers réels avec une taille de bloc de 64 Ko, une petite modification peut invalider des centaines de mégaoctets de blocs.
Le chunking défini par le contenu maintient des limites stables
Avec CDC, les limites sont placées là où le contenu correspond à un motif — et non à des intervalles fixes. Cela signifie qu'une insertion n'affecte que le fragment où la modification a lieu. Les fragments avant et après restent identiques :
Original file, content-defined chunks (boundaries marked by "|"):
|The quick |brown fox |jumps over |the lazy dog|
chunk 1 chunk 2 chunk 3 chunk 4
Insert "very " before "lazy":
|The quick |brown fox |jumps over |the very lazy dog|
chunk 1 chunk 2 chunk 3 chunk 4'
(same) (same) (same) (changed)Seul 1 des 4 fragments a changé — celui contenant la modification. Les trois autres sont identiques octet par octet et sont dédupliqués. C'est pourquoi le CDC est si efficace pour les données versionnées : lorsque vous mettez à jour un point de contrôle de modèle ou que vous ajoutez des lignes à un jeu de données, seules les parties modifiées doivent être téléversées et stockées.
Des Chunks au Stockage
Le pipeline complet de déduplication fonctionne comme suit :
Lorsqu’un fichier est découpé en fragments, l’empreinte de chaque fragment est vérifiée par rapport à ce qui est déjà stocké. Cela se produit à plusieurs niveaux : d’abord par rapport aux fragments déjà rencontrés dans la session de téléversement en cours, puis par rapport à un cache local des métadonnées des téléversements précédents, et enfin un sous-ensemble de fragments est vérifié par rapport à l’ensemble du stockage Xet via une requête de déduplication globale. Les fragments en double sont entièrement ignorés. Les nouveaux fragments sont regroupés en blocs de 64 Mo et téléversés. Chaque bloc est stocké une seule fois dans un magasin adressé par contenu (CAS), indexé par son empreinte.
Économies de stockage en pratique
La recommandation actuelle du Hub est de limiter les fichiers à 200 Go. Avec une taille de bloc de 64 Ko, un fichier de 20 Go contient 312 500 blocs, dont beaucoup restent inchangés d’une version à l’autre. Git LFS est conçu pour ne détecter que le fait qu’un fichier a été modifié et pour stocker l’intégralité de cette révision. En dédupliquant au niveau des blocs, le backend Xet permet de ne stocker que le contenu modifié d’un fichier (qui ne représente parfois que quelques Ko ou Mo) et de dédupliquer de manière sécurisée les blocs partagés entre les dépôts. Pour les fichiers binaires volumineux présents dans les dépôts de modèles et de jeux de données, cela apporte des améliorations significatives des temps de transfert de fichiers.
Pour plus de détails, consultez les articles de blog From Files to Chunks et From Chunks to Blocks, ou l’article Git is for Data de Low et al., qui a servi de point de départ à XetHub avant son rachat par Hugging Face.
Update on GitHub