# 모델 카드 생성 및 공유

`huggingface_hub` 라이브러리를 사용하면 Python 인터페이스를 통해 Model Card를 생성, 공유 및 업데이트할 수 있습니다. Hub의 Model Card가 무엇인지, 그리고 내부적으로 어떻게 작동하는지에 대한 자세한 내용은 [전용 문서 페이지](https://huggingface.co/docs/hub/models-cards)를 참고하세요.

## Hub에서 모델 카드 로드

Hub에서 기존 카드를 로드하려면 [ModelCard.load()](/docs/huggingface_hub/v2.4.0/ko/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/ko/package_reference/cards#huggingface_hub.ModelCardData) 인스턴스를 반환합니다. 이 인스턴스에 `.to_dict()`를 호출하여 딕셔너리 형식의 표현을 가져올 수 있습니다.
  - `card.text`: 카드의 텍스트를 반환하며, *메타데이터 헤더는 제외*됩니다.
  - `card.content`: 카드의 텍스트 내용을 반환하며, *메타데이터 헤더를 포함*합니다.

## 모델 카드 만들기

### 텍스트에서

`ModelCard`를 초기화할 때 텍스트로 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를 사용하는 것입니다. 다음 예시에서는:

- [ModelCardData.to_yaml()](/docs/huggingface_hub/v2.4.0/ko/package_reference/cards#huggingface_hub.CardData.to_yaml)을 사용하여 정의한 메타데이터를 YAML로 변환하여 모델 카드에 YAML 블록을 삽입할 수 있습니다.
- Python f-strings를 사용하여 템플릿 변수를 사용하는 방법을 보여줍니다.

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

생성된 카드의 마크다운은 다음과 같습니다:

```
---
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/ko/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/ko/package_reference/authentication#huggingface_hub.login)을 사용한 경우)라면, [ModelCard.push_to_hub()](/docs/huggingface_hub/v2.4.0/ko/package_reference/cards#huggingface_hub.RepoCard.push_to_hub)를 호출하기만 하면 카드를 Hub에 push할 수 있습니다. 방법을 살펴보겠습니다...

먼저 인증된 사용자의 네임스페이스 아래 '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)에서 확인할 수 있습니다.

대신 pull request로 카드를 push하려면 `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)에서 확인할 수 있습니다.

## 메타데이터 업데이트

repo cards에 포함된 메타데이터가 무엇인지, 그리고 이를 어떻게 업데이트하는지 살펴보겠습니다.

`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"})
```

이 두 줄의 코드로 메타데이터를 업데이트하여 새로운 `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/ko/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/ko/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
```

