Гайды

38

13 марта 2026

Файнтюнинг (дообучение) больших языковых моделей позволяет адаптировать модель под свою задачу: от чат-бота на корпоративных данных до генерации кода в вашем стеке. Но полный файнтюнинг модели на 7B параметров требует ~112 ГБ VRAM — это 2× A100.

LoRA (Low-Rank Adaptation) решает эту проблему: вместо обновления всех весов модели обучаются только маленькие адаптерные матрицы. Результат — файнтюнинг 7B модели на одной RTX 3090, а с QLoRA — даже на RTX 4060 с 8 ГБ VRAM.

Как работает LoRA

Проблема: полный файнтюнинг слишком дорог

При полном файнтюнинге с Adam-оптимизатором в FP32 нужно хранить в VRAM:

Компонент Байт/параметр 7B модель
Веса модели 4 28 ГБ
Градиенты 4 28 ГБ
Adam states (m + v) 8 56 ГБ
Итого (без активаций) 16 112 ГБ

Плюс активации — ещё 10–50 ГБ в зависимости от batch size и длины контекста.

Решение: обучаем только адаптеры

LoRA замораживает все оригинальные веса модели и добавляет пару маленьких матриц (A и B) к каждому целевому слою:

W_new = W_frozen + α × (B × A)

Где:
- W_frozen — оригинальные веса (заморожены, не обновляются)
- A — матрица [hidden_dim × r] (инициализируется случайно)
- B — матрица [r × hidden_dim] (инициализируется нулями)
- r — ранг адаптера (обычно 8–64)
- α — scaling factor

Пример: для слоя 4096×4096 с r=16:
- Оригинал: 16.7M параметров
- LoRA: 4096×16 + 16×4096 = 131K параметров (в 128× меньше)

Обучаемых параметров обычно 0.1–2% от общего числа. Вместо 112 ГБ для 7B модели нужно ~16 ГБ с LoRA и ~6 ГБ с QLoRA.

LoRA vs QLoRA

Характеристика LoRA QLoRA
Веса базовой модели FP16 INT4 (NF4)
VRAM для 7B ~16 ГБ ~6 ГБ
VRAM для 13B ~32 ГБ ~10 ГБ
VRAM для 70B ~150 ГБ ~40 ГБ
Качество Чуть лучше ~99% качества LoRA
Скорость обучения Быстрее Медленнее (~1.5×)

QLoRA = LoRA + квантизация базовой модели в 4-bit NF4. Модель загружается в INT4, а LoRA-адаптеры обучаются в FP16/BF16. При этом вычисления идут в BFloat16 через деквантизацию «на лету».

Рекомендация: если VRAM хватает — используйте LoRA (быстрее и чуть лучше). Если VRAM ограничен — QLoRA даёт почти то же качество.

Требования к VRAM

QLoRA (рекомендуемые конфигурации)

Модель r batch Контекст VRAM GPU
7B (Qwen, Llama, Mistral) 64 4 2048 ~8 ГБ RTX 4060, RTX 3070
7B 64 4 4096 ~12 ГБ RTX 4070, RTX 3060 12GB
13B 32 2 2048 ~12 ГБ RTX 4070
13B 64 4 2048 ~16 ГБ RTX 4080
32B (Qwen2.5-32B) 16 1 2048 ~20 ГБ RTX 3090
32B 32 2 2048 ~24 ГБ RTX 4090
70B (Llama 3.1) 16 1 2048 ~42 ГБ 2× RTX 3090

Факторы, влияющие на VRAM

Фактор Влияние
Ранг (r) r=16 → r=64 = +2–4 ГБ
Batch size ×2 batch ≈ +30–50% VRAM
Длина контекста 2048 → 4096 ≈ +30% VRAM
Gradient checkpointing Включить = −30–50% VRAM (но −20% скорость)
Количество target_modules Больше слоёв = больше VRAM

Практика: файнтюнинг с Hugging Face

Установка

pip install transformers peft trl bitsandbytes datasets accelerate

QLoRA файнтюнинг Qwen2.5-7B-Instruct

import torch
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from trl import SFTTrainer
from datasets import load_dataset

# 1. Конфигурация квантизации (QLoRA)
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,  # Важно: bfloat16, НЕ float16
    bnb_4bit_use_double_quant=True,  # Экономит ещё ~0.4 бит/параметр
)

# 2. Загрузка модели
model_name = "Qwen/Qwen2.5-7B-Instruct"

tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,
)
model = prepare_model_for_kbit_training(model)

# 3. Конфигурация LoRA
lora_config = LoraConfig(
    r=32,                          # Ранг адаптера
    lora_alpha=64,                 # Scaling (обычно 2× r)
    target_modules=[               # Какие слои адаптировать
        "q_proj", "k_proj", "v_proj", "o_proj",
        "gate_proj", "up_proj", "down_proj",
    ],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Пример вывода: trainable params: 41,943,040 || all params: 7,657,300,480 || 0.55%

# 4. Загрузка датасета
dataset = load_dataset("your-dataset", split="train")

# 5. Параметры обучения
training_args = TrainingArguments(
    output_dir="./output",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,    # Эффективный batch = 16
    gradient_checkpointing=True,      # Экономит VRAM
    learning_rate=2e-4,
    lr_scheduler_type="cosine",
    warmup_ratio=0.05,
    logging_steps=10,
    save_strategy="epoch",
    bf16=True,                        # BFloat16 обучение
    optim="paged_adamw_8bit",         # 8-bit Adam (экономит VRAM)
    max_grad_norm=0.3,
    report_to="none",
)

# 6. Запуск обучения
trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=dataset,
    args=training_args,
    max_seq_length=2048,
)

trainer.train()

# 7. Сохранение адаптера
model.save_pretrained("./lora-adapter")
tokenizer.save_pretrained("./lora-adapter")

Важные детали

bnb_4bit_compute_dtype=torch.bfloat16 — используйте bfloat16, не float16! Float16 вызывает NaN-ы при обучении на Ampere+ GPU (RTX 3000+, A100).

bnb_4bit_use_double_quant=True — двойная квантизация. Квантизует сами квантизационные константы, экономя ~0.4 бит/параметр без потери качества.

paged_adamw_8bit — 8-bit Adam оптимизатор с пейджингом в CPU RAM при нехватке VRAM. Экономит 4–8 ГБ на больших моделях.

Выбор гиперпараметров

Ранг (r)

Задача Рекомендуемый r
Простая классификация 8
Генерация в определённом стиле 16–32
Обучение на специализированном домене 32–64
Сложные задачи (код, математика) 64–128

Общее правило: r=32 — хороший дефолт. Увеличивайте, если модель недообучается. Уменьшайте, если VRAM не хватает.

lora_alpha

Обычно lora_alpha = 2 × r. Это scaling factor: ΔW = (α/r) × B × A. При alpha=2r и r=32 scaling = 2.0.

target_modules

Вариант Обучаемые параметры Качество VRAM
Только attention (q, v) 0.1–0.3% Хорошее Минимум
Все attention (q, k, v, o) 0.3–0.5% Лучше Среднее
Attention + MLP (gate, up, down) 0.5–1.5% Лучшее Больше

Рекомендация: включайте все attention + MLP слои (как в примере выше). Разница в VRAM минимальна, а качество заметно лучше.

Learning rate

  • QLoRA: 1e-4 — 3e-4 (выше, чем при полном файнтюнинге)
  • LoRA (FP16 base): 5e-5 — 2e-4
  • Используйте cosine scheduler с warmup 3–5%

Подготовка датасета

Формат для instruction tuning

[
    {
        "instruction": "Объясни что такое LoRA простыми словами",
        "input": "",
        "output": "LoRA — это метод дообучения нейросетей..."
    },
    {
        "instruction": "Переведи на английский",
        "input": "Привет, как дела?",
        "output": "Hello, how are you?"
    }
]

Формат chat (для чат-моделей)

[
    {
        "messages": [
            {"role": "system", "content": "Ты помощник по Python."},
            {"role": "user", "content": "Как отсортировать список?"},
            {"role": "assistant", "content": "Используйте sorted() или list.sort()..."}
        ]
    }
]

Сколько данных нужно?

Задача Примеров Эпох
Стиль / тон 100–500 3–5
Доменные знания 1 000–10 000 2–3
Сложные навыки (код, математика) 10 000–100 000 1–3

Лучше 500 качественных примеров, чем 50 000 шумных.

Использование обученного адаптера

Инференс

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel

# Загружаем базовую модель
base_model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen2.5-7B-Instruct",
    device_map="auto",
    torch_dtype=torch.bfloat16,
)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")

# Накладываем LoRA-адаптер
model = PeftModel.from_pretrained(base_model, "./lora-adapter")

# Генерация
inputs = tokenizer("Ваш промпт", return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=512)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

Merge адаптера в базовую модель

Для продакшена можно слить адаптер с базой:

merged_model = model.merge_and_unload()
merged_model.save_pretrained("./merged-model")
tokenizer.save_pretrained("./merged-model")

После merge получается обычная модель, которую можно квантизовать в GGUF и запускать через llama.cpp.

Multi-GPU обучение

Для моделей, которые не помещаются на одну GPU:

# FSDP (рекомендуется для 2+ GPU)
accelerate launch --multi_gpu --num_processes 2 train.py

Или через DeepSpeed ZeRO Stage 2:

accelerate launch --config_file ds_config.yaml train.py

Частые ошибки

CUDA OOM при обучении

  1. Уменьшите per_device_train_batch_size (до 1)
  2. Увеличьте gradient_accumulation_steps (компенсация)
  3. Включите gradient_checkpointing=True
  4. Уменьшите max_seq_length
  5. Уменьшите ранг r

NaN loss

  1. Убедитесь: bnb_4bit_compute_dtype=torch.bfloat16 (не float16!)
  2. Уменьшите learning rate
  3. Добавьте max_grad_norm=0.3 (gradient clipping)
  4. Проверьте датасет на пустые / битые примеры

Модель не учится (loss не падает)

  1. Увеличьте learning rate (попробуйте 3e-4)
  2. Увеличьте ранг r (16 → 64)
  3. Добавьте MLP-слои в target_modules
  4. Проверьте формат данных (должен совпадать с chat template модели)
  5. Убедитесь, что достаточно данных (минимум 100 примеров)

Выбор GPU для файнтюнинга

Бюджет GPU Лучшая модель для QLoRA
~$300 RTX 4060 8GB 7B (r=32, batch=2)
~$400 RTX 4060 Ti 16GB 13B (r=32, batch=2)
~$600 Б/у RTX 3090 24GB 32B (r=16, batch=1)
~$1 800 RTX 4090 24GB 32B (r=32, batch=2)
~$1 200 2× б/у RTX 3090 70B (r=16, batch=1)

Для серьёзного файнтюнинга больших моделей (32B+) аренда GPU-сервера с A100 или RTX 4090 — самый экономичный вариант.

Итог

Параметр Рекомендация
Метод QLoRA (экономит VRAM)
Ранг r=32 (дефолт), r=64 для сложных задач
Target modules Все attention + MLP слои
Learning rate 2e-4 с cosine scheduler
Оптимизатор paged_adamw_8bit
Compute dtype bfloat16 (обязательно!)
Данные 500+ качественных примеров

LoRA/QLoRA демократизировали файнтюнинг — теперь дообучить 7B модель можно на GPU за $300, а 70B — на паре б/у RTX 3090.


Нужен мощный GPU для файнтюнинга? Арендуйте GPU-сервер в облаке Intelion — RTX 4090, A100, H100 с оплатой по минутам.

Гайды

#GPU

#LLM

#VRAM

#LoRA

#QLoRA

#файнтюнинг

#PEFT

#обучение