Hub documentation

Guía de Webhooks: Configuración de un sistema automático para volver a entrenar un modelo cuando cambia un conjunto de datos

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Guía de Webhooks: Configuración de un sistema automático para volver a entrenar un modelo cuando cambia un conjunto de datos

Esta guía te ayudará a configurar un pipeline de entrenamiento automático en la plataforma de Hugging Face utilizando HF Datasets, Webhooks, Spaces y AutoTrain.

Construiremos un Webhook que escucha los cambios en un conjunto de datos de clasificación de imágenes y desencadena el ajuste fino de microsoft/resnet-50 usando AutoTrain.

Prerrequisito: Sube tu conjunto de datos al Hub

Utilizaremos un conjunto de datos simple de clasificación de imágenes a efectos del ejemplo. Obtenga más información sobre la carga de sus datos en el Hub aquí.

dataset

Crea un Webhook para reaccionar a los cambios del conjunto de datos

Primero, creemos un Webhook desde tus ajustes.

  • Seleccione su conjunto de datos como el repositorio de destino. En este ejemplo, el objetivo será huggingface-projects/input-dataset.
  • Puedes poner una URL de Webhook ficticia por ahora. Al definir tu Webhook podrás ver los eventos que se enviarán a él. También puedes reproducirlos, lo cual será útil para depurar!
  • Introduce un secreto para aumentar la seguridad.
  • Suscríbase a los eventos de “Repo update” ya que queremos reaccionar a los cambios de datos

Tu Webhook se verá así:

webhook-creation

Crea un Space para reaccionar a tu Webhook

Ahora necesitamos una forma de reaccionar a tus eventos de Webhook. Una forma sencilla de hacerlo es usar un Space

Puedes encontrar un ejemplo de Space aquí.

Este Space utiliza Docker, Python, FastAPI y uvicorn para ejecutar un servidor HTTP simple. Lea más sobre los Spaces de Docker aquí.

El punto de entrada es src/main.py. Repasemos este archivo y detallemos lo que hace:

  1. Crea una aplicación de FastAPI que escuchará las solicitudes HTTP POST en /webhook:
from fastapi import FastAPI

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

# ...
    1. Esta ruta comprueba que la cabecera X-Webhook-Secret esté presente y que su valor sea el mismo que el que configuraste en la configuración de tu Webhook. El secreto WEBHOOK_SECRET debe estar configurado en la configuración del Space y ser el mismo que el secreto configurado en tu 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. El payload del evento se codifica como JSON. Aquí, usaremos modelos de pydantic para analizar el payload del evento. También especificamos que ejecutaremos nuestro Webhook solo cuando:
  • el evento se refiere al conjunto de datos de entrada
  • el evento es una actualización del contenido del repositorio, es decir, se ha realizado un nuevo commit
# 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 el payload es válido, el siguiente paso es crear un proyecto en AutoTrain, programar el fine-tuning del modelo de entrada (microsoft/resnet-50 en nuestro ejemplo) sobre el conjunto de datos de entrada y crear una discusión en el conjunto de datos cuando esté terminado.
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"])

Visita el enlace dentro del comentario para revisar la estimación del costo de entrenamiento y ¡comienza a ajustar el modelo!

community tab notification

En este ejemplo, usamos Hugging Face AutoTrain para ajustar nuestro modelo rápidamente, pero por supuesto que puedes usar tu propia infraestructura de entrenamiento.

Siéntase libre de duplicar el Space en su espacio de nombres personal y experimente con él. Deberá proporcionar dos secretos:

  • WEBHOOK_SECRET : el secreto de tu Webhook.
  • HF_ACCESS_TOKEN : un token de acceso de usuario con permisos de write. Puedes crear uno desde tu configuración.

También deberá ajustar el archivo config.json para utilizar el conjunto de datos y el modelo de su elección:

{
	"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"
}

Configura tu Webhook para enviar eventos a tu Space

Por último, pero no menos importante, deberá configurar su webhook para enviar solicitudes POST a su Space.

Primero, obtengamos la “URL directa” de nuestro Space desde el menú contextual. Haz clic en “Embed this Space” y copia la “Direct URL”.

embed this Space

direct URL

Actualiza tu Webhook para enviar solicitudes a esa URL:

webhook settings

¡Y eso es todo! Ahora cada commit al conjunto de datos de entrada activará un fine-tuning de ResNet-50 con AutoTrain 🎉

Update on GitHub