Hub Python Library documentation

Téléverser des fichiers sur le Hub

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v2.4.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Téléverser des fichiers sur le Hub

Partager vos fichiers et votre travail est un aspect important du Hub. La bibliothèque huggingface_hub propose plusieurs options pour téléverser vos fichiers sur le Hub. Vous pouvez utiliser ces fonctions de manière indépendante ou les intégrer à votre bibliothèque, ce qui facilite l’interaction de vos utilisateurs avec le Hub.

Chaque fois que vous souhaitez téléverser des fichiers sur le Hub, vous devez vous connecter à votre compte Hugging Face. Pour plus de détails sur l’authentification, consultez cette section.

Téléverser un fichier

Une fois que vous avez créé un dépôt avec create_repo(), vous pouvez téléverser un fichier dans votre dépôt à l’aide de upload_file().

Spécifiez le chemin du fichier à téléverser, l’emplacement souhaité dans le dépôt et le nom du dépôt auquel vous souhaitez ajouter le fichier. Selon le type de votre dépôt, vous pouvez éventuellement définir le type de dépôt comme dataset, model ou space.

>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.upload_file(
...     path_or_fileobj="/path/to/local/folder/README.md",
...     path_in_repo="README.md",
...     repo_id="username/test-dataset",
...     repo_type="dataset",
... )

Téléverser un dossier

Utilisez la fonction upload_folder() pour téléverser un dossier local vers un dépôt existant. Spécifiez le chemin du dossier local à téléverser, l’emplacement dans le dépôt où vous souhaitez téléverser le dossier, ainsi que le nom du dépôt auquel vous souhaitez ajouter le dossier. Selon le type de votre dépôt, vous pouvez éventuellement définir le type de dépôt comme dataset, model ou space.

>>> from huggingface_hub import HfApi
>>> api = HfApi()

# Upload all the content from the local folder to your remote Space.
# By default, files are uploaded at the root of the repo
>>> api.upload_folder(
...     folder_path="/path/to/local/space",
...     repo_id="username/my-cool-space",
...     repo_type="space",
... )

Par défaut, le fichier .gitignore est pris en compte pour déterminer quels fichiers doivent être commités ou non. Par défaut, nous vérifions si un fichier .gitignore est présent dans un commit, et sinon, nous vérifions s'il existe sur le Hub. Veuillez noter que seul un fichier .gitignore présent à la racine du répertoire sera utilisé. Nous ne vérifions pas les fichiers .gitignore dans les sous-répertoires.

Si vous ne souhaitez pas utiliser un fichier .gitignore codé en dur, vous pouvez utiliser les arguments allow_patterns et ignore_patterns pour filtrer les fichiers à téléverser. Ces paramètres acceptent soit un motif unique, soit une liste de motifs. Les motifs sont des jokers standard (motifs globbing) tels que documentés ici. Si allow_patterns et ignore_patterns sont tous deux fournis, les deux contraintes s’appliquent.

En plus du fichier .gitignore et des motifs d'autorisation/ignorance, tout dossier .git/ présent dans un sous-dossier sera ignoré.

>>> api.upload_folder(
...     folder_path="/path/to/local/folder",
...     path_in_repo="my-dataset/train", # Upload to a specific folder
...     repo_id="username/test-dataset",
...     repo_type="dataset",
...     ignore_patterns="**/logs/*.txt", # Ignore all text logs
... )

Vous pouvez également utiliser l’argument delete_patterns pour spécifier les fichiers que vous souhaitez supprimer du dépôt dans le même commit. Cela peut s’avérer utile si vous voulez nettoyer un dossier distant avant d’y pousser des fichiers et que vous ne savez pas quels fichiers existent déjà.

L’exemple ci-dessous téléverse le dossier local ./logs vers le dossier distant /experiment/logs/. Seuls les fichiers txt sont téléversés, mais avant cela, tous les journaux précédents du dépôt sont supprimés. Tout cela dans un seul commit.

>>> api.upload_folder(
...     folder_path="/path/to/local/folder/logs",
...     repo_id="username/trained-model",
...     path_in_repo="experiment/logs/",
...     allow_patterns="*.txt", # Upload all local text files
...     delete_patterns="*.txt", # Delete all remote text files before
... )

Comment les fichiers sont téléversés

Lorsque hf_xet est installé (ce qui est le cas par défaut), upload_folder() téléverse les fichiers via un pipeline en streaming : les fichiers sont vérifiés par rapport au Hub, téléversés vers le backend de stockage Xet (qui effectue le découpage, la déduplication et les nouvelles tentatives de transfert en interne), puis validés par lots adaptatifs, le tout en parallèle. En pratique, cela signifie :

  • Dossiers de toute taille : les petits dossiers sont téléversés en un seul commit, tandis que les dossiers contenant de nombreux fichiers sont automatiquement répartis en plusieurs commits afin de rester sous les limites du serveur. Dans ce cas, les commits suivants reçoivent un suffixe (part 2), (part 3), … dans le message du commit.
  • Reprise possible : si le téléversement est interrompu pour quelque raison que ce soit, il suffit de relancer le même appel. Les fichiers déjà validés sont détectés et ignorés, et les fragments déjà téléversés sont dédupliqués — leur re-téléversement ne transfère (presque) aucune donnée. Aucun état local n’est impliqué : vous pouvez même reprendre depuis une autre machine. Une exception : avec create_pr=True, la relance ouvre une nouvelle pull request. Nous recommandons plutôt de relancer avec revision="refs/pr/N" lors de la reprise du téléversement.
  • Aucune double lecture : les fichiers sont hachés pendant leur découpage pour l’envoi, en une seule passe de lecture. Il n’y a pas de phase de « hachage » distincte avant le début de l’envoi.

L’affichage de progression en direct suit les trois étapes :

Found 5,000 files to upload
  Preparing   ████████████████████  5,000 / 5,000 ✓
  Uploading   ██████████████░░░░░░  423 / 603 files  3.8GB · 19.7MB/s
  Committing  ██████████████████░░  4,580 / 5,000  6 commits

Si hf_xet n'est pas installé, upload_folder() bascule sur le comportement legacy : hacher d'abord tout le contenu, téléverser via HTTP, puis créer un commit unique. Nous recommandons toujours de conserver hf_xet installé pour une meilleure robustesse

Téléverser depuis l'interface en ligne de commande

Vous pouvez utiliser la commande hf upload depuis le terminal pour téléverser directement des fichiers sur le Hub. Elle utilise en interne les mêmes fonctions d’aide upload_file() et upload_folder() décrites ci-dessus.

Vous pouvez soit téléverser un fichier unique, soit un dossier entier :

# Usage:  hf upload [repo_id] [local_path] [path_in_repo]
>>> hf upload Wauplin/my-cool-model ./models/model.safetensors model.safetensors
https://huggingface.co/Wauplin/my-cool-model/blob/main/model.safetensors

>>> hf upload Wauplin/my-cool-model ./models .
https://huggingface.co/Wauplin/my-cool-model/tree/main

local_path et path_in_repo sont facultatifs et peuvent être inférés implicitement. Si local_path n’est pas défini, l’outil vérifie si un dossier ou un fichier local porte le même nom que repo_id. Si c’est le cas, son contenu sera téléversé. Sinon, une exception est levée demandant à l’utilisateur de définir explicitement local_path. Dans tous les cas, si path_in_repo n’est pas défini, les fichiers sont téléversés à la racine du dépôt.

La destination peut également être exprimée sous forme d'un unique URI hf:// suivant la grammaire hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>] (voir la référence des URI HF pour la syntaxe complète). Le type de dépôt, la révision et le path_in_repo sont alors lus depuis l'URI, qui ne peut pas être combinée aux options --repo-type et --revision :

# Upload a single file to a dataset on a specific branch
>>> hf upload hf://datasets/Wauplin/my-cool-dataset@my-branch/data/train.csv ./train.csv
https://huggingface.co/datasets/Wauplin/my-cool-dataset/blob/my-branch/data/train.csv

Pour un débit de téléchargement maximal sur les fichiers volumineux, définissez la variable d’environnement HF_XET_HIGH_PERFORMANCE=1. Cela active le mode haute performance de hf_xet, qui sature la bande passante et les cœurs CPU disponibles. Remarque : l’indicateur hérité HF_HUB_ENABLE_HF_TRANSFER=1 n’est plus utilisé depuis le remplacement de hf_transfer par hf_xet — définissez plutôt HF_XET_HIGH_PERFORMANCE=1.

Pour plus de détails sur la commande d'upload CLI, veuillez consulter le guide CLI.

Téléverser un grand dossier

upload_folder() et la commande hf upload sont les solutions de référence pour téléverser des fichiers sur le Hub, y compris pour des dossiers très volumineux. Les fichiers sont diffusés vers le Hub en plusieurs commits et le processus reprend automatiquement en cas d’interruption. Il suffit de relancer le même appel et les fichiers déjà téléversés sont ignorés.

>>> api.upload_folder(
...     repo_id="HuggingFaceM4/Docmatix",
...     repo_type="dataset",
...     folder_path="/path/to/local/docmatix",
... )

ou depuis le terminal :

hf upload HuggingFaceM4/Docmatix --repo-type=dataset /path/to/local/docmatix

Astuces et conseils pour les gros téléversements

Il existe certaines limites à prendre en compte lors de la manipulation d’un grand volume de données dans votre dépôt. Compte tenu du temps nécessaire pour diffuser les données, il peut être très agaçant qu’un téléversement/push échoue en fin de processus ou que l’expérience soit dégradée, que ce soit sur hf.co ou lors d’un travail local.

Consultez notre guide Limites et recommandations des dépôts pour les bonnes pratiques de structuration de vos dépôts sur le Hub. Passons maintenant à quelques conseils pratiques pour rendre votre processus de téléversement aussi fluide que possible.

  • Commencez petit : Nous recommandons de commencer avec un petit volume de données pour tester votre script de téléversement. Il est plus facile d’itérer sur un script lorsque l’échec ne prend que peu de temps.
  • Prévoyez des échecs : le streaming de grandes quantités de données est complexe. Vous ne savez pas ce qui peut se passer, mais il est toujours préférable de considérer que quelque chose échouera au moins une fois, que ce soit à cause de votre machine, de votre connexion ou de nos serveurs. Par exemple, si vous prévoyez de téléverser un grand nombre de fichiers, il est préférable de suivre localement les fichiers que vous avez déjà téléversés avant de passer au lot suivant. Il est garanti qu'un fichier LFS déjà commit ne sera jamais re-téléversé deux fois, mais le vérifier côté client peut tout de même faire gagner du temps. C'est ce que fait upload_folder() pour vous.
  • Utiliser hf_xet : ce dernier exploite le nouveau backend de stockage du Hub, est écrit en Rust et est désormais disponible pour tous. En effet, hf_xet est déjà activé par défaut lors de l'utilisation de huggingface_hub ! Pour des performances maximales, définissez HF_XET_HIGH_PERFORMANCE=1 en tant que variable d'environnement. Notez que lorsque le mode haute performance est activé, l'outil tentera d'utiliser toute la bande passante et tous les cœurs CPU disponibles.

Fonctionnalités avancées

Dans la plupart des cas, vous n’aurez besoin que de upload_file() et upload_folder() pour téléverser vos fichiers sur le Hub. Cependant, huggingface_hub propose des fonctionnalités plus avancées pour faciliter les choses. Voyons-les !

Téléversements plus rapides

Profitez de téléversements plus rapides grâce à hf_xet, le binding Python de la bibliothèque xet-core qui permet la déduplication par blocs pour des téléversements et téléchargements plus rapides. hf_xet s’intègre parfaitement à huggingface_hub, mais utilise la bibliothèque Rust xet-core et le stockage Xet au lieu de LFS.

hf_xet utilise le système de stockage Xet, qui découpe les fichiers en chunks immuables, stocke des collections de ces chunks (appelés blocks ou xorbs) à distance et les récupère pour réassembler le fichier lorsqu’il est demandé. Lors d’un téléversement, après avoir confirmé que l’utilisateur est autorisé à écrire dans ce dépôt, hf_xet analyse les fichiers, les découpe en chunks et regroupe ces chunks en xorbs (avec déduplication par rapport aux chunks connus), puis téléverse ces xorbs vers le service de contenu adressable (CAS) de Xet, qui vérifie l’intégrité des xorbs, enregistre les métadonnées des xorbs avec l’empreinte SHA256 LFS (pour permettre la recherche et le téléchargement) et écrit les xorbs dans le stockage distant.

Pour l'activer, il suffit d'installer la dernière version de huggingface_hub :

pip install -U "huggingface_hub"

À partir de huggingface_hub 0.32.0, cela installera également hf_xet.

Toutes les autres API de huggingface_hub continueront de fonctionner sans aucune modification. Pour en savoir plus sur les avantages du stockage Xet et de hf_xet, consultez cette section.

Précautions à prendre lors du téléchargement sur un système de fichiers de cluster / distribué

Lors d’un téléversement depuis un cluster, les fichiers à téléverser résident souvent sur un système de fichiers distribué ou réseau (NFS, EBS, Lustre, Fsx, etc.). Le stockage Xet découpe ces fichiers en blocs (également appelés xorbs) et les écrit localement, puis les téléverse une fois le bloc terminé. Pour de meilleures performances lors du téléversement depuis un système de fichiers distribué, assurez-vous de définir HF_XET_CACHE sur un répertoire situé sur un disque local (par ex. un disque NVMe ou SSD local). L’emplacement par défaut du cache Xet se trouve sous HF_HOME à (~/.cache/huggingface/xet) et, comme il se situe dans le répertoire personnel de l’utilisateur, il est souvent également localisé sur le système de fichiers distribué.

Téléversements non bloquants

Dans certains cas, vous souhaitez envoyer des données sans bloquer votre thread principal. Cela est particulièrement utile pour téléverser des journaux et des artefacts tout en poursuivant un entraînement. Pour ce faire, vous pouvez utiliser l'argument run_as_future dans upload_file() et upload_folder(). Cela renverra un objet concurrent.futures.Future que vous pouvez utiliser pour vérifier l'état du téléversement.

>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> future = api.upload_folder( # Upload in the background (non-blocking action)
...     repo_id="username/my-model",
...     folder_path="checkpoints-001",
...     run_as_future=True,
... )
>>> future
Future(...)
>>> future.done()
False
>>> future.result() # Wait for the upload to complete (blocking action)
...

Les tâches en arrière-plan sont mises en file d'attente lors de l'utilisation de run_as_future=True. Cela signifie que vous avez la garantie que les tâches seront exécutées dans le bon ordre.

Bien que les tâches en arrière-plan soient surtout utiles pour téléverser des données ou créer des commits, vous pouvez mettre en file d’attente n’importe quelle méthode de votre choix à l’aide de run_as_future(). Par exemple, vous pouvez l’utiliser pour créer un dépôt puis téléverser des données dans celui-ci en arrière-plan. L’argument intégré run_as_future des méthodes de téléversement n’est qu’un alias à ce sujet.

>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.run_as_future(api.create_repo, "username/my-model", exists_ok=True)
Future(...)
>>> api.upload_file(
...     repo_id="username/my-model",
...     path_in_repo="file.txt",
...     path_or_fileobj=b"file content",
...     run_as_future=True,
... )
Future(...)

Copier des fichiers entre les dépôts

Utilisez copy_files() pour copier des fichiers ou des dossiers entre les dépôts du Hub sans télécharger ni réenvoyer de grandes données. C’est utile lorsque vous souhaitez dupliquer des poids entre des variantes de modèles, copier des fichiers de jeu de données entre des dépôts, ou réorganiser des fichiers entre vos dépôts. En interne, cela crée un commit avec des opérations CommitOperationCopy.

>>> from huggingface_hub import HfApi
>>> api = HfApi()

# Copy a single file between repos
>>> api.copy_files(
...     "hf://username/source-model/weights.safetensors",
...     "hf://username/target-model/weights.safetensors",
... )

# Copy an entire folder
>>> api.copy_files(
...     "hf://datasets/username/source-dataset/data/",
...     "hf://datasets/username/target-dataset/data/",
... )

Vous pouvez également copier au sein du même dépôt :

# Duplicate a file in the same repo
>>> api.copy_files(
...     "hf://username/my-model/config.json",
...     "hf://username/my-model/backup/config.json",
... )

Lors de la copie d'un dossier, un / final sur la source utilise des sémantiques de type rsync, ce qui signifie que le contenu du dossier est copié, sans imbriquer le dossier lui-même. Sans / final, le dossier lui-même est imbriqué à la destination.

copy_files() prend également en charge la copie de fichiers vers des Buckets. Consultez le guide des Buckets pour plus de détails.

Téléversements planifiés

Le Hugging Face Hub facilite l’enregistrement et la gestion des versions des données. Toutefois, certaines limites apparaissent lors de la mise à jour du même fichier des milliers de fois. Par exemple, vous pourriez vouloir enregistrer les journaux d’un processus d’entraînement ou les retours des utilisateurs sur un Space déployé. Dans ces cas, il est pertinent de téléverser les données en tant que jeu de données sur le Hub, mais cela peut s’avérer difficile à réaliser correctement. La raison principale est que vous ne souhaitez pas versionner chaque mise à jour de vos données, car cela rendrait le dépôt git inutilisable. La classe CommitScheduler propose une solution à ce problème.

L’idée est d’exécuter une tâche en arrière-plan qui pousse régulièrement un dossier local vers le Hub. Supposons que vous disposiez d’un Space Gradio qui prend en entrée du texte et génère deux traductions. L’utilisateur peut ensuite sélectionner la traduction de son choix. Pour chaque exécution, vous souhaitez enregistrer l’entrée, la sortie et la préférence de l’utilisateur afin d’analyser les résultats. C’est un cas d’usage idéal pour CommitScheduler ; vous voulez enregistrer des données sur le Hub (potentiellement des millions de retours utilisateurs), mais vous n’avez pas besoin de sauvegarder en temps réel l’entrée de chaque utilisateur. Vous pouvez plutôt enregistrer les données localement dans un fichier JSON et les téléverser toutes les 10 minutes. Par exemple :

>>> import json
>>> import uuid
>>> from pathlib import Path
>>> import gradio as gr
>>> from huggingface_hub import CommitScheduler

# Define the file where to save the data. Use UUID to make sure not to overwrite existing data from a previous run.
>>> feedback_file = Path("user_feedback/") / f"data_{uuid.uuid4()}.json"
>>> feedback_folder = feedback_file.parent

# Schedule regular uploads. Remote repo and local folder are created if they don't already exist.
>>> scheduler = CommitScheduler(
...     repo_id="report-translation-feedback",
...     repo_type="dataset",
...     folder_path=feedback_folder,
...     path_in_repo="data",
...     every=10,
... )

# Define the function that will be called when the user submits its feedback (to be called in Gradio)
>>> def save_feedback(input_text:str, output_1: str, output_2:str, user_choice: int) -> None:
...     """
...     Append input/outputs and user feedback to a JSON Lines file using a thread lock to avoid concurrent writes from different users.
...     """
...     with scheduler.lock:
...         with feedback_file.open("a") as f:
...             f.write(json.dumps({"input": input_text, "output_1": output_1, "output_2": output_2, "user_choice": user_choice}))
...             f.write("\n")

# Start Gradio
>>> with gr.Blocks() as demo:
>>>     ... # define Gradio demo + use `save_feedback`
>>> demo.launch()

Et c’est tout ! Les entrées/sorties des utilisateurs et les retours seront disponibles sous forme de jeu de données sur le Hub. En utilisant un nom de fichier JSON unique, vous êtes garanti de ne pas écraser les données d’une exécution précédente ou les données d’autres Spaces/réplicas poussant simultanément vers le même dépôt.

Pour plus de détails sur le CommitScheduler, voici ce qu'il faut savoir :

  • ajout uniquement : Il est supposé que vous n'ajouterez que du contenu au dossier. Vous devez uniquement ajouter des données aux fichiers existants ou créer de nouveaux fichiers. Supprimer ou écraser un fichier pourrait corrompre votre dépôt.
  • historique git : Le planificateur effectuera un commit du dossier toutes les every minutes. Pour éviter de polluer excessivement le dépôt git, il est recommandé de définir une valeur minimale de 5 minutes. Par ailleurs, le planificateur est conçu pour éviter les commits vides. Si aucun nouveau contenu n'est détecté dans le dossier, le commit planifié est annulé.
  • errors : Le planificateur s'exécute en tant que thread en arrière-plan. Il démarre lors de l'instantiation de la classe et continue de s'exécuter jusqu'à ce que stop() soit appelé ou que le processus se termine. Si une erreur se produit pendant le téléversement (par exemple : problème de connexion), l'erreur est journalisée et le planificateur réessaie lors du prochain engagement planifié.
  • scripts : Dans un script à durée de vie limitée (par exemple, l’entraînement), utilisez le planificateur en tant que gestionnaire de contexte. La sortie du bloc with déclenche un dernier envoi, attend sa fin et arrête le planificateur.
  • sécurité des threads : Dans la plupart des cas, il est sûr de supposer que vous pouvez écrire dans un fichier sans avoir à vous soucier d'un fichier de verrouillage. Le planificateur ne plantera pas et ne sera pas corrompu si vous écrivez du contenu dans le dossier pendant qu'il téléverse. En pratique, il est possible que des problèmes de concurrence surviennent pour les applications fortement sollicitées. Dans ce cas, nous conseillons d'utiliser le verrou scheduler.lock pour garantir la sécurité des threads. Le verrou est bloqué uniquement lorsque le planificateur scanne le dossier à la recherche de modifications, et non lors du téléversement des données. Vous pouvez supposer sans risque qu'il n'affectera pas l'expérience utilisateur sur votre Space.

Démo de persistance d'espace

La persistance des données d’un Space vers un Dataset sur le Hub est le cas d’usage principal de CommitScheduler. Selon le cas d’usage, vous pouvez vouloir structurer vos données différemment. La structure doit être robuste face aux utilisateurs concurrents et aux redémarrages, ce qui implique souvent de générer des UUID. Outre la robustesse, vous devez téléverser les données dans un format lisible par la bibliothèque 🤗 Datasets pour une réutilisation ultérieure. Nous avons créé un Space qui montre comment enregistrer plusieurs formats de données différents (vous devrez peut-être l’adapter à vos besoins spécifiques).

Téléversements personnalisés

CommitScheduler suppose que vos données sont en ajout uniquement et doivent être téléversées « telles quelles ». Toutefois, vous pourriez souhaiter personnaliser la manière dont les données sont téléversées. Vous pouvez le faire en créant une classe héritant de CommitScheduler et en écrasant la méthode push_to_hub (n’hésitez pas à l’écraser comme vous le souhaitez). Il est garanti qu’elle sera appelée toutes les every minutes dans un thread en arrière-plan. Vous n’avez pas à vous soucier de la concurrence ni des erreurs, mais vous devez faire attention à d’autres aspects, tels que le téléversement de commits vides ou de données dupliquées.

Dans l'exemple (simplifié) ci-dessous, nous réécrivons push_to_hub pour compresser tous les fichiers PNG dans une seule archive afin d'éviter de surcharger le dépôt sur le Hub :

class ZipScheduler(CommitScheduler):
    def push_to_hub(self):
        # 1. List PNG files
        png_files = list(self.folder_path.glob("*.png"))
        if len(png_files) == 0:
            return None  # return early if nothing to commit

        # 2. Zip png files in a single archive
        with tempfile.TemporaryDirectory() as tmpdir:
            archive_path = Path(tmpdir) / "train.zip"
            with zipfile.ZipFile(archive_path, "w", zipfile.ZIP_DEFLATED) as zip:
                for png_file in png_files:
                    zip.write(filename=png_file, arcname=png_file.name)

            # 3. Upload archive
            self.api.upload_file(..., path_or_fileobj=archive_path)

        # 4. Delete local png files to avoid re-uploading them later
        for png_file in png_files:
            png_file.unlink()

Lorsque vous écrasez push_to_hub, vous avez accès aux attributs de CommitScheduler et notamment :

  • Client HfApi : api
  • Paramètres de dossier : folder_path et path_in_repo
  • Paramètres du dépôt : repo_id, repo_type, revision
  • Le verrou de thread : lock

Pour plus d'exemples de planificateurs personnalisés, consultez notre Space de démonstration qui contient différentes implémentations selon vos cas d'usage.

create_commit

Les fonctions upload_file() et upload_folder() sont des API de haut niveau, généralement pratiques à utiliser. Nous recommandons d’essayer ces fonctions en premier si vous n’avez pas besoin de travailler à un niveau inférieur. Toutefois, si vous souhaitez travailler au niveau des commits, vous pouvez utiliser directement la fonction create_commit().

Trois types d'opérations sont pris en charge par create_commit() :

  • CommitOperationAdd téléverse un fichier sur le Hub. Si le fichier existe déjà, son contenu est écrasé. Cette opération accepte deux arguments :

    • path_in_repo : le chemin du dépôt vers lequel téléverser un fichier.
    • path_or_fileobj : soit un chemin vers un fichier sur votre système de fichiers, soit un objet de type fichier. Il s’agit du contenu du fichier à téléverser sur le Hub.
  • CommitOperationDelete supprime un fichier ou un dossier d’un dépôt. Cette opération accepte path_in_repo comme argument.

  • CommitOperationCopy copie un fichier au sein d'un dépôt ou entre dépôts. Cette opération accepte les arguments suivants :

    • src_path_in_repo : le chemin du fichier à copier dans le dépôt.
    • path_in_repo : le chemin du dépôt où le fichier doit être copié.
    • src_revision : facultatif - la révision du fichier à copier si vous souhaitez copier un fichier depuis une autre branche/révision.
    • src_repo_id : facultatif - le dépôt source à copier (par ex. "username/source-model"). Par défaut, le dépôt de destination est utilisé.
    • src_repo_type : facultatif - le type du dépôt source ("model", "dataset" ou "space"). Obligatoire lorsque src_repo_id est défini.

Par exemple, si vous souhaitez téléverser deux fichiers et supprimer un fichier dans un dépôt du Hub :

  1. Utilisez l’opération CommitOperation appropriée pour ajouter ou supprimer un fichier et pour supprimer un dossier :
>>> from huggingface_hub import HfApi, CommitOperationAdd, CommitOperationDelete
>>> api = HfApi()
>>> operations = [
...     CommitOperationAdd(path_in_repo="LICENSE.md", path_or_fileobj="~/repo/LICENSE.md"),
...     CommitOperationAdd(path_in_repo="weights.h5", path_or_fileobj="~/repo/weights-final.h5"),
...     CommitOperationDelete(path_in_repo="old-weights.h5"),
...     CommitOperationDelete(path_in_repo="logs/"),
...     CommitOperationCopy(src_path_in_repo="image.png", path_in_repo="duplicate_image.png"),
... ]
  1. Passez vos opérations à create_commit() :
>>> api.create_commit(
...     repo_id="lysandre/test-model",
...     operations=operations,
...     commit_message="Upload my model weights and license",
... )

En plus de upload_file() et upload_folder(), les fonctions suivantes utilisent également create_commit() en interne :

Pour plus de détails, consultez la référence HfApi.

Pré-téléverser les fichiers LFS avant le commit

Dans certains cas, vous pouvez vouloir téléverser de très gros fichiers sur S3 avant d'effectuer l'appel de commit. Par exemple, si vous commitez un jeu de données en plusieurs shards générés en mémoire, vous devrez téléverser les shards un par un pour éviter un problème de mémoire insuffisante. Une solution consiste à téléverser chaque shard comme un commit distinct sur le dépôt. Bien que parfaitement valide, cette solution présente l'inconvénient de potentiellement désorganiser l'historique git en générant des dizaines de commits. Pour contourner ce problème, vous pouvez téléverser vos fichiers un par un sur S3 puis créer un commit unique à la fin. Cela est possible en utilisant preupload_lfs_files() en combinaison avec create_commit().

Ceci est une méthode destinée aux utilisateurs avancés. Dans la grande majorité des cas, il est préférable d’utiliser directement upload_file(), upload_folder() ou create_commit() plutôt que de gérer la logique de bas niveau de pré-téléversement des fichiers. La principale précaution à prendre avec preupload_lfs_files() est que, tant que le commit n’a pas réellement été effectué, les fichiers téléversés ne sont pas accessibles sur le dépôt du Hub. Si vous avez une question, n’hésitez pas à nous contacter sur notre Discord ou via une issue GitHub.

Voici un exemple simple illustrant comment pré-téléverser des fichiers :

>>> from huggingface_hub import CommitOperationAdd, preupload_lfs_files, create_commit, create_repo

>>> repo_id = create_repo("test_preupload").repo_id

>>> operations = [] # List of all `CommitOperationAdd` objects that will be generated
>>> for i in range(5):
...     content = ... # generate binary content
...     addition = CommitOperationAdd(path_in_repo=f"shard_{i}_of_5.bin", path_or_fileobj=content)
...     preupload_lfs_files(repo_id, additions=[addition])
...     operations.append(addition)

>>> # Create commit
>>> create_commit(repo_id, operations=operations, commit_message="Commit all shards")

Tout d’abord, nous créons les objets CommitOperationAdd un par un. Dans un exemple concret, ceux-ci contiendraient les shards générés. Chaque fichier est téléversé avant de générer le suivant. Lors de l’étape preupload_lfs_files(), l’objet CommitOperationAdd est modifié. Vous ne devez l’utiliser que pour le transmettre directement à create_commit(). La principale mise à jour de l’objet est que le contenu binaire en est retiré, ce qui signifie qu’il sera collecté par le ramasse-miettes si vous ne conservez pas une autre référence à cet objet. C’est attendu, car nous ne souhaitons pas conserver en mémoire le contenu qui a déjà été téléversé. Enfin, nous créons le commit en transmettant toutes les opérations à create_commit(). Vous pouvez transmettre des opérations supplémentaires (ajout, suppression ou copie) qui n’ont pas encore été traitées, et elles seront gérées correctement.

Update on GitHub