Hub documentation

Guide des webhooks : Configurer un système automatique pour réentraîner un modèle lorsqu'un jeu de données change

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

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.

dataset

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 :

webhook-creation

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 :

  1. Il crée une application FastAPI qui écoutera les requêtes HTTP POST sur /webhook :
from fastapi import FastAPI

# [...]
@app.post("/webhook")
async def post_webhook(
	# ...
):

# ...
    1. Cette route vérifie que l’en-tête X-Webhook-Secret est présent et que sa valeur est identique à celle définie dans les paramètres de votre Webhook. Le secret WEBHOOK_SECRET doit être défini dans les paramètres du Space et être identique au secret défini dans votre Webhook.
# [...]

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)
	# [...]
  1. 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}
	#[...]
  1. 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-50 dans 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 !

community tab notification

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 droits write. 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 ».

embed this Space

direct URL

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

webhook settings

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