Hub Python Library documentation
Comprendre la mise en cache
Comprendre la mise en cache
huggingface_hub utilise un cache local basé sur des fichiers pour stocker les fichiers individuels téléchargés depuis le Hub et éviter de retélécharger les fichiers inchangés lors d’une mise à jour d’un dépôt. De plus, hf_xet stocke un cache de shards et des données de staging pour optimiser les téléversements (voir Cache Xet).
Ce guide présente les outils de gestion du cache spécifiques à Python fournis par
huggingface_hub. Pour une vue d’ensemble indépendante du langage sur le fonctionnement du système de cache du Hugging Face Hub, consultez la documentation du Hub sur la mise en cache locale.
Mise en cache basée sur les fichiers
Le système de cache du Hugging Face Hub est conçu pour être le cache central partagé entre les bibliothèques qui dépendent du Hub. Il a été mis à jour dans la v0.8.0 pour éviter le téléchargement à nouveau des mêmes fichiers entre les révisions.
Le système de cache est conçu comme suit :
<CACHE_DIR>
├─ <MODELS>
├─ <DATASETS>
├─ <SPACES>
├─ <KERNELS>Le <CACHE_DIR> par défaut est ~/.cache/huggingface/hub. Il est toutefois personnalisable via l'argument cache_dir sur toutes les méthodes, ou en spécifiant la variable d'environnement HF_HOME ou HF_HUB_CACHE.
Les modèles, les jeux de données, les espaces et les noyaux partagent une racine commune. Chacun de ces dépôts contient le type de dépôt, l'espace de noms (organisation ou nom d'utilisateur) s'il existe et le nom du dépôt :
<CACHE_DIR>
├─ models--julien-c--EsperBERTo-small
├─ models--lysandrejik--arxiv-nlp
├─ models--bert-base-cased
├─ datasets--glue
├─ datasets--huggingface--DataMeasurementsFiles
├─ spaces--dalle-mini--dalle-miniC’est dans ces dossiers que tous les fichiers seront désormais téléchargés depuis le Hub. La mise en cache garantit qu’un fichier n’est pas téléchargé deux fois s’il existe déjà et n’a pas été mis à jour ; mais s’il a été mis à jour et que vous demandez le fichier le plus récent, celui-ci sera téléchargé (le fichier précédent étant conservé intact au cas où vous en auriez à nouveau besoin).
Pour y parvenir, tous les dossiers contiennent le même squelette :
<CACHE_DIR>
├─ datasets--glue
│ ├─ refs
│ ├─ blobs
│ ├─ snapshots
│ ├─ trees
...Chaque dossier est conçu pour contenir les éléments suivants :
Références
Le dossier refs contient des fichiers qui indiquent la dernière révision de la référence donnée. Par exemple,
si nous avons précédemment récupéré un fichier de la branche main d'un dépôt, le dossier refs contiendra un fichier nommé main, qui contiendra lui-même l'identifiant de commit de la tête actuelle.
Si le dernier commit de main a aaaaaa comme identifiant, alors il contiendra aaaaaa.
Si cette même branche est mise à jour avec un nouveau commit, dont l’identifiant est bbbbbb, alors
la nouvelle récupération d’un fichier à partir de cette référence mettra à jour le fichier refs/main pour qu’il contienne bbbbbb.
Blobs
Le dossier blobs contient les fichiers réellement téléchargés. Le nom de chaque fichier est son hachage.
Instantanés
Le dossier snapshots contient des liens symboliques vers les blobs mentionnés ci-dessus. Il est lui-même composé de plusieurs dossiers :
un par révision connue !
Dans l’explication ci-dessus, nous avions d’abord récupéré un fichier de la révision aaaaaa, avant de récupérer un fichier de la révision bbbbbb. Dans cette situation, nous aurions maintenant deux dossiers dans le dossier snapshots : aaaaaa et bbbbbb.
Chacun de ces dossiers contient des liens symboliques vivants portant les noms des fichiers que nous avons téléchargés. Par exemple, si nous avions téléchargé le fichier README.md à la révision aaaaaa, nous aurions le chemin suivant :
<CACHE_DIR>/<REPO_NAME>/snapshots/aaaaaa/README.mdLe fichier README.md est en réalité un lien symbolique pointant vers le blob qui contient l'empreinte du fichier.
En créant le squelette de cette manière, nous ouvrons la voie au partage de fichiers : si le même fichier avait été récupéré dans la révision bbbbbb, il aurait le même hachage et le fichier n’aurait pas besoin d’être à nouveau téléchargé.
Arbres
Le dossier trees met en cache la liste des fichiers contenus dans un dépôt à un commit donné. Un commit étant immuable, sa liste de fichiers ne change jamais. Cela signifie que la liste peut être mise en cache indéfiniment sans jamais avoir besoin d’être vérifiée à nouveau sur le Hub.
Chaque liste mise en cache est nommée d’après un hachage de commit et stockée sous forme de fichier JSON, par exemple trees/aaaaaa.json. Pour chaque fichier du dépôt à ce commit, elle enregistre les informations nécessaires pour télécharger le fichier : son chemin, sa taille et son hachage. Il s’agit des mêmes informations que le Hub renverrait autrement, mais il faut normalement un appel réseau par fichier pour les récupérer.
Ce cache est écrit par snapshot_download(). La première fois que vous téléchargez un commit, la liste des fichiers est récupérée une fois et enregistrée ici. La fois suivante, lorsque vous téléchargez le même commit, la liste est lue depuis le disque au lieu d’être récupérée à nouveau. En conséquence, relancer un téléchargement lorsque tout est déjà en cache ne coûte qu’un seul appel réseau : celui nécessaire pour résoudre le nom de la branche ou de la balise en un hachage de commit.
Les fonctions snapshot_download() et hf_hub_download() lisent ce cache pour éviter les appels réseau. Lorsque vous téléchargez un fichier en utilisant un hachage de commit comme révision (c'est exactement ce que fait snapshot_download() en interne pour chaque fichier), les métadonnées de téléchargement sont lues depuis la liste de fichiers mise en cache et l'appel réseau par fichier est ignoré. Cela signifie qu'un appel à hf_hub_download() pour un seul fichier bénéficie également d'une liste de fichiers enregistrée par un appel antérieur à snapshot_download() pour le même commit.
La liste de fichiers en cache décrit exactement ce qu'un commit doit contenir, snapshot_download() peut donc également déterminer si un instantané local est complet. Si le Hub est inaccessible (vous êtes hors ligne, la connexion échoue, ou vous avez passé local_files_only=True) et que certains fichiers attendus manquent dans l'instantané local, snapshot_download() lève IncompleteSnapshotError au lieu de retourner un dossier partiel. Avant cela, un instantané incomplet était retourné silencieusement, ce qui pouvait vous amener à travailler avec des fichiers manquants sans le savoir. Les fichiers exclus par allow_patterns ou ignore_patterns ne sont pas comptés comme manquants. L'exception expose le chemin de l'instantané incomplet via son attribut snapshot_path, ce qui vous permet toujours de localiser les fichiers partiellement en cache si nécessaire.
.no_exist (avancé)
En plus des dossiers blobs, refs et snapshots, vous pouvez également trouver un dossier .no_exist dans votre cache. Ce dossier suit les fichiers que vous avez tenté de télécharger une fois mais qui n'existent pas sur le Hub. Sa structure est identique à celle du dossier snapshots, avec un sous-dossier par révision connue :
<CACHE_DIR>/<REPO_NAME>/.no_exist/aaaaaa/config_that_does_not_exist.jsonContrairement au dossier snapshots, les fichiers sont de simples fichiers vides (pas de liens symboliques). Dans cet exemple,
le fichier "config_that_does_not_exist.json" n'existe pas sur le Hub pour la révision "aaaaaa".
Comme il ne stocke que des fichiers vides, ce dossier est négligeable en termes d'espace disque.
Vous vous demandez peut-être pourquoi cette information est pertinente.
Dans certains cas, un framework tente de charger des fichiers optionnels pour un modèle. Enregistrer l’absence
de fichiers optionnels accélère le chargement d’un modèle, car cela évite un appel HTTP par fichier optionnel possible.
C’est le cas, par exemple, dans transformers, où chaque tokenizer peut prendre en charge des fichiers supplémentaires.
La première fois que vous chargez le tokenizer sur votre machine, il met en cache les fichiers optionnels existants (et
ceux qui ne le sont pas) afin de réduire le temps de chargement lors des initialisations suivantes.
Pour tester si un fichier est mis en cache localement (sans effectuer de requête HTTP), vous pouvez utiliser l’assistant try_to_load_from_cache(). Il renverra le chemin du fichier (s’il existe et est en cache), l’objet _CACHED_NO_EXIST (si son absence est mise en cache) ou None (si nous ne le savons pas).
from huggingface_hub import try_to_load_from_cache, _CACHED_NO_EXIST
filepath = try_to_load_from_cache()
if isinstance(filepath, str):
# file exists and is cached
...
elif filepath is _CACHED_NO_EXIST:
# non-existence of file is cached
...
else:
# file is not cached
...En pratique
En pratique, votre cache doit ressembler à l'arborescence suivante :
[ 96] .
└── [ 160] models--julien-c--EsperBERTo-small
├── [ 160] blobs
│ ├── [321M] 403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
│ ├── [ 398] 7cb18dc9bafbfcf74629a4b760af1b160957a83e
│ └── [1.4K] d7edf6bd2a681fb0175f7735299831ee1b22b812
├── [ 96] refs
│ └── [ 40] main
├── [ 128] snapshots
│ ├── [ 128] 2439f60ef33a0d46d85da5001d52aeda5b00ce9f
│ │ ├── [ 52] README.md -> ../../blobs/d7edf6bd2a681fb0175f7735299831ee1b22b812
│ │ └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
│ └── [ 128] bbc77c8132af1cc5cf678da3f1ddf2de43606d48
│ ├── [ 52] README.md -> ../../blobs/7cb18dc9bafbfcf74629a4b760af1b160957a83e
│ └── [ 76] pytorch_model.bin -> ../../blobs/403450e234d65943a7dcf7e05a771ce3c92faa84dd07db4ac20f592037a1e4bd
└── [ 96] trees
├── [ 521] 2439f60ef33a0d46d85da5001d52aeda5b00ce9f.json
└── [ 521] bbc77c8132af1cc5cf678da3f1ddf2de43606d48.jsonCACHEDIR.TAG
huggingface_hub crée automatiquement un fichier CACHEDIR.TAG à l’intérieur du répertoire de cache. Ce
marqueur suit la Cache Directory Tagging Standard et indique aux outils de sauvegarde (par ex. Borg,
restic, rsync) que le répertoire contient des données de cache téléchargeables à nouveau et peut donc être
exclu en toute sécurité des sauvegardes.
Limites
Afin de disposer d'un système de cache efficace, huggingface-hub utilise des liens symboliques. Cependant, les liens symboliques ne sont pas pris en charge sur toutes les machines. Il s'agit d'une limitation connue, notamment sur Windows. Dans ce cas, huggingface_hub n'utilise pas le répertoire blobs/ mais stocke directement les fichiers dans le répertoire snapshots/. Ce contournement permet aux utilisateurs de télécharger et de mettre en cache les fichiers du Hub de la même manière. Les outils d'inspection et de suppression du cache (voir ci-dessous) sont également pris en charge. Toutefois, le système de cache est moins efficace, car un fichier unique peut être téléchargé plusieurs fois si plusieurs révisions du même dépôt sont téléchargées.
Si vous souhaitez profiter du système de cache basé sur les liens symboliques sur une machine Windows, vous devez soit activer le mode développeur, soit exécuter Python en tant qu'administrateur.
Si vous souhaitez utiliser de manière proactive le mode de cache sans lien symbolique (par exemple sur un système de fichiers partagé qui ne gère pas bien les liens symboliques), vous pouvez définir la variable d’environnement HF_HUB_DISABLE_SYMLINKS sur 1. Les fichiers seront copiés directement dans snapshots/ au lieu d’être liés symboliquement à blobs/.
Lorsque les liens symboliques ne sont pas pris en charge, un message d'avertissement est affiché à l'utilisateur pour l'alerter qu'il utilise une version dégradée du système de cache. Cet avertissement peut être désactivé en définissant la variable d'environnement HF_HUB_DISABLE_SYMLINKS_WARNING sur true.
Blobs partagés entre les dépôts
Par défaut, les fichiers Xet sont également dédupliqués entre les dépôts. Un fichier Xet téléchargé via hf_xet est stocké une seule fois dans <CACHE_DIR>/blobs/<prefix>/<xet_hash>, et l’entrée blobs/<etag> du dépôt est un lien symbolique relatif vers ce fichier. Lorsqu’un autre dépôt a besoin du même fichier, il reçoit un lien symbolique au lieu d’un téléchargement : aucun octet n’est transféré et aucun espace supplémentaire n’est utilisé. La structure des instantanés ne change pas. Un fichier marqueur identifie le magasin, de sorte qu’un répertoire blobs qui n’a pas été créé par huggingface_hub n’est jamais modifié.
Chaque fichier partagé possède un manifeste <xet_hash>.refs qui répertorie les blobs du dépôt qui l’utilisent. hf cache rm le lit pour ne vérifier que les fichiers partagés affectés par une suppression, et hf cache prune supprime les fichiers partagés qui ne sont plus utilisés par aucun dépôt en cache. Le manifeste n’est qu’un indice : chaque entrée est vérifiée par rapport au système de fichiers, et un fichier dont les métadonnées sont manquantes ou illisibles est conservé. Le nettoyage privilégie la conservation de données récupérables plutôt que la rupture d’une entrée de cache valide.
Les tailles par dépôt restent logiques, de sorte qu'un fichier partagé est compté pour chaque dépôt qui l'utilise. La taille size_on_disk de l'ensemble du cache est physique : chaque fichier partagé est compté une seule fois, y compris les fichiers qu'aucun dépôt n'utilise plus.
Les anciens clients (huggingface_hub, huggingface.js, hf-hub, llama.cpp, et tout ce qui suit les liens symboliques) continuent de lire et de télécharger normalement, dans les mêmes dossiers de dépôt. Deux limitations :
huggingface_hub<=1.31laisse les fichiers partagés d’un dépôt supprimé dans le store, oùhf cache lsles signale ethf cache pruneles supprime. Les outils de suppression de cache d’autres clients peuvent au contraire supprimer un fichier partagé encore utilisé par d’autres dépôts ; les fichiers concernés sont alors ré-telechargés lors de leur prochaine utilisation. Utilisez une version à jour dehuggingface_hubpourhf cache rm,hf cache pruneet la suppression programmatique.- Leurs analyseurs de cache peuvent signaler le répertoire
blobsde premier niveau comme une entrée inconnue.
Le magasin requiert la structure de cache basée sur les liens symboliques et est désactivé par HF_HUB_DISABLE_XET=1. Tout échec lors du partage d’un fichier, tel qu’un système de fichiers non pris en charge, une erreur d’autorisation ou un répertoire blobs existant non marqué, bascule silencieusement sur le stockage local du dépôt. Définissez HF_HUB_DISABLE_SHARED_BLOBS=1 pour y renoncer entièrement.
Épingler une révision (avancé)
Si vous intégrez le Hub dans une bibliothèque ML, un simple appel à snapshot_download() reste l’approche recommandée : il résout la révision une seule fois, télécharge tout en parallèle et met en cache la liste des fichiers. Ce qui suit n’est utile que pour les bibliothèques complexes qui téléchargent et chargent de nombreux composants séparément (config, poids, tokenizer, processeur, adaptateurs, …) et ne peuvent pas utiliser un seul appel.
Lorsqu’une bibliothèque télécharge plusieurs fichiers un par un, chaque appel doit à nouveau résoudre revision="main" en un hachage de commit. Cela coûte un appel HTTP par fichier et, pire encore, deux appels effectués à quelques secondes d’intervalle peuvent aboutir à deux commits différents si le dépôt est mis à jour entre-temps.
HfApi.resolve_revision() résout la révision une seule fois et renvoie un ResolvedRevision :
>>> from huggingface_hub import resolve_revision
>>> revision = resolve_revision("openai-community/gpt2")
>>> revision
ResolvedRevision(initial=None, resolved='607a30d783dfa663caf39e06633721c8d4cfcd7e')ResolvedRevision est une sous-classe de str, il peut donc être transmis à toute méthode de huggingface_hub acceptant un argument revision. Sa valeur en chaîne de caractères correspond à ce que l’utilisateur a initialement demandé ("main" ici, d’où des messages d’erreur lisibles), tandis que .resolved contient l’identifiant de commit :
>>> revision == "main"
True
>>> revision.resolved
'607a30d783dfa663caf39e06633721c8d4cfcd7e'Les utilitaires de téléchargement (hf_hub_download(), snapshot_download(), get_cached_repo_tree()) détectent un ResolvedRevision et utilisent directement l’empreinte de commit. Chaque fichier est garanti de provenir du même commit, et une fois les fichiers mis en cache, aucun appel HTTP n’est nécessaire :
>>> from huggingface_hub import hf_hub_download
>>> config = hf_hub_download("openai-community/gpt2", "config.json", revision=revision)
>>> weights = hf_hub_download("openai-community/gpt2", "model.safetensors", revision=revision)La correspondance revision -> commit hash est également écrite dans le dossier refs/ du cache (voir Refs). Cela signifie que si le Hub ne peut pas être atteint ultérieurement (mode hors ligne, erreur de connexion, délai d’attente, indisponibilité du Hub), HfApi.resolve_revision() bascule de manière transparente sur la valeur mise en cache. Si rien n’est mis en cache non plus, une RevisionResolutionError est levée.
Un hash de commit n’a de sens que pour le dépôt auquel il a été résolu, et les utilitaires de téléchargement l’utilisent tel quel. Ainsi, un ResolvedRevision ne doit être transmis qu’au dépôt pour lequel il a été résolu. Si une bibliothèque télécharge également depuis un autre dépôt (un modèle de base, un adaptateur, un composant hébergé dans son propre dépôt, …), elle a besoin d’une révision résolue pour ce dépôt. Il suffit de renvoyer le ResolvedRevision à HfApi.resolve_revision() : ce dernier se souvient du dépôt auquel il appartient et résout à nouveau la révision initialement demandée ("main" ici) pour le nouveau dépôt.
>>> other_revision = resolve_revision("openai-community/gpt2-medium", revision=revision) # resolves "main" again
>>> other_revision.resolved
'6dcaa7a952f72f9298047fd5137cd6e4f05f41da'
>>> config = hf_hub_download("openai-community/gpt2-medium", "config.json", revision=other_revision)Mise en cache Xet
Pour fournir des téléversements plus efficaces, hf_xet ajoute un répertoire xet au cache existant de huggingface_hub. Il y stocke les shards (une structure de données qui associe les fichiers à des chunks) ainsi que les données de staging utilisées pour la déduplication et la reprise des téléversements. Pour plus d'informations sur le système de stockage Xet, consultez cette section.
hf_xet n’utilise plus de cache local de chunks pour les téléchargements. La définition de HF_XET_CHUNK_CACHE_SIZE_BYTES n’en active pas un. Les fichiers téléchargés sont toujours mis en cache dans le cache basé sur les fichiers.
Le répertoire xet, situé par défaut à ~/.cache/huggingface/xet, peut être configuré avec HF_XET_CACHE. Il présente la structure suivante :
<CACHE_DIR> ├─ xet │ ├─ environment_identifier │ │ ├─ shard-cache │ │ ├─ staging
Le répertoire environment_identifier est une chaîne encodée (il peut apparaître sur votre machine sous la forme https___cas_serv-tGqkUaZf_CBPHQ6h). Il est utilisé pendant le développement, permettant ainsi à des versions locales et de production du cache de coexister simultanément. Il est également utilisé lors du téléchargement depuis des dépôts situés dans des régions de stockage différentes. Vous pouvez voir plusieurs entrées de ce type dans le répertoire xet, chacune correspondant à un environnement différent, mais leur structure interne est identique.
Les répertoires internes servent aux fins suivantes :
shard-cachecontient des shards en cache utilisés sur le chemin de téléversement.stagingest un espace de travail conçu pour prendre en charge les téléversements reprenables.
Ils sont documentés ci-dessous.
Le cache de shards et les données de staging sont gérés par hf_xet en tant que couche d’optimisation pour les téléversements. Pour gérer les fichiers téléchargés, utilisez les API de cache basées sur les fichiers de huggingface_hub.
shard-cache
Ce cache est utilisé lors de la mise en ligne de contenu sur le Hub. Le répertoire est à plat, ne contenant que des fichiers de shards, chacun utilisant un ID comme nom de shard.
<CACHE_DIR> ├─ xet │ ├─ environment_identifier │ │ ├─ shard-cache │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdb │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb │ │ │ ├─ ceeeb7ea4cf6c0a8d395a2cf9c08871211fbbd17b9b5dc1005811845307e6b8f.mdb │ │ │ ├─ e8535155b1b11ebd894c908e91a1e14e3461dddd1392695ddc90ae54a548d8b2.mdb
Le shard-cache contient des shards qui sont :
- Généré localement et téléversé avec succès dans le CAS
- Téléchargé depuis CAS dans le cadre de l'algorithme de déduplication global
Les shards fournissent une correspondance entre les fichiers et les chunks. Lors des téléversements, chaque fichier est découpé en chunks et l’empreinte (hash) de chaque chunk est enregistrée. Chaque shard du cache est ensuite consulté. Si un shard contient un hash de chunk présent dans le fichier local en cours de téléversement, ce chunk peut être écarté, car il est déjà stocké dans le CAS.
Tous les shards ont une date d'expiration de 3 à 4 semaines à compter de leur téléchargement. Les shards expirés ne sont pas chargés lors de la mise en ligne et sont supprimés une semaine après leur expiration.
staging
Lorsqu'un téléversement s'interrompt avant que le nouveau contenu n'ait été validé dans le dépôt, vous devez reprendre le transfert du fichier. Toutefois, il est possible que certains blocs aient été téléversés avec succès avant l'interruption.
Afin de ne pas avoir à recommencer depuis le début, le répertoire staging sert d'espace de travail pendant les téléversements, en stockant les métadonnées des segments téléversés avec succès. Le répertoire staging a la structure suivante :
<CACHE_DIR>
├─ xet
│ ├─ environment_identifier
│ │ ├─ staging
│ │ │ ├─ shard-session
│ │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb
│ │ │ │ ├─ xorb-metadata
│ │ │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdbLorsque les fichiers sont traités et que les fragments sont téléversés avec succès, leurs métadonnées sont stockées dans xorb-metadata sous forme de shard. Lors de la reprise d’une session de téléversement, chaque fichier est à nouveau traité et les shards de ce répertoire sont consultés. Tout contenu déjà téléversé avec succès est ignoré, et tout nouveau contenu est téléversé (et ses métadonnées sont enregistrées).
Pendant ce temps, shard-session stocke les informations de fichiers et de fragments pour les fichiers traités. Une fois le téléchargement terminé avec succès, le contenu de ces fragments est déplacé vers le shard-cache plus persistant.
Limites et restrictions
Le shard-cache a une limite souple de 16 Go, configurable via la variable d’environnement HF_XET_SHARD_CACHE_SIZE_LIMIT. Il n’existe pas d’API de haut niveau pour gérer ce cache.
Le cache de shards et les données de staging sont utilisés pour optimiser les téléversements. Pour interagir avec les actifs eux-mêmes, il est recommandé d’utiliser les API du système de cache de huggingface_hub.
Si vous devez libérer l’espace utilisé par Xet ou déboguer d’éventuels problèmes liés au cache, supprimez simplement le cache xet en exécutant rm -rf ~/<cache_dir>/xet, où <cache_dir> est l’emplacement de votre cache Hugging Face, généralement ~/.cache/huggingface.
Exemple d'arborescence du répertoire de cache xet :
<CACHE_DIR> ├─ xet │ ├─ environment_identifier │ │ ├─ shard-cache │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdb │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb │ │ │ ├─ ceeeb7ea4cf6c0a8d395a2cf9c08871211fbbd17b9b5dc1005811845307e6b8f.mdb │ │ │ ├─ e8535155b1b11ebd894c908e91a1e14e3461dddd1392695ddc90ae54a548d8b2.mdb │ │ ├─ staging │ │ │ ├─ shard-session │ │ │ │ ├─ 906ee184dc1cd0615164a89ed64e8147b3fdccd1163d80d794c66814b3b09992.mdb │ │ │ │ ├─ xorb-metadata │ │ │ │ │ ├─ 1fe4ffd5cf0c3375f1ef9aec5016cf773ccc5ca294293d3f92d92771dacfc15d.mdb
Pour en savoir plus sur Xet Storage, consultez cette section.
Mise en cache des ressources
En plus de mettre en cache les fichiers du Hub, les bibliothèques en aval ont souvent besoin de mettre en cache d'autres fichiers liés à HF mais non gérés directement par huggingface_hub (par exemple : fichiers téléchargés depuis GitHub, données prétraitées, journaux, …). Pour mettre en cache ces fichiers, appelés assets, on peut utiliser cached_assets_path(). Ce petit utilitaire génère des chemins dans le cache HF de manière unifiée, en se basant sur le nom de la bibliothèque qui en fait la demande et, le cas échéant, sur un espace de noms et un nom de sous-dossier. L'objectif est de laisser chaque bibliothèque en aval gérer ses assets à sa manière (par exemple : aucune règle sur la structure), tant qu'elle reste dans le bon dossier d'assets. Ces bibliothèques peuvent ensuite s'appuyer sur les outils de huggingface_hub pour gérer le cache, notamment pour parcourir et supprimer des parties des assets via une commande CLI.
from huggingface_hub import cached_assets_path
assets_path = cached_assets_path(library_name="datasets", namespace="SQuAD", subfolder="download")
something_path = assets_path / "something.json" # Do anything you like in your assets folder !cached_assets_path() est la méthode recommandée pour stocker les ressources, mais elle n’est pas obligatoire. Si votre bibliothèque utilise déjà son propre cache, n’hésitez pas à l’utiliser !
Les assets en pratique
En pratique, votre cache d'actifs doit ressembler à l'arborescence suivante :
assets/
└── datasets/
│ ├── SQuAD/
│ │ ├── downloaded/
│ │ ├── extracted/
│ │ └── processed/
│ ├── Helsinki-NLP--tatoeba_mt/
│ ├── downloaded/
│ ├── extracted/
│ └── processed/
└── transformers/
├── default/
│ ├── something/
├── bert-base-cased/
│ ├── default/
│ └── training/
hub/
└── models--julien-c--EsperBERTo-small/
├── blobs/
│ ├── (...)
│ ├── (...)
├── refs/
│ └── (...)
└── [ 128] snapshots/
├── 2439f60ef33a0d46d85da5001d52aeda5b00ce9f/
│ ├── (...)
└── bbc77c8132af1cc5cf678da3f1ddf2de43606d48/
└── (...)Gérer votre cache basé sur des fichiers
Inspecter votre cache
Pour le moment, les fichiers en cache ne sont jamais supprimés de votre répertoire local : lorsque vous téléchargez une nouvelle révision d’une branche, les fichiers précédents sont conservés au cas où vous en auriez à nouveau besoin. Il peut donc être utile d’inspecter votre répertoire de cache afin de savoir quels dépôts et quelles révisions occupent le plus d’espace disque. huggingface_hub fournit des utilitaires que vous pouvez utiliser depuis l’interface en ligne de commande hf ou depuis Python.
Inspecter le cache depuis le terminal
Exécutez hf cache ls pour explorer ce qui est stocké localement. Par défaut, la commande agrège les informations par dépôt :
➜ hf cache ls ID SIZE LAST_ACCESSED LAST_MODIFIED REFS ------------------------------------ ------- ------------- ------------- ------------------- dataset/glue 116.3K 4 days ago 4 days ago 2.4.0 main 1.17.0 dataset/google/fleurs 64.9M 1 week ago 1 week ago main refs/pr/1 model/Jean-Baptiste/camembert-ner 441.0M 2 weeks ago 16 hours ago main model/bert-base-cased 1.9G 1 week ago 2 years ago model/t5-base 10.1K 3 months ago 3 months ago main model/t5-small 970.7M 3 days ago 3 days ago main refs/pr/1 Found 6 repo(s) for a total of 12 revision(s) and 3.4G on disk.
Ajoutez --revisions pour lister chaque instantané mis en cache et enchaînez les filtres pour vous concentrer sur l’essentiel. Les filtres comprennent les tailles et durées lisibles par l’humain, de sorte que des expressions telles que size>1GB ou accessed>30d fonctionnent immédiatement :
➜ hf cache ls --revisions --filter "size>1GB" --filter "accessed>30d" ID REVISION SIZE LAST_MODIFIED REFS ------------------------------------ ------------------ ------- ------------- ------------------- model/bert-base-cased 6d1d7a1a2a6cf4c2 1.9G 2 years ago model/t5-small 1c610f6b3f5e7d8a 1.1G 3 months ago main Found 2 repo(s) for a total of 2 revision(s) and 3.0G on disk.
Besoin d’une sortie exploitable par des machines ? Utilisez --format json pour obtenir des objets structurés ou --format csv pour des tableurs. Sinon, --quiet n’affiche que les identifiants (un par ligne) afin de pouvoir les transmettre à d’autres outils. Utilisez --sort pour trier les entrées par accessed, modified, name ou size (ajoutez :asc ou :desc pour contrôler l’ordre) et --limit pour limiter les résultats aux N premières entrées. Combinez ces options avec --cache-dir lorsque vous devez inspecter un cache stocké en dehors de HF_HOME.
Filtrer avec des outils shell courants
Une sortie tabulaire signifie que vous pouvez continuer à utiliser les outils que vous connaissez déjà. Par exemple, l'extrait de code ci-dessous trouve toutes les révisions en cache associées à t5-small :
➜ eval "hf cache ls --revisions" | grep "t5-small" model/t5-small 1c610f6b3f5e7d8a 1.1G 3 months ago main model/t5-small 8f3ad1c90fed7a62 820.1M 2 weeks ago refs/pr/1
Inspecter le cache depuis Python
Pour un usage plus avancé, utilisez scan_cache_dir(), l'utilitaire Python appelé par l'outil CLI.
Vous pouvez l'utiliser pour obtenir un rapport détaillé structuré autour de 4 dataclasses :
- HFCacheInfo : rapport complet renvoyé par scan_cache_dir()
- CachedRepoInfo : informations sur un dépôt mis en cache
- CachedRevisionInfo : informations sur une révision mise en cache (par exemple « snapshot ») au sein d’un dépôt
- CachedFileInfo : informations sur un fichier mis en cache dans un instantané
Voici un exemple d'utilisation simple. Consultez la référence pour plus de détails.
>>> from huggingface_hub import scan_cache_dir
>>> hf_cache_info = scan_cache_dir()
HFCacheInfo(
size_on_disk=3398085269,
repos=frozenset({
CachedRepoInfo(
repo_id='t5-small',
repo_type='model',
repo_path=PosixPath(...),
size_on_disk=970726914,
nb_files=11,
last_accessed=1662971707.3567169,
last_modified=1662971107.3567169,
revisions=frozenset({
CachedRevisionInfo(
commit_hash='d78aea13fa7ecd06c29e3e46195d6341255065d5',
size_on_disk=970726339,
snapshot_path=PosixPath(...),
# No `last_accessed` as blobs are shared among revisions
last_modified=1662971107.3567169,
files=frozenset({
CachedFileInfo(
file_name='config.json',
size_on_disk=1197
file_path=PosixPath(...),
blob_path=PosixPath(...),
blob_last_accessed=1662971707.3567169,
blob_last_modified=1662971107.3567169,
),
CachedFileInfo(...),
...
}),
),
CachedRevisionInfo(...),
...
}),
),
CachedRepoInfo(...),
...
}),
warnings=[
CorruptedCacheException("Snapshots dir doesn't exist in cached repo: ..."),
CorruptedCacheException(...),
...
],
)Vérifier votre cache
huggingface_hub peut vérifier que vos fichiers en cache correspondent aux sommes de contrôle du Hub. Utilisez la commande CLI hf cache verify pour valider la cohérence des fichiers d’une révision spécifique d’un dépôt spécifique :
>>> hf cache verify meta-llama/Llama-3.2-1B-Instruct
✅ Verified 13 file(s) for 'meta-llama/Llama-3.2-1B-Instruct' (model) in ~/.cache/huggingface/hub/models--meta-llama--Llama-3.2-1B-Instruct/snapshots/9213176726f574b556790deb65791e0c5aa438b6
All checksums match.Vérifier une révision mise en cache spécifique :
>>> hf cache verify meta-llama/Llama-3.1-8B-Instruct --revision 0e9e39f249a16976918f6564b8830bc894c89659Consultez la référence de la CLI
hf cache verifypour plus de détails sur l'utilisation et la liste complète des options.
Nettoyer votre cache
Analyser votre cache est intéressant, mais ce que vous voulez généralement faire ensuite, c’est supprimer certaines parties pour libérer de l’espace sur votre disque. C’est possible à l’aide des commandes CLI hf cache rm et hf cache prune. On peut également utiliser de manière programmatique les fonctions d’aide delete_revisions() et delete_files() de l’objet HFCacheInfo renvoyé lors de l’analyse du cache.
Stratégie de suppression
Pour supprimer une partie du cache, vous devez passer une liste de révisions à supprimer. L’outil définit une stratégie de libération de l’espace sur la base de cette liste. Il renvoie un objet DeleteCacheStrategy qui décrit les fichiers et dossiers qui seront supprimés. L’objet DeleteCacheStrategy vous indique la quantité d’espace attendue à libérer. Une fois que vous êtes d’accord avec la suppression, vous devez l’exécuter pour qu’elle prenne effet. Afin d’éviter toute incohérence, vous ne pouvez pas modifier manuellement un objet de stratégie.
La stratégie pour supprimer les révisions est la suivante :
- le dossier
snapshotcontenant les liens symboliques de révision est supprimé. - Les fichiers blobs qui ne sont ciblés que par des révisions à supprimer sont également supprimés.
- si une révision est liée à un ou plusieurs
refs, les références sont supprimées. - si toutes les révisions d'un dépôt sont supprimées, le dépôt en cache est supprimé dans son intégralité.
La suppression de fichiers individuels avec delete_files() suit la même logique : les entrées de snapshot sont supprimées, et leurs blobs ne sont supprimés que si aucun autre fichier en cache ne les référence. Les refs et les dossiers de snapshot sont conservés.
Les hachures de révision sont uniques pour tous les dépôts.
hf cache rmaccepte donc soit un identifiant de dépôt (par exemplemodel/bert-base-uncased), soit un hachure de révision seul ; lorsque vous passez un hachure, vous n’avez pas besoin de spécifier le dépôt séparément.
Si une révision n’est pas trouvée dans le cache, elle est ignorée silencieusement. De plus, si un fichier ou un dossier ne peut pas être trouvé lors de la tentative de suppression, un avertissement est consigné dans le journal, mais aucune erreur n’est levée. La suppression se poursuit pour les autres chemins contenus dans l’objet DeleteCacheStrategy.
Nettoyer le cache depuis le terminal
Utilisez hf cache rm pour supprimer définitivement des dépôts ou des révisions de votre cache. Transmettez
un ou plusieurs identifiants de dépôt (par exemple model/bert-base-uncased) ou des hachages de révision :
➜ hf cache rm model/bert-base-cased About to delete 1 repo(s) totalling 1.9G. - model/bert-base-cased (entire repo) Proceed with deletion? [y/N]: y Deleted 1 repo(s) and 1 revision(s); freed 1.9G.
Vous pouvez également utiliser hf cache rm en combinaison avec hf cache ls --quiet pour supprimer en masse les entrées identifiées par un filtre :
>>> hf cache rm $(hf cache ls --filter "accessed>1y" -q) -y
About to delete 2 repo(s) totalling 5.31G.
- model/meta-llama/Llama-3.2-1B-Instruct (entire repo)
- model/hexgrad/Kokoro-82M (entire repo)
Deleted 2 repo(s) and 2 revision(s); freed 5.31G.Mélangez des dépôts et des révisions dans le même appel. Ajoutez --dry-run pour prévisualiser l’impact,
ou --yes pour ignorer la demande de confirmation lors de l’automatisation :
➜ hf cache rm model/t5-small 8f3ad1c --dry-run
About to delete 1 repo(s) and 1 revision(s) totalling 1.1G.
- model/t5-small:
8f3ad1c [main] 1.1G
Dry run: no files were deleted.Pour supprimer un fichier unique plutôt qu’un dépôt entier, par exemple une quantification GGUF,
passez un URI de fichier hf://. Le fichier est supprimé de toutes les révisions mises en cache du dépôt, et
son blob est supprimé uniquement si aucun autre fichier mis en cache ne le référence encore. La révision reste
utilisable, et un fichier supprimé est à nouveau téléchargé la prochaine fois qu’il est nécessaire. Les chemins doivent correspondre
exactement : les dossiers et les motifs glob ne sont pas pris en charge.
➜ hf cache rm hf://models/unsloth/gemma-3-27b-it-GGUF/gemma-3-27b-it-Q4_K_M.gguf --dry-run About to delete 1 file(s) totalling 16.5G. - model/unsloth/gemma-3-27b-it-GGUF@3f4b5c1d2e6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c/gemma-3-27b-it-Q4_K_M.gguf Dry run: no files were deleted.
Lorsque vous travaillez hors de l'emplacement de cache par défaut, associez la commande à --cache-dir PATH.
Pour nettoyer les résidus du cache en masse, exécutez hf cache prune. Cette commande supprime automatiquement les révisions qui ne sont plus référencées par une branche ou un tag, les fichiers .incomplete résiduels issus de téléchargements interrompus, ainsi que les blobs partagés qui ne sont plus référencés par aucun dépôt en cache :
➜ hf cache prune
About to delete 3 unreferenced revision(s) and 2 incomplete download(s) (2.4G total).
- model/t5-small:
1c610f6b [refs/pr/1] 820.1M
d4ec9b72 [(detached)] 640.5M
- dataset/google/fleurs:
2b91c8dd [(detached)] 937.6M
Proceed? [y/N]: y
Deleted 3 unreferenced revision(s) and 2 incomplete download(s); freed 2.4G.Les fichiers .incomplete sont des blobs partiels laissés derrière lors d’une interruption de téléchargement. Ils ne sont pas suivis par le scan basé sur les révisions, de sorte que hf cache ls ne les signale que par un indice (Found X incomplete download(s) ...), tandis que hf cache prune est la commande qui les supprime réellement. hf cache rm ne les touche jamais, sauf lorsqu’elle supprime un dépôt entier.
Les deux commandes prennent en charge --dry-run, --yes et --cache-dir, ce qui vous permet d'effectuer un aperçu, d'automatiser et de cibler des répertoires de cache alternatifs au besoin.
Nettoyer le cache depuis Python
Pour plus de flexibilité, vous pouvez également utiliser la méthode delete_revisions() de manière programmatique. Voici un exemple simple. Consultez la référence pour plus de détails.
>>> from huggingface_hub import scan_cache_dir
>>> delete_strategy = scan_cache_dir().delete_revisions(
... "81fd1d6e7847c99f5862c9fb81387956d99ec7aa"
... "e2983b237dccf3ab4937c97fa717319a9ca1a96d",
... "6c0e6080953db56375760c0471a8c5f2929baf11",
... )
>>> print("Will free " + delete_strategy.expected_freed_size_str)
Will free 8.6G
>>> delete_strategy.execute()