PEFT documentation
Adaptación de bajo rango con descomposición de pesos (DoRA)
Adaptación de bajo rango con descomposición de pesos (DoRA)
Esta es una variante de LoRA y, por lo tanto, todo lo que es posible con LoRA es válido para este método, salvo que se indique lo contrario en esta página.
Esta técnica descompone las actualizaciones de los pesos en dos partes: magnitud y dirección. La dirección se maneja con LoRA normal, mientras que la magnitud se maneja mediante un parámetro aprendible separado. Esto puede mejorar el rendimiento de LoRA, especialmente en rangos bajos. Para obtener más información sobre DoRA, consulte https://huggingface.co/papers/2402.09353.
from peft import LoraConfig
config = LoraConfig(use_dora=True, ...)Si partes del modelo o del adaptador DoRA se descargan a la CPU, puede obtenerse una aceleración significativa a costa de una sobrecarga temporal (efímera) de VRAM al usar ephemeral_gpu_offload=True en config.runtime_config.
from peft import LoraConfig, LoraRuntimeConfig
config = LoraConfig(use_dora=True, runtime_config=LoraRuntimeConfig(ephemeral_gpu_offload=True), ...)Un PeftModel con un adaptador DoRA también se puede cargar con la bandera ephemeral_gpu_offload=True usando el método from_pretrained así como el método load_adapter.
from peft import PeftModel
model = PeftModel.from_pretrained(base_model, peft_model_id, ephemeral_gpu_offload=True)Optimización
DoRA está optimizado (calcula más rápido y consume menos memoria) para modelos en modo de evaluación, o cuando dropout se establece en 0. En esos casos, reutilizamos el resultado base para obtener la aceleración.
Ejecutar el ajuste fino con dora con 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 en una 4090 con la acumulación de gradientes establecida en 2 y el paso máximo en 20 dio lugar a las siguientes observaciones:
| Sin optimización | Con Optimización | |
|---|---|---|
| tiempo de entrenamiento (seg) | 359.7298 | 279.2676 |
| muestras de entrenamiento por segundo | 1.779 | 2.292 |
| pasos de entrenamiento por segundo | 0.056 | 0.072 |
Además, es posible aumentar aún más el rendimiento en tiempo de ejecución de DoRA mediante el uso del contexto auxiliar DoraCaching. Esto requiere que el modelo esté en modo eval:
from peft.helpers import DoraCaching
model.eval()
with DoraCaching():
output = model(inputs)Para meta-llama/Llama-3.1-8B, el script de benchmark de caché de DoRA muestra que, en comparación con LoRA:
- DoRA sin caché requiere un 139% más de tiempo
- DoRA sin caché requiere un 4% más de memoria
- DoRA con caché requiere un 17% más de tiempo
- DoRA con caché requiere un 41% más de memoria
Por lo tanto, el almacenamiento en caché puede hacer que la inferencia con DoRA sea significativamente más rápida, pero también requiere mucha más memoria. Idealmente, si el caso de uso lo permite, simplemente fusiona el adaptador DoRA para evitar tanto la sobrecarga de memoria como la de tiempo de ejecución.
Precauciones
- DoRA solo admite capas de embedding, lineales y Conv2d por el momento.
- DoRA introduce una sobrecarga mayor que el LoRA puro, por lo que se recomienda fusionar los pesos para la inferencia, consulte LoraModel.merge_and_unload().
- DoRA debería funcionar con pesos cuantizados con bitsandbytes (“QDoRA”). Sin embargo, se han reportado problemas al usar QDoRA con DeepSpeed Zero2.