# PEANuT: Adaptação Eficiente de Parâmetros com Ajustadores Neurais Conscientes de Pesos

[PEANuT](https://arxiv.org/abs/2410.01870) é uma técnica de ajuste fino eficiente em parâmetros que introduz tweakers neurais conscientes de pesos para gerar atualizações de adaptadores a partir dos próprios pesos pré-treinados congelados. Em vez de aprender uma atualização linear de baixo posto puramente, como no LoRA, o PEANuT condiciona a transformação do adaptador no peso base, o que torna a regra de atualização mais expressiva, mantendo o número de parâmetros treináveis pequeno.

PEANuT usa uma projeção de entrada `A`, uma projeção de saída `B` e pares opcionais de codificador/decodificador residuais intermediários com ativações não lineares. Isso permite modelar padrões de atualização mais complexos do que adaptadores lineares agnósticos de peso, mantendo-se ainda assim dentro do contexto de PEFT.

O PEANuT atualmente apresenta as seguintes limitações:

Vantagens:
- Expressividade teórica superior em comparação com atualizações de baixo posto lineares.
- Desempenho melhor que o do LoRA em uma variedade de tarefas sob orçamentos semelhantes.
- Funciona bem em regimes de parâmetros muito baixos, por exemplo, em torno de `0.2M` parâmetros treináveis.

Desvantagens:
- Uso de memória maior que o do LoRA, pois `ΔW` é explicitamente construído antes de ser aplicado.
- Treinamento e inferência mais lentos do que com LoRA, e camadas intermediárias mais profundas aumentam ainda mais a sobrecarga.
- A não linearidade pode exigir um ajuste mais cuidadoso dos hiperparâmetros, especialmente a taxa de aprendizado e as configurações de otimização relacionadas.

Se esses compromissos não se adequarem ao seu caso de uso, considere outros métodos de PEFT, como LoRA.

O resumo do artigo é:

> O ajuste fino de grandes modelos de fundação pré-treinados frequentemente resulta em excelente desempenho em tarefas downstream, mas é proibitivamente caro ao atualizar todos os parâmetros. Métodos de ajuste fino eficiente em parâmetros (PEFT), como LoRA, mitigam isso ao introduzir módulos de atualização leves, mas geralmente dependem de aproximações lineares agnósticas a pesos, limitando sua expressividade. Neste trabalho, propomos o PEANuT, um novo framework de PEFT que introduz tweakers neurais conscientes de pesos, módulos neurais compactos que geram atualizações adaptadas à tarefa condicionadas aos pesos pré-treinados congelados. O PEANuT oferece uma maneira flexível e eficiente de capturar padrões de atualização complexos sem o ajuste completo do modelo. Mostramos teoricamente que o PEANuT alcança expressividade equivalente ou superior à de métodos lineares de PEFT existentes, com parâmetros comparáveis ou menores. Experimentos extensivos em quatro benchmarks com mais de vinte conjuntos de dados demonstram que o PEANuT supera consistentemente baselines fortes em tarefas de NLP e visão, mantendo baixo sobrecarga computacional.

## Visão geral do benchmark

<iframe src="https://peft-internal-testing-peft-method-comparison-embed.hf.space/?highlight[type]=PEANUT" frameborder="0" width="850" height="1000"
>

# API

## PeanutConfig[[peft.PeanutConfig]]

#### peft.PeanutConfig[[peft.PeanutConfig]]

```python
peft.PeanutConfig(task_type: Optional[Union[str, TaskType]] = None, peft_type: Optional[Union[str, PeftType]] = None, auto_mapping: Optional[dict] = None, peft_version: Optional[str] = None, base_model_name_or_path: Optional[str] = None, revision: Optional[str] = None, inference_mode: bool = False, r: int = 32, depth: int = 0, act_fn: str = 'relu', scaling: float = 1.0, target_modules: Optional[Union[list[str], str]] = None, exclude_modules: Optional[Union[list[str], str]] = None, modules_to_save: Optional[list[str]] = None, layers_to_transform: Optional[Union[list[int], int]] = None, layers_pattern: Optional[Union[list[str], str]] = None, init_weights: bool = True)
```

[Fonte](https://github.com/huggingface/peft/blob/main/src/peft/tuners/peanut/config.py#L26)

**Parâmetros:**

r (`int`) : rank do PEANuT. Esta é a dimensão oculta usada pelos adaptadores. Assim como o rank do LoRA, um `r` maior aumenta a capacidade dos adaptadores e o número de parâmetros treináveis.

depth (`int`) : Número de camadas ocultas de adaptador por lado do codificador/decodificador no PEANuT. A projeção de entrada `A` e a projeção de saída `B` estão sempre presentes, além dessas camadas ocultas. Portanto, `depth` deve ser um inteiro não negativo.  - `depth=0`: `A`, `B`. - `depth=1`: `A`, um codificador, um decodificador, `B`. - `depth=2`: `A`, dois codificadores, dois decodificadores, `B`. - `depth=3`: `A`, três codificadores, três decodificadores, `B`, etc.

act_fn (`str`) : Ativação não linear aplicada na rede PEANuT. Isso corresponde a `non_linear` na implementação vanilla do PyTorch. O padrão é `"relu"`. Qualquer chave de ativação disponível em `transformers.activations.ACT2FN` é suportada e pode ter um desempenho melhor em diferentes tarefas.

scaling (`float`) : Um multiplicador escalar aplicado à saída do PEANuT antes de adicioná-la à saída da camada base congelada. A contribuição final do adaptador é `scaling * (x @ delta_w)`.

target_modules (`Union[List[str], str]`, *opcional*) : Os nomes dos módulos aos quais aplicar PEANuT. Pode ser uma lista de strings com nomes de módulos (por exemplo, `['q_proj', 'v_proj']`) ou um padrão de expressão regular.

modules_to_save (`List[str]`, *opcional*) : Lista de módulos, exceto as camadas PEANuT, que devem ser configurados como treináveis e salvos no checkpoint final.

exclude_modules (`Union[List[str], str]`, *opcional*) : Os nomes dos módulos para os quais o adaptador não deve ser aplicado. Ao passar uma string, será realizada uma correspondência por regex. Ao passar uma lista de strings, será realizada uma correspondência exata ou será verificado se o nome do módulo termina com qualquer uma das strings passadas.

layers_to_transform (`Union[list[int], int]`, *opcional*) : Os índices das camadas a serem transformadas. Se este argumento for especificado, o PEFT transformará apenas os índices das camadas especificados nesta lista. Se um único inteiro for passado, o PEFT transformará apenas a camada neste índice.

layers_pattern (`Optional[Union[List[str], str]]`, *opcional*) : O nome do padrão da camada, usado apenas se `layers_to_transform` não for None e se o padrão da camada não estiver no padrão de camadas comuns.

init_weights (`bool`) : Se deve inicializar os pesos do adaptador PEANuT usando o esquema de inicialização padrão:  - Se `True`: todos os pesos, exceto `B`, são inicializados com Kaiming uniform, e `B` é inicializado com zero. - Se `False`: todos os pesos (incluindo `B`) são inicializados com Kaiming uniform.  Inicializar `B` com zero faz com que o adaptador comece como um no-op exato.

Esta é a classe de configuração para armazenar a configuração de um [PeanutModel](/docs/peft/main/pt/package_reference/peanut#peft.PeanutModel).

Observações: o PEANuT utiliza um caminho consciente de pesos, no qual o peso delta é condicionado ao peso base. O adaptador `A` é aplicado sobre a dimensão de saída do peso base, portanto `A` tem a forma `(out_dim -> r)` em vez da forma usual `(in_dim -> r)` usada por métodos semelhantes ao LoRA.

## PeanutModel[[peft.PeanutModel]]

#### peft.PeanutModel[[peft.PeanutModel]]

```python
peft.PeanutModel(model, peft_config: Union[PeftConfig, dict[str, PeftConfig]], adapter_name: str, low_cpu_mem_usage: bool = False, state_dict: Optional[dict[str, torch.Tensor]] = None)
```

[Fonte](https://github.com/huggingface/peft/blob/main/src/peft/tuners/peanut/model.py#L28)

**Parâmetros:**

model (`torch.nn.Module`) : O modelo a ser adaptado.

config ([PeanutConfig](/docs/peft/main/pt/package_reference/peanut#peft.PeanutConfig)) : A configuração do modelo PEANuT.

adapter_name (`str`) : O nome do adaptador, padrão é `"default"`.

**Retorna:** `torch.nn.Module`

O modelo PEFT PEANuT.

Cria um modelo PEANuT a partir de um modelo transformers pré-treinado.

O método é descrito em detalhes em https://arxiv.org/abs/2410.01870.

**Atributos**:
- **model** ([PreTrainedModel](https://huggingface.co/docs/transformers/main/en/main_classes/model#transformers.PreTrainedModel)) -- O modelo a ser adaptado.
- **peft_config** ([PeanutConfig](/docs/peft/main/pt/package_reference/peanut#peft.PeanutConfig)): A configuração do modelo PEANuT.

