PEFT documentation
Adaptação de Baixo Rango com Decomposição de Peso (DoRA)
Adaptação de Baixo Rango com Decomposição de Peso (DoRA)
Esta é uma variante do LoRA e, portanto, tudo o que é possível com o LoRA é válido para este método, exceto quando indicado o contrário nesta página.
Essa técnica decompõe as atualizações dos pesos em duas partes, magnitude e direção. A direção é tratada pelo LoRA normal, enquanto a magnitude é tratada por um parâmetro aprendível separado. Isso pode melhorar o desempenho do LoRA, especialmente em ranks baixos. Para mais informações sobre DoRA, veja https://huggingface.co/papers/2402.09353.
from peft import LoraConfig
config = LoraConfig(use_dora=True, ...)Se partes do modelo ou do adaptador DoRA forem descarregadas para a CPU, você pode obter um aumento significativo de velocidade, com o custo de uma sobrecarga temporária (efêmera) de VRAM, usando ephemeral_gpu_offload=True em config.runtime_config.
from peft import LoraConfig, LoraRuntimeConfig
config = LoraConfig(use_dora=True, runtime_config=LoraRuntimeConfig(ephemeral_gpu_offload=True), ...)Um PeftModel com um adaptador DoRA também pode ser carregado com a flag ephemeral_gpu_offload=True usando o método from_pretrained bem como o método load_adapter.
from peft import PeftModel
model = PeftModel.from_pretrained(base_model, peft_model_id, ephemeral_gpu_offload=True)Otimização
DoRA é otimizado (calcula mais rápido e ocupa menos memória) para modelos no modo de avaliação, ou quando o dropout é definido como 0. Nesses casos, reutilizamos o resultado base para obter a aceleração.
Executar dora finetuning com CUDA_VISIBLE_DEVICES=0 ZE_AFFINITY_MASK=0 time python examples/dora_finetuning/dora_finetuning.py --quantize --lora_dropout 0 --batch_size 16 --eval_step 2 --use_dora em uma 4090, com acúmulo de gradiente definido como 2 e passo máximo de 20, resultou nas seguintes observações:
| Sem Otimização | Com Otimização | |
|---|---|---|
| tempo de execução do treinamento (seg) | 359.7298 | 279.2676 |
| amostras de treinamento por segundo | 1.779 | 2.292 |
| etapas de treinamento por segundo | 0.056 | 0.072 |
Além disso, é possível aumentar ainda mais o desempenho em tempo de execução do DoRA usando o contexto auxiliar DoraCaching. Isso requer que o modelo esteja no modo eval:
from peft.helpers import DoraCaching
model.eval()
with DoraCaching():
output = model(inputs)Para meta-llama/Llama-3.1-8B, o script de benchmark de cache do DoRA mostra que, em comparação com o LoRA:
- DoRA sem cache requer 139% mais tempo
- DoRA sem cache requer 4% mais memória
- DoRA com cache requer 17% mais tempo
- DoRA com cache requer 41% mais memória
Assim, o cache pode tornar a inferência com DoRA significativamente mais rápida, mas também requer muito mais memória. Idealmente, se o caso de uso permitir, basta mesclar o adaptador DoRA para evitar tanto o sobrecarga de memória quanto a sobrecarga de tempo de execução.
Observações
- No momento, o DoRA suporta apenas camadas de embedding, linear e Conv2d.
- DoRA introduz um overhead maior do que o LoRA puro, portanto, é recomendado mesclar os pesos para inferência, veja LoraModel.merge_and_unload().
- O DoRA deve funcionar com pesos quantizados com bitsandbytes (“QDoRA”). No entanto, problemas foram relatados ao usar QDoRA com DeepSpeed Zero2.