Hub documentation
Руководство по вебхукам: настройка автоматической системы для повторного обучения модели при изменении набора данных
Руководство по вебхукам: настройка автоматической системы для повторного обучения модели при изменении набора данных
В этом руководстве описано, как настроить автоматический конвейер обучения на платформе Hugging Face с использованием HF Datasets, Webhooks, Spaces и AutoTrain.
Мы создадим Webhook, который отслеживает изменения в наборе данных для классификации изображений и запускает дообучение модели microsoft/resnet-50 с помощью AutoTrain.
Предварительное условие: загрузите ваш набор данных в Hub
Для примера мы будем использовать простой набор данных для классификации изображений. Подробнее о загрузке данных в Hub можно узнать здесь.

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

Создайте Space для реакции на ваш Webhook
Теперь нам нужен способ реагировать на события вашего Webhook. Простой способ сделать это — использовать Space!
Пример Space можно найти здесь.
Этот Space использует Docker, Python, FastAPI и uvicorn для запуска простого HTTP-сервера. Подробнее о Docker Spaces можно прочитать здесь.
Точка входа — src/main.py. Разберём этот файл и подробно опишем, что он делает:
- Он запускает приложение FastAPI, которое будет ожидать HTTP-запросы
POSTпо адресу/webhook:
from fastapi import FastAPI
# [...]
@app.post("/webhook")
async def post_webhook(
# ...
):
# ...- Этот маршрут проверяет наличие заголовка
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)
# [...]- Платформа кодирует полезную нагрузку события в формате 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}
#[...]- Если данные корректны, следующим шагом является создание проекта на 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"])Перейдите по ссылке в комментарии, чтобы ознакомиться с оценкой стоимости обучения, и начните дообучение модели!

В этом примере мы использовали 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».


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

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