Hub documentation

Руководство по вебхукам: настройка автоматической системы для повторного обучения модели при изменении набора данных

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Руководство по вебхукам: настройка автоматической системы для повторного обучения модели при изменении набора данных

В этом руководстве описано, как настроить автоматический конвейер обучения на платформе Hugging Face с использованием HF Datasets, Webhooks, Spaces и AutoTrain.

Мы создадим Webhook, который отслеживает изменения в наборе данных для классификации изображений и запускает дообучение модели microsoft/resnet-50 с помощью AutoTrain.

Предварительное условие: загрузите ваш набор данных в Hub

Для примера мы будем использовать простой набор данных для классификации изображений. Подробнее о загрузке данных в Hub можно узнать здесь.

dataset

Создайте Webhook для реакции на изменения в наборе данных

Сначала создайте Webhook в своих настройках.

  • Выберите свой набор данных в качестве целевого репозитория. В этом примере мы будем использовать huggingface-projects/input-dataset.
  • Пока можно указать тестовый URL Webhook. Определение Webhook позволит просматривать события, которые будут на него отправляться. Кроме того, их можно воспроизвести заново, что будет полезно при отладке!
  • Введите секрет, чтобы повысить безопасность.
  • Подпишитесь на события «Repo update», так как мы хотим реагировать на изменения данных

Ваш Webhook будет выглядеть так:

webhook-creation

Создайте Space для реакции на ваш Webhook

Теперь нам нужен способ реагировать на события вашего Webhook. Простой способ сделать это — использовать Space!

Пример Space можно найти здесь.

Этот Space использует Docker, Python, FastAPI и uvicorn для запуска простого HTTP-сервера. Подробнее о Docker Spaces можно прочитать здесь.

Точка входа — src/main.py. Разберём этот файл и подробно опишем, что он делает:

  1. Он запускает приложение FastAPI, которое будет ожидать HTTP-запросы POST по адресу /webhook:
from fastapi import FastAPI

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

# ...
    1. Этот маршрут проверяет наличие заголовка X-Webhook-Secret и совпадение его значения с тем, что вы указали в настройках Webhook. Секрет WEBHOOK_SECRET должен быть задан в настройках Space и совпадать с секретом, установленным в вашем 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. Платформа кодирует полезную нагрузку события в формате JSON. Здесь мы будем использовать модели pydantic для разбора полезной нагрузки события. Мы также указываем, что наш Webhook будет выполняться только в том случае, если:
  • событие касается входного набора данных
  • событие представляет собой обновление содержимого репозитория, то есть был создан новый коммит
# 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. Если данные корректны, следующим шагом является создание проекта на AutoTrain, планирование дообучения входной модели (microsoft/resnet-50 в нашем примере) на входном наборе данных и создание обсуждения на наборе данных по завершении!
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"])

Перейдите по ссылке в комментарии, чтобы ознакомиться с оценкой стоимости обучения, и начните дообучение модели!

community tab notification

В этом примере мы использовали Hugging Face AutoTrain для быстрой дообучения модели, но, конечно, вы можете подключить собственную инфраструктуру обучения!

Вы можете скопировать Space в своё личное пространство и поэкспериментировать с ним. Вам потребуется указать два секрета:

  • WEBHOOK_SECRET : секрет из вашего Webhook.
  • HF_ACCESS_TOKEN : токен доступа пользователя с правами write. Вы можете создать его в настройках.

Вам также потребуется внести изменения в файл config.json, чтобы использовать выбранные вами набор данных и модель:

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

Настройте свой Webhook для отправки событий в ваше Space

И наконец, вам нужно настроить вебхук для отправки POST-запросов в ваше пространство.

Сначала получим «прямой URL» нашего Space из контекстного меню. Нажмите «Embed this Space» и скопируйте «Direct URL».

embed this Space

direct URL

Обновите ваш Webhook, чтобы отправлять запросы на этот URL:

webhook settings

И всё! Теперь каждый коммит в исходный набор данных будет запускать дообучение ResNet-50 с помощью AutoTrain 🎉

Update on GitHub