**Optimización Directa de Preferencias (DPO)**

La Optimización Directa de Preferencias (DPO) ofrece un enfoque simplificado para alinear modelos de lenguaje con las preferencias humanas. A diferencia de los métodos tradicionales de RLHF (Reinforcement Learning with Human Feedback), que requieren modelos de recompensas separados y algoritmos complejos de aprendizaje por refuerzo, DPO optimiza directamente el modelo utilizando datos de preferencia.

## Entendiendo DPO

DPO redefine la alineación de preferencias como un problema de clasificación basado en datos de preferencias humanas. Los enfoques tradicionales de RLHF requieren entrenar un modelo de recompensa separado y usar algoritmos complejos como PPO (Proximal Policy Optimization) para alinear las salidas del modelo. DPO simplifica este proceso al definir una función de pérdida que optimiza directamente la política del modelo en función de las salidas preferidas versus las no preferidas.

Este enfoque ha demostrado ser altamente efectivo en la práctica, utilizándose para entrenar modelos como Llama. Al eliminar la necesidad de un modelo de recompensa separado y una etapa de aprendizaje por refuerzo, DPO hace que la alineación de preferencias sea más accesible y estable.

## Cómo Funciona DPO

El proceso de DPO requiere un fine-tuning supervisado (SFT) para adaptar el modelo al dominio objetivo. Esto crea una base para el aprendizaje de preferencias mediante el entrenamiento en conjuntos de datos estándar de seguimiento de instrucciones. El modelo aprende a completar tareas básicas mientras mantiene sus capacidades generales.

Luego viene el aprendizaje de preferencias, donde el modelo se entrena con pares de salidas: una preferida y una no preferida. Los pares de preferencias ayudan al modelo a entender qué respuestas se alinean mejor con los valores y expectativas humanas.

La innovación central de DPO radica en su enfoque de optimización directa. En lugar de entrenar un modelo de recompensa separado, DPO utiliza una pérdida de entropía cruzada binaria para actualizar directamente los pesos del modelo en función de los datos de preferencia. Este proceso simplificado hace que el entrenamiento sea más estable y eficiente, logrando resultados comparables o mejores que los métodos tradicionales de RLHF.

## Conjuntos de Datos para DPO

Los conjuntos de datos para DPO se crean típicamente anotando pares de respuestas como preferidas o no preferidas. Esto se puede hacer manualmente o mediante técnicas de filtrado automatizado. A continuación, se muestra un ejemplo de la estructura de un conjunto de datos de preferencias para DPO en un turno único:

| Prompt | Elegido | Rechazado |
|--------|---------|-----------|
| ...    | ...     | ...       |
| ...    | ...     | ...       |
| ...    | ...     | ...       |

La columna `Prompt` contiene el prompt utilizado para generar las respuestas `Elegido` y `Rechazado`. Las columnas `Elegido` y `Rechazado` contienen las respuestas preferidas y no preferidas, respectivamente. Existen variaciones en esta estructura, por ejemplo, incluyendo una columna de `system_prompt` o `Input` con material de referencia. Los valores de `elegido` y `rechazado` pueden representarse como cadenas para conversaciones de un solo turno o como listas de conversación.

Puedes encontrar una colección de conjuntos de datos DPO en Hugging Face [aquí](https://huggingface.co/collections/argilla/preference-datasets-for-dpo-656f0ce6a00ad2dc33069478).

## Implementación con TRL

La biblioteca Transformers Reinforcement Learning (TRL) facilita la implementación de DPO. Las clases `DPOConfig` y `DPOTrainer` siguen la misma API de estilo `transformers`.

Aquí tienes un ejemplo básico de cómo configurar el entrenamiento de DPO:

```python
from trl import DPOConfig, DPOTrainer

# Definir los argumentos
training_args = DPOConfig(
    ...
)

# Inicializar el entrenador
trainer = DPOTrainer(
    model,
    train_dataset=dataset,
    tokenizer=tokenizer,
    ...
)

# Entrenar el modelo
trainer.train()
```

En el [tutorial de DPO](./notebooks/dpo_finetuning_example.ipynb) se cubrirán más detalles sobre cómo utilizar las clases `DPOConfig` y `DPOTrainer`.

## Mejores Prácticas

La calidad de los datos es crucial para una implementación exitosa de DPO. El conjunto de datos de preferencias debe incluir ejemplos diversos que cubran diferentes aspectos del comportamiento deseado. Las pautas claras de anotación aseguran un etiquetado consistente de respuestas preferidas y no preferidas. Puedes mejorar el rendimiento del modelo mejorando la calidad de tu conjunto de datos de preferencias. Por ejemplo, filtrando conjuntos de datos más grandes para incluir solo ejemplos de alta calidad o que estén más relacionados con tu caso de uso.

Durante el entrenamiento, monitorea cuidadosamente la convergencia de la pérdida y valida el rendimiento con datos retenidos. Es posible que sea necesario ajustar el parámetro beta para equilibrar el aprendizaje de preferencias con el mantenimiento de las capacidades generales del modelo. La evaluación regular sobre ejemplos diversos ayuda a garantizar que el modelo está aprendiendo las preferencias deseadas sin sobreajustarse.

Compara las salidas del modelo con el modelo de referencia para verificar la mejora en la alineación de preferencias. Probar el modelo con una variedad de prompts, incluidos los casos extremos, ayuda a garantizar un aprendizaje robusto de preferencias en diferentes escenarios.

## Próximos Pasos

⏩ Para obtener experiencia práctica con DPO, prueba el [Tutorial de DPO](./notebooks/dpo_finetuning_example.ipynb). Esta guía práctica te guiará a través de la implementación de la alineación de preferencias con tu propio modelo, desde la preparación de datos hasta el entrenamiento y la evaluación.

⏭ Después de completar el tutorial, puedes explorar la página de [ORPO](./orpo.md) para aprender sobre otra técnica de alineación de preferencias.

A course on aligning smol models.


**Optimización por Ratios de Probabilidad de Preferencias (ORPO)**

ORPO (Odds Ratio Preference Optimization) es una técnica novedosa de fine-tuning que combina el fine-tuning y la alineación de preferencias en un único proceso unificado. Este enfoque combinado ofrece ventajas en términos de eficiencia y rendimiento en comparación con métodos tradicionales como RLHF o DPO.

## Entendiendo ORPO

Los métodos de alineación como DPO suelen involucrar dos pasos separados: fine-tuning supervisado para adaptar el modelo a un dominio y formato, seguido de la alineación de preferencias para alinearse con las preferencias humanas. Mientras que el fine-tuning fino supervisado (SFT) adapta eficazmente los modelos a los dominios objetivo, puede aumentar inadvertidamente la probabilidad de generar tanto respuestas deseables como indeseables. ORPO aborda esta limitación integrando ambos pasos en un solo proceso, como se ilustra en la siguiente comparación:

![Comparación de Técnicas de Alineación](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-alignments.png)
*Comparación de diferentes técnicas de alineación de modelos*

## Cómo Funciona ORPO

El proceso de entrenamiento de ORPO utiliza un conjunto de datos de preferencias similar al que usamos para DPO, donde cada ejemplo de entrenamiento contiene un prompt de entrada junto con dos respuestas: una preferida y otra rechazada. A diferencia de otros métodos de alineación que requieren etapas separadas y modelos de referencia, ORPO integra la alineación de preferencias directamente en el proceso de fine-tuning supervisado. Este enfoque monolítico lo hace libre de modelos de referencia, computacionalmente más eficiente y eficiente en memoria, con menos FLOPs.

ORPO crea un nuevo objetivo combinando dos componentes principales:

1. **Pérdida de SFT**: La pérdida estándar de log-verosimilitud negativa utilizada en la modelización de lenguaje, que maximiza la probabilidad de generar tokens de referencia. Esto ayuda a mantener las capacidades generales del modelo en lenguaje.

2. **Pérdida de Odds Ratio**: Un componente novedoso que penaliza respuestas no deseadas mientras recompensa las preferidas. Esta función de pérdida utiliza odds ratios para contrastar eficazmente entre respuestas favorecidas y desfavorecidas a nivel de token.

Juntos, estos componentes guían al modelo para adaptarse a las generaciones deseadas para el dominio específico mientras desalienta activamente las generaciones del conjunto de respuestas rechazadas. El mecanismo de odds ratio proporciona una manera natural de medir y optimizar las preferencias del modelo entre respuestas elegidas y rechazadas. Si deseas profundizar en las matemáticas, puedes leer el [artículo de ORPO](https://arxiv.org/abs/2403.07691). Si deseas aprender sobre ORPO desde la perspectiva de implementación, puedes revisar cómo se calcula la pérdida de ORPO en la [biblioteca TRL](https://github.com/huggingface/trl/blob/b02189aaa538f3a95f6abb0ab46c0a971bfde57e/trl/trainer/orpo_trainer.py#L660).

## Rendimiento y Resultados

ORPO ha demostrado resultados impresionantes en varios puntos de referencia. En MT-Bench, alcanza puntuaciones competitivas en diferentes categorías:

![Resultados MT-Bench](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-mtbench.png)
*Resultados de MT-Bench por categoría para modelos Mistral-ORPO*

Cuando se compara con otros métodos de alineación, ORPO muestra un rendimiento superior en AlpacaEval 2.0:

![Resultados AlpacaEval](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-winrate.png)
*Puntuaciones de AlpacaEval 2.0 en diferentes métodos de alineación*

En comparación con SFT+DPO, ORPO reduce los requisitos computacionales al eliminar la necesidad de un modelo de referencia y reducir a la mitad el número de pasadas hacia adelante por lote. Además, el proceso de entrenamiento es más estable en diferentes tamaños de modelos y conjuntos de datos, lo que requiere menos hiperparámetros para ajustar. En cuanto al rendimiento, ORPO iguala a modelos más grandes mientras muestra una mejor alineación con las preferencias humanas.

## Implementación

La implementación exitosa de ORPO depende en gran medida de datos de preferencias de alta calidad. Los datos de entrenamiento deben seguir pautas claras de anotación y proporcionar una representación equilibrada de respuestas preferidas y rechazadas en diversos escenarios.

### Implementación con TRL

ORPO se puede implementar utilizando la biblioteca Transformers Reinforcement Learning (TRL). Aquí tienes un ejemplo básico:

```python
from trl import ORPOConfig, ORPOTrainer

# Configurar el entrenamiento de ORPO
orpo_config = ORPOConfig(
    learning_rate=1e-5,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    max_steps=1000,
    orpo_alpha=1.0,  # Controla la fuerza de la optimización de preferencias
    orpo_beta=0.1,   # Parámetro de temperatura para el cálculo de odds ratio
)

# Inicializar el entrenador
trainer = ORPOTrainer(
    model=model,
    args=orpo_config,
    train_dataset=dataset,
    tokenizer=tokenizer,
)

# Iniciar el entrenamiento
trainer.train()
```

Parámetros clave a considerar:
- `orpo_alpha`: Controla la fuerza de la optimización de preferencias
- `orpo_beta`: Parámetro de temperatura para el cálculo de odds ratio
- `learning_rate`: Debe ser relativamente pequeño para evitar el olvido catastrófico
- `gradient_accumulation_steps`: Ayuda con la estabilidad del entrenamiento

## Próximos Pasos

⏩ Prueba el [Tutorial de ORPO](./notebooks/orpo_tutorial.ipynb) para implementar este enfoque unificado de alineación de preferencias.

## Recursos
- [Artículo de ORPO](https://arxiv.org/abs/2403.07691)
- [Documentación de TRL](https://huggingface.co/docs/trl/index)
- [Guía de RLHF de Argilla](https://argilla.io/blog/mantisnlp-rlhf-part-8/)

A course on aligning smol models.


# Fine-Tuning Eficiente en Parámetros (PEFT)

A medida que los modelos de lenguaje se hacen más grandes, el *fine-tuning* tradicional se vuelve cada vez más complicado. Afinar completamente un modelo con 1.7 mil millones de parámetros, por ejemplo, requiere una memoria de GPU significativa, hace costoso almacenar copias separadas del modelo y puede ocasionar un olvido catastrófico de las capacidades originales del modelo. Los métodos de *fine-tuning* eficiente en parámetros (*Parameter-Efficient Fine-Tuning* o PEFT) abordan estos problemas modificando solo un subconjunto pequeño de los parámetros del modelo, mientras que la mayor parte del modelo permanece congelada.

El *fine-tuning* tradicional actualiza todos los parámetros del modelo durante el entrenamiento, lo cual resulta poco práctico para modelos grandes. Los métodos PEFT introducen enfoques para adaptar modelos utilizando una fracción mínima de parámetros entrenables, generalmente menos del 1% del tamaño original del modelo. Esta reducción dramática permite:

- Realizar *fine-tuning* en hardware de consumo con memoria de GPU limitada.
- Almacenar eficientemente múltiples adaptaciones de tareas específicas.
- Mejorar la generalización en escenarios con pocos datos.
- Entrenamientos y ciclos de iteración más rápidos.

## Métodos Disponibles

En este módulo, se cubrirán dos métodos populares de PEFT:

### 1⃣ LoRA (Adaptación de Bajo Rango)

LoRA se ha convertido en el método PEFT más adoptado, ofreciendo una solución sofisticada para la adaptación eficiente de modelos. En lugar de modificar el modelo completo, **LoRA inyecta matrices entrenables en las capas de atención del modelo.** Este enfoque, por lo general, reduce los parámetros entrenables en aproximadamente un 90%, manteniendo un rendimiento comparable al *fine-tuning* completo. Exploraremos LoRA en la sección [LoRA (Adaptación de Bajo Rango)](./lora_adapters.md).

### 2⃣ *Prompt Tuning*

El *prompt tuning* ofrece un enfoque **aún más ligero** al **añadir tokens entrenables a la entrada** en lugar de modificar los pesos del modelo. Aunque es menos popular que LoRA, puede ser útil para adaptar rápidamente un modelo a nuevas tareas o dominios. Exploraremos el *prompt tuning* en la sección [Prompt Tuning](./prompt_tuning.md).

## Notebooks de Ejercicios

| Título | Descripción | Ejercicio | Enlace | Colab |
|-------|-------------|-----------|--------|-------|
| *Fine-tuning* con LoRA | Aprende a realizar *fine-tuning* con adaptadores LoRA | 🐢 Entrena un modelo con LoRA
🐕 Experimenta con diferentes valores de rango
🦁 Compara el rendimiento con el *fine-tuning* completo | [Notebook](./notebooks/finetune_sft_peft.ipynb) |  |
| Carga Adaptadores LoRA | Aprende a cargar y usar adaptadores LoRA entrenados | 🐢 Carga adaptadores preentrenados
🐕 Combina adaptadores con el modelo base
🦁 Alterna entre múltiples adaptadores | [Notebook](./notebooks/load_lora_adapter_example.ipynb) |  |

## Recursos
- [Documentación de PEFT](https://huggingface.co/docs/peft)
- [Artículo de LoRA](https://arxiv.org/abs/2106.09685)
- [Artículo de QLoRA](https://arxiv.org/abs/2305.14314)
- [Artículo de *Prompt Tuning*](https://arxiv.org/abs/2104.08691)
- [Guía de PEFT en Hugging Face](https://huggingface.co/blog/peft)
- [Cómo hacer *Fine-Tuning* de LLMs en 2024 con Hugging Face](https://www.philschmid.de/fine-tune-llms-in-2024-with-trl)
- [TRL](https://huggingface.co/docs/trl/index)

A course on aligning smol models.


# LoRA (Adaptación de Bajo Rango)

LoRA (Low-Rank Adaptation) se ha convertido en el método PEFT más utilizado. Su funcionamiento se basa en añadir matrices de descomposición de rango reducido a los pesos de atención, lo que suele reducir los parámetros entrenables en un 90%.

## Entendiendo LoRA

LoRA es una técnica de fine-tuning eficiente en parámetros que congela los pesos del modelo preentrenado e inyecta matrices entrenables de descomposición de rango reducido en las capas del modelo. En lugar de entrenar todos los parámetros del modelo durante el fine-tuning, LoRA descompone las actualizaciones de los pesos en matrices más pequeñas mediante descomposición de rango, reduciendo significativamente la cantidad de parámetros entrenables mientras mantiene el rendimiento del modelo. Por ejemplo, se ha aplicado a GPT-3 175B. LoRA redujo los parámetros entrenables 10 000 veces y los requerimientos de memoria de GPU 3 veces en comparación con el fine-tuning completo. Puedes leer más sobre LoRA en el [paper de LoRA](https://arxiv.org/pdf/2106.09685).

LoRA funciona añadiendo pares de matrices de descomposición de rango reducido a las capas del transformador, normalmente enfocándose en los pesos de atención. Durante la inferencia, estos pesos adaptadores pueden fusionarse con el modelo base, lo que elimina la sobrecarga de latencia adicional. LoRA es especialmente útil para adaptar modelos de lenguaje grandes a tareas o dominios específicos mientras se mantienen requisitos de recursos manejables.

## Cargando adaptadores LoRA

Se pueden cargar adaptadores en un modelo preentrenado utilizando `load_adapter()`, lo cual es útil para probar diferentes adaptadores cuyos pesos no están fusionados. Se pueden establecer los pesos de los adaptadores activos con la función `set_adapter()`. Para devolver el modelo base, se puede usar `unload()` para descargar todos los módulos de LoRA. Esto permite cambiar fácilmente entre diferentes pesos específicos de tareas.

```python
from transformers import AutoModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("<base_model_name>")
peft_model_id = "<peft_adapter_id>"
model = PeftModel.from_pretrained(base_model, peft_model_id)
```

![lora_load_adapter](./images/lora_adapter.png)

## Fusionando adaptadores LoRA

Después de entrenar con LoRA, podrías querer fusionar los pesos del adaptador de vuelta en el modelo base para facilitar su implementación. Esto crea un único modelo con los pesos combinados, eliminando la necesidad de cargar adaptadores por separado durante la inferencia.

El proceso de fusión requiere atención al manejo de memoria y precisión. Como necesitarás cargar tanto el modelo base como los pesos del adaptador simultáneamente, asegúrate de tener suficiente memoria GPU/CPU disponible. Usar `device_map="auto"` en `transformers` ayudará con el manejo automático de memoria. Mantén una precisión consistente (por ejemplo, `float16`) durante todo el proceso, y guarda el modelo fusionado en el mismo formato para su implementación. Antes de implementar, siempre valida el modelo fusionado comparando sus salidas y métricas de rendimiento con la versión basada en adaptadores.

Los adaptadores también son convenientes para cambiar entre diferentes tareas o dominios. Puedes cargar el modelo base y los pesos del adaptador por separado, permitiendo un cambio rápido entre diferentes pesos específicos de tareas.

## Guía de implementación

El directorio `notebooks/` contiene tutoriales prácticos y ejercicios para implementar diferentes métodos PEFT. Comienza con `load_lora_adapter_example.ipynb` para una introducción básica, y luego explora `lora_finetuning.ipynb` para un análisis más detallado de cómo realizar fine-tuning en un modelo con LoRA y SFT.

Cuando implementes métodos PEFT, comienza con valores de rango pequeños (4-8) para LoRA y monitoriza la pérdida durante el entrenamiento. Utiliza conjuntos de validación para evitar el sobreajuste y compara los resultados con los baselines del fine-tuning completo cuando sea posible. La efectividad de los diferentes métodos puede variar según la tarea, por lo que la experimentación es clave.

## OLoRA

[OLoRA](https://arxiv.org/abs/2406.01775) utiliza descomposición QR para inicializar los adaptadores LoRA. OLoRA traduce los pesos base del modelo por un factor de sus descomposiciones QR, es decir, muta los pesos antes de realizar cualquier entrenamiento sobre ellos. Este enfoque mejora significativamente la estabilidad, acelera la velocidad de convergencia y logra un rendimiento superior.

## Usando TRL con PEFT

Los métodos PEFT pueden combinarse con TRL (Transformers Reinforcement Learning) para un fine-tuning eficiente. Esta integración es particularmente útil para RLHF (Reinforcement Learning from Human Feedback), ya que reduce los requisitos de memoria.

```python
from peft import LoraConfig
from transformers import AutoModelForCausalLM

# Carga el modelo con configuración PEFT
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

# Carga el modelo en un dispositivo específico
model = AutoModelForCausalLM.from_pretrained(
    "your-model-name",
    load_in_8bit=True,  # Opcional: usa la precisión de 8 bits
    device_map="auto",
    peft_config=lora_config
)
```

Aquí, usamos `device_map="auto"` para asignar automáticamente el modelo al dispositivo correcto. También puedes asignar manualmente el modelo a un dispositivo específico usando `device_map={"": device_index}`. Además, podrías escalar el entrenamiento en múltiples GPUs mientras mantienes un uso eficiente de memoria.

## Implementación básica de fusión

Después de entrenar un adaptador LoRA, puedes fusionar los pesos del adaptador de vuelta en el modelo base. Aquí tienes cómo hacerlo:

```python
import torch
from transformers import AutoModelForCausalLM
from peft import PeftModel

# 1. Carga el modelo base
base_model = AutoModelForCausalLM.from_pretrained(
    "base_model_name",
    torch_dtype=torch.float16,
    device_map="auto"
)

# 2. Carga el modelo PEFT con adaptador
peft_model = PeftModel.from_pretrained(
    base_model,
    "path/to/adapter",
    torch_dtype=torch.float16
)

# 3. Fusiona los pesos del adaptador con el modelo base
try:
    merged_model = peft_model.merge_and_unload()
except RuntimeError as e:
    print(f"Fusión fallida: {e}")
    # Implementa estrategia de respaldo u optimización de memoria

# 4. Guarda el modelo fusionado
merged_model.save_pretrained("path/to/save/merged_model")
```

Si encuentras discrepancias de tamaño en el modelo guardado, asegúrate de guardar también el tokenizer:

```python
# Guarda tanto el modelo como el tokenizer
tokenizer = AutoTokenizer.from_pretrained("base_model_name")
merged_model.save_pretrained("path/to/save/merged_model")
tokenizer.save_pretrained("path/to/save/merged_model")
```

## Próximos pasos

⏩ Pasa al [Prompt Tuning](prompt_tuning.md) para aprender a realizar fine-tuning en un modelo con prompt tuning.
⏩ Revisa el [Tutorial de Carga de Adaptadores LoRA](./notebooks/load_lora_adapter.ipynb) para aprender a cargar adaptadores LoRA.

# Recursos

- [LORA: ADAPTACIÓN DE BAJO RANGO PARA MODELOS DE LENGUAJE DE GRAN TAMAÑO](https://arxiv.org/pdf/2106.09685)
- [Documentación de PEFT](https://huggingface.co/docs/peft)
- [Publicación en el blog de Hugging Face sobre PEFT](https://huggingface.co/blog/peft)

A course on aligning smol models.


# Ajuste de Prompts

El ajuste de prompts es un enfoque eficiente en términos de parámetros que modifica las representaciones de entrada en lugar de los pesos del modelo. A diferencia del fine-tuning tradicional que actualiza todos los parámetros del modelo, el ajuste de prompts agrega y optimiza un pequeño conjunto de tokens entrenables mientras mantiene el modelo base congelado.

## Entendiendo el Ajuste de Prompts

El ajuste de prompts es una alternativa eficiente en términos de parámetros al fine-tuning del modelo que antepone vectores continuos entrenables (prompts suaves) al texto de entrada. A diferencia de los prompts discretos de texto, estos prompts suaves se aprenden mediante retropropagación mientras el modelo de lenguaje se mantiene congelado. El método fue introducido en ["El poder de la escala para el ajuste de prompts eficiente en parámetros"](https://arxiv.org/abs/2104.08691) (Lester et al., 2021), que demostró que el ajuste de prompts se vuelve más competitivo con el fine-tuning del modelo a medida que aumenta el tamaño del modelo. En el artículo, alrededor de 10 mil millones de parámetros, el ajuste de prompts iguala el rendimiento del fine-tuning del modelo mientras solo modifica unos pocos cientos de parámetros por tarea.

Estos prompts suaves son vectores continuos en el espacio de incrustación del modelo que se optimizan durante el entrenamiento. A diferencia de los prompts discretos tradicionales que usan tokens de lenguaje natural, los prompts suaves no tienen un significado inherente, pero aprenden a provocar el comportamiento deseado del modelo congelado mediante el descenso de gradiente. La técnica es particularmente efectiva para escenarios de múltiples tareas, ya que cada tarea requiere almacenar solo un pequeño vector de prompt (normalmente unos pocos cientos de parámetros) en lugar de una copia completa del modelo. Este enfoque no solo mantiene una huella de memoria mínima, sino que también permite una adaptación rápida de tareas simplemente intercambiando los vectores de prompt sin necesidad de recargar el modelo.

## Proceso de Entrenamiento

Los prompts suaves suelen ser entre 8 y 32 tokens y se pueden inicializar de forma aleatoria o a partir de texto existente. El método de inicialización juega un papel crucial en el proceso de entrenamiento, con la inicialización basada en texto a menudo obteniendo mejores resultados que la aleatoria.

Durante el entrenamiento, solo se actualizan los parámetros del prompt mientras que el modelo base permanece congelado. Este enfoque centrado utiliza objetivos de entrenamiento estándar, pero requiere una atención cuidadosa a la tasa de aprendizaje y el comportamiento de los gradientes de los tokens del prompt.

## Implementación con PEFT

La libreria PEFT facilita la implementación del ajuste de prompts. Aquí tienes un ejemplo básico:

```python
from peft import PromptTuningConfig, TaskType, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer

# Carga el modelo base
model = AutoModelForCausalLM.from_pretrained("your-base-model")
tokenizer = AutoTokenizer.from_pretrained("your-base-model")

# Configura el ajuste de prompt
peft_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM,
    num_virtual_tokens=8,  # Número de tokens entrenables
    prompt_tuning_init="TEXT",  # Inicializa a partir de texto
    prompt_tuning_init_text="Clasifique si este texto es positivo o negativo:",
    tokenizer_name_or_path="your-base-model",
)

# Crea el modelo ajustable por prompt
model = get_peft_model(model, peft_config)
```

## Comparación con Otros Métodos

Cuando se compara con otros enfoques de PEFT, el ajuste de prompts destaca por su eficiencia. Mientras que LoRA ofrece bajos recuentos de parámetros y uso de memoria pero requiere cargar adaptadores para el cambio de tareas, el ajuste de prompts logra un uso de recursos aún menor y permite un cambio de tareas inmediato. El fine-tuning completo, en contraste, exige recursos significativos y requiere copias separadas del modelo para diferentes tareas.

| Método            | Parámetros  | Memoria  | Cambio de Tarea |
|-------------------|-------------|----------|-----------------|
| Ajuste de Prompts | Muy Bajo    | Mínimo   | Fácil           |
| LoRA              | Bajo        | Bajo     | Requiere Carga  |
| Fine-tuning Completo   | Alto        | Alto     | Nueva Copia     |

Al implementar el ajuste de prompts, comienza con un pequeño número de tokens virtuales (8-16) y aumenta solo si la complejidad de la tarea lo requiere. La inicialización con texto generalmente da mejores resultados que la aleatoria, especialmente cuando se utiliza texto relevante para la tarea. La estrategia de inicialización debe reflejar la complejidad de la tarea objetivo.

El entrenamiento requiere consideraciones ligeramente diferentes al fine-tuning completo. Las tasas de aprendizaje más altas suelen funcionar bien, pero es esencial monitorear cuidadosamente los gradientes de los tokens de prompt. La validación regular con ejemplos diversos ayuda a garantizar un rendimiento robusto en diferentes escenarios.

## Aplicaciones

El ajuste de prompts sobresale en varios escenarios:

1. Despliegue de múltiples tareas
2. Entornos con limitaciones de recursos
3. Adaptación rápida de tareas
4. Aplicaciones sensibles a la privacidad

A medida que los modelos se hacen más pequeños, el ajuste de prompts se vuelve menos competitivo en comparación con el fine-tuning completo. Por ejemplo, en modelos como SmolLM2, el ajuste de prompts es menos relevante que el fine-tuning completo.

## Próximos Pasos

⏭ Pasa al [Tutorial de Adaptadores LoRA](./notebooks/finetune_sft_peft.ipynb) para aprender cómo ajustar un modelo con adaptadores LoRA.

## Recursos
- [Documentación de PEFT](https://huggingface.co/docs/peft)
- [Papel sobre Ajuste de Prompts](https://arxiv.org/abs/2104.08691)
- [Recetario de Hugging Face](https://huggingface.co/learn/cookbook/prompt_tuning_peft)

A course on aligning smol models.


# Evaluación

La evaluación es un paso crítico en el desarrollo y despliegue de modelos de lenguaje. Nos permite entender qué tan bien funcionan nuestros modelos en diferentes capacidades e identificar áreas de mejora. Este módulo cubre tanto los "becnhmarks" estándares como los enfoques de evaluación específicos para evaluar de manera integral tu modelo **smol**.

Usaremos [`lighteval`](https://github.com/huggingface/lighteval), una poderosa biblioteca de evaluación desarrollada por Hugging Face que se integra perfectamente con el ecosistema de Hugging Face. Para una explicación más detallada sobre los conceptos y mejores prácticas de evaluación, consulta la [guía de evaluación](https://github.com/huggingface/evaluation-guidebook).

## Descripción del Módulo

Una estrategia de evaluación completa examina múltiples aspectos del rendimiento del modelo. Evaluamos capacidades específicas en tareas como responder preguntas y resumir textos, para entender cómo el modelo maneja diferentes tipos de problemas. Medimos la calidad del "output" mediante factores como coherencia y precisión. A su vez, la evaluación de seguridad ayuda a identificar posibles "outputs" dañinas o sesgos. Finalmente, las pruebas de experticia en áreas especfícios verifican el conocimiento especializado del modelo en tu campo objetivo.

## Contenidos

### 1⃣ [Evaluaciones Automáticas](./automatic_benchmarks.md)
Aprende a evaluar tu modelo utilizando "benchmarks" y métricas estandarizadas. Exploraremos "benchmarks" comunes como MMLU y TruthfulQA, entenderemos las métricas clave de evaluación y configuraciones, y cubriremos mejores prácticas para una evaluación reproducible.

### 2⃣ [Evaluación Personalizada en un Dominio](./custom_evaluation.md)
Descubre cómo crear flujos de evaluación adaptados a tus casos de uso específicos. Te guiaremos en el diseño de tareas de evaluación personalizadas, la implementación de métricas especializadas y la construcción de conjuntos de datos de evaluación que se ajusten a tus necesidades.

### 3⃣ [Proyecto de Evaluación en un Dominio](./project/README.md)
Sigue un ejemplo completo de cómo construir un flujo de evaluación específico para un dominio. Aprenderás a generar conjuntos de datos de evaluación, usar Argilla para la anotación de datos, crear conjuntos de datos estandarizados y evaluar modelos utilizando LightEval.

### Cuadernos de Ejercicios

| Título | Descripción | Ejercicio | Enlace | Colab |
|--------|-------------|----------|-------|-------|
| Evalúa y analiza tu LLM | Aprende a usar LightEval para evaluar y comparar modelos en dominios específicos | 🐢 Usa tareas del dominio médico para evaluar un modelo
 🐕 Crea una evaluación de dominio con diferentes tareas MMLU
 🦁 Diseña una tarea de evaluación personalizada para tu dominio | [Cuaderno](./notebooks/lighteval_evaluate_and_analyse_your_LLM.ipynb) |  |

## Recursos

- [Guía de Evaluación](https://github.com/huggingface/evaluation-guidebook) - Guía completa para la evaluación de modelos de lenguaje
- [Documentación de LightEval](https://github.com/huggingface/lighteval) - Documentación oficial de la biblioteca LightEval
- [Documentación de Argilla](https://docs.argilla.io) - Aprende sobre la plataforma de anotación Argilla
- [Paper de MMLU](https://arxiv.org/abs/2009.03300) - Artículo sobre el benchmark MMLU
- [Crear una Tarea Personalizada](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [Crear una Métrica Personalizada](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- [Usar métricas existentes](https://github.com/huggingface/lighteval/wiki/Metric-List)

A course on aligning smol models.


# Benchmarks Automáticos

Los "benchmarks" automáticos sirven como herramientas estandarizadas para evaluar modelos de lenguaje en diferentes tareas y capacidades. Aunque proporcionan un punto de partida útil para entender el rendimiento de un modelo, es importante reconocer que representan solo una parte de una estrategia de evaluación integral.

## Entendiendo los Benchmarks Automáticos

Los "benchmarks" automáticos generalmente consisten en conjuntos de datos curados con tareas y métricas de evaluación predefinidas. Estos "benchmarks" buscan evaluar diversos aspectos de la capacidad del modelo, desde la comprensión básica del lenguaje hasta el razonamiento complejo. La principal ventaja de usar "benchmarks" automáticos es su estandarización: permiten comparaciones consistentes entre diferentes modelos y proporcionan resultados reproducibles.

Sin embargo, es crucial entender que el rendimiento en un "benchmark" no siempre se traduce directamente en efectividad en el mundo real. Un modelo que sobresale en "benchmarks" académicos puede tener dificultades en aplicaciones específicas de dominio o casos de uso prácticos.

## Benchmarks y Sus Limitaciones

### Benchmarks de Conocimientos Generales

MMLU (Massive Multitask Language Understanding) evalúa conocimientos en 57 materias, desde ciencias hasta humanidades. Aunque es extenso, puede no reflejar la profundidad de experiencia necesaria para dominios específicos. TruthfulQA evalúa la tendencia de un modelo a reproducir conceptos erróneos comunes, aunque no puede capturar todas las formas de desinformación.

### Benchmarks de Razonamiento

BBH (Big Bench Hard) y GSM8K se enfocan en tareas de razonamiento complejo. BBH evalúa el pensamiento lógico y la planificación, mientras que GSM8K se centra específicamente en la resolución de problemas matemáticos. Estos "benchmarks" ayudan a evaluar capacidades analíticas pero pueden no capturar el razonamiento matizado requerido en escenarios del mundo real.

### Comprensión del Lenguaje

HELM proporciona un marco de evaluación holístico, mientras que WinoGrande prueba el sentido común mediante la desambiguación de pronombres. Estos "benchmarks" ofrecen información sobre las capacidades de procesamiento del lenguaje, pero pueden no representar completamente la complejidad de las conversaciones naturales o la terminología específica de un dominio.

## Enfoques Alternativos de Evaluación

Muchas organizaciones han desarrollado métodos de evaluación alternativos para abordar las limitaciones de los "benchmarks" estándar:

### Model de lenguaje como Juez (LLM-as-Judge)

Usar un modelo de lenguaje para evaluar los "outputs" de otro modelo se ha vuelto cada vez más popular. Este enfoque puede proporcionar retroalimentación más matizada que las métricas tradicionales, aunque viene con sus propios sesgos y limitaciones.

### Arenas de Evaluación (Evaluation Arenas)

Plataformas como Chatbot Arena permiten que los modelos interactúen y se evalúen entre sí en entornos controlados. Esto puede revelar fortalezas y debilidades que podrían no ser evidentes en "benchmarks" tradicionales.

### Grupos de Benchmarks Personalizados

Las organizaciones a menudo desarrollan conjuntos de "benchmarks" internos adaptados a sus necesidades específicas y casos de uso. Estos pueden incluir pruebas de conocimientos específicos de dominio o escenarios de evaluación que reflejen las condiciones reales de despliegue.

## Creando Tu Propia Estrategia de Evaluación

Recuerda que aunque LightEval facilita ejecutar "benchmarks" estándar, también deberías invertir tiempo en desarrollar métodos de evaluación específicos para tu caso de uso.

Aunque los "benchmarks" estándares proporcionan una línea base útil, no deberían ser tu único método de evaluación. Así es como puedes desarrollar un enfoque más integral:

1. Comienza con "benchmarks" estándares relevantes para establecer una línea base y permitir comparaciones con otros modelos.

2. Identifica los requisitos y desafíos específicos de tu caso de uso. ¿Qué tareas realizará tu modelo realmente? ¿Qué tipos de errores serían más problemáticos?

3. Desarrolla conjuntos de datos de evaluación personalizados que reflejen tu caso de uso real. Esto podría incluir:
   - Consultas reales de usuarios en tu dominio
   - Casos límite comunes que hayas encontrado
   - Ejemplos de escenarios particularmente desafiantes

4. Considera implementar una estrategia de evaluación por capas:
   - Métricas automatizadas para retroalimentación rápida
   - Evaluación humana para una comprensión más matizada
   - Revisión por expertos en el dominio para aplicaciones especializadas
   - Pruebas A/B en entornos controlados

## Usando LightEval para "Benchmarking"

Las tareas de LightEval se definen usando un formato específico:
```
{suite}|{task}|{num_few_shot}|{auto_reduce}
```

- **suite**: El conjunto de "benchmarks" (por ejemplo, 'mmlu', 'truthfulqa')
- **task**: Tarea específica dentro del conjunto (por ejemplo, 'abstract_algebra')
- **num_few_shot**: Número de ejemplos a incluir en el "prompt" (0 para zero-shot)
- **auto_reduce**: Si se debe reducir automáticamente los ejemplos "few-shot" si el "prompt" es demasiado largo (0 o 1)

Ejemplo: `"mmlu|abstract_algebra|0|0"` evalúa la tarea de álgebra abstracta de MMLU sin ejempls en el "prompt" (i.e. "zero-shot").

### Ejemplo de Pipeline de Evaluación

Aquí tienes un ejemplo completo de configuración y ejecución de una evaluación utilizando "benchmarks" automáticos relevantes para un dominio específico:

```python
from lighteval.tasks import Task, Pipeline
from transformers import AutoModelForCausalLM

# Definir tareas para evaluar
domain_tasks = [
    "mmlu|anatomy|0|0",
    "mmlu|high_school_biology|0|0",
    "mmlu|high_school_chemistry|0|0",
    "mmlu|professional_medicine|0|0"
]

# Configurar parámetros del pipeline
pipeline_params = {
    "max_samples": 40,  # Número de muestras para evaluar
    "batch_size": 1,    # Tamaño del "batch" para la inferencia
    "num_workers": 4    # Número de procesos paralelos
}

# Crear tracker de evaluación
evaluation_tracker = EvaluationTracker(
    output_path="./results",
    save_generations=True
)

# Cargar modelo y crear pipeline
model = AutoModelForCausalLM.from_pretrained("your-model-name")
pipeline = Pipeline(
    tasks=domain_tasks,
    pipeline_parameters=pipeline_params,
    evaluation_tracker=evaluation_tracker,
    model=model
)

# Ejecutar evaluación
pipeline.evaluate()

# Obtener y mostrar resultados
results = pipeline.get_results()
pipeline.show_results()
```

Los resultados se muestran en formato tabular:
```
|                  Task                  |Version|Metric|Value |   |Stderr|
|----------------------------------------|------:|------|-----:|---|-----:|
|all                                     |       |acc   |0.3333|±  |0.1169|
|leaderboard:mmlu:_average:5             |       |acc   |0.3400|±  |0.1121|
|leaderboard:mmlu:anatomy:5              |      0|acc   |0.4500|±  |0.1141|
|leaderboard:mmlu:high_school_biology:5  |      0|acc   |0.1500|±  |0.0819|
```

También puedes manejar los resultados en un DataFrame de pandas y visualizarlos o representarlos como prefieras.

# Próximos Pasos

⏩ Explora [Evaluación Personalizada en un Dominio](./custom_evaluation.md) para aprender a crear flujos de evaluación adaptados a tus necesidades específicas.

A course on aligning smol models.


# Evaluación Personalizada en un Dominio

Aunque los "benchmarks" estándares proporcionan conocimiento relevante, muchas aplicaciones requieren enfoques de evaluación especializados que se adapten a dominios específicos o a casos de uso particulares. Esta guía te ayudará a crear flujos de evaluación personalizados que evalúen con precisión el rendimiento de tu modelo en tu dominio objetivo.

## Diseñando Tu Estrategia de Evaluación

Una estrategia de evaluación personalizada exitosa comienza con objetivos claros. Es fundamental considerar qué capacidades específicas necesita demostrar tu modelo en tu dominio. Esto podría incluir conocimientos técnicos, patrones de razonamiento o formatos específicos del dominio. Documenta estos requisitos cuidadosamente; ellos guiarán tanto el diseño de tus tareas como la selección de métricas.

Tu evaluación debe probar tanto casos de uso estándar como casos límite. Por ejemplo, en un dominio médico, podrías evaluar tanto escenarios comunes de diagnóstico como condiciones raras. En aplicaciones financieras, podrías probar tanto transacciones rutinarias como casos complejos que involucren múltiples monedas o condiciones especiales.

## Implementación con LightEval

LightEval proporciona un marco flexible para implementar evaluaciones personalizadas. Así es como puedes crear una tarea personalizada:

```python
from lighteval.tasks import Task, Doc
from lighteval.metrics import SampleLevelMetric, MetricCategory, MetricUseCase

class CustomEvalTask(Task):
    def __init__(self):
        super().__init__(
            name="custom_task",
            version="0.0.1",
            metrics=["accuracy", "f1"],  # Tus métricas elegidas
            description="Descripción de tu tarea de evaluación personalizada"
        )

    def get_prompt(self, sample):
        # Formatea tu entrada en un "prompt"
        return f"Question: {sample['question']}\nAnswer:"

    def process_response(self, response, ref):
        # Procesa el "output" del modelo y compáralo con la referencia
        return response.strip() == ref.strip()
```

## Métricas Personalizadas

Las tareas específicas de dominio a menudo requieren métricas especializadas. LightEval proporciona un marco flexible para crear métricas personalizadas que capturen aspectos relevantes del rendimiento del dominio:

```python
from aenum import extend_enum
from lighteval.metrics import Metrics, SampleLevelMetric, SampleLevelMetricGrouping
import numpy as np

# Definir una función de métrica a nivel de muestra
def custom_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> dict:
    """Ejemplo de métrica que genera múltiples puntuaciones por muestra"""
    response = predictions[0]
    return {
        "accuracy": response == formatted_doc.choices[formatted_doc.gold_index],
        "length_match": len(response) == len(formatted_doc.reference)
    }

# Crear una métrica que genere múltiples valores por muestra
custom_metric_group = SampleLevelMetricGrouping(
    metric_name=["accuracy", "length_match"],  # Nombres de submétricas
    higher_is_better={  # define si valores más altos son mejores para cada métrica
        "accuracy": True,
        "length_match": True
    },
    category=MetricCategory.CUSTOM,
    use_case=MetricUseCase.SCORING,
    sample_level_fn=custom_metric,
    corpus_level_fn={  # define cómo agregar cada métrica
        "accuracy": np.mean,
        "length_match": np.mean
    }
)

# Registrar la métrica en LightEval
extend_enum(Metrics, "custom_metric_name", custom_metric_group)
```

Para casos más simples donde solo necesitas un valor por muestra:

```python
def simple_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> bool:
    """Ejemplo de métrica que genera una única puntuación por muestra"""
    response = predictions[0]
    return response == formatted_doc.choices[formatted_doc.gold_index]

simple_metric_obj = SampleLevelMetric(
    metric_name="simple_accuracy",
    higher_is_better=True,
    category=MetricCategory.CUSTOM,
    use_case=MetricUseCase.SCORING,
    sample_level_fn=simple_metric,
    corpus_level_fn=np.mean  # define cómo agregar resultados entre muestras
)

extend_enum(Metrics, "simple_metric", simple_metric_obj)
```

Una vez definas tus métricas personalizadas, puedes usarlas luego en tus tareas de evaluación haciendo referencia a ellas en la configuración de la tarea. Las métricas se calcularán automáticamente en todas las muestras y se agregarán según las funciones que especifiques.

Para métricas más complejas, considera:
- Usar metadatos en tus documentos formateados para ponderar o ajustar puntuaciones
- Implementar funciones de agregación personalizadas para estadísticas a nivel de corpus
- Agregar verificaciones de validación para las entradas de tus métricas
- Documentar casos límite y comportamientos esperados

Para un ejemplo completo de métricas personalizadas en acción, consulta nuestro [proyecto de evaluación de dominio](./project/README.md).

## Creación de Conjuntos de Datos

La evaluación de alta calidad requiere conjuntos de datos cuidadosamente curados. Considera estos enfoques para la creación de conjuntos de datos:

1. **Anotación por Expertos**: Trabaja con expertos del dominio para crear y validar ejemplos de evaluación. Herramientas como [Argilla](https://github.com/argilla-io/argilla) hacen este proceso más eficiente.

2. **Datos del Mundo Real**: Recopila y anonimiza datos de uso real, asegurándote de que representen escenarios reales de despliegue del modelo.

3. **Generación Sintética**: Usa LLMs para generar ejemplos iniciales y luego permite que expertos los validen y refinen.

## Mejores Prácticas

- Documenta tu metodología de evaluación a fondo, incluidas los supuestos o limitaciones
- Incluye casos de prueba diversos que cubran diferentes aspectos de tu dominio
- Considera tanto métricas automatizadas como evaluaciones humanas donde sea apropiado
- Controla las versiones de tus conjuntos de datos y código de evaluación
- Actualiza regularmente tu conjunto de evaluaciones a medida que descubras nuevos casos límite o requisitos

## Referencias

- [Guía de Tareas Personalizadas en LightEval](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [Métricas Personalizadas en LightEval](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- [Documentación de Argilla](https://docs.argilla.io) para anotación de conjuntos de datos
- [Guía de Evaluación](https://github.com/huggingface/evaluation-guidebook) para principios generales de evaluación

# Próximos Pasos

⏩ Para un ejemplo completo de cómo implementar estos conceptos, consulta nuestro [proyecto de evaluación de dominio](./project/README.md).

A course on aligning smol models.


# インストラクションチューニング

このモジュールでは、言語モデルのインストラクションチューニングのプロセスをガイドします。インストラクションチューニングとは、特定のタスクに対してモデルを適応させるために、特定のタスクに関連するデータセットで追加のトレーニングを行うことを指します。このプロセスは、特定のタスクにおけるモデルのパフォーマンスを向上させるのに役立ちます。

このモジュールでは、2つのトピックを探ります：1) チャットテンプレートと2) 教師あり微調整

## 1⃣ チャットテンプレート

チャットテンプレートは、ユーザーとAIモデル間のインタラクションを構造化し、一貫性のある文脈に適した応答を保証します。これらのテンプレートには、システムメッセージや役割に基づくメッセージなどのコンポーネントが含まれます。詳細については、[チャットテンプレート](./chat_templates.md)セクションを参照してください。

## 2⃣ 教師あり微調整

教師あり微調整（SFT）は、事前トレーニングされた言語モデルを特定のタスクに適応させるための重要なプロセスです。これは、ラベル付きの例を含む特定のタスクのデータセットでモデルをトレーニングすることを含みます。SFTの詳細なガイド、重要なステップ、およびベストプラクティスについては、[教師あり微調整](./supervised_fine_tuning.md)ページを参照してください。

## 演習ノートブック

| タイトル | 説明 | 演習 | リンク | Colab |
|--------|-------------|-----------|--------|-------|
| チャットテンプレート | SmolLM2を使用してチャットテンプレートを使用し、チャットml形式のデータセットを処理する方法を学びます | 🐢 `HuggingFaceTB/smoltalk`データセットをchatml形式に変換
 🐕 `openai/gsm8k`データセットをchatml形式に変換 | [ノートブック](./notebooks/chat_templates_example.ipynb) |  |
| 教師あり微調整 | SFTTrainerを使用してSmolLM2を微調整する方法を学びます | 🐢 `HuggingFaceTB/smoltalk`データセットを使用
 🐕 `bigcode/the-stack-smol`データセットを試す
 🦁 実際の使用ケースに関連するデータセットを選択 | [ノートブック](./notebooks/sft_finetuning_example.ipynb) |  |

## 参考文献

- [Transformersのチャットテンプレートに関するドキュメント](https://huggingface.co/docs/transformers/main/en/chat_templating)
- [TRLの教師あり微調整スクリプト](https://github.com/huggingface/trl/blob/main/examples/scripts/sft.py)
- [TRLの`SFTTrainer`](https://huggingface.co/docs/trl/main/en/sft_trainer)
- [直接選好最適化に関する論文](https://arxiv.org/abs/2305.18290)
- [TRLを使用した教師あり微調整](https://huggingface.co/docs/trl/main/en/tutorials/supervised_fine_tuning)
- [ChatMLとHugging Face TRLを使用したGoogle Gemmaの微調整方法](https://www.philschmid.de/fine-tune-google-gemma)
- [LLMを微調整してペルシャ語の商品カタログをJSON形式で生成する方法](https://huggingface.co/learn/cookbook/en/fine_tuning_llm_to_generate_persian_product_catalogs_in_json_format)

A course on aligning smol models.


# チャットテンプレート

チャットテンプレートは、言語モデルとユーザー間のインタラクションを構造化するために不可欠です。これらは会話の一貫した形式を提供し、モデルが各メッセージの文脈と役割を理解し、適切な応答パターンを維持することを保証します。

## ベースモデル vs インストラクションモデル

ベースモデルは次のトークンを予測するために生のテキストデータでトレーニングされる一方、インストラクションモデルは特定の指示に従い会話に参加するように微調整されたモデルです。例えば、`SmolLM2-135M`はベースモデルであり、`SmolLM2-135M-Instruct`はその指示に特化したバリアントです。

ベースモデルをインストラクションモデルのように動作させるためには、モデルが理解できるようにプロンプトを一貫してフォーマットする必要があります。ここでチャットテンプレートが役立ちます。ChatMLは、システム、ユーザー、アシスタントの役割を明確に示すテンプレート形式で会話を構造化します。

ベースモデルは異なるチャットテンプレートで微調整される可能性があるため、インストラクションモデルを使用する際には、正しいチャットテンプレートを使用していることを確認する必要があります。

## チャットテンプレートの理解

チャットテンプレートの核心は、言語モデルと通信する際に会話がどのようにフォーマットされるべきかを定義することです。これには、システムレベルの指示、ユーザーメッセージ、およびアシスタントの応答が含まれ、モデルが理解できる構造化された形式で提供されます。この構造は、インタラクションの一貫性を維持し、モデルがさまざまな種類の入力に適切に応答することを保証します。以下はチャットテンプレートの例です：

```sh
<|im_end|>ユーザー
こんにちは！<|im_end|>
<|im_end|>アシスタント
はじめまして！<|im_end|>
<|im_end|>ユーザー
質問してもいいですか？<|im_end|>
<|im_end|>アシスタント
```

`transformers`ライブラリは、モデルのトークナイザーに関連してチャットテンプレートを自動的に処理します。`transformers`でチャットテンプレートがどのように構築されるかについて詳しくは[こちら](https://huggingface.co/docs/transformers/en/chat_templating#how-do-i-use-chat-templates)を参照してください。私たちはメッセージを正しい形式で構造化するだけで、残りはトークナイザーが処理します。以下は基本的な会話の例です：

```python
messages = [
    {"role": "system", "content": "あなたは技術的なトピックに焦点を当てた役立つアシスタントです。"},
    {"role": "user", "content": "チャットテンプレートとは何か説明できますか？"},
    {"role": "assistant", "content": "チャットテンプレートは、ユーザーとAIモデル間の会話を構造化します..."}
]
```

上記の例を分解して、チャットテンプレート形式にどのようにマッピングされるかを見てみましょう。

## システムメッセージ

システムメッセージは、モデルの動作の基礎を設定します。これらは、以降のすべてのインタラクションに影響を与える持続的な指示として機能します。例えば：

```python
system_message = {
    "role": "system",
    "content": "あなたはプロフェッショナルなカスタマーサービスエージェントです。常に礼儀正しく、明確で、役立つようにしてください。"
}
```

## 会話

チャットテンプレートは、ユーザーとアシスタント間の以前のやり取りを保存し、会話の履歴を通じて文脈を維持します。これにより、複数ターンにわたる一貫した会話が可能になります：

```python
conversation = [
    {"role": "user", "content": "注文に関して助けが必要です"},
    {"role": "assistant", "content": "お手伝いします。注文番号を教えていただけますか？"},
    {"role": "user", "content": "注文番号はORDER-123です"},
]
```

## Transformersを使用した実装

`transformers`ライブラリは、チャットテンプレートのための組み込みサポートを提供します。使用方法は以下の通りです：

```python
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-135M-Instruct")

messages = [
    {"role": "system", "content": "あなたは役立つプログラミングアシスタントです。"},
    {"role": "user", "content": "リストをソートするPython関数を書いてください"},
]

# チャットテンプレートを適用
formatted_chat = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
```

## カスタムフォーマット

異なる役割に対して特別なトークンやフォーマットを追加するなど、さまざまなメッセージタイプのフォーマットをカスタマイズできます。例えば：

```python
template = """
<|system|>{system_message}
<|user|>{user_message}
<|assistant|>{assistant_message}
""".lstrip()
```

## マルチターン会話のサポート

テンプレートは、文脈を維持しながら複雑なマルチターン会話を処理できます：

```python
messages = [
    {"role": "system", "content": "あなたは数学の家庭教師です。"},
    {"role": "user", "content": "微積分とは何ですか？"},
    {"role": "assistant", "content": "微積分は数学の一分野です..."},
    {"role": "user", "content": "例を教えてください。"},
]
```

⏭ [次へ: Supervised Fine-Tuning](./supervised_fine_tuning.md)

## リソース

- [Hugging Face Chat Templating Guide](https://huggingface.co/docs/transformers/main/en/chat_templating)
- [Transformers Documentation](https://huggingface.co/docs/transformers)
- [Chat Templates Examples Repository](https://github.com/chujiezheng/chat_templates)

A course on aligning smol models.


# 教師あり微調整

教師あり微調整（SFT）は、事前トレーニングされた言語モデルを特定のタスクやドメインに適応させるための重要なプロセスです。事前トレーニングされたモデルは一般的な能力を持っていますが、特定のユースケースで優れたパフォーマンスを発揮するためにはカスタマイズが必要です。SFTは、慎重に選ばれた人間によって検証された例を含むデータセットを使用してモデルをトレーニングすることで、このギャップを埋めます。

## 教師あり微調整の理解

教師あり微調整の核心は、事前トレーニングされたモデルに特定のタスクを実行する方法を教えることです。これは、入力と出力の例を多数提示し、モデルが特定のユースケースのパターンを学習できるようにすることを含みます。

SFTは、事前トレーニング中に獲得した基本的な知識を活用しながら、モデルの動作を特定のニーズに合わせて調整するため、効果的です。

## 教師あり微調整を使用するタイミング

SFTを使用するかどうかの決定は、現在のモデルの能力と特定の要件とのギャップに依存します。SFTは、モデルの出力を正確に制御する必要がある場合や、専門的なドメインで作業する場合に特に価値があります。

例えば、カスタマーサービスアプリケーションを開発している場合、モデルが一貫して企業のガイドラインに従い、技術的な問い合わせを標準化された方法で処理することを望むかもしれません。同様に、医療や法律のアプリケーションでは、正確さと特定のドメインの用語に従うことが重要です。これらの場合、SFTはモデルの応答を専門的な基準とドメインの専門知識に合わせるのに役立ちます。

## 教師あり微調整（SFT）のプロセス

教師あり微調整のプロセスは、特定のタスクのデータセットでモデルの重みをトレーニングすることを含みます。

まず、ターゲットタスクを表すデータセットを準備または選択する必要があります。このデータセットには、モデルが直面するさまざまなシナリオをカバーする多様な例が含まれている必要があります。これらのデータの品質は重要です。各例は、モデルが生成することを望む出力の種類を示している必要があります。次に、微調整のフェーズがあり、ここでは`transformers`やHugging Faceの`trl`などのフレームワークを使用して、データセットでモデルをトレーニングします。

プロセス全体を通じて、継続的な評価が重要です。モデルが望ましい動作を学習していることを確認するために、検証セットでのパフォーマンスを監視する必要があります。これにより、モデルが一般的な能力を失うことなく、特定のタスクに適応していることを確認できます。[モジュール4](../4_evaluation)では、モデルの評価方法について詳しく説明します。

## 教師あり微調整の役割

SFTは、言語モデルを人間の好みに合わせる上で重要な役割を果たします。人間のフィードバックを使用した強化学習（RLHF）や直接選好最適化（DPO）などの技術は、SFTを使用してタスクの基本的な理解を形成し、その後、モデルの応答を望ましい結果にさらに合わせます。事前トレーニングされたモデルは、一般的な言語能力に優れているにもかかわらず、必ずしも人間の好みに一致する出力を生成するわけではありません。SFTは、特定のドメインのデータとガイダンスを導入することで、このギャップを埋め、モデルが人間の期待により密接に一致する応答を生成する能力を向上させます。

## トランスフォーマーの強化学習（TRL）を使用した教師あり微調整

教師あり微調整のための主要なソフトウェアパッケージは、トランスフォーマーの強化学習（TRL）です。TRLは、強化学習（RL）を使用してトランスフォーマーモデルをトレーニングするためのツールセットです。

Hugging FaceのTransformersライブラリに基づいており、ユーザーが事前トレーニングされた言語モデルを直接ロードできるようにし、ほとんどのデコーダーおよびエンコーダーデコーダーアーキテクチャと互換性があります。このライブラリは、教師あり微調整（SFT）、報酬モデリング（RM）、近接ポリシー最適化（PPO）、および直接選好最適化（DPO）など、言語モデリングで使用される主要なRLプロセスを容易にします。このリポジトリ全体で、さまざまなモジュールでTRLを使用します。

# 次のステップ

次のチュートリアルを試して、TRLを使用したSFTの実践的な経験を積んでください：

⏭ [チャットテンプレートのチュートリアル](./notebooks/chat_templates_example.ipynb)

⏭ [教師あり微調整のチュートリアル](./notebooks/supervised_fine_tuning_tutorial.ipynb)

A course on aligning smol models.


# 選好の整合

このモジュールでは、言語モデルを人間の選好に合わせるための技術について説明します。教師あり微調整（SFT）がモデルにタスクを学習させるのに役立つ一方で、選好の整合は出力が人間の期待や価値観に一致するようにします。

## 概要

選好の整合の典型的な方法には、複数のステージが含まれます：
1. 教師あり微調整（SFT）でモデルを特定のドメインに適応させる。
2. 選好の整合（RLHFやDPOなど）で応答の質を向上させる。

ORPOのような代替アプローチは、指示調整と選好の整合を単一のプロセスに統合します。ここでは、DPOとORPOのアルゴリズムに焦点を当てます。

さまざまな整合技術について詳しく知りたい場合は、[Argillaのブログ](https://argilla.io/blog/mantisnlp-rlhf-part-8)を参照してください。

### 1⃣ 直接選好最適化（DPO）

直接選好最適化（DPO）は、選好データを使用してモデルを直接最適化することで、選好の整合を簡素化します。このアプローチは、別個の報酬モデルや複雑な強化学習を必要とせず、従来のRLHFよりも安定して効率的です。詳細については、[直接選好最適化（DPO）のドキュメント](./dpo.md)を参照してください。

### 2⃣ 選好確率比最適化（ORPO）

ORPOは、指示調整と選好の整合を単一のプロセスに統合する新しいアプローチを導入します。これは、負の対数尤度損失とトークンレベルのオッズ比項を組み合わせて標準的な言語モデリングの目的を修正します。このアプローチは、単一のトレーニングステージ、参照モデル不要のアーキテクチャ、および計算効率の向上を提供します。ORPOは、さまざまなベンチマークで印象的な結果を示しており、従来の方法と比較してAlpacaEvalで優れたパフォーマンスを示しています。詳細については、[選好確率比最適化（ORPO）のドキュメント](./orpo.md)を参照してください。

## 実習ノートブック

| タイトル | 説明 | 実習内容 | リンク | Colab |
|-------|-------------|----------|------|-------|
| DPOトレーニング | 直接選好最適化を使用してモデルを��レーニングする方法を学ぶ | 🐢 AnthropicのHH-RLHFデータセットを使用してモデルをトレーニングする
🐕 独自の選好データセットを使用する
🦁 さまざまな選好データセットとモデルサイズで実験する | [ノートブック](./notebooks/dpo_finetuning_example.ipynb) |  |
| ORPOトレーニング | 選好確率比最適化を使用してモデルをトレーニングする方法を学ぶ | 🐢 指示と選好データを使用してモデルをトレーニングする
🐕 損失の重みを変えて実験する
🦁 ORPOとDPOの結果を比較する | [ノートブック](./notebooks/orpo_finetuning_example.ipynb) |  |

## リソース

- [TRLのドキュメント](https://huggingface.co/docs/trl/index) - DPOを含むさまざまな整合技術を実装するためのTransformers Reinforcement Learning（TRL）ライブラリのドキュメント。
- [DPO論文](https://arxiv.org/abs/2305.18290) - 人間のフィードバックを用いた強化学習の代替として、選好データを使用して言語モデルを直接最適化するシンプルなアプローチを紹介する論文。
- [ORPO論文](https://arxiv.org/abs/2403.07691) - 指示調整と選好の整合を単一のトレーニングステージに統合する新しいアプローチを紹介する論文。
- [ArgillaのRLHFガイド](https://argilla.io/blog/mantisnlp-rlhf-part-8/) - RLHF、DPOなどのさまざまな整合技術とその実践的な実装について説明するガイド。
- [DPOに関するブログ記事](https://huggingface.co/blog/dpo-trl) - TRLライブラリを使用してDPOを実装する方法についての実践ガイド。コード例とベストプラクティスが含まれています。
- [TRLのDPOスクリプト例](https://github.com/huggingface/trl/blob/main/examples/scripts/dpo.py) - TRLライブラリを使用してDPOトレーニングを実装する方法を示す完全なスクリプト例。
- [TRLのORPOスクリプト例](https://github.com/huggingface/trl/blob/main/examples/scripts/orpo.py) - TRLライブラリを使用してORPOトレーニングを実装するためのリファレンス実装。詳細な設定オプションが含まれています。
- [Hugging Faceの整合ハンドブック](https://github.com/huggingface/alignment-handbook) - SFT、DPO、RLHFなどのさまざまな技術を使用して言語モデルを整合させるためのガイドとコード。

A course on aligning smol models.


**直接選好最適化（DPO）**

直接選好最適化（DPO）は、言語モデルを人間の好みに合わせるための簡素化されたアプローチを提供します。従来のRLHF（人間のフィードバックを用いた強化学習）メソッドとは異なり、DPOは別個の報酬モデルや複雑な強化学習アルゴリズムを必要とせず、選好データを使用してモデルを直接最適化します。

## DPOの理解

DPOは、選好の整合を人間の選好データに基づく分類問題として再定義します。従来のRLHFアプローチでは、別個の報酬モデルをトレーニングし、PPO（近接ポリシー最適化）などの複雑なアルゴリズムを使用してモデルの出力を整合させる必要があります。DPOは、好ましい出力と好ましくない出力に基づいてモデルのポリシーを直接最適化する損失関数を定義することで、このプロセスを簡素化します。

このアプローチは実際に非常に効果的であり、Llamaなどのモデルのトレーニングに使用されています。別個の報酬モデルや強化学習のステージを必要としないため、DPOは選好の整合をよりアクセスしやすく、安定したものにします。

## DPOの仕組み

DPOのプロセスには、ターゲットドメインにモデルを適応させるための教師あり微調整（SFT）が必要です。これにより、標準的な指示追従データセットでトレーニングすることで、選好学習の基盤が形成されます。モデルは基本的なタスクを完了しながら、一般的な能力を維持することを学びます。

次に、選好学習が行われ、モデルは好ましい出力と好ましくない出力のペアでトレーニングされます。選好ペアは、モデルがどの応答が人間の価値観や期待に最も一致するかを理解するのに役立ちます。

DPOの中心的な革新は、その直接最適化アプローチにあります。別個の報酬モデルをトレーニングする代わりに、DPOはバイナリクロスエントロピー損失を使用して、選好データに基づいてモデルの重みを直接更新します。この簡素化されたプロセスにより、トレーニングがより安定し、効率的になり、従来のRLHFメソッドと同等またはそれ以上の結果が得られます。

## DPOのデータセット

DPOのデータセットは、通常、選好または非選好として注釈された応答ペアを含むように作成されます。これは手動で行うか、自動フィルタリング技術を使用して行うことができます。以下は、単一ターンのDPO選好データセットの構造の例です：

| プロンプト | 選好 | 非選好 |
|--------|---------|-----------|
| ...    | ...     | ...       |
| ...    | ...     | ...       |
| ...    | ...     | ...       |

`Prompt`列には、`選好`および`非選好`の応答を生成するために使用されたプロンプトが含まれています。`選好`および`非選好`列には、それぞれ好ましい応答と好ましくない応答が含まれています。この構造にはバリエーションがあり、例えば、`system_prompt`や`Input`列に参照資料を含めることができます。`選好`および`非選好`の値は、単一ターンの会話の場合は文字列として、または会話リストとして表現されることがあります。

Hugging FaceでDPOデータセットのコレクションを[こちら](https://huggingface.co/collections/argilla/preference-datasets-for-dpo-656f0ce6a00ad2dc33069478)で見つけることができます。

## TRLを使用した実装

Transformers Reinforcement Learning（TRL）ライブラリは、DPOの実装を容易にします。`DPOConfig`および`DPOTrainer`クラスは、`transformers`スタイルのAPIに従います。

以下は、DPOトレーニングを設定する基本的な例です：

```python
from trl import DPOConfig, DPOTrainer

# 引数を定義
training_args = DPOConfig(
    ...
)

# トレーナーを初期化
trainer = DPOTrainer(
    model,
    train_dataset=dataset,
    tokenizer=tokenizer,
    ...
)

# モデルをトレーニング
trainer.train()
```

DPOConfigおよびDPOTrainerクラスの使用方法の詳細については、[DPOチュートリアル](./notebooks/dpo_finetuning_example.ipynb)を参照してください。

## ベストプラクティス

データの品質は、DPOの成功した実装にとって重要です。選好データセットには、望ましい行動のさまざまな側面をカバーする多様な例が含まれている必要があります。明確な注釈ガイドラインは、選好および非選好の応答の一貫したラベル付けを保証します。選好データセットの品質を向上させることで、モデルのパフォーマンスを向上させることができます。例えば、より大きなデータセットをフィルタリングして、高品質の例やユースケースに関連する例のみを含めることができます。

トレーニング中は、損失の収束を慎重に監視し、保持データでパフォーマンスを検証します。選好学習とモデルの一般的な能力の維持をバランスさせるために、ベータパラメータを調整する必要がある場合があります。多様な例での定期的な評価は、モデルが望ましい選好を学習しながら過剰適合しないことを保証するのに役立ちます。

モデルの出力を基準モデルと比較して、選好の整合性の向上を確認します。さまざまなプロンプト、特にエッジケースを使用してモデルをテストすることで、さまざまなシナリオでの選好学習の堅牢性を保証します。

## 次のステップ

⏩ DPOの実践的な経験を得るために、[DPOチュートリアル](./notebooks/dpo_finetuning_example.ipynb)を試してみてください。この実践ガイドでは、データの準備からトレーニングおよび評価まで、選好整合の実装方法を説明します。

⏭ チュートリアルを完了した後、別の選好整合技術について学ぶために[ORPOページ](./orpo.md)を探索してください。

A course on aligning smol models.


**選好確率比最適化（ORPO）**

選好確率比最適化（ORPO）は、微調整と選好整合を単一の統合プロセスで組み合わせる新しいアプローチです。この統合アプローチは、従来のRLHFやDPOなどの方法と比較して、効率とパフォーマンスの面で利点を提供します。

## ORPOの理解

DPOのような選好整合方法は、通常、微調整と選好整合の2つの別々のステップを含みます。微調整はモデルを特定のドメインや形式に適応させ、選好整合は人間の選好に合わせて出力を調整します。SFT（教師あり微調整）は、モデルをターゲットドメインに適応させるのに効果的ですが、望ましい応答と望ましくない応答の両方の確率を増加させる可能性があります。ORPOは、以下の比較図に示すように、これらのステップを単一のプロセスに統合することで、この制限に対処します。

![モデル整合技術の比較](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-alignments.png)
*モデル整合技術の比較*

## ORPOの仕組み

ORPOのトレーニングプロセスは、DPOと同様に、入力プロンプトと2つの応答（1つは選好、もう1つは非選好）を含む選好データセットを使用します。他の整合方法とは異なり、ORPOは選好整合を教師あり微調整プロセスに直接統合します。この統合アプローチにより、参照モデルが不要になり、計算効率とメモリ効率が向上し、FLOP数が減少します。

ORPOは、次の2つの主要なコンポーネントを組み合わせて新しい目的を作成します：

1. **SFT損失**：負の対数尤度損失を使用して、参照トークンの生成確率を最大化します。これにより、モデルの一般的な言語能力が維持されます。
2. **オッズ比損失**：望ましくない応答をペナルティし、選好される応答を報酬する新しいコンポーネントです。この損失関数は、トークンレベルで選好される応答と非選好の応答を効果的に対比するためにオッズ比を使用します。

これらのコンポーネントを組み合わせることで、モデルは特定のドメインに対して望ましい生成を適応させながら、非選好の応答を積極的に抑制します。オッズ比メカニズムは、選好された応答と拒否された応答の間のモデルの選好を測定および最適化する自然な方法を提供します。数学的な詳細については、[ORPO論文](https://arxiv.org/abs/2403.07691)を参照してください。実装の観点からORPOについて学びたい場合は、[TRLライブラリ](https://github.com/huggingface/trl/blob/b02189aaa538f3a95f6abb0ab46c0a971bfde57e/trl/trainer/orpo_trainer.py#L660)でORPO損失がどのように計算されるかを確認してください。

## パフォーマンスと結果

ORPOは、さまざまなベンチマークで印象的な結果を示しています。MT-Benchでは、さまざまなカテゴリで競争力のあるスコアを達成しています：

![MT-Benchの結果](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-mtbench.png)
*MT-Benchのカテゴリ別結果（Mistral-ORPOモデル）*

他の整合方法と比較すると、ORPOはAlpacaEval 2.0で優れたパフォーマンスを示しています：

![AlpacaEvalの結果](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-winrate.png)
*さまざまな整合方法におけるAlpacaEval 2.0スコア*

SFT+DPOと比較して、ORPOは参照モデルが不要であり、バッチごとのフォワードパスの数を半減させることで計算要件を削減します。さらに、トレーニングプロセスは、さまざまなモデルサイズとデータセットでより安定しており、調整するハイパーパラメータが少なくて済みます。パフォーマンスに関しては、ORPOはより大きなモデルと同等のパフォーマンスを示しながら、人間の選好に対する整合性が向上しています。

## 実装

ORPOの成功した実装は、高品質の選好データに大きく依存します。トレーニングデータは明確な注釈ガイドラインに従い、さまざまなシナリオで好ましい応答と拒否された応答のバランスの取れた表現を提供する必要があります。

### TRLを使用した実装

ORPOは、Transformers Reinforcement Learning（TRL）ライブラリを使用して実装できます。以下は基本的な例です：

```python
from trl import ORPOConfig, ORPOTrainer

# ORPOトレーニングの設定
orpo_config = ORPOConfig(
    learning_rate=1e-5,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    max_steps=1000,
    orpo_alpha=1.0,  # 選好最適化の強度を制御
    orpo_beta=0.1,   # オッズ比計算の温度パラメータ
)

# トレーナーを初期化
trainer = ORPOTrainer(
    model=model,
    args=orpo_config,
    train_dataset=dataset,
    tokenizer=tokenizer,
)

# トレーニングを開始
trainer.train()
```

考慮すべき主要なパラメータ：
- `orpo_alpha`：選好最適化の強度を制御
- `orpo_beta`：オッズ比計算の温度パラメータ
- `learning_rate`：忘却のカタストロフィーを避けるために比較的小さく設定
- `gradient_accumulation_steps`：トレーニングの安定性を向上

## 次のステップ

⏩ この統合された選好整合アプローチを実装するための[ORPOチュートリアル](./notebooks/orpo_tutorial.ipynb)を試してみてください。

## リソース
- [ORPO論文](https://arxiv.org/abs/2403.07691)
- [TRLドキュメント](https://huggingface.co/docs/trl/index)
- [ArgillaのRLHFガイド](https://argilla.io/blog/mantisnlp-rlhf-part-8/)

A course on aligning smol models.


# パラメータ効率の良い微調整 (PEFT)

言語モデルが大きくなるにつれて、従来の微調整はますます困難になります。1.7Bパラメータのモデルの完全な微調整には、かなりのGPUメモリが必要であり、別々のモデルコピーを保存することが高価であり、モデルの元の能力を破壊的に忘れるリスクがあります。パラメータ効率の良い微調整（PEFT）メソッドは、モデルパラメータの小さなサブセットのみを変更し、ほとんどのモデルを固定したままにすることで、これらの課題に対処します。

従来の微調整は、トレーニング中にすべてのモデルパラメータを更新しますが、これは大規模なモデルには実用的ではありません。PEFTメソッドは、元のモデルサイズの1％未満のパラメータを使用してモデルを適応させるアプローチを導入します。この劇的な学習可能なパラメータの削減により、次のことが可能になります：

- 限られたGPUメモリを持つ消費者向けハードウェアでの微調整
- 複数のタスク固有の適応を効率的に保存
- 低データシナリオでのより良い一般化
- より速いトレーニングと反復サイクル

## 利用可能なメソッド

このモジュールでは、2つの人気のあるPEFTメソッドを紹介します：

### 1⃣ LoRA (低ランク適応)

LoRAは、効率的なモデル適応のためのエレガントなソリューションを提供する最も広く採用されているPEFTメソッドとして浮上しました。モデル全体を変更する代わりに、**LoRAはモデルの注意層に学習可能な行列を注入します。**このアプローチは、通常、完全な微調整と比較して約90％の学習可能なパラメータを削減しながら、同等の性能を維持します。[LoRA (低ランク適応)](./lora_adapters.md)セクションでLoRAを詳しく見ていきます。

### 2⃣ プロンプトチューニング

プロンプトチューニングは、モデルの重みを変更するのではなく、**入力に学習可能なトークンを追加する**さらに軽量なアプローチを提供します。プロンプトチューニングはLoRAほど人気はありませんが、モデルを新しいタスクやドメインに迅速に適応させるための便利な技術です。[プロンプトチューニング](./prompt_tuning.md)セクションでプロンプトチューニングを詳しく見ていきます。

## 演習ノートブック

| タイトル | 説明 | 演習 | リンク | Colab |
|-------|-------------|----------|------|-------|
| LoRA微調整 | LoRAアダプタを使用してモデルを微調整する方法を学ぶ | 🐢 LoRAを使用してモデルをトレーニング
🐕 異なるランク値で実験
🦁 完全な微調整と性能を比較 | [ノートブック](./notebooks/finetune_sft_peft.ipynb) |  |
| LoRAアダプタの読み込み | トレーニングされたLoRAアダプタを読み込んで使用する方法を学ぶ | 🐢 事前学習されたアダプタを読み込む
🐕 アダプタをベースモデルと統合
🦁 複数のアダプタ間を切り替える | [ノートブック](./notebooks/load_lora_adapter.ipynb) |  |

## リソース
- [PEFTドキュメント](https://huggingface.co/docs/peft)
- [LoRA論文](https://arxiv.org/abs/2106.09685)
- [QLoRA論文](https://arxiv.org/abs/2305.14314)
- [プロンプトチューニング論文](https://arxiv.org/abs/2104.08691)
- [Hugging Face PEFTガイド](https://huggingface.co/blog/peft)
- [2024年にHugging FaceでLLMを微調整する方法](https://www.philschmid.de/fine-tune-llms-in-2024-with-trl)
- [TRL](https://huggingface.co/docs/trl/index)

A course on aligning smol models.


# LoRA (低ランク適応)

LoRAは最も広く採用されているPEFTメソッドとなっています。これは、注意重み行列に小さなランク分解行列を追加することで機能し、通常、学習可能なパラメータを約90％削減します。

## LoRAの理解

LoRA（低ランク適応）は、事前学習されたモデルの重みを固定し、学習可能なランク分解行列をモデルの層に注入するパラメータ効率の良い微調整技術です。微調整中にすべてのモデルパラメータを学習する代わりに、LoRAは低ランク分解を通じて重みの更新を小さな行列に分解し、学習可能なパラメータの数を大幅に削減しながらモデルの性能を維持します。例えば、GPT-3 175Bに適用した場合、LoRAは学習可能なパラメータを10,000倍、GPUメモリ要件を3倍削減しました。LoRAについての詳細は[LoRA論文](https://arxiv.org/pdf/2106.09685)を参照してください。

LoRAは、通常、注意重みに焦点を当てて、トランスフォーマーレイヤーにランク分解行列のペアを追加することで機能します。推論中に、これらのアダプタ重みはベースモデルと統合され、追加の遅延オーバーヘッドが発生しません。LoRAは、大規模な言語モデルを特定のタスクやドメインに適応させるのに特に役立ち、リソース要件を管理可能に保ちます。

## LoRAアダプタの読み込み

アダプタは、load_adapter()を使用して事前学習されたモデルに読み込むことができ、これは重みが統合されていない異なるアダプタを試すのに便利です。set_adapter()関数を使用してアクティブなアダプタ重みを設定します。ベースモデルに戻るには、unload()を使用してすべてのLoRAモジュールをアンロードできます。これにより、異なるタスク固有の重み間の切り替えが容易になります。

```python
from transformers import AutoModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("<base_model_name>")
peft_model_id = "<peft_adapter_id>"
model = PeftModel.from_pretrained(base_model, peft_model_id)
```

![lora_load_adapter](./images/lora_adapter.png)

## LoRAアダプタの統合

LoRAでトレーニングした後、アダプタ重みをベースモデルに統合して、デプロイを容易にすることができます。これにより、統合された重みを持つ単一のモデルが作成され、推論中にアダプタを別々に読み込む必要がなくなります。

統合プロセスには、メモリ管理と精度に注意が必要です。ベースモデルとアダプタ重みの両方を同時に読み込む必要があるため、十分なGPU/CPUメモリが利用可能であることを確認してください。`transformers`の`device_map="auto"`を使用すると、自動メモリ管理が容易になります。トレーニング中に使用した精度（例：float16）を一貫して維持し、統合されたモデルを同じ形式で保存してデプロイします。デプロイ前に、アダプタベースのバージョンと出力および性能メトリックを比較して、統合されたモデルを検証してください。

アダプタは、異なるタスクやドメイン間の切り替えにも便利です。ベースモデルとアダプタ重みを別々に読み込むことができます。これにより、異なるタスク固有の重み間の迅速な切り替えが可能になります。

## 実装ガイド

`notebooks/`ディレクトリには、さまざまなPEFTメソッドを実装するための実践的なチュートリアルと演習が含まれています。基本的な紹介には`load_lora_adapter_example.ipynb`を、LoRAとSFTを使用したモデルの微調整について詳しく知りたい場合は`lora_finetuning.ipynb`を参照してください。

PEFTメソッドを実装する際は、LoRAのランク値（4-8）を小さく設定し、トレーニング損失を監視します。検証セットを使用して過学習を防ぎ、可能であればフルファインチューニングのベースラインと結果を比較します。異なるメソッドの有効性はタスクによって異なるため、実験が重要です。

## OLoRA

[OLoRA](https://arxiv.org/abs/2406.01775)は、QR分解を使用してLoRAアダプタを初期化します。OLoRAは、QR分解の係数によってモデルのベース重みを変換します。つまり、トレーニングを行う前に重みを変換します。このアプローチは、安定性を大幅に向上させ、収束速度を加速し、最終的に優れた性能を達成します。

## TRLとPEFTの使用

PEFTメソッドは、TRL（Transformers Reinforcement Learning）と組み合わせて効率的な微調整を行うことができます。この統合は、RLHF（Reinforcement Learning from Human Feedback）に特に有用であり、メモリ要件を削減します。

```python
from peft import LoraConfig
from transformers import AutoModelForCausalLM

# PEFT設定でモデルを読み込む
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

# 特定のデバイスにモデルを読み込む
model = AutoModelForCausalLM.from_pretrained(
    "your-model-name",
    load_in_8bit=True,  # オプション: 8ビット精度を使用
    device_map="auto",
    peft_config=lora_config
)
```

上記では、`device_map="auto"`を使用してモデルを自動的に適切なデバイスに割り当てました。また、`device_map={"": device_index}`を使用してモデルを特定のデバイスに手動で割り当てることもできます。メモリ使用量を効率的に保ちながら、複数のGPUにトレーニングをスケールすることもできます。

## 基本的な統合実装

LoRAアダプタをトレーニングした後、アダプタ重みをベースモデルに統合することができます。以下はその方法です：

```python
import torch
from transformers import AutoModelForCausalLM
from peft import PeftModel

# 1. ベースモデルを読み込む
base_model = AutoModelForCausalLM.from_pretrained(
    "base_model_name",
    torch_dtype=torch.float16,
    device_map="auto"
)

# 2. アダプタを持つPEFTモデルを読み込む
peft_model = PeftModel.from_pretrained(
    base_model,
    "path/to/adapter",
    torch_dtype=torch.float16
)

# 3. アダプタ重みをベースモデルと統合
try:
    merged_model = peft_model.merge_and_unload()
except RuntimeError as e:
    print(f"統合に失敗しました: {e}")
    # フォールバック戦略またはメモリ最適化を実装

# 4. 統合されたモデルを保存
merged_model.save_pretrained("path/to/save/merged_model")
```

保存されたモデルのサイズに不一致がある場合は、トークナイザーも保存していることを確認してください：

```python
# モデルとトークナイザーの両方を保存
tokenizer = AutoTokenizer.from_pretrained("base_model_name")
merged_model.save_pretrained("path/to/save/merged_model")
tokenizer.save_pretrained("path/to/save/merged_model")
```

## 次のステップ

⏩ [プロンプトチューニング](prompt_tuning.md)ガイドに進み、プロンプトチューニングでモデルを微調整する方法を学びましょう。
⏩ [LoRAアダプタの読み込みチュートリアル](./notebooks/load_lora_adapter.ipynb)に進み、LoRAアダプタを読み込む方法を学びましょう。

# リソース

- [LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS](https://arxiv.org/pdf/2106.09685)
- [PEFTドキュメント](https://huggingface.co/docs/peft)
- [Hugging FaceのPEFTに関するブログ記事](https://huggingface.co/blog/peft)

A course on aligning smol models.


# プロンプトチューニング

プロンプトチューニングは、モデルの重みではなく入力表現を変更するパラメータ効率の良いアプローチです。従来の微調整がすべてのモデルパラメータを更新するのに対し、プロンプトチューニングはベースモデルを固定したまま、少数の学習可能なトークンを追加して最適化します。

## プロンプトチューニングの理解

プロンプトチューニングは、学習可能な連続ベクトル（ソフトプロンプト）を入力テキストの前に追加するパラメータ効率の良い微調整方法です。従来の離散テキストプロンプトとは異なり、これらのソフトプロンプトはベースモデルを固定したまま、逆伝播を通じて学習されます。この方法は、["The Power of Scale for Parameter-Efficient Prompt Tuning"](https://arxiv.org/abs/2104.08691)（Lester et al., 2021）で紹介され、モデルサイズが大きくなるにつれてプロンプトチューニングがモデル微調整と競争力を持つようになることが示されました。論文内では、約100億パラメータのモデルで、プロンプトチューニングがモデル微調整の性能に匹敵し、タスクごとに数百のパラメータしか変更しないことが示されています。

これらのソフトプロンプトは、トレーニング中に最適化されるモデルの埋め込み空間内の連続ベクトルです。従来の自然言語トークンを使用する離散プロンプトとは異なり、ソフトプロンプトは固有の意味を持たず、勾配降下を通じて固定モデルから望ましい動作を引き出すことを学習します。この技術は、各タスクに対して小さなプロンプトベクトル（通常は数百パラメータ）を保存するだけで済むため、マルチタスクシナリオに特に効果的です。このアプローチは、最小限のメモリフットプリントを維持するだけでなく、モデルの再読み込みなしにプロンプトベクトルを交換するだけで迅速なタスク切り替えを可能にします。

## トレーニングプロセス

ソフトプロンプトは通常、8〜32トークンで構成され、ランダムに初期化するか、既存のテキストから初期化されます。初期化方法はトレーニングプロセスにおいて重要な役割を果たし、テキストベースの初期化はランダム初期化よりも優れた性能を発揮することがよくあります。

トレーニング中は、プロンプトパラメータのみが更新され、ベースモデルは固定されたままです。この集中アプローチは標準的なトレーニング目標を使用しますが、プロンプトトークンの学習率と勾配の挙動に注意を払う必要があります。

## PEFTを使用した実装

PEFTライブラリを使用すると、プロンプトチューニングの実装が簡単になります。以下は基本的な例です：

```python
from peft import PromptTuningConfig, TaskType, get_peft_model
from transformers import AutoModelForCausalLM, AutoTokenizer

# ベースモデルを読み込む
model = AutoModelForCausalLM.from_pretrained("your-base-model")
tokenizer = AutoTokenizer.from_pretrained("your-base-model")

# プロンプトチューニングを設定
peft_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM,
    num_virtual_tokens=8,  # 学習可能なトークンの数
    prompt_tuning_init="TEXT",  # テキストから初期化
    prompt_tuning_init_text="このテキストがポジティブかネガティブかを分類してください：",
    tokenizer_name_or_path="your-base-model",
)

# プロンプトチューニング可能なモデルを作成
model = get_peft_model(model, peft_config)
```

## 他の方法との比較

他のPEFTアプローチと比較すると、プロンプトチューニングはその効率性で際立っています。LoRAは低パラメータ数とメモリ使用量を提供しますが、タスク切り替えにはアダプタの読み込みが必要です。プロンプトチューニングはさらに低いリソース使用量を達成し、即時のタスク切り替えを可能にします。対照的に、フルファインチューニングは多くのリソースを必要とし、異なるタスクごとに別々のモデルコピーが必要です。

| 方法 | パラメータ | メモリ | タスク切り替え |
|--------|------------|---------|----------------|
| プロンプトチューニング | 非常に低い | 最小限 | 簡単 |
| LoRA | 低い | 低い | 読み込みが必要 |
| フルファインチューニング | 高い | 高い | 新しいモデルコピー |

プロンプトチューニングを実装する際は、最初に少数の仮想トークン（8〜16）を使用し、タスクの複雑さが要求する場合にのみ増やします。タスクに関連するテキストを使用したテキスト初期化は、ランダム初期化よりも優れた結果をもたらすことがよくあります。初期化戦略は、ターゲットタスクの複雑さを反映する必要があります。

トレーニングには、フルファインチューニングとは異なる考慮事項が必要です。高い学習率が効果的なことが多いですが、プロンプトトークンの勾配を注意深く監視することが重要です。多様な例で定期的に検証することで、さまざまなシナリオでの堅牢な性能を確保します。

## 応用

プロンプトチューニングは、次のようなシナリオで優れた効果を発揮します：

1. マルチタスク展開
2. リソース制約のある環境
3. 迅速なタスク適応
4. プライバシーに敏感なアプリケーション

モデルが小さくなるにつれて、プロンプトチューニングはフルファインチューニングと比較して競争力が低下します。例えば、SmolLM2のようなモデルでは、プロンプトチューニングはフルファインチューニングよりも関連性が低くなります。

## 次のステップ

⏭ [LoRAアダプタのチュートリアル](./notebooks/finetune_sft_peft.ipynb)に進み、LoRAアダプタでモデルを微調整する方法を学びましょう。

## リソース
- [PEFTドキュメント](https://huggingface.co/docs/peft)
- [プロンプトチューニング論文](https://arxiv.org/abs/2104.08691)
- [Hugging Face Cookbook](https://huggingface.co/learn/cookbook/prompt_tuning_peft)

A course on aligning smol models.


# 評価

評価は、言語モデルの開発と展開において重要なステップです。評価は、モデルがさまざまな能力にわたってどれだけうまく機能するかを理解し、改善の余地を特定するのに役立ちます。このモジュールでは、標準ベンチマークとドメイン固有の評価アプローチの両方をカバーし、smolモデルを包括的に評価します。

Hugging Faceが開発した強力な評価ライブラリである[`lighteval`](https://github.com/huggingface/lighteval)を使用します。評価の概念とベストプラクティスについて詳しく知りたい場合は、評価[ガイドブック](https://github.com/huggingface/evaluation-guidebook)を参照してください。

## モジュール概要

徹底した評価戦略は、モデル性能の複数の側面を検討します。質問応答や要約などのタスク固有の能力を評価し、モデルがさまざまなタイプの問題にどれだけうまく対処できるかを理解します。出力の品質を一貫性や事実の正確性などの要素で測定します。安全性評価は、潜在的な有害な出力やバイアスを特定するのに役立ちます。最後に、ドメインの専門知識テストは、ターゲット分野でのモデルの専門知識を検証します。

## コンテンツ

### 1⃣ [自動ベンチマーク](./automatic_benchmarks.md)

標準化されたベンチマークとメトリクスを使用してモデルを評価する方法を学びます。MMLUやTruthfulQAなどの一般的なベンチマークを探求し、主要な評価メトリクスと設定を理解し、再現可能な評価のベストプラクティスをカバーします。

### 2⃣ [カスタムドメイン評価](./custom_evaluation.md)

特定のユースケースに合わせた評価パイプラインを作成する方法を学びます。カスタム評価タスクの設計、専門的なメトリクスの実装、要件に合った評価データセットの構築について説明します。

### 3⃣ [ドメイン評価プロジェクト](./project/README.md)

ドメイン固有の評価パイプラインを構築する完全な例を紹介します。評価データセットの生成、データ注釈のためのArgillaの使用、標準化されたデータセットの作成、LightEvalを使用したモデルの評価方法を学びます。

### 演習ノートブック

| タイトル | 説明 | 演習 | リンク | Colab |
|-------|-------------|----------|------|-------|
| LLMの評価と分析 | LightEvalを使用して特定のドメインでモデルを評価および比較する方法を学びます | 🐢 医療ドメインタスクを使用してモデルを評価する
 🐕 異なるMMLUタスクで新しいドメイン評価を作成する
 🦁 ドメイン固有のカスタム評価タスクを作成する | [ノートブック](./notebooks/lighteval_evaluate_and_analyse_your_LLM.ipynb) |  |

## リソース

- [評価ガイドブック](https://github.com/huggingface/evaluation-guidebook) - LLM評価の包括的なガイド
- [LightEvalドキュメント](https://github.com/huggingface/lighteval) - LightEvalライブラリの公式ドキュメント
- [Argillaドキュメント](https://docs.argilla.io) - Argillaアノテーションプラットフォームについて学ぶ
- [MMLU論文](https://arxiv.org/abs/2009.03300) - MMLUベンチマークを説明する論文
- [カスタムタスクの作成](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [カスタムメトリクスの作成](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- [既存のメトリクスの使用](https://github.com/huggingface/lighteval/wiki/Metric-List)

A course on aligning smol models.


# 自動ベンチマーク

自動ベンチマークは、さまざまなタスクや能力にわたって言語モデルを評価するための標準化されたツールとして機能します。これらはモデルの性能を理解するための有用な出発点を提供しますが、包括的な評価戦略の一部に過ぎないことを認識することが重要です。

## 自動ベンチマークの理解

自動ベンチマークは通常、事前に定義されたタスクと評価指標を持つキュレーションされたデータセットで構成されます。これらのベンチマークは、基本的な言語理解から複雑な推論まで、モデルのさまざまな側面を評価することを目的としています。自動ベンチマークの主な利点はその標準化にあります。これにより、異なるモデル間で一貫した比較が可能となり、再現性のある結果が得られます。

ただし、ベンチマークの性能が必ずしも実世界での有効性に直結するわけではないことを理解することが重要です。学術的なベンチマークで優れた成績を収めたモデルでも、特定のドメインアプリケーションや実際のユースケースでは苦労することがあります。

## ベンチマークとその限界

### 一般知識ベンチマーク

MMLU（Massive Multitask Language Understanding）は、科学から人文科学まで57の科目にわたる知識をテストします。包括的ではありますが、特定のドメインに必要な専門知識の深さを反映しているわけではありません。TruthfulQAは、モデルが一般的な誤解を再現する傾向を評価しますが、すべての形態の誤情報を捉えることはできません。

### 推論ベンチマーク
BBH（Big Bench Hard）とGSM8Kは、複雑な推論タスクに焦点を当てています。BBHは論理的思考と計画をテストし、GSM8Kは特に数学的な問題解決を対象としています。これらのベンチマークは分析能力を評価するのに役立ちますが、実世界のシナリオで必要とされる微妙な推論を完全に捉えることはできません。

### 言語理解
HELMは包括的な評価フレームワークを提供し、WinoGrandeは代名詞の曖昧性解消を通じて常識をテストします。これらのベンチマークは言語処理能力に関する洞察を提供しますが、自然な会話やドメイン固有の用語の複雑さを完全に表現することはできません。

## 代替評価アプローチ

多くの組織は、標準ベンチマークの限界に対処するために代替評価方法を開発しています：

### LLM-as-Judge
ある言語モデルを使用して別のモデルの出力を評価する方法がますます人気を集めています。このアプローチは、従来の指標よりも微妙なフィードバックを提供することができますが、それ自体のバイアスと限界も伴います。

### 評価アリーナ
AnthropicのConstitutional AI Arenaのようなプラットフォームでは、モデルが相互に対話し、制御された環境で互いを評価することができます。これにより、従来のベンチマークでは明らかにならない強みと弱みが明らかになります。

### カスタムベンチマークスイート
組織は、特定のニーズやユースケースに合わせた内部ベンチマークスイートを開発することがよくあります。これには、ドメイン固有の知識テストや実際の展開条件を反映した評価シナリオが含まれることがあります。

## 独自の評価戦略の作成

LightEvalを使用して標準ベンチマークを実行するのは簡単ですが、ユースケースに特化した評価方法の開発にも時間を投資する必要があります。

標準ベンチマークは有用なベースラインを提供しますが、それだけが評価方法であってはなりません。より包括的なアプローチを開発する方法は次のとおりです：

1. 関連する標準ベンチマークから始めて、ベースラインを確立し、他のモデルとの比較を可能にします。

2. ユースケースの特定の要件と課題を特定します。モデルが実際に実行するタスクは何ですか？どのようなエラーが最も問題になりますか？

3. 実際のユースケースを反映したカスタム評価データセットを開発します。これには次のようなものが含まれるかもしれません：
   - ドメインからの実際のユーザークエリ
   - 遭遇した一般的なエッジケース
   - 特に挑戦的なシナリオの例

4. 多層評価戦略の実装を検討します：
   - クイックフィードバックのための自動指標
   - 微妙な理解のための人間の評価
   - 専門家によるレビュー
   - 制御された環境でのA/Bテスト

## LightEvalを使用したベンチマーク

LightEvalタスクは特定の形式を使用して定義されます：
```
{suite}|{task}|{num_few_shot}|{auto_reduce}
```

- **suite**: ベンチマークスイート（例：'mmlu', 'truthfulqa'）
- **task**: スイート内の特定のタスク（例：'abstract_algebra'）
- **num_few_shot**: プロンプトに含める例の数（ゼロショットの場合は0）
- **auto_reduce**: プロンプトが長すぎる場合に少数ショットの例を自動的に削減するかどうか（0または1）

例：`"mmlu|abstract_algebra|0|0"`は、ゼロショット推論でMMLUの抽象代数学タスクを評価します。

### 評価パイプラインの例

特定のドメインに関連する自動ベンチマークの評価を設定して実行する完全な例を次に示します：

```python
from lighteval.tasks import Task, Pipeline
from transformers import AutoModelForCausalLM

# 評価するタスクを定義
domain_tasks = [
    "mmlu|anatomy|0|0",
    "mmlu|high_school_biology|0|0",
    "mmlu|high_school_chemistry|0|0",
    "mmlu|professional_medicine|0|0"
]

# パイプラインパラメータを設定
pipeline_params = {
    "max_samples": 40,  # 評価するサンプル数
    "batch_size": 1,    # 推論のバッチサイズ
    "num_workers": 4    # ワーカープロセスの数
}

# 評価トラッカーを作成
evaluation_tracker = EvaluationTracker(
    output_path="./results",
    save_generations=True
)

# モデルを読み込み、パイプラインを作成
model = AutoModelForCausalLM.from_pretrained("your-model-name")
pipeline = Pipeline(
    tasks=domain_tasks,
    pipeline_parameters=pipeline_params,
    evaluation_tracker=evaluation_tracker,
    model=model
)

# 評価を実行
pipeline.evaluate()

# 結果を取得して表示
results = pipeline.get_results()
pipeline.show_results()
```

結果は次のような表形式で表示されます：
```
|                  Task                  |Version|Metric|Value |   |Stderr|
|----------------------------------------|------:|------|-----:|---|-----:|
|all                                     |       |acc   |0.3333|±  |0.1169|
|leaderboard:mmlu:_average:5             |       |acc   |0.3400|±  |0.1121|
|leaderboard:mmlu:anatomy:5              |      0|acc   |0.4500|±  |0.1141|
|leaderboard:mmlu:high_school_biology:5  |      0|acc   |0.1500|±  |0.0819|
```

結果をpandas DataFrameで処理し、視覚化や表現を自由に行うこともできます。

# 次のステップ

⏩ [カスタムドメイン評価](./custom_evaluation.md)を探索し、特定のニーズに合わせた評価パイプラインの作成方法を学びましょう

A course on aligning smol models.


# カスタムドメイン評価

標準ベンチマークは貴重な洞察を提供しますが、多くのアプリケーションでは特定のドメインやユースケースに合わせた評価アプローチが必要です。このガイドでは、ターゲットドメインでモデルの性能を正確に評価するためのカスタム評価パイプラインを作成する方法を説明します。

## 評価戦略の設計

成功するカスタム評価戦略は、明確な目標から始まります。ドメインでモデルが示すべき具体的な能力を考慮してください。これには、技術的な知識、推論パターン、ドメイン固有の形式が含まれるかもしれません。これらの要件を慎重に文書化してください。これがタスク設計とメトリック選択の両方を導きます。

評価は、標準的なユースケースとエッジケースの両方をテストする必要があります。例えば、医療ドメインでは、一般的な診断シナリオと稀な状態の両方を評価するかもしれません。金融アプリケーションでは、通常の取引と複数の通貨や特別な条件を含む複雑なエッジケースの両方をテストするかもしれません。

## LightEvalを使用した実装

LightEvalは、カスタム評価を実装するための柔軟なフレームワークを提供します。カスタムタスクを作成する方法は次のとおりです：

```python
from lighteval.tasks import Task, Doc
from lighteval.metrics import SampleLevelMetric, MetricCategory, MetricUseCase

class CustomEvalTask(Task):
    def __init__(self):
        super().__init__(
            name="custom_task",
            version="0.0.1",
            metrics=["accuracy", "f1"],  # 選択したメトリック
            description="カスタム評価タスクの説明"
        )

    def get_prompt(self, sample):
        # 入力をプロンプトにフォーマット
        return f"質問: {sample['question']}\n回答:"

    def process_response(self, response, ref):
        # モデルの出力を処理し、参照と比較
        return response.strip() == ref.strip()
```

## カスタムメトリック

ドメイン固有のタスクには、専門的なメトリックが必要なことがよくあります。LightEvalは、ドメインに関連する性能の側面を捉えるカスタムメトリックを作成するための柔軟なフレームワークを提供します：

```python
from aenum import extend_enum
from lighteval.metrics import Metrics, SampleLevelMetric, SampleLevelMetricGrouping
import numpy as np

# サンプルレベルのメトリック関数を定義
def custom_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> dict:
    """サンプルごとに複数のスコアを返す例のメトリック"""
    response = predictions[0]
    return {
        "accuracy": response == formatted_doc.choices[formatted_doc.gold_index],
        "length_match": len(response) == len(formatted_doc.reference)
    }

# サンプルごとに複数の値を返すメトリックを作成
custom_metric_group = SampleLevelMetricGrouping(
    metric_name=["accuracy", "length_match"],  # サブメトリックの名前
    higher_is_better={  # 各メトリックで高い値が良いかどうか
        "accuracy": True,
        "length_match": True
    },
    category=MetricCategory.CUSTOM,
    use_case=MetricUseCase.SCORING,
    sample_level_fn=custom_metric,
    corpus_level_fn={  # 各メトリックを集計する方法
        "accuracy": np.mean,
        "length_match": np.mean
    }
)

# LightEvalにメトリックを登録
extend_enum(Metrics, "custom_metric_name", custom_metric_group)
```

サンプルごとに1つのメトリック値のみが必要な場合の簡単なケース：

```python
def simple_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> bool:
    """サンプルごとに単一のスコアを返す例のメトリック"""
    response = predictions[0]
    return response == formatted_doc.choices[formatted_doc.gold_index]

simple_metric_obj = SampleLevelMetric(
    metric_name="simple_accuracy",
    higher_is_better=True,
    category=MetricCategory.CUSTOM,
    use_case=MetricUseCase.SCORING,
    sample_level_fn=simple_metric,
    corpus_level_fn=np.mean  # サンプル全体で集計する方法
)

extend_enum(Metrics, "simple_metric", simple_metric_obj)
```

カスタムメトリックを評価タスクで参照することで、評価タスクで自動的に計算され、指定された関数に従って集計されます。

より複雑なメトリックの場合、次のことを検討してください：
- フォーマットされたドキュメントのメタデータを使用してスコアを重み付けまたは調整
- コーパスレベルの統計のためのカスタム集計関数の実装
- メトリック入力の検証チェックの追加
- エッジケースと期待される動作の文書化

これらの概念を実装する完全な例については、[ドメイン評価プロジェクト](./project/README.md)を参照してください。

## データセットの作成

高品質の評価には、慎重にキュレーションされたデータセットが必要です。データセット作成のアプローチを次に示します：

1. 専門家のアノテーション：ドメインの専門家と協力して評価例を作成および検証します。[Argilla](https://github.com/argilla-io/argilla)のようなツールを使用すると、このプロセスがより効率的になります。

2. 実世界のデータ：実際の使用データを収集し、匿名化して、実際の展開シナリオを反映します。

3. 合成生成：LLMを使用して初期例を生成し、専門家がそれを検証および洗練します。

## ベストプラクティス

- 評価方法論を徹底的に文書化し、仮定や制限を含める
- ドメインのさまざまな側面をカバーする多様なテストケースを含める
- 自動メトリックと人間の評価の両方を適用する
- 評価データセットとコードをバージョン管理する
- 新しいエッジケースや要件を発見するたびに評価スイートを定期的に更新する

## 参考文献

- [LightEvalカスタムタスクガイド](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [LightEvalカスタムメトリック](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- データセットアノテーションのための[Argillaドキュメント](https://docs.argilla.io)
- 一般的な評価原則のための[評価ガイドブック](https://github.com/huggingface/evaluation-guidebook)

# 次のステップ

⏩ これらの概念を実装する完全な例については、[ドメイン評価プロジェクト](./project/README.md)を参照してください。

A course on aligning smol models.


# ビジョン言語モデル

## 1. VLMの使用

ビジョン言語モデル（VLM）は、画像キャプション生成、視覚質問応答、マルチモーダル推論などのタスクを可能にするために、テキストと並行して画像入力を処理します。

典型的なVLMアーキテクチャは、視覚的特徴を抽出する画像エンコーダ、視覚的およびテキスト表現を整列させるプロジェクション層、およびテキストを処理または生成する言語モデルで構成されます。これにより、モデルは視覚要素と言語概念の間の接続を確立できます。

VLMは、使用ケースに応じてさまざまな構成で使用できます。ベースモデルは一般的なビジョン言語タスクを処理し、チャット最適化されたバリアントは会話型インタラクションをサポートします。一部のモデルには、視覚的証拠に基づいて予測を行うための追加コンポーネントや、物体検出などの特定のタスクに特化したコンポーネントが含まれています。

VLMの技術的な詳細と使用方法については、[VLMの使用](./vlm_usage.md)ページを参照してください。

## 2. VLMのファインチューニング

VLMのファインチューニングは、特定のタスクを実行するため、または特定のデータセットで効果的に動作するように、事前トレーニングされたモデルを適応させるプロセスです。このプロセスは、モジュール1および2で紹介されたように、教師ありファインチューニング、好みの最適化、またはその両方を組み合わせたハイブリッドアプローチなどの方法論に従うことができます。

コアツールと技術はLLMで使用されるものと似ていますが、VLMのファインチューニングには、画像のデータ表現と準備に特に注意を払う必要があります。これにより、モデルが視覚データとテキストデータの両方を効果的に統合および処理し、最適なパフォーマンスを発揮できるようになります。デモモデルであるSmolVLMは、前のモジュールで使用された言語モデルよりも大幅に大きいため、効率的なファインチューニング方法を探ることが重要です。量子化やPEFTなどの技術を使用することで、プロセスをよりアクセスしやすく、コスト効果の高いものにし、より多くのユーザーがモデルを試すことができます。

VLMのファインチューニングに関する詳細なガイダンスについては、[VLMのファインチューニング](./vlm_finetuning.md)ページを参照してください。

## 演習ノートブック

| タイトル | 説明 | 演習 | リンク | Colab |
|-------|-------------|----------|------|-------|
| VLMの使用 | 事前トレーニングされたVLMをさまざまなタスクに使用する方法を学ぶ | 🐢 画像を処理する
🐕 バッチ処理で複数の画像を処理する
🦁 ビデオ全体を処理する | [ノートブック](./notebooks/vlm_usage_sample.ipynb) |  |
| VLMのファインチューニング | タスク固有のデータセットに対して事前トレーニングされたVLMをファインチューニングする方法を学ぶ | 🐢 基本的なデータセットを使用してファインチューニングする
🐕 新しいデータセットを試す
🦁 代替のファインチューニング方法を試す | [ノートブック](./notebooks/vlm_sft_sample.ipynb) |  |

## 参考文献
- [Hugging Face Learn: Supervised Fine-Tuning VLMs](https://huggingface.co/learn/cookbook/fine_tuning_vlm_trl)
- [Hugging Face Learn: Supervised Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_smol_vlm_sft_trl)
- [Hugging Face Learn: Preference Optimization Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_vlm_dpo_smolvlm_instruct)
- [Hugging Face Blog: Preference Optimization for VLMs](https://huggingface.co/blog/dpo_vlm)
- [Hugging Face Blog: Vision Language Models](https://huggingface.co/blog/vlms)
- [Hugging Face Blog: SmolVLM](https://huggingface.co/blog/smolvlm)
- [Hugging Face Model: SmolVLM-Instruct](https://huggingface.co/HuggingFaceTB/SmolVLM-Instruct)
- [CLIP: Learning Transferable Visual Models from Natural Language Supervision](https://arxiv.org/abs/2103.00020)
- [Align Before Fuse: Vision and Language Representation Learning with Momentum Distillation](https://arxiv.org/abs/2107.07651)

A course on aligning smol models.


# VLMファインチューニング
## 効率的なファインチューニング

### 量子化
量子化は、モデルの重みとアクティベーションの精度を低下させ、メモリ使用量を大幅に削減し、計算速度を向上させます。たとえば、`float32`から`bfloat16`に切り替えると、パラメータごとのメモリ要件が半分になり、パフォーマンスを維持できます。より積極的な圧縮のために、8ビットおよび4ビットの量子化を使用してメモリ使用量をさらに削減できますが、精度が若干低下する可能性があります。これらの技術は、モデルとオプティマイザの設定の両方に適用でき、リソースが限られたハードウェアでの効率的なトレーニングを可能にします。

### PEFT & LoRA
モジュール3で紹介されたように、LoRA（Low-Rank Adaptation）は、元のモデルの重みを固定したまま、コンパクトなランク分解行列を学習することに焦点を当てています。これにより、トレーニング可能なパラメータの数が大幅に削減され、リソース要件が大幅に削減されます。LoRAはPEFTと統合されることで、大規模モデルのファインチューニングを可能にし、トレーニング可能なパラメータの小さなサブセットのみを調整します。このアプローチは、タスク固有の適応に特に効果的であり、数十億のトレーニング可能なパラメータを数百万に削減しながらパフォーマンスを維持します。

### バッチサイズの最適化
ファインチューニングのバッチサイズを最適化するには、大きな値から始め、メモリ不足（OOM）エラーが発生した場合は減らします。`gradient_accumulation_steps`を増やして補い、複数の更新にわたって合計バッチサイズを実質的に維持します。さらに、`gradient_checkpointing`を有効にして、逆伝播中に中間状態を再計算することでメモリ使用量を削減し、計算時間を犠牲にしてアクティベーションメモリ要件を削減します。これらの戦略は、ハードウェアの利用を最大化し、メモリ制約を克服するのに役立ちます。

```python
from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir="./fine_tuned_model",  # モデルチェックポイントのディレクトリ
    per_device_train_batch_size=4,   # デバイスごとのバッチサイズ（GPU/TPU）
    num_train_epochs=3,              # トレーニングの総エポック数
    learning_rate=5e-5,              # 学習率
    save_steps=1000,                 # 1000ステップごとにチェックポイントを保存
    bf16=True,                       # トレーニングに混合精度を使用
    gradient_checkpointing=True,     # アクティベーションメモリ使用量を削減するために有効にする
    gradient_accumulation_steps=16,  # 16ステップにわたって勾配を蓄積
    logging_steps=50                 # 50ステップごとにメトリクスをログ
)
```

## **教師ありファインチューニング（SFT）**

教師ありファインチューニング（SFT）は、事前トレーニングされたビジョン言語モデル（VLM）を特定のタスクに適応させるために、画像と対応するテキストを含むラベル付きデータセットを活用するプロセスです。この方法は、視覚質問応答、画像キャプション生成、チャート解釈などのドメイン固有またはタスク固有の機能を実行するモデルの能力を向上させます。

### **概要**
SFTは、ベースモデルの一般的な能力が不足する場合に、特定のドメインや特定の問題を解決するためにVLMを専門化する必要がある場合に不可欠です。たとえば、モデルが独自の視覚的特徴やドメイン固有の用語に苦労する場合、SFTはラベル付きデータから学習することでこれらの領域に焦点を当てることができます。

SFTは非常に効果的ですが、いくつかの制限があります：
- **データ依存性**：タスクに合わせた高品質のラベル付きデータセットが必要です。
- **計算リソース**：大規模なVLMのファインチューニングはリソース集約的です。
- **過学習のリスク**：モデルがあまりにも狭くファインチューニングされると、一般化能力を失う可能性があります。

これらの課題にもかかわらず、SFTは特定のコンテキストでのモデルパフォーマンスを向上させるための強力な手法です。

### **使用方法**
1. **データ準備**：画像とテキストのペアを含むラベル付きデータセットから始めます。たとえば、チャート分析のタスクでは、`HuggingFaceM4/ChartQA`データセットにはチャート画像、クエリ、および簡潔な応答が含まれています。

2. **モデル設定**：タスクに適した事前トレーニングされたVLM（例：`HuggingFaceTB/SmolVLM-Instruct`）と、テキストと画像の入力を準備するためのプロセッサをロードします。モデルを教師あり学習に設定し、ハードウェアに適した設定を行います。

3. **ファインチューニングプロセス**：
   - **データのフォーマット**：データセットをチャットボットのような形式に構造化し、システムメッセージ、ユーザークエリ、および対応する回答をペアにします。
   - **トレーニング設定**：Hugging Faceの`TrainingArguments`やTRLの`SFTConfig`などのツールを使用してトレーニングパラメータを設定します。これには、バッチサイズ、学習率、およびリソース使用を最適化するための勾配蓄積ステップが含まれます。
   - **最適化技術**：トレーニング中のメモリを節約するために**gradient checkpointing**を使用します。メモリ要件を削減し、計算速度を向上させるために量子化モデルを使用します。
   - TRLライブラリの`SFTTrainer`トレーナーを使用して、トレーニングプロセスを簡素化します。

## 好みの最適化

好みの最適化、特に直接好みの最適化（DPO）は、ビジョン言語モデル（VLM）を人間の好みに合わせるためのトレーニング手法です。事前定義された指示に厳密に従うのではなく、モデルは人間が主観的に好む出力を優先することを学習します。このアプローチは、創造的な判断、微妙な推論、または許容される回答が異なるタスクに特に有用です。

### **概要**
好みの最適化は、主観的な人間の好みがタスクの成功にとって重要なシナリオに対処します。好みをエンコードしたデータセットでファインチューニングすることで、DPOはモデルの応答生成能力を強化し、ユーザーの期待に文脈的およびスタイル的に一致させます。この方法は、創造的な執筆、顧客との対話、または複数の選択肢があるシナリオなどのタスクに特に効果的です。

その利点にもかかわらず、好みの最適化にはいくつかの課題があります：
- **データ品質**：高品質の好みが注釈されたデータセットが必要であり、データ収集がボトルネックになることがあります。
- **複雑さ**：トレーニングには、好みのペアワイズサンプリングや計算リソースのバランスなどの高度なプロセスが含まれることがあります。

好みのデータセットは、候補出力間の明確な好みをキャプチャする必要があります。たとえば、データセットは質問と2つの応答（1つは好まれ、もう1つは受け入れられない）をペアにすることがあります。モデルは、完全に正しくなくても、より人間の判断に一致する好ましい応答を予測することを学習します。

### **使用方法**
1. **データセットの準備**
   トレーニングには、好みがラベル付けされたデータセットが重要です。各例は通常、プロンプト（例：画像と質問）と2つの候補応答（1つは選択され、もう1つは拒否される）で構成されます。たとえば：

   - **質問**：家族は何人ですか？
     - **拒否**：画像には家族に関する情報はありません。
     - **選択**：画像には18,000家族のユニオン組織のテーブル設定が表示されています。

   データセットは、モデルに完全に正しくなくても、より人間の判断に一致する好ましい応答を優先することを教えます。

2. **モデル設定**
   事前トレーニングされたVLMをロードし、DPOをサポートするHugging FaceのTRLライブラリと統合し、テキストと画像の入力を準備するためのプロセッサを使用します。モデルを教師あり学習に設定し、ハードウェアに適した設定を行います。

3. **トレーニングパイプライン**
   トレーニングには、DPO固有のパラメータの設定が含まれます。プロセスの概要は次のとおりです：

   - **データセットのフォーマット**：各サンプルをプロンプト、画像、および候補応答で構成します。
   - **損失関数**：好みに基づく損失関数を使用して、好ましい出力を選択するようにモデルを最適化します。
   - **効率的なトレーニング**：量子化、勾配蓄積、LoRAアダプタなどの技術を組み合わせて、メモリと計算を最適化します。

## リソース

- [Hugging Face Learn: Supervised Fine-Tuning VLMs](https://huggingface.co/learn/cookbook/fine_tuning_vlm_trl)
- [Hugging Face Learn: Supervised Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_smol_vlm_sft_trl)
- [Hugging Face Learn: Preference Optimization Fine-Tuning SmolVLM](https://huggingface.co/learn/cookbook/fine_tuning_vlm_dpo_smolvlm_instruct)
- [Hugging Face Blog: Preference Optimization for VLMs](https://huggingface.co/blog/dpo_vlm)

## 次のステップ

⏩ この統一アプローチを好みの最適化に実装するには、[vlm_finetune_sample.ipynb](./notebooks/vlm_finetune_sample.ipynb)を試してください。

A course on aligning smol models.


# ビジュアル言語モデル

ビジュアル言語モデル（VLM）は、画像とテキストの間のギャップを埋め、画像キャプションの生成、視覚に基づく質問への回答、テキストと視覚データの関係の理解などの高度なタスクを可能にします。そのアーキテクチャは、両方のモダリティをシームレスに処理するように設計されています。

### アーキテクチャ

VLMは、画像処理コンポーネントとテキスト生成モデルを組み合わせて、統一された理解を実現します。主な要素は次のとおりです：

![VLMアーキテクチャ](./images/VLM_Architecture.png)

- **画像エンコーダ**：生の画像をコンパクトな数値表現に変換します。CLIPやビジョントランスフォーマー（ViT）などの事前トレーニングされたエンコーダが一般的に使用されます。
- **埋め込みプロジェクタ**：画像特徴をテキスト埋め込みと互換性のある空間にマッピングします。通常、密な層や線形変換を使用します。
- **テキストデコーダ**：マルチモーダル情報を翻訳して一貫したテキストを生成する言語生成コンポーネントです。LlamaやVicunaなどの生成モデルが例として挙げられます。
- **マルチモーダルプロジェクタ**：画像とテキストの表現をブレンドするための追加の層を提供します。LLaVAのようなモデルでは、2つのモダリティ間の強力な接続を確立するために重要です。

ほとんどのVLMは、事前トレーニングされた画像エンコーダとテキストデコーダを活用し、ペアになった画像テキストデータセットで追加のファインチューニングを行います。このアプローチにより、効率的なトレーニングが可能になり、モデルが効果的に一般化できるようになります。

### 使用方法

![VLMプロセス](./images/VLM_Process.png)

VLMは、さまざまなマルチモーダルタスクに適用されます。その適応性により、さまざまなドメインで異なるレベルのファインチューニングを行うことができます：

- **画像キャプション生成**：画像の説明を生成します。
- **視覚質問応答（VQA）**：画像の内容に関する質問に答えます。
- **クロスモーダル検索**：特定の画像に対応するテキストを見つける、またはその逆を行います。
- **クリエイティブなアプリケーション**：デザイン支援、アート生成、魅力的なマルチメディアコンテンツの作成などに役立ちます。

![VLMの使用](./images/VLM_Usage.png)

VLMのトレーニングとファインチューニングには、画像とテキストの注釈がペアになった高品質なデータセットが必要です。Hugging Faceの`transformers`ライブラリなどのツールを使用すると、事前トレーニングされたVLMに簡単にアクセスでき、カスタムファインチューニングのワークフローが簡素化されます。

### チャット形式

多くのVLMは、使いやすさを向上させるためにチャットボットのような形式で構造化されています。この形式には次の要素が含まれます：

- モデルの役割やコンテキストを設定する**システムメッセージ**（例：「あなたは視覚データを分析するアシスタントです」）。
- テキスト入力と関連する画像を組み合わせた**ユーザークエリ**。
- マルチモーダル分析から得られたテキスト出力を提供する**アシスタントの応答**。

この会話形式は直感的であり、特にカスタマーサービスや教育ツールなどのインタラクティブなアプリケーションにおいて、ユーザーの期待に沿ったものです。

フォーマットされた入力の例を次に示します：

```json
[
    {
        "role": "system",
        "content": [{"type": "text", "text": "あなたはチャート画像の視覚データを解釈する専門のビジュアル言語モデルです..."}]
    },
    {
        "role": "user",
        "content": [
            {"type": "image", "image": "<image_data>"},
            {"type": "text", "text": "棒グラフの最高値は何ですか？"}
        ]
    },
    {
        "role": "assistant",
        "content": [{"type": "text", "text": "42"}]
    }
]
```

**複数の画像やビデオの処理**

VLMは、入力構造を適応させることで、複数の画像やビデオを処理することもできます。ビデオの場合、フレームを抽出して個々の画像として処理し、時間順序を維持します。

## リソース

- [Hugging Face Blog: Vision Language Models](https://huggingface.co/blog/vlms)
- [Hugging Face Blog: SmolVLM](https://huggingface.co/blog/smolvlm)

## 次のステップ

⏩ SMOLVLMのさまざまな使用方法を試すには、[vlm_usage_sample.ipynb](./notebooks/vlm_usage_sample.ipynb)を試してください。

A course on aligning smol models.


# 合成データセット

合成データは、実際の使用状況を模倣する人工的に生成されたデータです。データセットを拡張または強化することで、データの制限を克服することができます。合成データはすでにいくつかのユースケースで使用されていましたが、大規模な言語モデルは、言語モデルの事前および事後トレーニング、および評価のための合成データセットをより一般的にしました。

私たちは、検証済みの研究論文に基づいた迅速で信頼性が高くスケーラブルなパイプラインを必要とするエンジニアのための合成データとAIフィードバックのフレームワークである[`distilabel`](https://distilabel.argilla.io/latest/)を使用します。パッケージとベストプラクティスの詳細については、[ドキュメント](https://distilabel.argilla.io/latest/)を参照してください。

## モジュール概要

言語モデルの合成データは、インストラクション、嗜好、批評の3つの分類に分類できます。私たちは、インストラクションチューニングと嗜好調整のためのデータセットの生成に焦点を当てます。両方のカテゴリでは、既存のデータをモデルの批評とリライトで改善するための第3のカテゴリの側面もカバーします。

![合成データの分類](./images/taxonomy-synthetic-data.png)

## コンテンツ

### 1. [インストラクションデータセット](./instruction_datasets.md)

インストラクションチューニングのためのインストラクションデータセットの生成方法を学びます。基本的なプロンプトを使用してインストラクションチューニングデータセットを作成する方法や、論文から得られたより洗練された技術を使用する方法を探ります。SelfInstructやMagpieのような方法を使用して、インコンテキスト学習のためのシードデータを使用してインストラクションチューニングデータセットを作成できます。さらに、EvolInstructを通じたインストラクションの進化についても探ります。[学び始める](./instruction_datasets.md)。

### 2. [嗜好データセット](./preference_datasets.md)

嗜好調整のための嗜好データセットの生成方法を学びます。セクション1で紹介した方法と技術を基に構築し、追加の応答を生成します。次に、EvolQualityプロンプトを使用して応答を改善する方法を学びます。最後に、スコアと批評を生成するUltraFeedbackプロンプトを探り、嗜好ペアを作成します。[学び始める](./preference_datasets.md)。

### 演習ノートブック

| タイトル | 説明 | 演習 | リンク | Colab |
|-------|-------------|----------|------|-------|
| インストラクションデータセット | インストラクションチューニングのためのデータセットを生成する | 🐢 インストラクションチューニングデータセットを生成する
 🐕 シードデータを使用してインストラクションチューニングのためのデータセットを生成する
 🦁 シードデータとインストラクションの進化を使用してインストラクションチューニングのためのデータセットを生成する | [リンク](./notebooks/instruction_sft_dataset.ipynb) | [Colab](https://githubtocolab.com/huggingface/smol-course/tree/main/6_synthetic_datasets/notebooks/instruction_sft_dataset.ipynb) |
| 嗜好データセット | 嗜好調整のためのデータセットを生成する | 🐢 嗜好調整データセットを生成する
 🐕 応答の進化を使用して嗜好調整のためのデータセットを生成する
 🦁 応答の進化と批評を使用して嗜好調整のためのデータセットを生成する | [リンク](./notebooks/preference_alignment_dataset.ipynb) | [Colab](https://githubtocolab.com/huggingface/smol-course/tree/main/6_synthetic_datasets/notebooks/preference_alignment_dataset.ipynb) |

## リソース

- [Distilabel Documentation](https://distilabel.argilla.io/latest/)
- [Synthetic Data Generator is UI app](https://huggingface.co/blog/synthetic-data-generator)
- [SmolTalk](https://huggingface.co/datasets/HuggingFaceTB/smoltalk)
- [Self-instruct](https://arxiv.org/abs/2212.10560)
- [Evol-Instruct](https://arxiv.org/abs/2304.12244)
- [Magpie](https://arxiv.org/abs/2406.08464)
- [UltraFeedback](https://arxiv.org/abs/2310.01377)
- [Deita](https://arxiv.org/abs/2312.15685)

A course on aligning smol models.