Hub Python Library documentation
Interagir avec le Hub via l'API Filesystem
Interagir avec le Hub via l'API Filesystem
En plus de HfApi, la bibliothèque huggingface_hub fournit HfFileSystem, une interface de fichiers compatible fsspec et pythonique pour le Hugging Face Hub. HfFileSystem s’appuie sur HfApi et propose des opérations typiques d’un système de fichiers, telles que cp, mv, ls, du, glob, get_file et put_file.
HfFileSystem offre une compatibilité avec fsspec, ce qui est utile pour les bibliothèques qui en ont besoin (par exemple, pour lire directement les jeux de données et les buckets Hugging Face avec
pandas). Cependant, cette couche de compatibilité introduit un surcoût supplémentaire. Pour de meilleures performances et une meilleure fiabilité, il est recommandé d’utiliser les méthodes de HfApi lorsque c’est possible.
Utilisation
>>> from huggingface_hub import hffs
>>> # List all files in a dataset directory
>>> hffs.ls("datasets/my-username/my-dataset-repo/data", detail=False)
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']
>>> # List all files in a bucket directory
>>> hffs.ls("buckets/my-username/my-bucket/experiment-data", detail=False)
['bucket/my-username/my-bucket/data/train-0000.parquet', 'bucket/my-username/my-bucket/data/train-0001.parquet', ...]
>>> # List all ".csv" files in a dataset repository
>>> hffs.glob("datasets/my-username/my-dataset-repo/**/*.csv")
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']
>>> # Read a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/train.csv", "r") as f:
... train_data = f.readlines()
>>> # Read the content of a remote file as a string
>>> train_data = hffs.read_text("datasets/my-username/my-dataset-repo/data/train.csv", revision="dev")
>>> # Write a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/validation.csv", "w") as f:
... f.write("text,label")
... f.write("Fantastic movie!,good")L'argument facultatif revision peut être transmis pour exécuter une opération à partir d'un commit spécifique, tel qu'une branche, un nom de tag ou un hachage de commit. Notez que revision n'est pas compatible avec Buckets.
Contrairement à la fonction open intégrée de Python, la fonction open de fsspec utilise par défaut le mode binaire, "rb". Cela signifie qu’il faut définir explicitement le mode sur "r" pour la lecture et sur "w" pour l’écriture en mode texte. L’ajout à un fichier (modes "a" et "ab") n’est pas encore pris en charge.
Lister les dépôts volumineux
Les opérations qui listent les fichiers de manière récursive, telles que find et glob, doivent récupérer l’intégralité du contenu du dépôt. Le Hub renvoie ces entrées page par page, et une page ne peut être demandée qu’une fois la précédente reçue : lister un dépôt contenant 800 k fichiers nécessite environ 800 requêtes séquentielles, soit environ 30 minutes.
Pour éviter cela, HfFileSystem liste les grands dépôts répertoire par répertoire, en parallèle :
>>> from huggingface_hub import hffs
>>> # Takes ~30s on a repository holding 800k files
>>> files = hffs.glob("datasets/allenai/objaverse/**/*.glb", maxdepth=3)Le nombre de requêtes simultanées est contrôlé par l’argument max_workers de HfFileSystem. Sa valeur par défaut est 16
et il peut être défini à 1 pour désactiver les listings parallèles.
Notez que le passage d’un maxdepth accélère également considérablement les listings, car le Hub ne renvoie alors que les entrées
effectivement demandées.
Gardez les listes à jour
Les répertoires sont listés une seule fois et leur contenu est mis en cache, de sorte qu’un répertoire modifié par quelqu’un d’autre n’est pas pris en compte automatiquement. HfFileSystem.invalidate_cache() supprime les listes mises en cache, soit pour un chemin donné (et ses parents), soit pour l’ensemble du système lorsqu’il est appelé sans argument :
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # listing is cached
>>> # ... another process uploads a file to the bucket ...
>>> hffs.invalidate_cache("buckets/my-username/my-bucket/data")
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # listed again
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']Pour les buckets, huggingface_hub peut le faire pour vous : le Hub transmet en continu les modifications de fichiers d’un bucket au fur et à mesure qu’elles se produisent, et HfFileSystem supprime les listes affectées par une modification dès son arrivée. Activez-le avec live_follow=True :
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(live_follow=True)
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # starts following that bucket
>>> # ... another process uploads a file to the bucket ...
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False) # refreshed as changes arrive
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']Il peut également être transmis via fsspec, avec fsspec.filesystem("hf", live_follow=True) ou via l'argument storage_options des bibliothèques qui l'acceptent (pandas, arrow, …).
Quelques points à connaître à ce sujet :
- Buckets uniquement. Les dépôts de modèles, de jeux de données et d’espaces sont des dépôts git et le Hub ne diffuse pas leurs modifications : passez
refresh=Trueà HfFileSystem.ls() (ou utilisez HfApi.list_repo_tree()) pour voir un nouvel engagement. - Seules les listes et les métadonnées qu’elles contiennent sont actualisées. La lecture d’un fichier demande toujours son contenu au Hub, de sorte que le suivi en direct n’affecte que ce que
ls,info,exists,glob, … rapportent. - Le suivi démarre dès qu’un seau est listé, et une connexion d’arrière-plan est maintenue ouverte par seau suivi, partagée par toutes les instances HfFileSystem. C’est pourquoi cette option est activable manuellement.
Intégrations
Le HfFileSystem peut être utilisé avec toute bibliothèque qui intègre fsspec, à condition que l’URL suive le schéma :
hf://[<repo_type_prefix>]<repo_id>[@<revision>]/<path/in/repo>
Le repo_type_prefix est datasets/ pour les jeux de données, spaces/ pour les Spaces, et les modèles n’ont pas besoin de préfixe dans l’URL.
En plus des dépôts, le HfFileSystem prend également en charge les Buckets Hugging Face, qui constituent un stockage d’objets de type S3 (voir ce guide pour plus de détails) :
hf://buckets/<bucket_id>/<path/in/bucket>Voici quelques intégrations intéressantes dans lesquelles HfFileSystem simplifie l’interaction avec le Hub :
Lecture/écriture d'un DataFrame Pandas depuis/vers un dépôt du Hub :
>>> import pandas as pd >>> # Read a remote CSV file into a dataframe >>> df = pd.read_csv("hf://datasets/my-username/my-dataset-repo/train.csv") >>> df = pd.read_csv("hf://buckets/my-username/my-bucket/train.csv") >>> # Write a dataframe to a remote CSV file >>> df.to_csv("hf://datasets/my-username/my-dataset-repo/test.csv") >>> df.to_csv("hf://buckets/my-username/my-bucket/test.csv")
Le même flux de travail peut également être utilisé pour les DataFrames Dask et Polars.
Interroger les fichiers (distants) du Hub avec DuckDB :
>>> from huggingface_hub import HfFileSystem >>> import duckdb >>> fs = HfFileSystem() >>> duckdb.register_filesystem(fs) >>> # Query a remote file and get the result back as a dataframe >>> fs_query_file = "hf://datasets/my-username/my-dataset-repo/data_dir/data.parquet" >>> df = duckdb.query(f"SELECT * FROM '{fs_query_file}' LIMIT 10").df()Utiliser le Hub comme magasin de tableaux avec Zarr :
>>> import numpy as np >>> import zarr >>> embeddings = np.random.randn(50000, 1000).astype("float32") >>> # Write an array to a repo >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="w") >>> foo = root.create_group("embeddings") >>> foobar = foo.zeros(name="experiment_0", shape=(50000, 1000), chunks=(10000, 1000), dtype="f4") >>> foobar[:] = embeddings >>> # Read an array from a repo >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="r") >>> first_row = root["embeddings/experiment_0"][0]
Authentification
Dans de nombreux cas, vous devez être connecté avec un compte Hugging Face pour interagir avec le Hub. Reportez-vous à la section Authentication de la documentation pour en savoir plus sur les méthodes d’authentification sur le Hub.
Il est également possible de se connecter de manière programmatique en passant votre token en argument à HfFileSystem :
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(token=token)Si vous vous connectez de cette manière, prenez soin de ne pas divulguer accidentellement le jeton lors du partage de votre code source !
Update on GitHub