# Adaptación de bajo rango con descomposición de pesos (DoRA)

> [!NOTE]
> 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.

```py
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`.

```py
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`.

```py
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 [dora finetuning](https://github.com/huggingface/peft/blob/main/examples/dora_finetuning/dora_finetuning.py) 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 acumulación de gradientes establecida en 2 y 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`:

```py
from peft.helpers import DoraCaching

model.eval()
with DoraCaching():
    output = model(inputs)
```

Para [`meta-llama/Llama-3.1-8B`](https://huggingface.co/meta-llama/Llama-3.1-8B), el [script de benchmark de caché de DoRA](https://github.com/huggingface/peft/blob/main/examples/dora_finetuning/dora-caching.py) 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()](/docs/peft/main/es/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.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.

