PEFT documentation
Низкоранговая адапция с разложением весов (DoRA)
Низкоранговая адапция с разложением весов (DoRA)
Это вариант LoRA, поэтому всё, что возможно с LoRA, применимо и к этому методу, если на этой странице не указано иное.
Этот метод разлагает обновления весов на две части: величину и направление. Направление обрабатывается обычным LoRA, тогда как величина — отдельным обучаемым параметром. Это может повысить производительность LoRA, особенно при низких рангах. Подробнее о DoRA см. https://huggingface.co/papers/2402.09353.
from peft import LoraConfig
config = LoraConfig(use_dora=True, ...)Если части модели или адаптера DoRA выгружаются на CPU, вы можете получить значительное ускорение за счёт некоторого временного (эфемерного) потребления VRAM, используя ephemeral_gpu_offload=True в config.runtime_config.
from peft import LoraConfig, LoraRuntimeConfig
config = LoraConfig(use_dora=True, runtime_config=LoraRuntimeConfig(ephemeral_gpu_offload=True), ...)Модель PeftModel с адаптером DoRA также можно загрузить с флагом ephemeral_gpu_offload=True с помощью метода from_pretrained, а также метода load_adapter.
from peft import PeftModel
model = PeftModel.from_pretrained(base_model, peft_model_id, ephemeral_gpu_offload=True)Оптимизация
DoRA оптимизирован (вычисляется быстрее и занимает меньше памяти) для моделей в режиме оценки или когда dropout установлен в 0. В этих случаях мы повторно используем базовый результат, чтобы ускорить работу.
Запуск дообучения dora с помощью 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 на 4090 с накоплением градиентов, установленным в 2, и максимальным числом шагов 20 привел к следующим наблюдениям:
| Без оптимизации | С оптимизацией | |
|---|---|---|
| время обучения (сек) | 359.7298 | 279.2676 |
| образцов обучения в секунду | 1.779 | 2.292 |
| шагов обучения в секунду | 0.056 | 0.072 |
Более того, производительность DoRA во время выполнения можно дополнительно повысить с помощью контекста-помощника DoraCaching. Для этого модель должна находиться в режиме eval:
from peft.helpers import DoraCaching
model.eval()
with DoraCaching():
output = model(inputs)Для meta-llama/Llama-3.1-8B скрипт бенчмаркинга кэширования DoRA показывает, что по сравнению с LoRA:
- DoRA без кэширования требует на 139% больше времени
- DoRA без кэширования требует на 4% больше памяти
- DoRA с кэшированием требует на 17% больше времени
- DoRA с кэшированием требует на 41% больше памяти
Таким образом, кэширование может значительно ускорить инференс с DoRA, но также требует значительно больше памяти. В идеале, если это позволяет сценарий использования, следует просто объединить адаптер DoRA, чтобы избежать как накладных расходов на память, так и на время выполнения.
Ограничения
- В настоящее время DoRA поддерживает только слои embedding, linear и Conv2d.
- DoRA introduces a bigger overhead than pure LoRA, so it is recommended to merge weights for inference, see LoraModel.merge_and_unload().
- DoRA должна работать с квантованными весами с помощью bitsandbytes («QDoRA»). Однако были зафиксированы проблемы при использовании QDoRA с DeepSpeed Zero2.