Дообучение LLM методом LoRA (Low-Rank Adaptation)

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Дообучение LLM методом LoRA (Low-Rank Adaptation)
Средняя
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Дообучение LLM методом LoRA (Low-Rank Adaptation)

LoRA — метод параметрически эффективного дообучения, при котором исходные веса модели замораживаются, а рядом с ними обучаются небольшие матрицы низкого ранга. Метод предложен в 2021 году (Hu et al., Microsoft Research) и стал стандартом de facto для fine-tuning LLM. LoRA позволяет дообучить 7B модель на одном GPU A100 40GB вместо нескольких, при этом потеря качества по сравнению с Full Fine-Tuning минимальна для большинства задач.

Математика LoRA

Для весовой матрицы W ∈ R^(d×k) LoRA добавляет произведение двух матриц:

W' = W + ΔW = W + BA
где B ∈ R^(d×r), A ∈ R^(r×k), r << min(d, k)

Ранг r — ключевой гиперпараметр. При r=16 и d=k=4096 (типичные размеры attention проекций в 7B модели) количество обучаемых параметров в одном слое: 16×4096 + 4096×16 = 131 072 вместо 4096×4096 = 16 777 216. Это сжатие в 128×.

При инициализации A — случайная гауссова матрица, B — нулевая. Это обеспечивает ΔW=0 в начале — модель начинает с оригинального поведения.

Конфигурация LoRA: ключевые гиперпараметры

from peft import LoraConfig

config = LoraConfig(
    r=16,               # Ранг: 4, 8, 16, 32, 64, 128
    lora_alpha=32,      # Масштаб: обычно = 2*r
    target_modules=[    # Какие слои адаптируем
        "q_proj", "v_proj",          # Минимум
        "k_proj", "o_proj",          # Расширенный вариант
        "gate_proj", "up_proj", "down_proj"  # MLP включительно
    ],
    lora_dropout=0.05,  # Регуляризация адаптера
    bias="none",        # "none", "all", "lora_only"
    task_type="CAUSAL_LM",
    modules_to_save=["embed_tokens", "lm_head"],  # Обучаем полностью
)

Выбор r: чем сложнее задача и чем сильнее домен отличается от предобучения — тем выше r. Для классификации и форматирования: r=4–8. Для генерации в специфическом стиле: r=16–32. Для сложного domain adaptation: r=64–128.

lora_alpha: контролирует масштаб адаптера. Эффективный lr адаптера = lr × (alpha/r). Стандартная практика: alpha = 2r.

DoRA: улучшение LoRA

DoRA (Weight-Decomposed Low-Rank Adaptation) разделяет обновление весов на magnitude и direction компоненты:

config = LoraConfig(
    r=16,
    use_dora=True,  # Включает DoRA вместо обычной LoRA
    ...
)

DoRA улучшает качество на 1–3% по сравнению со стандартной LoRA без увеличения инференс-затрат.

Практический кейс: LoRA для классификации NER

Задача: извлечение именованных сущностей из медицинских записей (4 класса: MEDICATION, DOSAGE, CONDITION, PROCEDURE).

Базовая модель: Llama 3.1 8B Instruct.

Конфигурация: r=16, alpha=32, target_modules=["q_proj","v_proj"], 3 эпохи.

Датасет: 2200 примеров, A100 40GB, QLoRA 4-bit, время обучения 2.5 часа.

Метрика Базовая модель (5-shot) LoRA r=8 LoRA r=16 LoRA r=32
F1 MEDICATION 0.71 0.88 0.91 0.92
F1 DOSAGE 0.64 0.83 0.87 0.88
F1 CONDITION 0.79 0.91 0.94 0.94
F1 PROCEDURE 0.68 0.85 0.89 0.90

Разрыв между r=16 и r=32 незначителен — r=16 оптимален.

Слияние адаптера для деплоя

LoRA-адаптер можно слить с базовой моделью для упрощения инференса:

from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3.1-8B-Instruct")
model = PeftModel.from_pretrained(base_model, "./lora-adapter")

# Слияние: результат — обычная модель без PEFT overhead
merged = model.merge_and_unload()
merged.save_pretrained("./merged-model")

После слияния модель идентична по скорости инференса полно обученной — overhead LoRA на inference исчезает.

Сроки

  • Подготовка данных: 2–4 недели
  • Обучение (7B, LoRA, A100 40GB): 2–8 часов
  • Итерации гиперпараметров: 3–5 дней
  • Итого: 3–6 недель