PEFT documentation
PaCA: Adaptação de Conexão Parcial
PaCA: Adaptação de Conexão Parcial
PaCA (ICLR 2025) é um método PEFT que visa a velocidade de treinamento e a memória de ativação. Ele faz o ajuste fino de r colunas de entrada selecionadas aleatoriamente (“conexões parciais”) de cada peso pré-treinado alvo. Os únicos parâmetros treináveis são as atualizações dessas colunas; diferentemente do LoRA, o PaCA não adiciona matrizes de baixo posto extras.
Métodos como LoRA executam um pequeno ramo de baixo posto ao lado de cada camada pré-treinada. O ramo requer poucos FLOPs, mas é executado sequencialmente com a camada pré-treinada e mantém sua própria cópia da ativação de entrada para a passagem reversa. O PaCA evita ambos:
- Um GEMM por camada. As colunas adaptadas são gravadas no peso pré-treinado imediatamente antes do matmul e restauradas imediatamente depois, de modo que o forward e o backward executam cada um um único matmul, exatamente como a camada base congelada.
- Ativações parciais. O gradiente das colunas adaptadas depende apenas dos
rcanais de entrada correspondentes, portanto, apenas esses são salvos para a passagem reversa, em vez da entrada completa.
Em termos dos pesos resultantes, um adaptador PaCA é equivalente a um adaptador LoRA de rank r cuja matriz A é um seletor de colunas fixo: W' = W + delta @ S, em que S seleciona as r colunas. Portanto, ele pode ser convertido em um adaptador LoRA de rank r sem perda por meio de convert_to_lora(), por exemplo, para servi-lo com uma pilha de inferência LoRA.
Quando usar o PaCA:
- Você deseja precisão no nível do LoRA, mas com etapas de fine-tuning mais rápidas e menor memória de ativação, por exemplo, para caber sequências mais longas ou lotes maiores na mesma GPU.
- Você deseja um adaptador que se mescla exatamente nos pesos base (a atualização é uma atualização simples de coluna).
Restrições atuais:
- Somente camadas
nn.Linear(incluindo camadas lineares quantizadas) são suportadas. - O PaCA executa o matmul em si, em vez de chamar o
forwardda camada base, portanto os hooks de forward registrados na camada base não são chamados (um aviso é emitido). Registre os hooks na camada PaCA. - Lotes de adaptadores mistos (argumento
adapter_names) não são suportados. - O treinamento com pesos fragmentados (FSDP, DeepSpeed ZeRO-3) ainda não foi testado.
torch.compileé suportado: durante a compilação, a troca de colunas, o matmul e a restauração são executados como operações personalizadas opacas (torch.ops.peft.paca_linear_forward/_backward), de modo que o compilador não copia os pesos base. Isso requertorch.library.custom_op(PyTorch >= 2.4); caso contrário, a implementação eager é rastreada.paca_alpha / rescala a atualização da coluna e, portanto, atua como um multiplicador da taxa de aprendizado efetiva.- Para inferência, merge o adaptador (
merge_and_unload()); o forward não mesclado ainda troca as colunas a cada chamada.
Uso
from transformers import AutoModelForCausalLM
from peft import PacaConfig, get_peft_model
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-3B")
config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear", random_seed=0)
model = get_peft_model(model, config)
model.print_trainable_parameters()Por padrão, cada camada alvo faz o fine-tuning de r colunas selecionadas aleatoriamente; no artigo, isso teve desempenho equivalente ao de selecionar as colunas pela norma de peso ou pelos gradientes acumulados. Para escolher as colunas você mesmo, por exemplo para tentar outra estratégia de seleção ou para usar um número diferente de colunas por camada, passe paca_indices_pattern. Suas chaves são nomes de camadas ou expressões regulares, como em rank_pattern do LoRA:
config = PacaConfig(
r=16,
paca_alpha=16,
target_modules=["q_proj", "v_proj"],
paca_indices_pattern={"layers.0.self_attn.q_proj": [0, 2, 4, 6], "layers.1.self_attn.v_proj": list(range(32))},
)Camadas que correspondem a uma chave fazem o fine-tuning das colunas dadas, enquanto todas as outras camadas-alvo selecionam r colunas aleatórias. A escala é paca_alpha / r com o r da configuração em cada camada, de modo que paca_alpha significa o mesmo para todas as camadas.
O resumo do artigo é:
Algoritmos de ajuste fino eficiente em parâmetros (PEFT) anteriores reduzem o uso de memória e os custos computacionais do ajuste fino de grandes modelos de redes neurais treinando apenas alguns parâmetros adicionais de adaptador, em vez do modelo inteiro. No entanto, a redução nos custos computacionais devido ao PEFT não se traduz necessariamente em uma redução no tempo de treinamento; embora os custos computacionais das camadas de adaptador sejam muito menores do que os das camadas pré-treinadas, é bem conhecido que esses dois tipos de camadas são processados sequencialmente em GPUs, resultando em um sobrecarga significativa de latência. LoRA e suas variantes evitam essa sobrecarga de latência mesclando as matrizes de adaptador de baixo rank com os pesos pré-treinados durante a inferência. No entanto, essas camadas não podem ser mescladas durante o treinamento, pois os pesos pré-treinados devem permanecer congelados enquanto as matrizes de adaptador de baixo rank são atualizadas continuamente ao longo do treinamento. Além disso, LoRA e suas variantes não reduzem a memória de ativação, pois a primeira matriz de adaptador de baixo rank ainda requer as ativações de entrada dos pesos pré-treinados para calcular os gradientes dos pesos. Para mitigar esse problema, propomos a Adaptação de Conexão Parcial (PaCA), que ajusta conexões parciais selecionadas aleatoriamente dentro dos pesos pré-treinados, em vez de introduzir camadas de adaptador no modelo. A PaCA não apenas melhora a velocidade de treinamento ao eliminar a sobrecarga de tempo devido ao processamento sequencial das camadas de adaptador e pré-treinadas, mas também reduz a memória de ativação, pois apenas ativações parciais, em vez de ativações completas, precisam ser armazenadas para o cálculo de gradientes. Em comparação com o LoRA, a PaCA reduz o tempo de treinamento em 22% e o uso total de memória em 16%, mantendo precisão comparável em vários cenários de ajuste fino, como ajuste fino no conjunto de dados MMLU e ajuste de instruções no conjunto de dados Oasst1. A PaCA também pode ser combinada com quantização, permitindo o ajuste fino de grandes modelos, como o LLaMA3.1-70B. Além disso, a PaCA permite o treinamento com sequências 23% mais longas e melhora a taxa de transferência em 16% tanto na GPU NVIDIA A100 quanto no HPU INTEL Gaudi2, em comparação com o LoRA.
Visão geral do benchmark
API
PacaConfig
classe peft.PacaConfig
< source >( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falser: int = 8paca_alpha: int = 8target_modules: list[str] | str | None = Noneexclude_modules: list[str] | str | None = Nonelayers_to_transform: list[int] | int | None = Nonelayers_pattern: list[str] | str | None = Nonerandom_seed: int | None = Nonepaca_indices_pattern: dict | None = <factory>init_weights: bool = Truemodules_to_save: list[str] | None = None )
Parâmetros
- r (
int, opcional, padrão8) — Número de colunas de entrada (conexões parciais) que são ajustadas em cada camada alvo. Para um peso de forma(out_features, in_features), o PaCA treinar * out_featuresparâmetros, o mesmo número que a matrizBde um adaptador LoRA com rankr. Não deve excederin_features. - paca_alpha (
int, opcional, padrão8) — Fator de escala. A atualização das colunas selecionadas épaca_alpha / r * delta. Assim comolora_alpha, isso age como um multiplicador da taxa de aprendizado efetiva do adaptador. - target_modules (
Union[list[str], str], opcional) — Lista de nomes de módulos ou expressão regular dos nomes de módulos a serem substituídos por PaCA. Por exemplo,['q_proj', 'v_proj']ou'.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'. Se especificado como'all-linear', todos os módulos lineares, exceto a camada de saída, são selecionados. Apenas camadasnn.Linearsão suportadas. - exclude_modules (
Union[list[str], str], opcional) — Os nomes dos módulos aos quais o adaptador não deve ser aplicado. Ao passar uma string, será realizada uma correspondência por expressão regular. 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 dentro desta 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 de camada, usado apenas selayers_to_transformfor diferente deNone. Isso deve apontar para onn.ModuleListdo modelo, que frequentemente é chamado de'layers'ou'h'. - random_seed (
int, opcional, padrãoNone) — Semente usada para selecionar as conexões parciais. Cada camada usa uma seleção diferente derivada desta semente e do nome da camada. SeNone, o gerador global de números aleatórios do torch é utilizado. Os índices selecionados são sempre armazenados no checkpoint do adaptador, portanto a semente não é necessária para carregar um adaptador treinado. - paca_indices_pattern (
dict, opcional) — Mapeamento opcional de nomes de camadas ou expressões regulares para os índices das colunas de entrada que são ajustadas nas camadas correspondentes, em vez dercolunas selecionadas aleatoriamente, por exemplo{'^model.layers.0.self_attn.q_proj': [0, 2, 4]}. Isso também permite um número diferente de colunas por camada. Os índices de uma camada devem ser únicos e menores quein_features. A escala épaca_alpha / rcom ordeste config em todas as camadas, independentemente do número de índices fornecidos. Camadas-alvo que não correspondem a nenhuma chave usamrcolunas selecionadas aleatoriamente. - init_weights (
bool, opcional, padrãoTrue) — SeTrue, a atualização das colunas selecionadas é inicializada com zero, ou seja, o modelo adaptado é idêntico ao modelo base na inicialização. Defina comoFalsepara inicializar com valores aleatórios; isso é destinado apenas para testes. - modules_to_save (
list[str], opcional) — Lista de módulos, além das camadas PaCA, que devem ser configurados como treináveis e salvos no checkpoint final. Por exemplo, em tarefas de Classificação de Sequência ou Classificação de Token, a camada finalclassifier/scoreé inicializada aleatoriamente e, portanto, precisa ser treinável e salva.
Esta é a classe de configuração para armazenar a configuração de um PacaModel.
PaCA (Partial Connection Adaptation, https://huggingface.co/papers/2503.01905) faz o fine-tuning de r colunas de entrada selecionadas aleatoriamente (conexões parciais) de cada peso pré-treinado alvo. Os únicos parâmetros treináveis são as atualizações dessas colunas; diferentemente do LoRA, o PaCA não adiciona matrizes de baixo posto extras. Imediatamente antes do matmul, as colunas adaptadas são substituídas no peso pré-treinado e restauradas imediatamente depois, de modo que o forward e o backward executam cada um um único GEMM, e apenas os r canais de entrada selecionados são mantidos na memória para o passo de backward.
PacaModel
classe peft.PacaModel
< source >( modelpeft_config: Union[PeftConfig, dict[str, PeftConfig]]adapter_name: strlow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict[str, torch.Tensor]] = None ) → torch.nn.Module
Parâmetros
- model (PreTrainedModel) — O modelo a ser adaptado.
- config (PacaConfig) — A configuração do modelo PaCA.
- adapter_name (
str) — O nome do adaptador, padrão é"default". - low_cpu_mem_usage (
bool,optional, defaults toFalse) — Cria pesos de adaptador vazios no dispositivo meta. Útil para acelerar o processo de carregamento.
Retorna
torch.nn.Module
O modelo PaCA.
Cria um modelo de Adaptação de Conexão Parcial (PaCA) a partir de um modelo pré-treinado. O método é descrito em https://huggingface.co/papers/2503.01905.
Exemplo:
>>> from transformers import AutoModelForCausalLM
>>> from peft import PacaConfig, get_peft_model
>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear")
>>> model = get_peft_model(base_model, config)Atributos:
- model (PreTrainedModel) — O modelo a ser adaptado.
- peft_config (PacaConfig): A configuração do modelo PaCA.