PEFT documentation
AdaLoRA
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 é 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 é ajustado de acordo com uma pontuação de importância. é 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
< 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 = 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
< source >( 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 toFalse) — 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:
- model (transformers.PreTrainedModel) — O modelo a ser adaptado.
- peft_config (AdaLoraConfig): A configuração do modelo AdaLora.
Este método não é suportado para AdaLoRA, use LoRA em vez disso.
update_and_allocate
< source >( global_step )
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.