Hub documentation
Руководство по вебхукам: Настройка автоматического контроля качества метаданных для моделей и наборов данных
Руководство по вебхукам: Настройка автоматического контроля качества метаданных для моделей и наборов данных
В этом руководстве вы узнаете, как создать систему, которая реагирует на изменения моделей или наборов данных пользователя или организации на Hub и создаёт «metadata review» для изменённого репозитория.
Что мы создаем и зачем?
Прежде чем перейти к техническим деталям данного рабочего процесса, кратко опишем, что именно мы создаём и зачем.
Карточки моделей и карточки наборов данных — это необходимые инструменты для документирования моделей машинного обучения и наборов данных. Hugging Face Hub использует файл README.md с заголовочным блоком YAML для генерации карточек моделей и наборов данных. Этот раздел YAML определяет метаданные, относящиеся к модели или набору данных. Например:
---
language:
- "List of ISO 639-1 code for your language"
- lang1
- lang2
tags:
- tag1
- tag2
license: "any valid license identifier"
datasets:
- dataset1
---Эти метаданные содержат важную информацию о вашей модели или наборе данных для потенциальных пользователей. Например, лицензия определяет условия, на которых модель или набор данных могут использоваться. Пользователи Hub также могут использовать поля, определённые в метаданных YAML, в качестве фильтров для поиска моделей или наборов данных, соответствующих определённым критериям.
Поскольку метаданные, определённые в этом блоке, имеют решающее значение для потенциальных пользователей наших моделей и наборов данных, важно заполнить этот раздел. В командной или организационной среде пользователи, загружающие модели и наборы данных в Hub, могут по-разному осознавать важность этого блока метаданных в формате YAML. Хотя кто-то из команды может взять на себя ответственность за проверку этих метаданных, мы можем автоматизировать этот процесс, чтобы решить проблему. Результатом станет отчёт о проверке метаданных, который автоматически публикуется или обновляется при изменении репозитория в Hub. С точки зрения качества метаданных эта система работает аналогично CI/CD.

Вы также можете найти пример рецензии здесь.
Создание карточки обзора модели с использованием библиотеки клиента Hub
huggingface_hub — это библиотека Python, которая позволяет взаимодействовать с Hub. С помощью этой библиотеки можно скачивать карточки моделей и наборов данных с Hub, используя методы DatasetCard.load или ModelCard.load. В частности, мы будем использовать эти методы для загрузки словаря Python, содержащего метаданные, определённые в YAML нашей карточки модели или набора данных. Мы создадим небольшую функцию Python, которая обернёт эти методы и выполнит обработку исключений.
from huggingface_hub import DatasetCard, ModelCard
from huggingface_hub.utils import EntryNotFoundError
def load_repo_card_metadata(repo_type, repo_name):
if repo_type == "dataset":
try:
return DatasetCard.load(repo_name).data.to_dict()
except EntryNotFoundError:
return {}
if repo_type == "model":
try:
return ModelCard.load(repo_name).data.to_dict()
except EntryNotFoundError:
return {}Эта функция возвращает словарь Python, содержащий метаданные, связанные с репозиторием (или пустой словарь, если метаданные отсутствуют).
{'license': 'afl-3.0'}Создание отчёта о проверке метаданных
Когда у нас есть словарь Python, содержащий метаданные, связанные с репозиторием, мы создадим «отчёт» для проверки метаданных. В данном случае мы будем проверять метаданные, определяя те поля метаданных, для которых нам нужны значения. Например, мы можем захотеть убедиться, что поле license всегда заполнено. Чтобы оценить качество метаданных, мы посчитаем, сколько из желаемых полей метаданных присутствуют, и вернём процентный балл на основе охвата обязательных полей метаданных, для которых мы хотим видеть значения.
Поскольку у нас есть словарь Python, содержащий метаданные, мы можем перебрать его, чтобы проверить наличие нужных ключей. Если поле метаданных (ключ в словаре) отсутствует, мы присвоим ему значение None.
def create_metadata_key_dict(card_data, repo_type: str):
shared_keys = ["tags", "license"]
if repo_type == "model":
model_keys = ["library_name", "datasets", "metrics", "co2", "pipeline_tag"]
shared_keys.extend(model_keys)
keys = shared_keys
return {key: card_data.get(key) for key in keys}
if repo_type == "dataset":
# [...]Эта функция возвращает словарь, содержащий ключи, представляющие поля метаданных, необходимые для нашей модели или набора данных. Значения словаря будут содержать либо введённые метаданные для данного поля, либо None, если это поле метаданных отсутствует в YAML.
{'tags': None,
'license': 'afl-3.0',
'library_name': None,
'datasets': None,
'metrics': None,
'co2': None,
'pipeline_tag': None}После создания этого словаря мы можем сформировать отчёт с метаданными. В целях краткости мы не приводим здесь полный код, однако в репозитории Hugging Face Spaces для этого Webhook доступен полный код.
Мы создаём одну функцию, которая формирует таблицу в формате Markdown, чтобы представить данные из нашего словаря покрытия метаданных в более наглядном виде.
def create_metadata_breakdown_table(desired_metadata_dictionary):
# [...]
return tabulate(
table_data, tablefmt="github", headers=("Metadata Field", "Provided Value")
)Также у нас есть функция на Python, которая генерирует оценку (представляющую собой процент присутствующих требуемых полей метаданных)
def calculate_grade(desired_metadata_dictionary):
# [...]
return round(score, 2)и функцию на Python, которая создаёт отчёт в формате Markdown для проверки метаданных. Этот отчёт содержит как таблицу с оценками, так и таблицу метаданных, а также пояснение о содержании отчёта.
def create_markdown_report(
desired_metadata_dictionary, repo_name, repo_type, score, update: bool = False
):
# [...]
return reportКак автоматически опубликовать отзыв?
Теперь у нас есть отчёт о проверке метаданных в формате Markdown. Мы будем использовать библиотеку huggingface_hub, чтобы опубликовать этот отчёт. Мы определяем функцию, которая принимает данные Webhook, полученные от Hub, разбирает их и создаёт отчёт о метаданных. В зависимости от того, был ли ранее создан отчёт, функция создаёт новый отчёт или публикует новую issue в существующей ветке обсуждения проверки метаданных.
def create_or_update_report(data):
if parsed_post := parse_webhook_post(data):
repo_type, repo_name = parsed_post
else:
return Response("Unable to parse webhook data", status_code=400)
# [...]
return True
:=— это синтаксис оператора присваивания, добавленный в язык Python в версии 3.8 (в обиходе его называют оператором моржа). Мнения об этом синтаксисе неоднозначны, и он не меняет способ, которым Python выполняет код, если вы им не пользуетесь. Подробнее об этом операторе можно прочитать в этой статье на Real Python.
Создание Webhook для реагирования на изменения на Hub
Теперь у нас есть базовая функциональность для создания отчёта о проверке метаданных модели или набора данных. Следующий шаг — использовать Webhooks для автоматического реагирования на изменения.
Создайте Webhook в профиле пользователя
Сначала создайте свой Webhook, перейдя по адресу https://huggingface.co/settings/webhooks.
- Введите несколько целевых репозиториев, на которые будет реагировать ваш Webhook (скорее всего, вы захотите ограничить их только своими репозиториями или репозиториями организации, к которой вы принадлежите).
- Введите секрет, чтобы повысить безопасность вашего Webhook (если вы не знаете, что выбрать, вы можете использовать генератор паролей, чтобы создать достаточно длинную случайную строку для секрета).
- Пока что для параметра
Webhook URLможно передать фиктивный URL.
Ваш Webhook будет выглядеть так:

Создать новый профиль пользователя Bot
В этом руководстве создаётся отдельная учётная запись пользователя, которая будет публиковать обзоры метаданных.

При создании бота, который будет взаимодействовать с другими пользователями на Hub, мы просим явно указать в аккаунте, что это «Бот» (см. скриншот профиля).
Создание слушателя Webhook
Теперь нам нужен способ отслеживать события Webhook. Существует множество инструментов, которые можно использовать для прослушивания событий Webhook. Многие существующие сервисы, такие как Zapier и IFTTT, могут использовать Webhooks для запуска действий (например, публиковать твит каждый раз при обновлении модели). В данном случае мы реализуем наш слушатель Webhook с помощью FastAPI.
FastAPI — это веб-фреймворк на Python. Мы будем использовать FastAPI для создания слушателя Webhook. В частности, нам нужно реализовать маршрут, который принимает запросы POST на /webhook. Для аутентификации мы будем сравнивать заголовок X-Webhook-Secret с секретом WEBHOOK_SECRET, который можно передать в наш Docker-контейнер во время выполнения.
from fastapi import FastAPI, Request, Response
import os
KEY = os.environ.get("WEBHOOK_SECRET")
app = FastAPI()
@app.post("/webhook")
async def webhook(request: Request):
if request.method == "POST":
if request.headers.get("X-Webhook-Secret") != KEY:
return Response("Invalid secret", status_code=401)
data = await request.json()
result = create_or_update_report(data)
return "Webhook received!" if result else resultФункция, приведённая выше, будет получать события Webhook и создавать или обновлять отчёт о проверке метаданных для изменённого репозитория.
Используйте Spaces для развертывания нашего приложения Webhook
Наш файл main.py содержит весь код, необходимый для нашего приложения Webhook. Для его развертывания мы будем использовать Space.
Для нашего Space мы будем использовать Docker для запуска приложения. Dockerfile копирует файл нашего приложения, устанавливает необходимые зависимости и запускает приложение. Чтобы заполнить переменную KEY, мы также установим секрет WEBHOOK_SECRET для нашего Space, используя сгенерированный ранее секрет. Подробнее о Docker Spaces можно прочитать здесь.
Наконец, нам нужно обновить URL в настройках Webhook, указав URL нашего Space. «Прямой URL» (direct URL) нашего Space можно получить из контекстного меню. Нажмите «Embed this Space» и скопируйте «Direct URL».

После получения этого URL мы можем передать его в параметр Webhook URL в настройках Webhook. Теперь наш бот должен начинать публиковать отзывы при изменениях в отслеживаемых репозиториях!
Выводы и следующие шаги
Теперь у нас есть автоматический бот для проверки метаданных! Вот несколько идей, как можно расширить этот гайд:
- Проверка метаданных, выполняемая нашим ботом, была относительно примитивной; вы можете добавить более сложные правила для проверки метаданных.
- Вы можете использовать полный файл
README.mdдля проведения ревью. - Вы можете определить «правила», которые особенно важны для вашей организации, и использовать вебхук для проверки их соблюдения.
Если вы создадите приложение для контроля качества метаданных с использованием Webhooks, пожалуйста, отметьте меня @davanstrien; мне было бы очень интересно узнать об этом!
Update on GitHub