Hub documentation
Guide des webhooks : Configurer un système automatique pour réentraîner un modèle lorsqu'un jeu de données change
Guide des webhooks : Configurer un système automatique pour réentraîner un modèle lorsqu'un jeu de données change
Ce guide vous accompagne dans la configuration d’un pipeline d’entraînement automatique sur la plateforme Hugging Face en utilisant HF Datasets, Webhooks, Spaces et AutoTrain.
Nous allons créer un Webhook qui écoute les modifications d’un jeu de données de classification d’images et déclenche un fine-tuning de microsoft/resnet-50 à l’aide de AutoTrain.
Prérequis : téléversez votre jeu de données sur le Hub
Nous utiliserons un jeu de données simple de classification d’images à titre d’exemple. En savoir plus sur la mise en ligne de vos données sur le Hub ici.

Créer un Webhook pour réagir aux modifications du jeu de données
Tout d'abord, créons un Webhook depuis vos paramètres.
- Sélectionnez votre jeu de données comme dépôt cible. Dans cet exemple, nous visons huggingface-projects/input-dataset.
- Vous pouvez saisir une URL Webhook fictive pour l'instant. La définition de votre Webhook vous permettra de consulter les événements qui y seront envoyés. Vous pourrez également les rejouer, ce qui sera utile pour le débogage !
- Saisissez un secret pour renforcer la sécurité.
- S'abonner aux événements « Repo update » car nous voulons réagir aux modifications des données
Votre Webhook ressemblera à ceci :

Créer un Space pour réagir à votre Webhook
Nous avons maintenant besoin d'un moyen de réagir à vos événements Webhook. Une façon simple de le faire est d'utiliser un Space !
Vous pouvez trouver un exemple de Space ici.
Cet espace utilise Docker, Python, FastAPI et uvicorn pour exécuter un serveur HTTP simple. En savoir plus sur les espaces Docker ici.
Le point d’entrée est src/main.py. Parcourons ce fichier et détaillons ce qu’il fait :
- Il crée une application FastAPI qui écoutera les requêtes HTTP
POSTsur/webhook:
from fastapi import FastAPI
# [...]
@app.post("/webhook")
async def post_webhook(
# ...
):
# ...- Cette route vérifie que l’en-tête
X-Webhook-Secretest présent et que sa valeur est identique à celle définie dans les paramètres de votre Webhook. Le secretWEBHOOK_SECRETdoit être défini dans les paramètres du Space et être identique au secret défini dans votre Webhook.
- Cette route vérifie que l’en-tête
# [...]
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET")
# [...]
@app.post("/webhook")
async def post_webhook(
# [...]
x_webhook_secret: Optional[str] = Header(default=None),
# ^ checks for the X-Webhook-Secret HTTP header
):
if x_webhook_secret is None:
raise HTTPException(401)
if x_webhook_secret != WEBHOOK_SECRET:
raise HTTPException(403)
# [...]- La charge utile de l'événement est encodée en JSON. Ici, nous utiliserons des modèles pydantic pour analyser la charge utile de l'événement. Nous spécifions également que notre Webhook ne sera exécuté que lorsque :
- l'événement concerne le jeu de données d'entrée
- l'événement est une mise à jour du contenu du dépôt, c'est-à-dire qu'un nouveau commit a été effectué
# defined in src/models.py
class WebhookPayloadEvent(BaseModel):
action: Literal["create", "update", "delete", "move"]
scope: str
class WebhookPayloadRepo(BaseModel):
type: Literal["dataset", "model", "space"]
name: str
id: str
private: bool
headSha: str
class WebhookPayload(BaseModel):
event: WebhookPayloadEvent
repo: WebhookPayloadRepo
# [...]
@app.post("/webhook")
async def post_webhook(
# [...]
payload: WebhookPayload,
# ^ Pydantic model defining the payload format
):
# [...]
if not (
payload.event.action == "update"
and payload.event.scope.startswith("repo.content")
and payload.repo.name == config.input_dataset
and payload.repo.type == "dataset"
):
# no-op if the payload does not match our expectations
return {"processed": False}
#[...]- Si la charge utile est valide, l’étape suivante consiste à créer un projet sur AutoTrain, à planifier un fine-tuning du modèle d’entrée (
microsoft/resnet-50dans notre exemple) sur le jeu de données d’entrée, puis à créer une discussion sur le jeu de données une fois terminé !
def schedule_retrain(payload: WebhookPayload):
# Create the autotrain project
try:
project = AutoTrain.create_project(payload)
AutoTrain.add_data(project_id=project["id"])
AutoTrain.start_processing(project_id=project["id"])
except requests.HTTPError as err:
print("ERROR while requesting AutoTrain API:")
print(f" code: {err.response.status_code}")
print(f" {err.response.json()}")
raise
# Notify in the community tab
notify_success(project["id"])Consultez le lien dans le commentaire pour examiner l’estimation du coût d’entraînement, puis lancez le fine-tuning du modèle !

Dans cet exemple, nous avons utilisé Hugging Face AutoTrain pour affiner notre modèle rapidement, mais vous pouvez bien sûr intégrer votre propre infrastructure d'entraînement !
N'hésitez pas à dupliquer le Space dans votre espace de noms personnel et à l'essayer. Vous devrez fournir deux secrets :
WEBHOOK_SECRET: le secret de votre Webhook.HF_ACCESS_TOKEN: un jeton d’accès utilisateur avec les droitswrite. Vous pouvez en créer un dans vos paramètres.
Vous devrez également ajuster le fichier config.json pour utiliser le jeu de données et le modèle de votre choix :
{
"target_namespace": "the namespace where the trained model should end up",
"input_dataset": "the dataset on which the model will be trained",
"input_model": "the base model to re-train",
"autotrain_project_prefix": "A prefix for the AutoTrain project"
}Configurez votre Webhook pour envoyer des événements à votre Space
Enfin, vous devrez configurer votre webhook pour envoyer des requêtes POST vers votre Space.
Commençons par récupérer l’« URL directe » de notre Space depuis le menu contextuel. Cliquez sur « Intégrer ce Space » et copiez l’« URL directe ».


Mettez à jour votre Webhook pour envoyer des requêtes vers cette URL :

Et c’est tout ! Désormais, chaque commit sur le jeu de données d’entrée déclenchera un fine-tuning de ResNet-50 avec AutoTrain 🎉
Update on GitHub