# Smol-Course

## Docs

- [a smol course (um curso miudinho)](https://huggingface.co/learn/smol-course/pt-br/README.md)
- [Bem-vindo ao 🤗 smol-course](https://huggingface.co/learn/smol-course/pt-br/unit0/1.md)
- [Evaluation (Avaliação)](https://huggingface.co/learn/smol-course/pt-br/unit4/1.md)
- [Avaliação de Domínio Personalizado](https://huggingface.co/learn/smol-course/pt-br/unit4/3.md)
- [Benchmarks Automáticos](https://huggingface.co/learn/smol-course/pt-br/unit4/2.md)
- [Preference Alignment (Alinhamento de Preferência)](https://huggingface.co/learn/smol-course/pt-br/unit2/1.md)
- [Otimização de Preferências de Razão de Chances (ORPO)](https://huggingface.co/learn/smol-course/pt-br/unit2/3.md)
- [Otimização de Preferência Direta (DPO)](https://huggingface.co/learn/smol-course/pt-br/unit2/2.md)
- [Instruction Tuning (Ajuste de Instrução)](https://huggingface.co/learn/smol-course/pt-br/unit1/1.md)
- [Ajuste Fino Supervisionado](https://huggingface.co/learn/smol-course/pt-br/unit1/3.md)
- [Modelos de bate-papo](https://huggingface.co/learn/smol-course/pt-br/unit1/2.md)
- [Parameter-Efficient Fine-Tuning (PEFT) (Ajuste Fino com Eficiência de Parâmetro)](https://huggingface.co/learn/smol-course/pt-br/unit3/1.md)
- [Ajuste de Prompts](https://huggingface.co/learn/smol-course/pt-br/unit3/3.md)
- [LoRA (Low-Rank Adaptation - Adaptação de Baixa Classificação)](https://huggingface.co/learn/smol-course/pt-br/unit3/2.md)

### a smol course (um curso miudinho)
https://huggingface.co/learn/smol-course/pt-br/README.md

# a smol course (um curso miudinho)

Este é um curso prático sobre alinhar modelos de linguagem para o seu caso de uso específico. É uma maneira útil de começar a alinhar modelos de linguagem, porque tudo funciona na maioria das máquinas locais. Existem requisitos mínimos de GPU e nenhum serviço pago. O curso é baseado na série de modelos de [SmolLM2](https://github.com/huggingface/smollm/tree/main), mas você pode transferir as habilidades que aprende aqui para modelos maiores ou outros pequenos modelos de linguagem.

<a href="http://hf.co/join/discord">
<img src="https://img.shields.io/badge/Discord-7289DA?&logo=discord&logoColor=white"/>
</a>

<div style="background: linear-gradient(to right, #e0f7fa, #e1bee7, orange); padding: 20px; border-radius: 5px; margin-bottom: 20px; color: purple;">
    <h2>A participação é aberta a todos, gratuita e já está disponível!</h2>
    <p>Este curso é aberto e avaliado por pares (peer reviewed). Para começar o curso, <strong>abra um pull request (PR)</strong> e envie seu trabalho para revisão. Aqui estão as etapas:</p>
    <ol>
        <li>Dê um fork no repositório <a href="https://github.com/huggingface/smol-course/fork">aqui</a></li>
        <li>Leia o material, faça alterações, faça os exercícios, adicione seus próprios exemplos</li>
        <li>Abra um PR no branch december_2024</li>
        <li>Tenha seu material revisado e mesclado no branch principal</li>
    </ol>
    <p>Isso deve te ajudar a aprender e a construir um curso feito pela comunidade, que está sempre melhorando.</p>
</div>

Podemos discutir o processo neste [tópico de discussão](https://github.com/huggingface/smol-course/discussions/2#discussion-7602932).

## Sumário do Curso

Este curso fornece uma abordagem prática para trabalhar com pequenos modelos de linguagem, desde o treinamento inicial até a implantação de produção.

| Módulo | Descrição | Status | Data de Lançamento |
|--------|-------------|---------|--------------|
| [Instruction Tuning (Ajuste de Instrução)](./1_instruction_tuning) | Aprenda sobre o ajuste fino supervisionado, modelos de bate-papo e a fazer o modelo seguir instruções básicas | ✅ Completo | 3 Dez, 2024 |
| [Preference Alignment (Alinhamento de Preferência)](./2_preference_alignment) | Explore técnicas DPO e ORPO para alinhar modelos com preferências humanas | ✅ Completo  | 6 Dez, 2024 |
| [Parameter-efficient Fine-tuning (Ajuste Fino com Eficiência de Parâmetro)](./3_parameter_efficient_finetuning) | Aprenda sobre LoRA, ajuste de prompt e métodos de adaptação eficientes | ✅ Completo | 9 Dez, 2024 |
| [Evaluation (Avaliação)](./4_evaluation) | Use benchmarks automáticos e crie avaliações de domínio personalizadas | ✅ Completo | 13 Dez, 2024 |
| [Vision-language Models (Modelos de Conjunto Visão-linguagem)](./5_vision_language_models) | Adapte modelos multimodais para tarefas visão-linguagem | ✅ Completo | 16 Dez, 2024 |
| [Synthetic Datasets (Conjuntos de Dados Sintéticos)](./6_synthetic_datasets) | Criar e validar conjuntos de dados sintéticos para treinamento | [🚧 Em Progresso](https://github.com/huggingface/smol-course/issues/83) | 20 Dez, 2024 |
| [Inference (Inferência)](./7_inference) | Infira modelos com eficiência | 📝 Planejado | 23 Dez, 2024 |
| Projeto Experimental | Use o que você aprendeu para ser o top 1 na tabela de classificação! | [🚧 Em Progresso](https://github.com/huggingface/smol-course/pull/97) | Dec 23, 2024 |

## Por Que Pequenos Modelos de Linguagem?

Embora os grandes modelos de linguagem tenham mostrado recursos e capacidades impressionantes, eles geralmente exigem recursos computacionais significativos e podem ser exagerados para aplicativos focados. Os pequenos modelos de linguagem oferecem várias vantagens para aplicativos de domínios específicos:

- **Eficiência**: Requer significativamente menos recursos computacionais para treinar e implantar
- **Personalização**: Mais fácil de ajustar e se adaptar a domínios específicos
- **Controle**: Melhor compreensão e controle do comportamento do modelo
- **Custo**: Menores custos operacionais para treinamento e inferência
- **Privacidade**: Pode ser executado localmente sem enviar dados para APIs externas
- **Tecnologia Verde**: Defende o uso eficiente de recursos com redução da pegada de carbono 
- **Desenvolvimento de Pesquisa Acadêmica Mais Fácil**: Oferece um ponto de partida fácil para a pesquisa acadêmica com LLMs de ponta com menos restrições logísticas

## Pré-requisitos

Antes de começar, verifique se você tem o seguinte:
- Entendimento básico de machine learning e natural language processing.
- Familiaridade com Python, PyTorch e o módulo `transformers`.
- Acesso a um modelo de linguagem pré-treinado e um conjunto de dados rotulado.

## Instalação

Mantemos o curso como um pacote para que você possa instalar dependências facilmente por meio de um gerenciador de pacotes. Recomendamos [uv](https://github.com/astral-sh/uv) para esse fim, mas você pode usar alternativas como `pip` ou` pdm`.

### Usando `uv`

Com o `uv` instalado, você pode instalar o curso deste modo:

```bash
uv venv --python 3.11.0
uv sync
```

### Usando `pip`

Todos os exemplos são executados no mesmo ambiente **python 3.11**, então você deve criar um ambiente e instalar dependências desta maneira:

```bash
# python -m venv .venv
# source .venv/bin/activate
pip install -r requirements.txt
```

### Google Colab

**A partir do Google Colab** você precisará instalar dependências de maneira flexível com base no hardware que está usando. Pode fazer deste jeito:

```bash
pip install transformers trl datasets huggingface_hub
```

## Engajamento

Vamos compartilhar isso, desse jeito um monte de gente vai poder aprender a ajustar LLMs sem precisar de um computador super caro.

[![Gráfico de Histórico de Estrelas](https://api.star-history.com/svg?repos=huggingface/smol-course&type=Date)](https://star-history.com/#huggingface/smol-course&Date)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/README.md" />

### Bem-vindo ao 🤗 smol-course
https://huggingface.co/learn/smol-course/pt-br/unit0/1.md

# Bem-vindo ao 🤗 smol-course

Para a introdução completa deste curso, consulte a versão em inglês:

[Leia a introdução completa em inglês](https://huggingface.co/learn/smol-course/unit0/1)

## Sobre este curso em poucas palavras

- **Curso abrangente para Fine-Tuning de Modelos de Linguagem**
- **Do iniciante ao especialista** com aprendizado passo a passo
- Aprenda ajuste por instruções, avaliação, alinhamento de preferências e mais
- Inclui exercícios práticos e projetos reais

## Estrutura do curso

1. Ajuste por Instruções
2. Avaliação
3. Alinhamento de Preferências
4. Fine-tuning Eficiente em Parâmetros
5. Modelos de Linguagem Visual
6. Conjuntos de Dados Sintéticos

[Começar o curso](https://huggingface.co/smol-course)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit0/1.md" />

### Evaluation (Avaliação)
https://huggingface.co/learn/smol-course/pt-br/unit4/1.md

# Evaluation (Avaliação)

A avaliação é uma etapa crítica no desenvolvimento e implantação de modelos de linguagem. Ela nos ajuda a entender quão bem nossos modelos desempenham em diferentes capacidades e a identificar áreas para melhorias. Este módulo aborda benchmarks padrão e abordagens de avaliação específicas de domínio para avaliar de forma abrangente o seu modelo smol (miudinho).

Usaremos o [`lighteval`](https://github.com/huggingface/lighteval), uma poderosa biblioteca de avaliação desenvolvida pelo Hugging Face que se integra perfeitamente ao ecossistema Hugging Face. Para um aprendizado mais profundo nos conceitos e práticas recomendadas de avaliação, confira o [guia](https://github.com/huggingface/evaluation-guidebook).

## Visão Geral do Módulo 

Uma estratégia de avaliação completa examina múltiplos aspectos do desempenho do modelo. Avaliamos capacidades específicas de tarefas, como responder a perguntas e sumarização, para entender como o modelo lida com diferentes tipos de problemas. Medimos a qualidade do output através de fatores como coerência e precisão factual. A avaliação de segurança ajuda a identificar outputs potencialmente prejudiciais ou biases. Por fim, os testes de especialização de domínio verificam o conhecimento especializado do modelo no campo-alvo.

## Conteúdo

### 1️⃣ [Benchmarks Automáticos](./automatic_benchmarks.md)

Aprenda a avaliar seu modelo usando benchmarks e métricas padronizados. Exploraremos benchmarks comuns, como MMLU e TruthfulQA, entenderemos as principais métricas e configurações de avaliação e abordaremos as melhores práticas para avaliações reproduzíveis.

### 2️⃣ [Avaliação de Domnínio Personalizado](./custom_evaluation.md)

Descubra como criar pipelines de avaliação adaptados ao seu caso de uso específico. Veremos o design de tarefas de avaliação personalizadas, implementação de métricas especializadas e construção de conjuntos de dados de avaliação que atendam às suas necessidades.

### 3️⃣ [Projeto de Avaliação de Domínio](./project/README.md)

Siga um exemplo completo de construção de um pipeline de avaliação de domínio específico. Você aprenderá a gerar conjuntos de dados de avaliação, usar o Argilla para anotação de dados, criar conjuntos de dados padronizados e avaliar modelos usando o LightEval.

## Referências

- [Guia de Avaliação](https://github.com/huggingface/evaluation-guidebook) - Guia abrangente de avaliação de LLMs
- [Documentação do LightEval](https://github.com/huggingface/lighteval) - Documentação oficial do módulo LightEval
- [Documentação do Argilla](https://docs.argilla.io) - Saiba mais sobre a plataforma de anotação Argilla
- [Artigo do MMLU](https://arxiv.org/abs/2009.03300) - Artigo que descreve o benchmark MMLU
- [Criando uma Tarefa Personalizada](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [Criando uma Métrica Personalizada](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- [Usando Métricas Existentes](https://github.com/huggingface/lighteval/wiki/Metric-List)

<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit4/1.md" />

### Avaliação de Domínio Personalizado
https://huggingface.co/learn/smol-course/pt-br/unit4/3.md

# Avaliação de Domínio Personalizado

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/4_evaluation/lighteval_evaluate_and_analyse_your_LLM.ipynb"},
]} />

Embora benchmarks padrão ofereçam insights valiosos, muitas aplicações requerem abordagens de avaliação especializadas adaptadas a domínios ou casos de uso específicos. Este guia ajudará você a criar pipelines de avaliação personalizados que avaliem com precisão o desempenho do seu modelo no domínio-alvo.

## Planejando Sua Estratégia de Avaliação

Uma estratégia de avaliação personalizada bem-sucedida começa com objetivos claros. Considere quais capacidades específicas seu modelo precisa demonstrar no seu domínio. Isso pode incluir conhecimento técnico, padrões de raciocínio ou formatos específicos de domínio. Documente esses requisitos cuidadosamente, eles guiarão tanto o design da tarefa quanto a seleção de métricas.

Sua avaliação deve testar tanto casos de uso padrão quanto casos extremos. Por exemplo, em um domínio de medicina, você pode avaliar cenários com diagnósticos comuns e condições raras. Em aplicações financeiras, pode-se testar transações rotineiras e casos extremos envolvendo múltiplas moedas ou condições especiais.

## Implementação com LightEval

O LightEval fornece um framework flexível para implementar avaliações personalizadas. Veja como criar uma tarefa 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"],  # Your chosen metrics
            description="Description of your custom evaluation task"
        )
    
    def get_prompt(self, sample):
        # Format your input into a prompt
        return f"Question: {sample['question'
  ]}\nAnswer:"
    
    def process_response(self, response, ref):
        # Process model output and compare to reference
        return response.strip() == ref.strip()
```

## Métricas Personalizadas

Tarefas específicas de domínio frequentemente exigem métricas especializadas. O LightEval fornece um framework flexível para criar métricas personalizadas que capturam aspectos relevantes do desempenho no domínio:

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

# Define a sample-level metric function
def custom_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> dict:
    """Example metric that returns multiple scores per sample"""
    response = predictions[0]
    return {
        "accuracy": response == formatted_doc.choices[formatted_doc.gold_index],
        "length_match": len(response) == len(formatted_doc.reference)
    }

# Create a metric that returns multiple values per sample
custom_metric_group = SampleLevelMetricGrouping(
    metric_name=["accuracy", "length_match"],  # Names of sub-metrics
    higher_is_better={  # Whether higher values are better for each metric
        "accuracy": True,
        "length_match": True
    },
    category=MetricCategory.CUSTOM,
    use_case=MetricUseCase.SCORING,
    sample_level_fn=custom_metric,
    corpus_level_fn={  # How to aggregate each metric
        "accuracy": np.mean,
        "length_match": np.mean
    }
)

# Register the metric with LightEval
extend_enum(Metrics, "custom_metric_name", custom_metric_group)
```

Para casos mais simples onde você precisa de apenas um valor por amostra:

```python
def simple_metric(predictions: list[str], formatted_doc: Doc, **kwargs) -> bool:
    """Example metric that returns a single score per sample"""
    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  # How to aggregate across samples
)

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

Você pode então usar suas métricas personalizadas em tarefas de avaliação referenciando-as na configuração da tarefa. As métricas serão automaticamente calculadas para todas as amostras e agregadas de acordo com as funções especificadas.

Para métricas mais complexas, considere:
- Usar metadados em seus documentos formatados para ponderar ou ajustar pontuações
- Implementar funções de agregação personalizadas para estatísticas em nível de corpus
- Adicionar verificações de validação para as entradas da métrica
- Documentar casos extremos e comportamentos esperados

Para um exemplo completo de métricas personalizadas em ação, veja nosso [projeto de avaliação de domínio](./project/README.md).

## Criação de Conjuntos de Dados

Uma avaliação de alta qualidade requer conjuntos de dados cuidadosamente selecionados. Considere estas abordagens para criação de conjuntos de dados:

1. Anotação Avançada: Trabalhe com especialistas no domínio para criar e validar exemplos de avaliação. Ferramentas como o [Argilla](https://github.com/argilla-io/argilla) tornam esse processo mais eficiente.

2. Dados do Mundo Real: Colete e anonimize dados de uso real, garantindo que representem cenários reais de implantação.

3. Geração Sintética: Use LLMs para gerar exemplos iniciais e, em seguida, peça para especialistas validarem e refinarem esses exemplos.

## Melhores Práticas

- Documente sua metodologia de avaliação detalhadamente, incluindo quaisquer suposições ou limitações
- Inclua casos de teste diversificados que cubram diferentes aspectos do seu domínio
- Considere métricas automatizadas e avaliação humana, quando apropriado
- Faça o controle de versão dos seus conjuntos de dados e código de avaliação
- Atualize regularmente seu conjunto de avaliação à medida que descobrir novos casos extremos ou requisitos

## Referências

- [Guia de Tarefas Personalizadas do LightEval](https://github.com/huggingface/lighteval/wiki/Adding-a-Custom-Task)
- [Métricas Personalizadas do LightEval](https://github.com/huggingface/lighteval/wiki/Adding-a-New-Metric)
- [Documentação do Argilla](https://docs.argilla.io) para anotação de conjuntos de dados
- [Guia de Avaliação](https://github.com/huggingface/evaluation-guidebook) para princípios gerais de avaliação

# Próximos Passos

⏩ Para um exemplo completo de implementação desses conceitos, veja nosso [projeto de avaliação de domínio](./project/README.md).

<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit4/3.md" />

### Benchmarks Automáticos
https://huggingface.co/learn/smol-course/pt-br/unit4/2.md

# Benchmarks Automáticos

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/4_evaluation/lighteval_evaluate_and_analyse_your_LLM.ipynb"},
]} />

Os benchmarks automáticos servem como ferramentas padronizadas para avaliar modelos de linguagem em diferentes tarefas e capacidades. Embora forneçam um ponto de partida útil para entender o desempenho do modelo, é importante reconhecer que eles representam apenas uma parte de uma estratégia abrangente de avaliação.

## Entendendo os Benchmarks Automáticos

Os benchmarks automáticos geralmente consistem em conjuntos de dados organizados com tarefas e métricas de avaliação predefinidas. Esses benchmarks têm como objetivo avaliar vários aspectos da capacidade do modelo, desde compreensão básica de linguagem até raciocínio complexo. A principal vantagem de usar benchmarks automáticos é a padronização, eles permitem comparações consistentes entre diferentes modelos e fornecem resultados reproduzíveis.

No entanto, é crucial entender que o desempenho em benchmarks nem sempre se traduz diretamente em eficácia no mundo real. Um modelo que se destaca em benchmarks acadêmicos pode ainda enfrentar dificuldades em aplicações específicas de domínio ou casos práticos.

## Benchmarks e Suas Limitações

### Benchmarks de Conhecimento Geral

O MMLU (Massive Multitask Language Understanding) testa conhecimentos em 57 disciplinas, de ciências a humanidades. Embora abrangente, este benchmark pode não refletir a profundidade de especialização necessária para domínios específicos. O TruthfulQA avalia a tendência de um modelo em reproduzir conceitos equivocados comuns, embora não capture todas as formas de desinformação.

### Benchmarks de Raciocínio

BBH (Big Bench Hard) e GSM8K focam em tarefas de raciocínio complexo. O BBH testa pensamento lógico e planejamento, enquanto o GSM8K visa especificamente a resolução de problemas matemáticos. Esses benchmarks ajudam a avaliar capacidades analíticas, mas podem não captar o raciocínio detalhado exigido em cenários do mundo real.

### Compreensão de Linguagem

HELM fornece uma estrutura de avaliação holística, enquanto o WinoGrande testa o senso comum através da desambiguação de pronomes. Esses benchmarks oferecem insights sobre capacidades de processamento de linguagem, mas podem não representar totalmente a complexidade da conversação natural ou terminologia específica de domínio.

## Abordagens Alternativas de Avaliação

Muitas organizações desenvolveram métodos alternativos de avaliação para lidar com as limitações dos benchmarks padrão:

### LLM como Juiz

Usar um modelo de linguagem para avaliar os outputs de outro tornou-se cada vez mais popular. Essa abordagem pode fornecer feedback mais detalhado do que métricas tradicionais, embora apresente seus próprios vieses e limitações.

### Arenas de Avaliação

Plataformas como a IA Arena Constitucional da Anthropic permitem que modelos interajam e avaliem uns aos outros em ambientes controlados. Isso pode revelar pontos fortes e fracos que podem não ser evidentes em benchmarks tradicionais.

### Conjuntos de Benchmarks Personalizados

As organizações frequentemente desenvolvem conjuntos de benchmarks internos adaptados às suas necessidades e casos de uso específicos. Esses conjuntos podem incluir testes de conhecimento de domínio ou cenários de avaliação que refletem condições reais de implantação.

## Criando Sua Própria Estratégia de Avaliação

Embora o LightEval facilite a execução de benchmarks padrão, você também deve investir tempo no desenvolvimento de métodos de avaliação específicos para o seu caso de uso.

Sabendo que benchmarks padrão fornecem uma linha de base útil, eles não devem ser seu único método de avaliação. Aqui está como desenvolver uma abordagem mais abrangente:

1. Comece com benchmarks padrão relevantes para estabelecer uma linha de base e permitir comparações com outros modelos.

2. Identifique os requisitos específicos e desafios do seu caso de uso. Quais tarefas seu modelo realmente executará? Que tipos de erros seriam mais problemáticos?

3. Desenvolva conjuntos de dados de avaliação personalizados que reflitam seu caso de uso real. Isso pode incluir:
    - Consultas reais de usuários do seu domínio
    - Casos extremos comuns que você encontrou
    - Exemplos de cenários particularmente desafiadores

4. Considere implementar uma estratégia de avaliação em camadas:
    - Métricas automatizadas para feedback rápido
    - Avaliação humana para entendimento mais detalhado
    - Revisão por especialistas no domínio para aplicações especializadas
    - Testes A/B em ambientes controlados

## Usando LightEval para Benchmarks

As tarefas do LightEval são definidas usando um formato específico:

```
{suite}|{task}|{num_few_shot}|{auto_reduce}
```

- **suite**: O conjunto de benchmarks (ex.: 'mmlu', 'truthfulqa')
- **task**: Tarefa específica dentro do conjunto (ex.: 'abstract_algebra')
- **num_few_shot**: Número de exemplos a incluir no prompt (0 para zero-shot)
- **auto_reduce**: Se deve reduzir automaticamente exemplos few-shot caso o prompt seja muito longo (0 ou 1)

Exemplo: `"mmlu|abstract_algebra|0|0"` avalia a tarefa de álgebra abstrata do MMLU com inferência zero-shot.

### Exemplo de Pipeline de Avaliação

Aqui está um exemplo completo de configuração e execução de uma avaliação em benchmarks automáticos relevantes para um domínio específico:

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

# Define tasks to evaluate
domain_tasks = [
    "mmlu|anatomy|0|0",
    "mmlu|high_school_biology|0|0", 
    "mmlu|high_school_chemistry|0|0",
    "mmlu|professional_medicine|0|0"
]

# Configure pipeline parameters
pipeline_params = {
    "max_samples": 40,  # Number of samples to evaluate
    "batch_size": 1,    # Batch size for inference
    "num_workers": 4    # Number of worker processes
}

# Create evaluation tracker
evaluation_tracker = EvaluationTracker(
    output_path="./results",
    save_generations=True
)

# Load model and create pipeline
model = AutoModelForCausalLM.from_pretrained("your-model-name")
pipeline = Pipeline(
    tasks=domain_tasks,
    pipeline_parameters=pipeline_params,
    evaluation_tracker=evaluation_tracker,
    model=model
)

# Run evaluation
pipeline.evaluate()

# Get and display results
results = pipeline.get_results()
pipeline.show_results()
```

Os resultados são exibidos em formato tabular, mostrando:
```
|                  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|
```

Você também pode manipular os resultados em um DataFrame do pandas e visualizá-los conforme necessário.

# Próximos Passos

⏩ Veja a [Avaliação Personalizada de Domínio](./custom_evaluation.md) para aprender a criar pipelines de avaliação adaptados às suas necessidades específicas.


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit4/2.md" />

### Preference Alignment (Alinhamento de Preferência)
https://huggingface.co/learn/smol-course/pt-br/unit2/1.md

# Preference Alignment (Alinhamento de Preferência)

Este módulo abrange técnicas para alinhar modelos de linguagem com preferências humanas. Enquanto o ajuste fino supervisionado ajuda os modelos a aprender tarefas, o alinhamento de preferência incentiva os resultados a corresponder às expectativas e valores humanos.

## Visão Geral

Métodos de alinhamento típicos envolvem vários estágios:
1. Ajuste fino supervisionado (SFT) para adaptar os modelos a domínios específicos
2. Alinhamento de preferência (como RLHF ou DPO) para melhorar a qualidade da resposta

Abordagens alternativas como ORPO combinam ajuste de instrução e alinhamento de preferência em um único processo. Aqui, vamos focar nos algoritmos DPO e ORPO.

Se você quer aprender mais sobre as diferentes técnicas de alinhamento, você pode ler mais sobre isso no [Argilla Blog](https://argilla.io/blog/mantisnlp-rlhf-part-8). 

### 1️⃣ Otimização de Preferência Direta (DPO - Direct Preference Optimization)

Otimização de preferência direta (DPO) simplifica o alinhamento de preferência otimizando diretamente os modelos usando dados de preferência. Essa abordagem elimina a necessidade de usar modelos de recompensa que não fazem parte do sistema e aprendizado de reforço complexo, tornando-o mais estável e eficiente do que o tradicional aprendizado de reforço com o feedback humano (RLHF). Para mais detalhes,você pode ler mais em [Documentação sobre otimização de preferência direta (DPO)](./dpo.md).


### 2️⃣ Otimização de Preferências de Razão de Chances (ORPO - Odds Ratio Preference Optimization)

ORPO introduz uma abordagem combinada para ajuste de instrução e alinhamento de preferência em um único processo. Ele modifica o objetivo padrão de modelagem de linguagem combinando a perda de log-verossimilhança negativa com um termo de razão de chances em um nível de token. A abordagem apresenta um processo de treinamento unificado de estágio único, arquitetura sem modelo de referência e eficiência computacional aprimorada. O ORPO apresentou resultados impressionantes em vários benchmarks, demonstrando melhor desempenho no AlpacaEval em comparação com os métodos tradicionais. Para obter mais detalhes, consulte a [Documentação sobre Otimização de Preferências de Razão de Chances (ORPO)](./orpo.md)

## Referências

- [Documentação do TRL](https://huggingface.co/docs/trl/index) - Documentação do módulo Transformers Reinforcement Learning (TRL), que implementa várias técnicas de alinhamento, inclusive a DPO.
- [Artigo sobre DPO](https://arxiv.org/abs/2305.18290) - Documento de pesquisa original que apresenta a Otimização Direta de Preferência como uma alternativa mais simples ao RLHF que otimiza diretamente os modelos de linguagem usando dados de preferência.
- [Artigo sobre ORPO](https://arxiv.org/abs/2403.07691) - Apresenta a Otimização de preferências de razão de chances, uma nova abordagem que combina o ajuste de instruções e o alinhamento de preferências em um único estágio de treinamento.
- [Guia Argilla RLHF](https://argilla.io/blog/mantisnlp-rlhf-part-8/) - Um guia que explica diferentes técnicas de alinhamento, incluindo RLHF, DPO e suas implementações práticas.
- [Postagem de blog sobre DPO](https://huggingface.co/blog/dpo-trl) - Guia prático sobre a implementação de DPO usando a biblioteca TRL com exemplos de código e práticas recomendadas.
- [Exemplo de script TRL no DPO](https://github.com/huggingface/trl/blob/main/examples/scripts/dpo.py) - Script de exemplo completo que demonstra como implementar o treinamento em DPO usando a biblioteca TRL.
- [Exemplo de script TRL no ORPO](https://github.com/huggingface/trl/blob/main/examples/scripts/orpo.py) - Implementação de referência do treinamento ORPO usando a biblioteca TRL com opções de configuração detalhadas.
- [Manual de alinhamento do Hugging Face](https://github.com/huggingface/alignment-handbook) - Guias de recursos e base de código para alinhamento de modelos de linguagem usando várias técnicas, incluindo SFT, DPO e RLHF.

<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit2/1.md" />

### Otimização de Preferências de Razão de Chances (ORPO)
https://huggingface.co/learn/smol-course/pt-br/unit2/3.md

# Otimização de Preferências de Razão de Chances (ORPO)

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/2_preference_alignment/orpo_finetuning_example.ipynb"},
]} />

A ORPO (Odds Ratio Preference Optimization) é uma nova técnica de ajuste fino que combina o ajuste fino e o alinhamento de preferências em um único processo unificado. Essa abordagem combinada oferece vantagens em termos de eficiência e desempenho em comparação com métodos tradicionais como RLHF ou DPO.

## Entendendo sobre o ORPO

O alinhamento com métodos como o DPO normalmente envolve duas etapas separadas: ajuste fino supervisionado para adaptar o modelo a um domínio e formato, seguido pelo alinhamento de preferências para alinhar com as preferências humanas. Embora o SFT adapte efetivamente os modelos aos domínios-alvo, ele pode aumentar inadvertidamente a probabilidade de gerar respostas desejáveis e indesejáveis. O ORPO aborda essa limitação integrando as duas etapas em um único processo, conforme ilustrado na comparação abaixo:

![Comparação das Técnicas de Alinhamento](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-alignments.png)
*Comparação de diferentes técnicas de alinhamento de modelos*

## Como o ORPO Funciona

O processo de treinamento utiliza um conjunto de dados de preferências semelhante ao que usamos para o DPO, em que cada exemplo de treinamento contém um prompt de entrada com duas respostas: uma que é preferida e outra que é rejeitada. Diferentemente de outros métodos de alinhamento que exigem estágios e modelos de referência separados, o ORPO integra o alinhamento de preferências diretamente ao processo de ajuste fino supervisionado. Essa abordagem monolítica o torna livre de modelos de referência, computacionalmente mais eficiente e eficiente em termos de memória com menos FLOPs.

O ORPO cria um novo objetivo ao combinar dois componentes principais:

1. **Função de perda do SFT**: A perda padrão de log-verossimilhança negativa usada na modelagem de linguagem, que maximiza a probabilidade de gerar tokens de referência. Isso ajuda a manter as capacidades gerais de linguagem do modelo.

2. **Função de perda da Razão de Chances**: Um novo componente que penaliza respostas indesejáveis e recompensa as preferidas. Essa função de perda usa índices de probabilidade (razão de chances) para contrastar efetivamente entre respostas favorecidas e desfavorecidas no nível do token.

Juntos, esses componentes orientam o modelo a se adaptar às gerações desejadas para o domínio específico e, ao mesmo tempo, desencorajam ativamente as gerações do conjunto de respostas rejeitadas. O mecanismo de razão de chances oferece uma maneira natural de medir e otimizar a preferência do modelo entre os resultados escolhidos e rejeitados. Se quiser se aprofundar na matemática, você pode ler o [artigo sobre ORPO](https://arxiv.org/abs/2403.07691). Se quiser saber mais sobre o ORPO do ponto de vista da implementação, confira como a função de perda do ORPO é calculada no [módulo TRL](https://github.com/huggingface/trl/blob/b02189aaa538f3a95f6abb0ab46c0a971bfde57e/trl/trainer/orpo_trainer.py#L660).

## Desempenho e Resultados

O ORPO demonstrou resultados impressionantes em vários benchmarks. No MT-Bench, ele alcança pontuações competitivas em diferentes categorias:

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

Quando comparado a outros métodos de alinhamento, o ORPO apresenta desempenho superior no AlpacaEval 2.0:

![Resultados do AlpacaEval](https://argilla.io/images/blog/mantisnlp-rlhf/part-8-winrate.png)
*Pontuações do AlpacaEval 2.0 em diferentes métodos de alinhamento*

Em comparação com p SFT+DPO, o ORPO reduz os requisitos de computação, eliminando a necessidade de um modelo de referência e reduzindo pela metade o número de passagens de avanço por lote. Além disso, o processo de treinamento é mais estável em diferentes tamanhos de modelos e conjuntos de dados, exigindo menos hiperparâmetros para ajustar. Em termos de desempenho, o ORPO se iguala aos modelos maiores e mostra melhor alinhamento com as preferências humanas.

## Implementação 

A implementação bem-sucedida do ORPO depende muito de dados de preferência de alta qualidade. Os dados de treinamento devem seguir diretrizes claras de anotação e fornecer uma representação equilibrada das respostas preferidas e rejeitadas em diversos cenários. 

### Implementação com TRL

O ORPO pode ser implementado usando o módulo Transformers Reinforcement Learning (TRL). Aqui está um exemplo básico:

```python
from trl import ORPOConfig, ORPOTrainer

# Configure ORPO training
orpo_config = ORPOConfig(
    learning_rate=1e-5,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    max_steps=1000,
    orpo_alpha=1.0,  # Controls strength of preference optimization
    orpo_beta=0.1,   # Temperature parameter for odds ratio
)

# Initialize trainer
trainer = ORPOTrainer(
    model=model,
    args=orpo_config,
    train_dataset=dataset,
    tokenizer=tokenizer,
)

# Start training
trainer.train()
```

Principais parâmetros a serem considerados:
- `orpo_alpha`: Controla a força da otimização de preferências
- `orpo_beta`: Parâmetro de temperatura para o cálculo da razão de chances
- `learning_rate`: Deve ser relativamente pequeno para evitar o esquecimento catastrófico
- `gradient_accumulation_steps`: Ajuda na estabilidade do treinamento

## Próximos Passos

⏩ Experimente o [Tutorial do ORPO](../../../notebooks/pt-br/2_preference_alignment/orpo_tutorial.ipynb) para implementar essa abordagem unificada ao alinhamento de preferências.

## Referências
- [Artigo sobre ORPO](https://arxiv.org/abs/2403.07691)
- [Documentação TRL](https://huggingface.co/docs/trl/index)
- [Guia Argilla RLHF](https://argilla.io/blog/mantisnlp-rlhf-part-8/) 

<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit2/3.md" />

### Otimização de Preferência Direta (DPO)
https://huggingface.co/learn/smol-course/pt-br/unit2/2.md

# Otimização de Preferência Direta (DPO)

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/2_preference_alignment/dpo_finetuning_example.ipynb"},
]} />

Otimização de Preferência Direta (DPO) oferece uma abordagem simplificada para alinhar modelos de linguagem com preferências humanas. Ao contrário dos métodos RLHF tradicionais que requerem modelos de recompensa separados e aprendizado de reforço complexo, o DPO otimiza diretamente o modelo usando dados de preferência.

## Entendendo sobre o DPO

O DPO reformula o alinhamento da preferência como um problema de classificação nos dados de preferência humana. As abordagens tradicionais de RLHF exigem treinamento de um modelo de recompensa separado e usando algoritmos de aprendizado de reforço complexos como o PPO para alinhar os outputs do modelo. O DPO simplifica esse processo, definindo uma função de perda que otimiza diretamente a política do modelo com base em outputs preferidos versus não preferidos.

Esta abordagem se mostrou altamente eficaz quando colocada em prática, sendo usada para treinar modelos como o Llama. Ao eliminar a necessidade de usar modelos de recompensa que não fazem parte do sistema e aprendizado de reforço complexo, DPO faz o alinhamento de preferência muito mais acessível e estável.

## Como o DPO Funciona

O processo do DPO exige que o ajuste fino supervisionado (SFT) adapte o modelo ao domínio-alvo. Isso cria uma base para a aprendizagem de preferências por meio do treinamento em conjuntos de dados padrão que seguem instruções. O modelo aprende a concluir tarefas básicas enquanto mantém suas capacidades gerais.

Em seguida, vem o aprendizado de preferências, em que o modelo é treinado em pares de outputs - um preferido e outro não preferido. Os pares de preferências ajudam o modelo a entender quais respostas se alinham melhor com os valores e as expectativas humanas.

A principal inovação do DPO está em sua abordagem de otimização direta. Em vez de treinar um modelo de recompensa separado, o DPO usa uma perda de entropia cruzada binária para atualizar diretamente os pesos do modelo com base nos dados de preferência. Esse processo simplificado torna o treinamento mais estável e eficiente e, ao mesmo tempo, obtém resultados comparáveis ou melhores do que a RLHF tradicional.

## Conjuntos de Dados para DPO

Os conjuntos de dados para DPO são normalmente criados anotando pares de respostas como preferidas ou não preferidas. Isso pode ser feito manualmente ou usando técnicas de filtragem automatizadas. Abaixo está um exemplo de estrutura de conjunto de dados de preferência de turno único para DPO:

| Prompt | Escolhido | Rejeitado |
|--------|-----------|-----------|
| ...    | ...       | ...       |
| ...    | ...       | ...       |
| ...    | ...       | ...       |

A coluna `Prompt` contém o prompt usado para gerar as respostas `Escolhido` e `Rejeitado`. As colunas `Escolhido` e `Rejeitado` contêm as respostas preferidas e não preferidas, respectivamente. Há variações nessa estrutura, por exemplo, incluindo uma coluna de prompt do sistema ou uma coluna `Input` que contém material de referência. Os valores de `Escolhido` e `Rejeitado` podem ser representados como cadeias de caracteres para conversas de turno único ou como listas de conversas. 

Você pode encontrar uma coleção de conjuntos de dados DPO em Hugging Face [aqui](https://huggingface.co/collections/argilla/preference-datasets-for-dpo-656f0ce6a00ad2dc33069478).

## Implementação com TRL

O módulo Transformers Reinforcement Learning (TRL) facilita a implementação do DPO. As classes `DPOConfig` e `DPOTrainer` seguem a mesma API no estilo `transformers`.
Veja a seguir um exemplo básico de configuração de treinamento de DPO:

```python
from trl import DPOConfig, DPOTrainer

# Define arguments
training_args = DPOConfig(
    ...
)

# Initialize trainer
trainer = DPOTrainer(
    model,
    train_dataset=dataset,
    tokenizer=tokenizer,
    ...
)

# Train model
trainer.train()
```

Abordaremos mais detalhes sobre como usar as classes `DPOConfig` e `DPOTrainer` no [Tutotial sobre DPO](../../../notebooks/pt-br/2_preference_alignment/../notebooks/pt-br/2_preference_alignment/dpo_finetuning_example.ipynb). Esse guia prático o orientará na implementação do alinhamento de preferências com seu próprio modelo, desde a preparação dos dados até o treinamento e a avaliação. 

⏭️ Depois de concluir o tutorial, você pode explorar a página do [ORPO](./orpo.md) para conhecer outra técnica de alinhamento de preferências.

<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit2/2.md" />

### Instruction Tuning (Ajuste de Instrução)
https://huggingface.co/learn/smol-course/pt-br/unit1/1.md

# Instruction Tuning (Ajuste de Instrução)

Este módulo o guiará através de modelos de linguagem de ajuste de instrução. O ajuste de instrução envolve a adaptação de modelos pré-treinados a tarefas específicas, treinando-os ainda mais em conjuntos de dados específicos de tarefas. Esse processo ajuda os modelos a melhorar seu desempenho em certas tarefas específicas.

Neste módulo, exploraremos dois tópicos: 1) Modelos de bate-papo e 2) Ajuste fino supervisionado.

## 1️⃣ Modelos de Bate-Papo

Modelos de bate-papo estruturam interações entre usuários e modelos de IA, garantindo respostas consistentes e contextualmente apropriadas. Eles incluem componentes como avisos de sistema e mensagens baseadas em funções. Para informações mais detalhadas, Consulte a seção [Chat Templates (Modelos de Bate-Papo)](./chat_templates.md).

## 2️⃣ Ajuste Fino Supervisionado

Ajuste fino supervisionado (em inglês, SFT - Supervised Fine-Tuning) é um processo crítico para adaptar modelos de linguagem pré-treinados a tarefas específicas. O ajuste envolve treinar o modelo em um conjunto de dados de uma tarefa específica com exemplos rotulados. Para um guia detalhado sobre SFT, incluindo etapas importantes e práticas recomendadas, veja a página [Supervised Fine-Tuning (Ajuste Fino Supervisionado)](./supervised_fine_tuning.md).

## Referências

- [Documentação dos transformadores em modelos de bate-papo](https://huggingface.co/docs/transformers/main/en/chat_templating)
- [Script para ajuste fino supervisionado em TRL](https://github.com/huggingface/trl/blob/main/examples/scripts/sft.py)
- [`SFTTrainer` em TRL](https://huggingface.co/docs/trl/main/en/sft_trainer)
- [Artigo de otimização de preferência direta](https://arxiv.org/abs/2305.18290)
- [Ajuste fino supervisionado com TRL](https://huggingface.co/docs/trl/main/en/tutorials/supervised_finetuning)
- [Como ajustar o Google Gemma com ChatML e Hugging Face TRL](https://www.philschmid.de/fine-tune-google-gemma)
- [Fazendo o ajuste fino em uma LLM para gerar catálogos de produtos persas em formato JSON](https://huggingface.co/learn/cookbook/en/fine_tuning_llm_to_generate_persian_product_catalogs_in_json_format)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit1/1.md" />

### Ajuste Fino Supervisionado
https://huggingface.co/learn/smol-course/pt-br/unit1/3.md

# Ajuste Fino Supervisionado

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/1_instruction_tuning/sft_finetuning_example.ipynb"},
]} />

Ajuste fino supervisionado (em inglês, SFT - Supervised Fine-Tuning) é um processo crítico para adaptar modelos de linguagem pré-treinados a tarefas ou domínios específicos. Embora os modelos pré-treinados tenham recursos gerais impressionantes, eles geralmente precisam ser personalizados para se destacar em casos de usos específicos. O SFT preenche essa lacuna treinando ainda mais o modelo com conjuntos de dados cuidadosamente selecionados com exemplos validados por humanos.

## Entendendo o Ajuste Fino Supervisionado

Na sua essência, o ajuste fino supervisionado é sobre ensinar um modelo pré-treinado a executar tarefas específicas por meio de exemplos de tokens rotulados. O processo envolve mostrar muitos exemplos do comportamento desejado de input-output ao modelo, permitindo que ele aprenda os padrões específicos do seu caso de uso.

O SFT é eficaz porque usa o conhecimento fundamental adquirido durante o pré-treinamento, adaptando o comportamento do modelo para atender às suas necessidades específicas.

## Quando Usar o Ajuste Fino Supervisionado

A decisão de usar o SFT geralmente se resume à lacuna entre os recursos atuais do seu modelo e seus requisitos específicos. O SFT se torna particularmente valioso quando você precisa de controle preciso sobre os outputs do modelo ou ao trabalhar em domínios especializados.

Por exemplo, se você estiver desenvolvendo um aplicativo de atendimento ao cliente, você vai querer que seu modelo siga constantemente as diretrizes da empresa e lide com consultas técnicas de maneira padronizada. Da mesma forma, em aplicações médicas ou legais, a precisão e a adesão à terminologia específica do domínio se tornam cruciais. Nesses casos, o SFT pode ajudar a alinhar as respostas do modelo com padrões profissionais e experiência no campo de trabalho.

## O Processo de Ajuste Fino

O processo de ajuste fino supervisionado envolve o treinamento dos pesos do modelo em um conjunto de dados de tarefa específico. 

Primeiro, você precisará preparar ou selecionar um conjunto de dados que represente sua tarefa. Esse conjunto de dados deve incluir diversos exemplos que cobrem a gama de cenários que seu modelo encontrará. A qualidade desses dados é importante - cada exemplo deve demonstrar o tipo de output que você deseja que seu modelo produza. Em seguida, vem a fase real de ajuste fino, onde você usará estruturas como os módulos do Hugging Face, `transformers` e `trl`, para treinar o modelo no seu conjunto de dados. 

Ao longo do processo, a avaliação contínua é essencial. Você vai querer monitorar o desempenho do modelo em um conjunto de validação para garantir que ele esteja aprendendo os comportamentos desejados sem perder suas capacidades gerais. No [Módulo 4](../4_evaluation), abordaremos como avaliar seu modelo.

## O Papel do SFT no Alinhamento de Preferência

O SFT desempenha um papel fundamental no alinhamento de modelos de linguagem com preferências humanas. Técnicas como o aprendizado de reforço com o feedback humano (RLHF - Reinforcement Learning with Human Feedback) e a otimização de preferência direta (DPO - Direct Preference Optimization) dependem do SFT para formar um nível básico de entendimento da tarefa antes de alinhar ainda mais as respostas do modelo com os resultados desejados. Modelos pré-treinados, apesar de sua proficiência em linguagem geral, nem sempre podem gerar resultados que correspondam às preferências humanas. O SFT preenche essa lacuna introduzindo dados e orientações específicos de domínio, o que melhora a capacidade do modelo de gerar respostas que se alinham mais de perto com as expectativas humanas.

## Ajuste Fino Supervisionado com Aprendizado de Reforço de Transformadores

Um pacote de software importante para ajuste fino supervisionado é o aprendizado de reforço de transformadores (TRL - Transformer Reinforcement Learning). TRL é um kit de ferramentas usado para treinar modelos de linguagem de transformação usando o aprendizado de reforço.

Construído em cima do módulo de transformadores do Hugging Face, o TRL permite que os usuários carreguem diretamente modelos de linguagem pré-treinados e suporta a maioria das arquiteturas decodificadoras e codificador-decodificador. O módulo facilita os principais processos de RL usados ​​na modelagem de linguagem, incluindo ajuste fino supervisionado (SFT), modelagem de recompensa (RM - Reward Modeling), otimização de políticas proximais (PPO - Proximal Policy Optimization) e otimização de preferência direta (DPO). Usaremos o TRL em vários módulos ao longo deste repositório.

# Próximos passos

Experimente os seguintes tutoriais para obter experiência com o SFT usando TRL:

⏭️ [Tutorial de modelos de bate-papo](../../../notebooks/pt-br/1_instruction_tuning/../notebooks/pt-br/1_instruction_tuning/sft_finetuning_example.ipynb)

<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit1/3.md" />

### Modelos de bate-papo
https://huggingface.co/learn/smol-course/pt-br/unit1/2.md

# Modelos de bate-papo

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/1_instruction_tuning/chat_templates_example.ipynb"}
  ]} />

Os modelos de bate-papo são essenciais para estruturar interações entre modelos de linguagem e usuários. Eles fornecem um formato consistente para conversas, garantindo que os modelos entendam o contexto e o papel de cada mensagem, enquanto mantêm os padrões de resposta apropriados.

## Modelos Base vs Modelos de Instrução

Um modelo base é treinado em dados de texto bruto para prever o próximo token, enquanto um modelo de instrução é ajustado especificamente para seguir as instruções e se envolver em conversas. Por exemplo, `SmolLM2-135M` é um modelo base, enquanto o `SmolLM2-135M-Instruct` é sua variante ajustada por instrução.

Para fazer um modelo base se comportar como um modelo de instrução, precisamos formatar nossos prompts de uma maneira consistente que o modelo possa entender. É aqui que entram os modelos de bate-papo. ChatML é um desses formatos de modelo que estrutura conversas com indicadores claros de papéis (sistema, usuário, assistente).

É importante notar que o modelo base pode ser ajustado finamente em diferentes modelos de bate-papo, então, quando estamos usando um modelo de instrução, precisamos garantir que estamos usando o modelo de bate-papo correto.

## Entendendo os Modelos de Bate-papo

Na sua essência, os modelos de bate-papo definem como as conversas devem ser formatadas ao se comunicar com um modelo de linguagem. Eles incluem instruções no nível do sistema, mensagens do usuário e respostas assistentes em um formato estruturado que o modelo pode entender. Essa estrutura ajuda a manter a consistência entre as interações e garante que o modelo responda adequadamente a diferentes tipos de input de dados. Abaixo está um exemplo de modelo de bate-papo:

```sh
<|im_start|>user
Hi there!<|im_end|>
<|im_start|>assistant
Nice to meet you!<|im_end|>
<|im_start|>user
Can I ask a question?<|im_end|>
<|im_start|>assistant
```

O módulo `transformers` cuidará dos modelos de bate-papo para você em relação ao tokenizador do modelo. Leia mais sobre como os transformadores criam modelos de bate-papo [aqui](https://huggingface.co/docs/transformers/en/chat_templating#how-do-i-use-chat-templates). Tudo o que precisamos fazer é estruturar nossas mensagens da maneira correta e o tokenizador cuidará do resto. Abaixo, você verá um exemplo básico de uma conversa:

```python
messages = [
    {"role": "system", "content": "You are a helpful assistant focused on technical topics."},
    {"role": "user", "content": "Can you explain what a chat template is?"},
    {"role": "assistant", "content": "A chat template structures conversations between users and AI models..."}
]
```

Vamos ir passo-a-passo no exemplo acima e ver como ele mapeia o formato do modelo de bate-papo.

## Mensagens do Sistema

As mensagens do sistema definem a base de como o modelo deve se comportar. Elas agem como instruções persistentes que influenciam todas as interações subsequentes. Por exemplo:

```python
system_message = {
    "role": "system",
    "content": "You are a professional customer service agent. Always be polite, clear, and helpful."
}
```

## Conversas

Os modelos de bate-papo mantêm o contexto através do histórico de conversas, armazenando conversas anteriores entre os usuários e o assistente. Isso permite que as conversas de multi-turno sejam mais coerentes:

```python
conversation = [
    {"role": "user", "content": "I need help with my order"},
    {"role": "assistant", "content": "I'd be happy to help. Could you provide your order number?"},
    {"role": "user", "content": "It's ORDER-123"},
]
```

## Implementação com Transformadores

O módulo transformers fornece suporte interno para modelos de bate-papo. Veja como usá-los:

```python
from transformers import AutoTokenizer

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

messages = [
    {"role": "system", "content": "You are a helpful coding assistant."},
    {"role": "user", "content": "Write a Python function to sort a list"},
]

# Apply the chat template
formatted_chat = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
```

## Formatação Personalizada

Você pode personalizar como tipos diferentes de mensagens são formatadas. Por exemplo, adicionando tokens especiais ou formatando para diferentes funções:

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

## Suporte do Multi-turno

Os modelos podem lidar com conversas multi-turno complexas enquanto mantêm o contexto:

```python
messages = [
    {"role": "system", "content": "You are a math tutor."},
    {"role": "user", "content": "What is calculus?"},
    {"role": "assistant", "content": "Calculus is a branch of mathematics..."},
    {"role": "user", "content": "Can you give me an example?"},
]
```

⏭️ [Próxima: Supervised Fine-Tuning (Ajuste Fino Supervisionado)](./supervised_fine_tuning.md)

## Resources

- [Guia de modelos de bate-papo - Hugging Face](https://huggingface.co/docs/transformers/main/en/chat_templating)
- [Documentação do módulo Transformers](https://huggingface.co/docs/transformers)
- [Repositório de exemplos de modelos de bate-papo](https://github.com/chujiezheng/chat_templates) 


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit1/2.md" />

### Parameter-Efficient Fine-Tuning (PEFT) (Ajuste Fino com Eficiência de Parâmetro)
https://huggingface.co/learn/smol-course/pt-br/unit3/1.md

# Parameter-Efficient Fine-Tuning (PEFT) (Ajuste Fino com Eficiência de Parâmetro)

À medida que os modelos de linguagem aumentam, o ajuste fino tradicional torna-se cada vez mais desafiador. O ajuste fino completo de um modelo com 1,7 bilhão de parâmetros requer uma quantidade considerável de memória da GPU, torna caro o armazenamento de cópias separadas do modelo e apresenta o risco de um esquecimento catastrófico das capacidades originais do modelo. Os métodos de ajuste fino com eficiência de parâmetros (PEFT) abordam esses desafios modificando apenas um pequeno subconjunto de parâmetros do modelo e mantendo a maior parte do modelo congelada.

O ajuste fino tradicional atualiza todos os parâmetros do modelo durante o treinamento, o que se torna impraticável para modelos grandes. Os métodos PEFT introduzem abordagens para adaptar modelos usando menos parâmetros treináveis, geralmente menos de 1% do tamanho do modelo original. Essa redução drástica nos parâmetros treináveis permite:

- Ajuste fino no hardware do consumidor com memória de GPU limitada
- Armazenamento eficiente de várias adaptações de tarefas específicas
- Melhor generalização em cenários com poucos dados
- Ciclos de treinamento e iteração mais rápidos

## Métodos Disponíveis

Neste módulo, abordaremos dois métodos populares de PEFT:

### 1️⃣ LoRA (Low-Rank Adaptation - Adaptação de Baixa Classificação)

O LoRA surgiu como o método PEFT mais amplamente adotado, oferecendo uma solução elegante para a adaptação eficiente do modelo. Em vez de modificar o modelo inteiro, o **LoRA injeta matrizes treináveis nas camadas de atenção do modelo.**  Essa abordagem normalmente reduz os parâmetros treináveis em cerca de 90%, mantendo um desempenho comparável ao ajuste fino completo. Exploraremos o LoRA na seção [LoRA (Adaptação de Baixa Classificação)](./lora_adapters.md).
 
### 2️⃣ Ajuste de Prompts

O ajuste de prompts oferece uma abordagem **ainda mais leve** ao **adicionar tokens treináveis à entrada** em vez de modificar os pesos do modelo. O ajuste de prompt é menos popular que o LoRA, mas pode ser uma técnica útil para adaptar rapidamente um modelo a novas tarefas ou domínios. Exploraremos o ajuste de prompt na seção [Ajuste de Prompt](./prompt_tuning.md).

## Referências

- [Documentação PEFT](https://huggingface.co/docs/peft)
- [Artigo sobre LoRA](https://arxiv.org/abs/2106.09685)
- [Artigo sobre QLoRA](https://arxiv.org/abs/2305.14314)
- [Artigo sobre Ajuste de Prompts](https://arxiv.org/abs/2104.08691)
- [Guia PEFT do Hugging Face](https://huggingface.co/blog/peft)
- [Como ajustar os LLMs em 2024 com o Hugging Face](https://www.philschmid.de/fine-tune-llms-in-2024-with-trl) 
- [TRL](https://huggingface.co/docs/trl/index)

<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit3/1.md" />

### Ajuste de Prompts
https://huggingface.co/learn/smol-course/pt-br/unit3/3.md

# Ajuste de Prompts

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/3_parameter_efficient_finetuning/finetune_sft_peft.ipynb"},
]} />
  
O ajuste de prompts (prompt tuning) é uma abordagem eficiente em termos de parâmetros que modifica as representações de entrada em vez dos pesos do modelo. Diferente do ajuste fino tradicional, que atualiza todos os parâmetros do modelo, o ajuste de prompts adiciona e otimiza um pequeno conjunto de tokens treináveis, mantendo o modelo base congelado.

## Entendendo o Ajuste de Prompts

O ajuste de prompts é uma alternativa eficiente ao ajuste fino de modelos que adiciona vetores contínuos treináveis (soft prompts) ao texto de entrada. Diferente dos prompts de texto discretos, esses soft prompts são aprendidos através de retropropagação enquanto o modelo de linguagem permanece congelado. O método foi introduzido em ["The Power of Scale for Parameter-Efficient Prompt Tuning"](https://arxiv.org/abs/2104.08691) (Lester et al., 2021), que demonstrou que o ajuste de prompts se torna mais competitivo em relação ao ajuste fino conforme o tamanho do modelo aumenta. No artigo, em torno de 10 bilhões de parâmetros, o ajuste de prompts iguala o desempenho do ajuste fino, modificando apenas algumas centenas de parâmetros por tarefa.

Esses soft prompts são vetores contínuos no espaço de embedding do modelo que são otimizados durante o treinamento. Diferente dos prompts discretos tradicionais que usam tokens de linguagem natural, os soft prompts não possuem significado inerente, mas aprendem a evocar o comportamento desejado do modelo congelado por meio de gradiente descendente. A técnica é particularmente eficaz em cenários multitarefa, pois cada tarefa exige apenas o armazenamento de um pequeno vetor de prompt (normalmente algumas centenas de parâmetros) em vez de uma cópia completa do modelo. Essa abordagem não apenas mantém um uso mínimo de memória, mas também possibilita a troca rápida de tarefas apenas trocando os vetores de prompt sem precisar recarregar o modelo.

## Processo de Treinamento

Os soft prompts geralmente têm entre 8 e 32 tokens e podem ser inicializados aleatoriamente ou a partir de texto existente. O método de inicialização desempenha um papel crucial no processo de treinamento, com inicializações baseadas em texto frequentemente apresentando melhor desempenho do que inicializações aleatórias.

Durante o treinamento, apenas os parâmetros do prompt são atualizados, enquanto o modelo base permanece congelado. Essa abordagem focada utiliza objetivos de treinamento padrão, mas exige atenção cuidadosa à taxa de aprendizado e ao comportamento do gradiente dos tokens do prompt.

## Implementação com PEFT

O módulo PEFT facilita a implementação do ajuste de prompts. Aqui está um exemplo básico:

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

# Load base model
model = AutoModelForCausalLM.from_pretrained("your-base-model")
tokenizer = AutoTokenizer.from_pretrained("your-base-model")

# Configure prompt tuning
peft_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM,
    num_virtual_tokens=8,  # Number of trainable tokens
    prompt_tuning_init="TEXT",  # Initialize from text
    prompt_tuning_init_text="Classify if this text is positive or negative:",
    tokenizer_name_or_path="your-base-model",
)

# Create prompt-tunable model
model = get_peft_model(model, peft_config)
```

## Comparação com Outros Métodos

Quando comparado a outras abordagens PEFT, o ajuste de prompts se destaca por sua eficiência. Enquanto o LoRA oferece baixo uso de parâmetros e memória, mas exige o carregamento de adaptadores para troca de tarefas, o ajuste de prompts atinge um uso de recursos ainda menor e possibilita a troca imediata de tarefas. O ajuste fino completo, em contraste, demanda recursos significativos e requer cópias separadas do modelo para diferentes tarefas.

| Método | Parâmetros | Memória | Troca de Tarefas |
|--------|------------|---------|----------------|
| Ajuste de Prompts| Muito Baixo | Mínima | Fácil |
| LoRA | Baixo | Baixa | Requer Carregamento |
| Ajuste Fino | Alto | Alta | Nova Cópia do Modelo |

Ao implementar o ajuste de prompts, comece com um pequeno número de tokens virtuais (8-16) e aumente apenas se a complexidade da tarefa exigir. A inicialização baseada em texto geralmente apresenta melhores resultados do que a inicialização aleatória, especialmente ao usar texto relevante para a tarefa. A estratégia de inicialização deve refletir a complexidade da tarefa alvo.

O treinamento requer considerações ligeiramente diferentes do ajuste fino completo. Taxas de aprendizado mais altas geralmente funcionam bem, mas o monitoramento cuidadoso dos gradientes dos tokens do prompt é essencial. A validação regular com exemplos diversos ajuda a garantir um desempenho robusto em diferentes cenários.

## Aplicação

O ajuste de prompts se destaca em diversos cenários:

1. Implantação multitarefa
2. Ambientes com restrição de recursos
3. Adaptação rápida a tarefas
4. Aplicações sensíveis à privacidade

Conforme os modelos ficam menores, o ajuste de prompts se torna menos competitivo em comparação ao ajuste fino completo. Por exemplo, em modelos como SmolLM2, o ajuste de prompts é menos relevante do que o ajuste fino completo. 

## Próximos Passos

⏭️ Prossiga para o [Tutorial de Adaptadores LoRA](../../../notebooks/pt-br/3_parameter_efficient_finetuning/finetune_sft_peft.ipynb) para aprender como ajustar um modelo com adaptadores LoRA.

## Referências
- [Documentação PEFT](https://huggingface.co/docs/peft)
- [Artigo sobre Ajuste de Prompts](https://arxiv.org/abs/2104.08691)
- [Cookbook do Hugging Face](https://huggingface.co/learn/cookbook/prompt_tuning_peft)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit3/3.md" />

### LoRA (Low-Rank Adaptation - Adaptação de Baixa Classificação)
https://huggingface.co/learn/smol-course/pt-br/unit3/2.md

# LoRA (Low-Rank Adaptation - Adaptação de Baixa Classificação)

<CourseFloatingBanner chapter={10}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/smol-course/blob/main/notebooks/pt-br/3_parameter_efficient_finetuning/finetune_sft_peft.ipynb"},
]} />

LoRA tornou-se o método PEFT mais amplamente adotado. Ele funciona adicionando pequenas matrizes de decomposição de classificação aos pesos de atenção, reduzindo tipicamente os parâmetros treináveis em cerca de 90%.

## Entendendo o LoRA

LoRA (Adaptação de Baixa Classificação) é uma técnica de ajuste fino eficiente em termos de parâmetros que congela os pesos do modelo pré-treinado e injeta matrizes treináveis de decomposição de classificação nas camadas do modelo. Em vez de treinar todos os parâmetros do modelo durante o ajuste fino, o LoRA decompõe as atualizações de peso em matrizes menores por meio da decomposição de baixa classificação, reduzindo significativamente o número de parâmetros treináveis enquanto mantém o desempenho do modelo. Por exemplo, quando aplicado ao GPT-3 175B, o LoRA reduziu os parâmetros treináveis em 10.000x e os requisitos de memória GPU em 3x em comparação ao ajuste fino completo. Você pode saber mais sobre o LoRA no [Artigo sobre LoRA](https://arxiv.org/pdf/2106.09685).

O LoRA funciona adicionando pares de matrizes de decomposição de classificação às camadas do transformer, geralmente focando nos pesos de atenção. Durante a inferência, esses pesos adaptadores podem ser mesclados com o modelo base, resultando em nenhuma sobrecarga adicional de latência. LoRA é particularmente útil para adaptar modelos de linguagem de grande porte a tarefas ou domínios específicos, mantendo os requisitos de recursos gerenciáveis.

## Carregando Adaptadores LoRA

Os adaptadores podem ser carregados em um modelo pré-treinado com load_adapter(), o que é útil para experimentar diferentes adaptadores cujos pesos não estão mesclados. Defina os pesos do adaptador ativo com a função set_adapter(). Para retornar ao modelo base, você pode usar unload() para descarregar todos os módulos LoRA. Isso facilita a alternância entre pesos específicos de tarefas.

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

## Mesclando Adaptadores LoRA

Após o treinamento com LoRA, você pode querer mesclar os pesos do adaptador de volta ao modelo base para facilitar a implantação. Isso cria um único modelo com os pesos combinados, eliminando a necessidade de carregar adaptadores separadamente durante a inferência.

processo de mesclagem requer atenção ao gerenciamento de memória e precisão. Como será necessário carregar o modelo base e os pesos do adaptador simultaneamente, garanta memória suficiente na GPU/CPU. Usar `device_map="auto"` no `transformers` ajudará no gerenciamento automático de memória. Mantenha uma precisão consistente (por exemplo, float16) durante todo o processo, correspondendo à precisão usada durante o treinamento e salvando o modelo mesclado no mesmo formato para implantação. Antes de implantar, sempre valide o modelo mesclado comparando suas saídas e métricas de desempenho com a versão baseada em adaptadores.

Os adaptadores também são convenientes para alternar entre diferentes tarefas ou domínios. Você pode carregar o modelo base e os pesos do adaptador separadamente, permitindo alternâncias rápidas entre pesos específicos de tarefas. 

## Guia de Implementação

O diretório `notebooks/` contém tutoriais práticos e exercícios para implementar diferentes métodos PEFT. Comece com `load_lora_adapter_example.ipynb` para uma introdução básica e depois veja `lora_finetuning.ipynb` para um estudo mais detalhado sobre como ajustar um modelo com LoRA e SFT.

Ao implementar métodos PEFT, comece com valores baixos de classificação (4-8) para LoRA e monitore a perda de treinamento. Use conjuntos de validação para evitar overfitting e compare os resultados com as linhas de base de ajuste fino completo sempre que possível. A eficácia de diferentes métodos pode variar conforme a tarefa, então a experimentação é essencial.

## OLoRA

[OLoRA](https://arxiv.org/abs/2406.01775) utiliza decomposição QR para inicializar os adaptadores LoRA. OLoRA traduz os pesos base do modelo por um fator de suas decomposições QR, ou seja, altera os pesos antes de realizar qualquer treinamento sobre eles. Essa abordagem melhora significativamente a estabilidade, acelera a velocidade de convergência e, por fim, alcança um desempenho superior.

## Usando TRL com PEFT

Os métodos PEFT podem ser combinados com TRL (Reinforcement Learning com Transformers) para ajuste fino eficiente. Essa integração é particularmente útil para RLHF (Reinforcement Learning from Human Feedback), pois reduz os requisitos de memória.

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

# Load model with PEFT config
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

# Load model on specific device
model = AutoModelForCausalLM.from_pretrained(
    "your-model-name",
    load_in_8bit=True,  # Optional: use 8-bit precision
    device_map="auto",
    peft_config=lora_config
)
```

No exemplo acima, usamos `device_map="auto"` para atribuir automaticamente o modelo ao dispositivo correto. Você também pode atribuir manualmente o modelo a um dispositivo específico usando `device_map={"": device_index}`. Também é possível escalar o treinamento em várias GPUs enquanto mantém o uso de memória eficiente.

## Implementação Básica de Mesclagem

Após treinar um adaptador LoRA, você pode mesclar os pesos do adaptador de volta ao modelo base. Veja como fazer isso:

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

# 1. Load the base model
base_model = AutoModelForCausalLM.from_pretrained(
    "base_model_name",
    dtype=torch.float16,
    device_map="auto"
)

# 2. Load the PEFT model with adapter
peft_model = PeftModel.from_pretrained(
    base_model,
    "path/to/adapter",
    dtype=torch.float16
)

# 3. Merge adapter weights with base model
try:
    merged_model = peft_model.merge_and_unload()
except RuntimeError as e:
    print(f"Merging failed: {e}")
    # Implement fallback strategy or memory optimization

# 4. Save the merged model
merged_model.save_pretrained("path/to/save/merged_model")
```

Se você encontrar discrepâncias de tamanho no modelo salvo, garanta que está salvando também o tokenizador:

```python
# Save both model and 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 Passos

⏩ Prossiga para o guia de [Ajuste de Prompts](prompt_tuning.md) para aprender como ajustar um modelo com ajuste de prompts.
⏩ Veja o [Tutorial de Carregamento de Adaptadores LoRA](../../../notebooks/pt-br/3_parameter_efficient_finetuning/load_lora_adapter.ipynb) para aprender como carregar adaptadores LoRA.

# Referências

- [LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS](https://arxiv.org/pdf/2106.09685)
- [Documentação PEFT](https://huggingface.co/docs/peft)
- [Blog do Hugging Face sobre PEFT](https://huggingface.co/blog/peft)


<EditOnGithub source="https://github.com/huggingface/smol-course/blob/main/units/pt-br/unit3/2.md" />
