# Crear y compartir Model Cards

La biblioteca `huggingface_hub` ofrece una interfaz de Python para crear, compartir y actualizar Model Cards. Visita [la página de documentación dedicada](https://huggingface.co/docs/hub/models-cards) para una visión más profunda de qué son los Model Cards en el Hub y cómo funcionan por debajo.

## Cargar una tarjeta de modelo desde el Hub

Para cargar una tarjeta existente desde el Hub, puedes usar la función [ModelCard.load()](/docs/huggingface_hub/v2.4.0/es/package_reference/cards#huggingface_hub.RepoCard.load). Aquí, cargaremos la tarjeta de [`nateraw/vit-base-beans`](https://huggingface.co/nateraw/vit-base-beans).

```python
from huggingface_hub import ModelCard

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

Esta tarjeta tiene algunos atributos útiles que puede ser que desee acceder o aprovechar:
  - `card.data`: Devuelve una instancia de [ModelCardData](/docs/huggingface_hub/v2.4.0/es/package_reference/cards#huggingface_hub.ModelCardData) con los metadatos de la tarjeta del modelo. Llama a `.to_dict()` en esta instancia para obtener la representación como un diccionario.
  - `card.text`: Devuelve el texto de la tarjeta, *excluyendo la cabecera de metadatos*.
  - `card.content`: Devuelve el contenido de texto de la tarjeta, *incluyendo la cabecera de metadatos*.

## Crear tarjetas de modelo

### Desde texto

Para inicializar una Model Card a partir de texto, basta con pasar el contenido de texto de la tarjeta a `ModelCard` durante la inicialización.

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

# My Model Card
"""

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

Otra forma en la que podrías querer hacer esto es con f-strings. En el siguiente ejemplo,

- Use [ModelCardData.to_yaml()](/docs/huggingface_hub/v2.4.0/es/package_reference/cards#huggingface_hub.CardData.to_yaml) para convertir los metadatos que definimos a YAML, de modo que podamos usarlo para insertar el bloque YAML en la tarjeta del modelo.
- Muestra cómo podrías usar una variable de plantilla mediante f-strings de Python.

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

El ejemplo anterior nos dejaría con una tarjeta que se vería así:

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

# My Model Card

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

### Desde una plantilla Jinja

Si tienes `Jinja2` instalado, puedes crear Model Cards a partir de un archivo de plantilla jinja. Veamos un ejemplo básico:

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

El markdown de la tarjeta resultante se ve así:

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

Si actualizas cualquier card.data, se reflejará en la propia card.

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

Ahora, como puede ver, la cabecera de metadatos se ha actualizado:

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

A medida que actualizas los datos de la tarjeta, puedes validar que la tarjeta sigue siendo válida en el Hub llamando a [ModelCard.validate()](/docs/huggingface_hub/v2.4.0/es/package_reference/cards#huggingface_hub.RepoCard.validate). Esto garantiza que la tarjeta cumpla con las reglas de validación configuradas en el Hugging Face Hub.

### Desde la plantilla predeterminada

En lugar de usar tu propia plantilla, también puedes utilizar la [plantilla predeterminada](https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/templates/modelcard_template.md), que es una tarjeta de modelo completa con numerosas secciones que quizás quieras rellenar. Internamente, utiliza [Jinja2](https://jinja.palletsprojects.com/en/3.1.x/) para completar un archivo de plantilla.

> [!TIP]
> Tenga en cuenta que deberá tener Jinja2 instalado para usar `from_template`. Puede hacerlo con `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)
```

## Compartir tarjetas de modelos

Si has iniciado sesión en Hugging Face Hub (ya sea usando `hf auth login` o [login()](/docs/huggingface_hub/v2.4.0/es/package_reference/authentication#huggingface_hub.login)), puedes subir tarjetas al Hub simplemente llamando a [ModelCard.push_to_hub()](/docs/huggingface_hub/v2.4.0/es/package_reference/cards#huggingface_hub.RepoCard.push_to_hub). Veamos cómo hacerlo...

Primero, crearemos un nuevo repositorio llamado 'hf-hub-modelcards-pr-test' en el espacio de nombres del usuario autenticado:

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

Luego, crearemos una tarjeta a partir de la plantilla predeterminada (la misma que se definió en la sección anterior):

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

Por último, subiremos eso al hub

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

Puedes consultar la tarjeta resultante [aquí](https://huggingface.co/nateraw/hf-hub-modelcards-pr-test/blob/main/README.md).

Si en su lugar quisiera enviar una tarjeta como una solicitud de extracción, solo tiene que indicar `create_pr=True` al llamar a `push_to_hub`:

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

Un PR resultante creado desde este comando se puede ver [aquí](https://huggingface.co/nateraw/hf-hub-modelcards-pr-test/discussions/3).

## Actualizar metadatos

En esta sección veremos qué metadatos hay en las tarjetas de repositorios y cómo actualizarlos.

`metadata` se refiere a un mapa de hashes (o contexto de pares clave-valor) que proporciona información de alto nivel sobre un modelo, un dataset o un Space. Esa información puede incluir detalles como el `pipeline type`, el `model_id` o el `model_description` del modelo. Para más detalles, puedes consultar estas guías: [Model Card](https://huggingface.co/docs/hub/model-cards#model-card-metadata), [Dataset Card](https://huggingface.co/docs/hub/datasets-cards#dataset-card-metadata) y [Spaces Settings](https://huggingface.co/docs/hub/spaces-settings#spaces-settings). Ahora veamos algunos ejemplos de cómo actualizar esos metadatos.

Comencemos con un primer ejemplo:

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

Con estas dos líneas de código actualizarás los metadatos para establecer una nueva `pipeline_tag`.

Por defecto, no se puede actualizar una clave que ya existe en la tarjeta. Si desea hacerlo, debe pasar explícitamente `overwrite=True`:

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

A menudo ocurre que deseas sugerir algunos cambios en un repositorio en el que no tienes permiso de escritura. Puedes hacerlo creando un PR en ese repositorio, lo que permitirá a los propietarios revisar y fusionar tus sugerencias.

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

## Incluir resultados de evaluación

Para incluir los resultados de evaluación en los metadatos `model-index`, puedes pasar un [EvalResult](/docs/huggingface_hub/v2.4.0/es/package_reference/cards#huggingface_hub.EvalResult) o una lista de `EvalResult` con tus resultados de evaluación asociados. Internamente, se creará el `model-index` cuando llames a `card.data.to_dict()`. Para obtener más información sobre cómo funciona esto, puedes consultar [esta sección de la documentación de Hub](https://huggingface.co/docs/hub/models-cards#evaluation-results).

> [!TIP]
> Tenga en cuenta que el uso de esta función requiere incluir el atributo `model_name` en [ModelCardData](/docs/huggingface_hub/v2.4.0/es/package_reference/cards#huggingface_hub.ModelCardData).

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

El resultado de `card.data` debería ser así:

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

Si tienes más de un resultado de evaluación que quieras compartir, simplemente pasa una lista de `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
```

Lo que debería dejarte con el siguiente `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
```

