# モデルカードの作成と共有

`huggingface_hub` ライブラリは、Model Card の作成、共有、更新を行うための Python インターフェースを提供しています。Hub 上の Model Card が何であり、内部でどのように動作しているかについて詳しく知りたい場合は、[専用のドキュメントページ](https://huggingface.co/docs/hub/models-cards)をご覧ください。

## Hubからモデルカードを読み込む

Hubから既存のカードを読み込むには、[ModelCard.load()](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.RepoCard.load)関数を使用できます。ここでは、[`nateraw/vit-base-beans`](https://huggingface.co/nateraw/vit-base-beans)のカードを読み込みます。

```python
from huggingface_hub import ModelCard

card = ModelCard.load('nateraw/vit-base-beans')
```

このカードには、アクセスまたは活用したいと思われるいくつかの便利な属性があります：
  - `card.data`: モデルカードのメタデータを含む [ModelCardData](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.ModelCardData) インスタンスを返します。このインスタンスに対して `.to_dict()` を呼び出すことで、辞書としての表現を取得できます。
  - `card.text`: カードのテキストを返します。*メタデータヘッダーは除外されます*。
  - `card.content`: カードのテキストコンテンツを返します。*メタデータヘッダーを含む*。

## モデルカードの作成

### テキストから

テキストから Model Card を初期化するには、カードのテキスト内容を `ModelCard` の初期化時に渡すだけです。

```python
content = """
---
language: en
license: mit
---

# My Model Card
"""

card = ModelCard(content)
card.data.to_dict() == {'language': 'en', 'license': 'mit'}  # True
```

別の方法として、f-strings を使用することもできます。次の例では、以下を行います:

- 定義したメタデータをYAMLに変換するには、[ModelCardData.to_yaml()](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.CardData.to_yaml)を使用します。これにより、モデルカードにYAMLブロックを挿入できます。
- Pythonのf-stringを使用して、テンプレート変数を利用する方法を示します。

```python
card_data = ModelCardData(language='en', license='mit', library='timm')

example_template_var = 'nateraw'
content = f"""
---
{ card_data.to_yaml() }
---

# My Model Card

This model created by [@{example_template_var}](https://github.com/{example_template_var})
"""

card = ModelCard(content)
print(card)
```

上記の例を実行すると、以下のようになるカードが作成されます。

```
---
language: en
license: mit
library: timm
---

# My Model Card

This model created by [@nateraw](https://github.com/nateraw)
```

### Jinja テンプレートから

`Jinja2`がインストールされている場合、jinjaテンプレートファイルからModel Cardsを作成できます。基本的な例を見てみましょう:

```python
from pathlib import Path

from huggingface_hub import ModelCard, ModelCardData

# Define your jinja template
template_text = """
---
{{ card_data }}
---

# Model Card for MyCoolModel

This model does this and that.

This model was created by [@{{ author }}](https://hf.co/{{author}}).
""".strip()

# Write the template to a file
Path('custom_template.md').write_text(template_text)

# Define card metadata
card_data = ModelCardData(language='en', license='mit', library_name='keras')

# Create card from template, passing it any jinja template variables you want.
# In our case, we'll pass author
card = ModelCard.from_template(card_data, template_path='custom_template.md', author='nateraw')
card.save('my_model_card_1.md')
print(card)
```

生成されたカードのMarkdownは次のようになります。

```
---
language: en
license: mit
library_name: keras
---

# Model Card for MyCoolModel

This model does this and that.

This model was created by [@nateraw](https://hf.co/nateraw).
```

card.dataを更新すると、カード自体に反映されます。

```
card.data.library_name = 'timm'
card.data.language = 'fr'
card.data.license = 'apache-2.0'
print(card)
```

ご覧のとおり、メタデータヘッダーが更新されました:

```
---
language: fr
license: apache-2.0
library_name: timm
---

# Model Card for MyCoolModel

This model does this and that.

This model was created by [@nateraw](https://hf.co/nateraw).
```

カードデータを更新する際、[ModelCard.validate()](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.RepoCard.validate)を呼び出すことで、カードがHugging Face Hubに対して引き続き有効であることを検証できます。これにより、カードがHugging Face Hubに設定されたすべての検証ルールを満たしていることが保証されます。

### デフォルトのテンプレートから

独自のテンプレートを使用する代わりに、[デフォルトテンプレート](https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/templates/modelcard_template.md)を使用することもできます。これは、記入が必要な多くのセクションを備えた、機能豊富なモデルカードです。内部では、[Jinja2](https://jinja.palletsprojects.com/en/3.1.x/)を使用してテンプレートファイルを埋め込みます。

> [!TIP]
> `from_template`を使用するには、Jinja2のインストールが必要です。`pip install Jinja2`でインストールできます。

```python
card_data = ModelCardData(language='en', license='mit', library_name='keras')
card = ModelCard.from_template(
    card_data,
    model_id='my-cool-model',
    model_description="this model does this and that",
    developers="Nate Raw",
    repo="https://github.com/huggingface/huggingface_hub",
)
card.save('my_model_card_2.md')
print(card)
```

## モデルカードを共有

Hugging Face Hubに認証済み（`hf auth login`または[login()](/docs/huggingface_hub/v2.4.0/ja/package_reference/authentication#huggingface_hub.login)を使用）の場合、[ModelCard.push_to_hub()](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.RepoCard.push_to_hub)を呼び出すだけでカードをHubにプッシュできます。その方法を見ていきましょう。

まず、認証済みユーザーのネームスペース配下に、hf-hub-modelcards-pr-test という名前の新しいリポジトリを作成します。

```python
from huggingface_hub import whoami, create_repo

user = whoami()['name']
repo_id = f'{user}/hf-hub-modelcards-pr-test'
url = create_repo(repo_id, exist_ok=True)
```

次に、デフォルトのテンプレート（上記のセクションで定義されているものと同じ）からカードを作成します。

```python
card_data = ModelCardData(language='en', license='mit', library_name='keras')
card = ModelCard.from_template(
    card_data,
    model_id='my-cool-model',
    model_description="this model does this and that",
    developers="Nate Raw",
    repo="https://github.com/huggingface/huggingface_hub",
)
```

最後に、それをハブにプッシュします

```python
card.push_to_hub(repo_id)
```

生成されたカードは[こちら](https://huggingface.co/nateraw/hf-hub-modelcards-pr-test/blob/main/README.md)でご覧いただけます。

代わりにプルリクエストとしてカードをプッシュしたい場合は、`push_to_hub`を呼び出す際に`create_pr=True`と指定するだけです:

```python
card.push_to_hub(repo_id, create_pr=True)
```

このコマンドから作成された結果のPRは、[こちら](https://huggingface.co/nateraw/hf-hub-modelcards-pr-test/discussions/3)でご覧いただけます。

## メタデータの更新

このセクションでは、リポジトリカードに含まれるメタデータの内容と、その更新方法について説明します。

`metadata` は、モデル、データセット、または Space に関する高レベルな情報を提供するハッシュマップ（またはキーバリュー）のコンテキストを指します。この情報には、モデルの `pipeline type`、`model_id`、`model_description` などの詳細が含まれる場合があります。詳細については、[Model Card](https://huggingface.co/docs/hub/model-cards#model-card-metadata)、[Dataset Card](https://huggingface.co/docs/hub/datasets-cards#dataset-card-metadata)、[Spaces Settings](https://huggingface.co/docs/hub/spaces-settings#spaces-settings) のガイドをご覧ください。次に、これらのメタデータを更新する方法の例を見ていきましょう。

最初の例から始めましょう:

```python
>>> from huggingface_hub import metadata_update
>>> metadata_update("username/my-cool-model", {"pipeline_tag": "image-classification"})
```

この2行のコードで、新しい`pipeline_tag`を設定するようメタデータを更新できます。

デフォルトでは、カード上に既に存在するキーを更新することはできません。更新する場合は、`overwrite=True`を明示的に渡す必要があります。

```python
>>> from huggingface_hub import metadata_update
>>> metadata_update("username/my-cool-model", {"pipeline_tag": "text-generation"}, overwrite=True)
```

書き込み権限がないリポジトリに対して変更を提案したい場面はよくあります。そのリポジトリでPRを作成することで、オーナーが提案内容を確認してマージできるようになります。

```python
>>> from huggingface_hub import metadata_update
>>> metadata_update("someone/model", {"pipeline_tag": "text-classification"}, create_pr=True)
```

## 評価結果を含める

メタデータ `model-index` に評価結果を含めるには、関連する評価結果を伴う [EvalResult](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.EvalResult) または `EvalResult` のリストを渡すことができます。内部では、`card.data.to_dict()` を呼び出した際に `model-index` が作成されます。この仕組みの詳細については、[Hub ドキュメントのこのセクション](https://huggingface.co/docs/hub/models-cards#evaluation-results) をご覧ください。

> [!TIP]
> この関数を使用するには、[ModelCardData](/docs/huggingface_hub/v2.4.0/ja/package_reference/cards#huggingface_hub.ModelCardData)に`model_name`属性を含める必要があります。

```python
card_data = ModelCardData(
    language='en',
    license='mit',
    model_name='my-cool-model',
    eval_results = EvalResult(
        task_type='image-classification',
        dataset_type='beans',
        dataset_name='Beans',
        metric_type='accuracy',
        metric_value=0.7
    )
)

card = ModelCard.from_template(card_data)
print(card.data)
```

生成された`card.data`は、次のようになるはずです:

```
language: en
license: mit
model-index:
- name: my-cool-model
  results:
  - task:
      type: image-classification
    dataset:
      name: Beans
      type: beans
    metrics:
    - type: accuracy
      value: 0.7
```

共有したい評価結果が複数ある場合は、`EvalResult`のリストを渡すだけです。

```python
card_data = ModelCardData(
    language='en',
    license='mit',
    model_name='my-cool-model',
    eval_results = [
        EvalResult(
            task_type='image-classification',
            dataset_type='beans',
            dataset_name='Beans',
            metric_type='accuracy',
            metric_value=0.7
        ),
        EvalResult(
            task_type='image-classification',
            dataset_type='beans',
            dataset_name='Beans',
            metric_type='f1',
            metric_value=0.65
        )
    ]
)
card = ModelCard.from_template(card_data)
card.data
```

以下の`card.data`が残るはずです:

```
language: en
license: mit
model-index:
- name: my-cool-model
  results:
  - task:
      type: image-classification
    dataset:
      name: Beans
      type: beans
    metrics:
    - type: accuracy
      value: 0.7
    - type: f1
      value: 0.65
```

