Hub documentation

Guide des webhooks : Configurer une revue automatique de la qualité des métadonnées pour les modèles et les jeux de données

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Guide des webhooks : Configurer une revue automatique de la qualité des métadonnées pour les modèles et les jeux de données

Ce guide vous guide à travers la création d’un système qui réagit aux modifications des modèles ou des jeux de données d’un utilisateur ou d’une organisation sur le Hub et crée une « revue de métadonnées » pour le dépôt modifié.

Que construisons-nous et pourquoi ?

Avant de plonger dans les détails techniques de ce flux de travail en particulier, nous allons rapidement présenter ce que nous créons et pourquoi.

Les fiches de modèle et les fiches de jeu de données sont des outils essentiels pour documenter les modèles et les jeux de données d'apprentissage automatique. Le Hugging Face Hub utilise un fichier README.md contenant un bloc d'en-tête YAML pour générer les fiches de modèle et de jeu de données. Cette section YAML définit les métadonnées relatives au modèle ou au jeu de données. Par exemple :

---
language: 
  - "List of ISO 639-1 code for your language"
  - lang1
  - lang2
tags:
- tag1
- tag2
license: "any valid license identifier"
datasets:
- dataset1
---

Cette métadonnée contient des informations essentielles sur votre modèle ou votre jeu de données pour les utilisateurs potentiels. La licence, par exemple, définit les conditions dans lesquelles un modèle ou un jeu de données peut être utilisé. Les utilisateurs du Hub peuvent également utiliser les champs définis dans la métadonnée YAML comme filtres pour identifier les modèles ou les jeux de données qui correspondent à des critères spécifiques.

Les métadonnées définies dans ce bloc étant essentielles pour les utilisateurs potentiels de nos modèles et jeux de données, il est important de compléter cette section. Dans un contexte d’équipe ou d’organisation, les utilisateurs qui publient des modèles et des jeux de données sur le Hub peuvent avoir des niveaux de familiarité variables avec l’importance de ce bloc de métadonnées YAML. Si un membre de l’équipe peut prendre en charge la responsabilité de la revue de ces métadonnées, il est également possible de mettre en place une automatisation pour nous aider à résoudre ce problème. Le résultat sera un rapport de revue des métadonnées publié ou mis à jour automatiquement lorsqu’un dépôt sur le Hub est modifié. Pour la qualité de nos métadonnées, ce système fonctionne de manière similaire à CI/CD.

Metadata review

Vous pouvez également trouver un exemple d’examen ici.

Utiliser la bibliothèque client du Hub pour créer une fiche de révision de modèle

La bibliothèque huggingface_hub est une bibliothèque Python qui permet d’interagir avec le Hub. Nous pouvons utiliser cette bibliothèque pour télécharger les fiches de modèles et de jeux de données depuis le Hub à l’aide des méthodes DatasetCard.load ou ModelCard.load. En particulier, nous utiliserons ces méthodes pour charger un dictionnaire Python contenant les métadonnées définies dans le YAML de notre fiche de modèle ou de jeu de données. Nous créerons une petite fonction Python pour encapsuler ces méthodes et effectuer une gestion des exceptions.

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

Cette fonction renvoie un dictionnaire Python contenant les métadonnées associées au dépôt (ou un dictionnaire vide s'il n'y a pas de métadonnées).

{'license': 'afl-3.0'}

Création de notre rapport de revue des métadonnées

Une fois que nous disposons d’un dictionnaire Python contenant les métadonnées associées à un dépôt, nous créons une « fiche de notation » pour notre revue des métadonnées. Dans ce cas précis, nous examinons nos métadonnées en définissant certains champs pour lesquels nous souhaitons des valeurs. Par exemple, nous pouvons vouloir nous assurer que le champ license est toujours renseigné. Pour évaluer nos métadonnées, nous comptons les champs présents parmi ceux souhaités et retournons un score en pourcentage basé sur la couverture des champs de métadonnées requis pour lesquels nous voulons voir des valeurs.

Puisque nous disposons d'un dictionnaire Python contenant nos métadonnées, nous pouvons parcourir ce dictionnaire pour vérifier si les clés souhaitées y figurent. Si un champ de métadonnées souhaité (une clé de notre dictionnaire) est manquant, nous lui affecterons la valeur 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":
        # [...]

Cette fonction renvoie un dictionnaire contenant des clés représentant les champs de métadonnées requis pour notre modèle ou notre jeu de données. Les valeurs du dictionnaire incluront soit les métadonnées saisies pour ce champ, soit None si ce champ de métadonnées est manquant dans le YAML.

{'tags': None,
 'license': 'afl-3.0',
 'library_name': None,
 'datasets': None,
 'metrics': None,
 'co2': None,
 'pipeline_tag': None}

Une fois ce dictionnaire obtenu, nous pouvons créer notre rapport de métadonnées. Par souci de concision, nous n’incluons pas le code complet ici, mais le dépôt Hugging Face Spaces de ce Webhook contient le code intégral.

Nous créons une fonction qui génère un tableau Markdown, produisant une version plus lisible des données présentes dans notre dictionnaire de couverture des métadonnées.

def create_metadata_breakdown_table(desired_metadata_dictionary):
    # [...]
    return tabulate(
        table_data, tablefmt="github", headers=("Metadata Field", "Provided Value")
    )

Nous disposons également d'une fonction Python qui génère un score (représentant le pourcentage de champs de métadonnées souhaités présents)

def calculate_grade(desired_metadata_dictionary):
    # [...]
    return round(score, 2)

et une fonction Python qui crée un rapport Markdown pour notre revue de métadonnées. Ce rapport contient à la fois le score et le tableau des métadonnées, ainsi qu’une explication de ce que contient le rapport.

def create_markdown_report(
    desired_metadata_dictionary, repo_name, repo_type, score, update: bool = False
):
    # [...]
    return report

Comment publier automatiquement l'avis ?

Nous disposons désormais d’un rapport de revue des métadonnées au format Markdown. Nous utiliserons la bibliothèque huggingface_hub pour publier cette revue. Nous définissons une fonction qui reçoit les données Webhook émises par le Hub, les analyse et crée le rapport de métadonnées. Selon qu’un rapport a déjà été créé ou non, la fonction crée un nouveau rapport ou publie un nouvel issue dans un fil de revue des métadonnées existant.

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

:= est la syntaxe Python de l’opérateur d’expression d’affectation, ajoutée au langage Python à partir de la version 3.8 (communément appelé opérateur « walrus »). Les avis sur cette syntaxe sont partagés, et elle ne modifie pas la façon dont Python évalue le code si vous ne l’utilisez pas. Vous pouvez en savoir plus sur cet opérateur dans cet article de Real Python.

Créer un Webhook pour répondre aux modifications sur le Hub

Nous disposons désormais de la fonctionnalité de base pour créer un rapport de revue des métadonnées pour un modèle ou un jeu de données. L’étape suivante consiste à utiliser les Webhooks pour répondre automatiquement aux modifications.

Créer un Webhook dans votre profil utilisateur

Tout d'abord, créez votre Webhook en accédant à https://huggingface.co/settings/webhooks.

  • Saisissez quelques dépôts cibles auxquels votre Webhook écoutera (vous voudrez probablement limiter cela à vos propres dépôts ou aux dépôts de l'organisation à laquelle vous appartenez).
  • Saisissez un secret pour renforcer la sécurité de votre Webhook (si vous ne savez pas quoi choisir à ce sujet, vous pouvez utiliser un générateur de mots de passe pour générer une chaîne aléatoire suffisamment longue pour votre secret).
  • Nous pouvons, pour l'instant, passer une URL factice pour le paramètre Webhook URL.

Votre Webhook ressemblera à ceci :

webhook settings

Créer un nouveau profil d'utilisateur Bot

Ce guide crée un compte utilisateur distinct qui publiera les examens des métadonnées.

Bot user account

Lors de la création d'un bot qui interagira avec d'autres utilisateurs sur le Hub, nous vous demandons d'indiquer clairement sur le compte qu'il s'agit d'un « Bot » (voir la capture d'écran du profil).

Créer un écouteur Webhook

Nous avons maintenant besoin d’un moyen d’écouter les événements Webhook. Il existe de nombreux outils possibles pour écouter les événements Webhook. De nombreux services existants, tels que Zapier et IFTTT, peuvent utiliser des Webhooks pour déclencher des actions (par exemple, ils pourraient publier un tweet à chaque fois qu’un modèle est mis à jour). Dans ce cas, nous implémenterons notre écouteur Webhook en utilisant FastAPI.

FastAPI est un framework web Python. Nous utiliserons FastAPI pour créer un écouteur de Webhook. En particulier, nous devons implémenter une route qui accepte les requêtes POST sur /webhook. Pour l’authentification, nous comparerons l’en-tête X-Webhook-Secret avec un secret WEBHOOK_SECRET qui peut être transmis à notre conteneur Docker à l’exécution.

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

La fonction ci-dessus reçoit les événements Webhook et crée ou met à jour le rapport de revue des métadonnées pour le dépôt modifié.

Utilisez Spaces pour déployer notre application Webhook

Notre fichier main.py contient tout le code nécessaire pour notre application Webhook. Pour le déployer, nous utiliserons un Space.

Pour notre Space, nous utiliserons Docker pour exécuter notre application. Le Dockerfile copie notre fichier d’application, installe les dépendances requises et lance l’application. Pour alimenter la variable KEY, nous définirons également un secret WEBHOOK_SECRET pour notre Space avec le secret généré précédemment. Vous pouvez en savoir plus sur les Spaces Docker ici.

Enfin, nous devons mettre à jour l’URL dans nos paramètres de Webhook avec l’URL de notre Space. Nous pouvons obtenir l’« URL directe » de notre Space depuis le menu contextuel. Cliquez sur « Intégrer ce Space » et copiez l’« URL directe ».

direct url

Une fois que nous disposons de cette URL, nous pouvons la transmettre au paramètre Webhook URL dans nos paramètres de Webhook. Notre bot devrait maintenant commencer à publier des avis lorsque les dépôts surveillés sont modifiés !

Conclusion et prochaines étapes

Nous disposons désormais d'un bot de révision automatique des métadonnées ! Voici quelques idées pour vous aider à développer à partir de ce guide :

  • La revue des métadonnées effectuée par notre bot était relativement sommaire ; vous pouvez ajouter des règles plus complexes pour la revue des métadonnées.
  • Vous pouvez utiliser le fichier README.md complet pour effectuer la revue.
  • Vous pouvez définir des « règles » particulièrement importantes pour votre organisation et utiliser un webhook pour vérifier qu’elles sont respectées.

Si vous développez une application de qualité des métadonnées à l'aide de Webhooks, merci de me taguer @davanstrien ; j'adorerais en savoir plus !

Update on GitHub