# Webhookガイド: モデルとデータセットのメタデータ品質レビューの自動化セットアップ 

このガイドでは、Hub上のユーザーまたは組織のモデルやデータセットの変更を検知して、変更されたリポジトリに対して「メタデータレビュー」を作成するシステムの構築手順を説明します。

## 何を構築し、なぜ構築するのか

この特定のワークフローに関わる技術的な詳細に入る前に、私たちが何を作成し、なぜそれを行うのかを簡単に概要として示します。

[モデルカード](https://huggingface.co/docs/hub/model-cards)と[データセットカード](https://huggingface.co/docs/hub/datasets-cards)は、機械学習モデルとデータセットを文書化するための不可欠なツールです。Hugging Face Hub は、[YAML](https://en.wikipedia.org/wiki/YAML)ヘッダーブロックを含む`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](https://en.wikipedia.org/wiki/CI/CD)と同様の仕組みで機能します。

![Metadata review](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/webhooks-guides/003-metadata-review/metadata-report-screenshot.png)

例のレビューは[こちら](https://huggingface.co/datasets/davanstrien/test_webhook/discussions/1#63d932fe19aa7b8ed2718b3f)でも確認できます。

## Hub Client Libraryを使用してモデルレビューカードを作成する 

`huggingface_hub` は、Hub とのやり取りを可能にする Python ライブラリです。このライブラリを使用すると、`DatasetCard.load` または `ModelCard.load` メソッドを使って、Hub から[モデルカードやデータセットカードをダウンロード](https://huggingface.co/docs/huggingface_hub/how-to-model-cards)できます。具体的には、これらのメソッドを使用して、モデルカードまたはデータセットカードの`YAML` で定義されたメタデータを含む Python の辞書を読み込みます。これらのメソッドをラップし、例外処理を行う小さな Python 関数を作成します。

```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の辞書を返します（メタデータが存在しない場合は空の辞書を返します）。

```python
{'license': 'afl-3.0'}
```

## メタデータレビューレポートの作成

リポジトリに関連するメタデータを含む Python の辞書が手元に揃ったら、メタデータのレビュー用に「レポートカード」を作成します。ここでは、値の存在を確認したいメタデータフィールドをいくつか定義することで、メタデータをレビューします。例えば、`license` フィールドが常に記入されていることを確認したい場合があります。メタデータの評価として、希望するフィールドのうち実際に存在するメタデータフィールドの数を数え、値を確認したい必須メタデータフィールドの網羅率に基づいたパーセンテージスコアを返します。

メタデータを含む Python の辞書があるため、この辞書をループして、必要なキーが存在するか確認できます。必要なメタデータフィールド（辞書のキー）が欠けている場合、その値を`None`に割り当てます。

```python
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":
        # [...]
```

この関数は、モデルまたはデータセットに必要なメタデータフィールドを表すキーを含む辞書を返します。辞書の値は、そのフィールドに入力されたメタデータ、または`YAML`にそのメタデータフィールドが存在しない場合は`None`になります。

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

この辞書が用意できたら、メタデータレポートを作成できます。簡潔にするため、ここでは完全なコードは示しませんが、このWebhookのHugging Face Spaces [リポジトリ](https://huggingface.co/spaces/librarian-bot/webhook_metadata_reviewer/blob/main/main.py)には完全なコードが含まれています。

メタデータカバレッジ辞書に格納されているデータを、より見栄えのよい形式で表示するためのMarkdownテーブルを生成する関数を1つ作成します。

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

また、…というPython関数も用意されており、これは（必要なメタデータフィールドが存在する割合を表す）スコアを生成します。

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

メタデータレビュー用のMarkdownレポートを作成するPython関数です。このレポートには、スコアとメタデータテーブルの両方が含まれ、レポートの内容に関する説明も記載されています。

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

## レビューを自動的に投稿するにはどうすればよいですか？

Markdown形式のメタデータレビューレポートが作成できました。`huggingface_hub`ライブラリを使用して、このレビューを投稿します。Hubから受信したWebhookデータを受け取り、データを解析してメタデータレポートを作成する関数を定義します。以前にレポートが作成されているかどうかに応じて、関数は新しいレポートを作成するか、既存のメタデータレビュースレッドに新しいissueを投稿します。

```python
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
```

> [!TIP]
> `:=` は、Python 3.8 で追加された代入式演算子の Python 構文です（一般的には walrus operator と呼ばれます）。この構文については意見が分かれています。使用しない場合、Python がコードを評価する方法は変わりません。この演算子については、Real Python のこの記事で詳しく読むことができます。

## Hub での変更に応答するための Webhook の作成

これで、モデルまたはデータセットのメタデータレビューレポートを作成するコア機能が整いました。次のステップは、Webhooksを使用して変更に対して自動的に応答することです。

## ユーザープロファイルでWebhookを作成します

まず、https://huggingface.co/settings/webhooks にアクセスして Webhook を作成してください。

- Webhookが監視する対象のリポジトリをいくつか入力してください（通常、自分のリポジトリや所属する組織のリポジトリに限定することをお勧めします）。
- Webhook をより安全にするためにシークレットを入力してください（この項目で何を設定すればよいか分からない場合は、[パスワード生成ツール](https://1password.com/password-generator/)を使用して、シークレットとして十分な長さのランダムな文字列を生成することをお勧めします）。
- 現時点では、`Webhook URL`パラメータにはダミーのURLを渡すことができます。

Webhookは次のようになります:

![webhook settings](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/webhooks-guides/003-metadata-review/webhook-settings.png)

## 新しいBotユーザープロファイルを作成します

このガイドでは、メタデータのレビューを投稿するための別ユーザーアカウントを作成します。

![Bot user account](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/webhooks-guides/003-metadata-review/librarian-bot-profile.png)

> [!TIP]
> Hub上で他のユーザーとやり取りするボットを作成する際は、アカウントを明確に「Bot」としてラベル付けしてください（プロフィールのスクリーンショットを参照）。

## Webhookリスナーを作成する

次に、Webhookイベントを監視する方法が必要です。Webhookイベントを監視するために使用できるツールは多数あります。[Zapier](https://zapier.com/)や[IFTTT](https://ifttt.com)などの既存の多くのサービスは、Webhookを使用してアクションをトリガーできます（例えば、モデルが更新されるたびにツイートを投稿する、など）。ここでは、[FastAPI](https://fastapi.tiangolo.com/)を使用してWebhookリスナーを実装します。

[FastAPI](https://fastapi.tiangolo.com/)はPythonのWebフレームワークです。Webhookリスナーの作成にFastAPIを使用します。具体的には、`/webhook`で`POST`リクエストを受け入れるルートを実装する必要があります。認証については、`X-Webhook-Secret`ヘッダーを、[Dockerコンテナに実行時に渡すことができる](./spaces-sdks-docker#runtime)`WEBHOOK_SECRET`シークレットと比較します。

```python
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](https://huggingface.co/spaces/librarian-bot/webhook_metadata_reviewer/blob/main/main.py) ファイルには、Webhook アプリに必要なすべてのコードが含まれています。デプロイには、[Space](./spaces-overview) を使用します。

Spaceでは、Dockerを使用してアプリを実行します。[Dockerfile](https://huggingface.co/spaces/librarian-bot/webhook_metadata_reviewer/blob/main/Dockerfile)は、アプリファイルをコピーし、必要な依存関係をインストールして、アプリケーションを実行します。`KEY`変数に値を設定するために、先ほど生成したシークレットをSpaceの`WEBHOOK_SECRET`シークレットとして設定します。Docker Spacesの詳細については、[こちら](./spaces-sdks-docker)を参照してください。

最後に、Webhook 設定の URL を、私たちの Space の URL に更新する必要があります。Space の「直接 URL」は、コンテキストメニューから取得できます。「この Space を埋め込む」をクリックし、「直接 URL」をコピーしてください。

![direct url](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/webhooks-guides/003-metadata-review/direct-url.png)

この URL を取得したら、Webhook 設定の `Webhook URL` パラメータに渡すことができます。これで、監視対象のリポジトリに変更があると、ボットがレビューを投稿し始めるはずです！

## 結論と次のステップ

現在、自動メタデータレビューボットが利用可能になりました。このガイドを基に構築できるアイデアをいくつかご紹介します。

- ボットによるメタデータのレビューは比較的単純なものでしたが、メタデータのレビューに、より複雑なルールを追加できます。
- レビューを行うには、`README.md`ファイル全体を使用できます。
- 組織にとって特に重要な「ルール」を定義し、Webhook を使用してそれらが遵守されていることを確認する必要がある場合があります。

Webhooksを使用してメタデータ品質アプリを構築する場合は、@davanstrienでタグ付けしてください。ぜひその情報をお聞かせください！

