PEFT documentation

AdaLoRA

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.21.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

AdaLoRA

AdaLoRA (Adaptive LoRA) é um método para otimizar o número de parâmetros treináveis a serem atribuídos a matrizes de pesos e camadas. Diferente do LoRA, que distribui os parâmetros uniformemente entre todos os módulos, o AdaLoRA destina mais parâmetros às matrizes de pesos e camadas mais importantes, enquanto as menos importantes recebem menos. Você pode controlar a rank média desejada ou r das matrizes, bem como os módulos aos quais o AdaLoRA será aplicado, por meio de target_modules. Outros parâmetros importantes a definir são lora_alpha (fator de escala) e modules_to_save (os módulos, além das camadas do AdaLoRA, que devem ser treinados e salvos). Todos esses parâmetros — e mais — estão disponíveis no AdaLoraConfig.

O resumo do artigo é:

Fine-tuning de grandes modelos de linguagem pré-treinados em tarefas downstream tornou-se um paradigma importante em PLN. No entanto, a prática comum é fazer fine-tuning de todos os parâmetros de um modelo pré-treinado, o que se torna proibitivo quando há um grande número de tarefas downstream. Portanto, muitos métodos de fine-tuning foram propostos para aprender atualizações incrementais dos pesos pré-treinados de forma eficiente em parâmetros, por exemplo, incrementos de baixo rank. Esses métodos frequentemente distribuem uniformemente o orçamento de atualizações incrementais entre todas as matrizes de pesos pré-treinadas, ignorando a importância variável de diferentes parâmetros de peso. Como consequência, o desempenho do fine-tuning é subótimo. Para preencher essa lacuna, propomos o AdaLoRA, que aloca adaptativamente o orçamento de parâmetros entre as matrizes de pesos de acordo com sua pontuação de importância. Em particular, o AdaLoRA parametriza as atualizações incrementais na forma de decomposição em valores singulares. Essa abordagem inovadora nos permite podar efetivamente os valores singulares de atualizações não importantes, o que é essencialmente reduzir seu orçamento de parâmetros, mas contornar cálculos intensivos de SVD exato. Realizamos extensos experimentos com vários modelos pré-treinados em processamento de linguagem natural, question answering e geração de linguagem natural para validar a eficácia do AdaLoRA. Os resultados demonstram que o AdaLoRA apresenta melhorias notáveis em relação às baselines, especialmente em configurações de baixo orçamento. Nosso código está publicamente disponível em https://github.com/QingruZhang/AdaLoRA.

O AdaLoRA possui um método update_and_allocate() que deve ser chamado em cada etapa de treinamento para atualizar o orçamento de parâmetros e a máscara; caso contrário, a etapa de adaptação não é executada. Isso exige a criação de um loop de treinamento personalizado ou a subclassificação do Trainer para incorporar esse método. Como exemplo, veja este loop de treinamento personalizado.

O AdaLoRA gerencia o orçamento de parâmetros introduzido pelo LoRA alocando mais parâmetros — em outras palavras, um rank mais alto r - para matrizes de pesos importantes que se adaptam melhor a uma tarefa e eliminando as menos importantes. O rank é controlado por um método semelhante à decomposição em valores singulares (SVD). O ΔW\Delta W é parametrizado com duas matrizes ortogonais e uma matriz diagonal que contém os valores singulares. Este método de parametrização evita a aplicação iterativa da SVD, que é computacionalmente cara. Com base neste método, o rank de ΔW\Delta W é ajustado de acordo com uma pontuação de importância. ΔW\Delta W é dividido em trios e cada trio é pontuado de acordo com sua contribuição para o desempenho do modelo. Trios com pontuações de importância baixas são eliminados e trios com pontuações de importância altas são mantidos para o ajuste fino.

O treinamento com AdaLoRA tem três fases: a fase de inicialização, a fase de alocação de orçamento e a fase final. Na fase inicial, nenhuma alocação de orçamento é aplicada, portanto, os ranks não são alterados. Durante a fase de alocação de orçamento, o processo descrito acima é aplicado e o rank é redistribuído de acordo com um orçamento, com o objetivo de dar mais rank a adaptadores mais importantes e menos a camadas menos importantes. Ao atingir a fase final, a alocação de orçamento termina, os ranks são redistribuídos, mas podemos continuar treinando por um tempo com os ranks redistribuídos para melhorar ainda mais o desempenho.

Contribuições são bem-vindas: Esta seção precisa de esclarecimentos.

Não está claro como a importância é medida. As explicações também são um pouco redundantes e poderiam se beneficiar de uma consolidação. Veja aqui como contribuir.

Visão geral do benchmark

Uso

from peft import AdaLoraConfig, get_peft_model

config = AdaLoraConfig(
    r=8,
    init_r=12,
    tinit=200,
    tfinal=1000,
    deltaT=10,
    target_modules=["query", "value"],
    modules_to_save=["classifier"],
)
model = get_peft_model(model, config)
model.print_healthcheck()

[... training code ...]

model.update_and_allocate(step_idx)

API

AdaLoraConfig

classe peft.AdaLoraConfig

< >

( 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 = 8target_modules: Optional[Union[list[str], str]] = Noneexclude_modules: Optional[Union[list[str], str]] = Nonelora_alpha: int = 8lora_dropout: float = 0.0fan_in_fan_out: bool = Falsebias: Literal['none', 'all', 'lora_only'] = 'none'use_rslora: bool = Falsemodules_to_save: Optional[list[str]] = Noneinit_lora_weights: bool | Literal['gaussian', 'eva', 'olora', 'pissa', 'pissa_niter_[number of iters]', 'corda', 'astra', 'loftq', 'orthogonal', 'mica', 'nora'] = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Nonerank_pattern: dict | None = Nonealpha_pattern: Optional[dict] = <factory>megatron_config: Optional[dict] = Nonemegatron_core: Optional[str] = 'megatron.core'trainable_token_indices: Optional[Union[list[int], dict[str, list[int]]]] = Noneloftq_config: Union[LoftQConfig, dict] = <factory>eva_config: Optional[EvaConfig] = Nonecorda_config: Optional[CordaConfig] = Noneastra_config: Optional[AstraConfig] = Nonelora_ga_config: Optional[LoraGAConfig] = Noneuse_dora: bool = Falsevelora_config: Optional[Union[VeloraConfig, dict]] = Nonealora_invocation_tokens: Optional[list[int]] = Noneuse_qalora: bool = Falseqalora_group_size: int = 16monteclora_config: Optional[MontecloraConfig] = Nonelayer_replication: Optional[list[tuple[int, int]]] = Noneruntime_config: LoraRuntimeConfig = <factory>lora_bias: bool = Falsetarget_parameters: Optional[list[str]] = Noneuse_bdlora: Optional[BdLoraConfig] = Nonearrow_config: Optional[ArrowConfig] = Nonekasa_config: Optional[KasaConfig] = Noneensure_weight_tying: bool = Falsetarget_r: int = 8init_r: int = 12tinit: int = 0tfinal: int = 0deltaT: int = 1beta1: float = 0.85beta2: float = 0.85orth_reg_weight: float = 0.5total_step: int | None = None )

Parâmetros

  • target_r (int) — O rank médio alvo da matriz incremental.
  • init_r (int) — O rank inicial para cada matriz incremental.
  • tinit (int) — Os passos de aquecimento do ajuste fino inicial.
  • tfinal (int) — O número de etapas do ajuste fino final.
  • deltaT (int) — O intervalo de tempo entre duas alocações de orçamento.
  • beta1 (float) — O hiperparâmetro do EMA para suavização de sensibilidade.
  • beta2 (float) — O hiperparâmetro do EMA para quantificação de incerteza.
  • orth_reg_weight (float) — O coeficiente da regularização ortogonal.
  • total_step (int) — O total de etapas de treinamento que deve ser especificado antes do treinamento.
  • rank_pattern (list) — O rank alocado para cada matriz de pesos pelo RankAllocator.

Esta é a classe de configuração para armazenar a configuração de um AdaLoraModel.

AdaLoRA tem três fases definidas por tinit, tfinal e total_step.

A fase inicial pode ser entendida como uma etapa para o pré-treinamento dos adaptadores, de modo que, ao reduzir seu rank, já haja alguma informação codificada que possa ser reduzida, em vez de matrizes aleatórias. Essa fase é definida ao fornecer tinit.

Após o término da fase inicial (tinit passos foram concluídos) e antes do início da fase final, o AdaLoRA reduz o orçamento de quanto rank cada camada pode ter a cada passo. É aqui que a redução de rank ocorre. Isso continua até que total_step - tfinal passos sejam atingidos.

A última fase, que começa quando total_step - tfinal passos são atingidos, não altera mais os ranks das camadas, mas faz o fine-tuning das camadas de rank reduzido resultantes da fase anterior.

Um exemplo prático: tinit é 10, tfinal é 20 e total_step é 100. Gastamos 10 passos fazendo pré-treino sem redução de rank porque nosso orçamento é constante (fase de inicialização), depois gastamos 80 (100-20) passos na fase de redução, onde nosso orçamento diminui passo a passo e, por fim, 20 passos na etapa final de ajuste fino sem redução.

AdaLoraModel

classe peft.AdaLoraModel

< >

( modelconfigadapter_name**kwargs ) → torch.nn.Module

Parâmetros

  • model (transformers.PreTrainedModel) — O modelo a ser adaptado.
  • config (AdaLoraConfig) — A configuração do modelo AdaLora.
  • adapter_name (str) — O nome do adaptador, padrão é "default".
  • low_cpu_mem_usage (bool, optional, defaults to False) — Cria pesos de adaptador vazios no dispositivo meta. Útil para acelerar o processo de carregamento.

Retorna

torch.nn.Module

O modelo AdaLora.

Cria um modelo AdaLoRA (LoRA Adaptativo) a partir de um modelo transformers pré-treinado. Artigo: https://openreview.net/forum?id=lq62uWRJjiY

Exemplo:

>>> from transformers import AutoModelForSeq2SeqLM
>>> from peft import AdaLoraConfig, get_peft_model

>>> config = AdaLoraConfig(
...     peft_type="ADALORA",
...     task_type="SEQ_2_SEQ_LM",
...     init_r=12,
...     lora_alpha=32,
...     target_modules=["q", "v"],
...     lora_dropout=0.01,
...     total_step=1000,
... )
>>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
>>> adalora_model = get_peft_model(model, config)

Atributos:

add_weighted_adapter

< >

( *args**kwargs )

Este método não é suportado para AdaLoRA, use LoRA em vez disso.

update_and_allocate

< >

( global_step )

Parâmetros

  • global_step (int) — O passo de treinamento atual, usado para calcular o orçamento do adalora.

Este método atualiza o orçamento e a máscara do Adalora.

Isso deve ser chamado em cada etapa de treinamento, após loss.backward() e antes de zero_grad().

tinit, tfinal e deltaT são tratados dentro do método.

Exemplo:

>>> loss = model(**input).loss
>>> loss.backward()
>>> optimizer.step()
>>> model.base_model.update_and_allocate(i_step)
>>> optimizer.zero_grad()
Update on GitHub