У вашего юриста уходит полдня на проверку каждого договора вручную. ChatGPT не знает ваших шаблонов, оговорок и терминологии. Решение одно: донастроить нейросеть под себя. Раньше это стоило сотни тысяч долларов и требовало десятков видеокарт. Теперь хватит одной видеокарты и 100-300 долларов на эксперимент. Сделали это возможным три технологии: LoRA, QLoRA и общий подход PEFT (Parameter-Efficient Fine-Tuning - экономное дообучение).
Эта статья объясняет, что они дают бизнесу, как принять решение о запуске такого проекта и сколько реально стоит донастройка модели уровня Llama 3 8B (открытая модель Meta на 8 миллиардов параметров).
Зачем это бизнесу
Донастройка модели (fine-tuning, дальше FT) превращает универсальную нейросеть в специалиста. Универсальный Claude знает всё понемногу. Дообученная модель знает вашу предметную область как опытный сотрудник.
Разберём на примере юридической конторы с собственными шаблонами договоров (пример, не реальный кейс автора). Дообучение на 500 примерах даёт модель, которая работает в 2-3 раза точнее общего ChatGPT на ваших задачах. Это значит меньше ручной проверки, меньше ошибок, выше пропускная способность отдела.
Второй пример: колл-центр с собственным голосом бренда. Дообученная модель отвечает в нужном тоне, не уходит в общий корпоративный язык, не путает названия продуктов. Качество ответов в чате растёт без переписывания инструкций.
Раньше дообучение требовало обновить все веса модели, а это миллиарды чисел. Для модели на 8 миллиардов параметров нужно 48-64 гигабайта видеопамяти (VRAM - специальная память видеокарты для тяжёлых вычислений). Такое железо есть только в облачных кластерах, час работы стоит десятки долларов.
PEFT (экономное дообучение, общий класс методов) изменил подход. Вместо перезаписи всех весов меняется только маленькая часть. LoRA (Low-Rank Adaptation - метод дообучения через две маленькие матрицы вместо всей модели) сейчас самый популярный метод этого класса. QLoRA (LoRA с базовой моделью в сжатом виде) экономит ещё в 4 раза больше памяти.
Как работает LoRA на пальцах
Понимание идеи нужно, чтобы оценивать сроки и стоимость проектов от подрядчиков. Без этого легко переплатить за "полное переобучение", когда хватило бы экономного.
Полное дообучение нейросети меняет все веса модели. Для Llama 3 8B это 8 миллиардов чисел. Только под хранение весов в половинной точности нужно 16 гигабайт видеопамяти. Плюс служебные данные обучения (градиенты, состояние оптимизатора). В сумме 48-64 гигабайта. Для большинства компаний это недоступно без облачного кластера.
LoRA работает иначе. Исходные веса модели остаются нетронутыми. Рядом с ними обучаются две маленькие матрицы (A и B), которые отвечают за "поправку". Когда модель работает, к её ответу добавляется поправка от этих маленьких матриц.
Конкретные цифры для Llama 3 8B при размере скрытого слоя 4096 и ранге 16. Матрица B имеет размер 4096 на 16 (около 65 тысяч чисел), матрица A имеет размер 16 на 4096 (ещё 65 тысяч). Итого 130 тысяч параметров на один слой вместо 16,7 миллиона при полном дообучении. Снижение в 128 раз.
Ключевой параметр всей этой схемы называется ранг (буква r в формулах). Он определяет, насколько сложные изменения вы хотите внести в поведение модели.
- r=8, alpha=16: подходит для простых задач, таких как смена стиля и тона. Минимум видеопамяти.
- r=16, alpha=32: стандарт для большинства задач. Работает в 80% случаев.
- r=32, alpha=64: для сложных задач, таких как анализ кода или логические рассуждения.
- r=64, alpha=128: максимум для типичных задач. Выше этого значимого прироста нет.
Параметр alpha нормализует вклад поправки при изменении ранга. Практическое правило: alpha равен удвоенному рангу.
Этот код подгружает базовую модель Llama 3 8B и добавляет к ней настройку LoRA. Важная строка print_trainable_parameters() показывает, что только 1% весов будет реально обучаться. Остальные 99% заморожены и не тратят память на обучение.
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B")
lora_config = LoraConfig(
r=16, # Ранг адаптера
lora_alpha=32, # alpha = 2 * r
target_modules=[ # Слои для применения LoRA
"q_proj", "v_proj", "k_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: 83,886,080 || all params: 8,030,261,248 || trainable%: 1.0446
Итог: 1% обучаемых параметров, при этом качество на вашей задаче сопоставимо с полным дообучением.
QLoRA: ещё в 4 раза экономнее
QLoRA (квантованная LoRA - метод хранения базовой модели в сжатом виде) позволяет дообучать модели на доступном железе. Видеокарта за 800-1200 долларов вместо облачного кластера за тысячи долларов в день. Для пилотных проектов это критично.
Идея простая. Базовые веса модели хранятся не в обычном формате (16 бит на число), а в сжатом 4-битном формате под названием NF4. Сжатие умное: оно не влияет на качество обучения. Когда модель считает ответ, числа автоматически разжимаются до полной точности. Сжатие касается только хранения.
Сравнение требований по видеопамяти для Llama 3 8B.
- Обычные веса в формате bf16: 16 гигабайт только под веса.
- Веса в 4-битном NF4 через QLoRA: 4-5 гигабайт.
- Плюс адаптеры LoRA: 0,5-1 гигабайт.
- Плюс служебные данные обучения: 6-8 гигабайт.
- Итого: 12-14 гигабайт. Влезает в видеокарту за 800-1200 долларов.
Этот код включает 4-битное сжатие базовой модели перед загрузкой. Строка bnb_4bit_use_double_quant добавляет второй уровень сжатия, экономя ещё 0,3-0,5 бита на каждое число.
from transformers import BitsAndBytesConfig, AutoModelForCausalLM
import torch
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Meta-Llama-3-8B",
quantization_config=bnb_config,
device_map="auto"
)
model = prepare_model_for_kbit_training(model)
Инструменты для дообучения: unsloth и axolotl
Эти инструменты определяют, насколько быстро и дёшево можно провести эксперимент. Разница между "написать всё с нуля" и "запустить готовый конвейер" составляет 2-4 недели работы инженера.
Два наиболее удобных инструмента в 2026 году: unsloth и axolotl.
unsloth известен как самый быстрый инструмент. Специальные оптимизации дают ускорение в 2-5 раз по сравнению со стандартным решением от Hugging Face (главная платформа открытых моделей). Поддерживает все популярные модели: Llama, Mistral, Qwen, Gemma, Phi.
Этот код запускает загрузку модели через unsloth сразу с QLoRA и оптимизированным сохранением промежуточных вычислений. Строка use_gradient_checkpointing экономит ещё 20-30% видеопамяти.
from unsloth import FastLanguageModel
import torch
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Meta-Llama-3-8B-Instruct",
max_seq_length=2048,
dtype=torch.bfloat16,
load_in_4bit=True,
)
model = FastLanguageModel.get_peft_model(
model,
r=16,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
lora_alpha=32,
lora_dropout=0.05,
bias="none",
use_gradient_checkpointing="unsloth",
random_state=42,
)
Второй инструмент, axolotl, требует только настройки через файл конфигурации в формате YAML (текстовый формат настроек, читаемый человеком). Писать код не нужно. Это лучший выбор для команд без глубокого специалиста по машинному обучению в штате.
Этот файл конфигурации описывает всё дообучение целиком: базовую модель, параметры LoRA, набор данных, параметры обучения. Достаточно одной команды для запуска.
base_model: meta-llama/Meta-Llama-3-8B-Instruct
model_type: LlamaForCausalLM
load_in_4bit: true
bf16: true
adapter: lora
lora_r: 16
lora_alpha: 32
lora_dropout: 0.05
lora_target_modules:
- q_proj
- v_proj
- k_proj
- o_proj
datasets:
- path: ./train.jsonl
type: alpaca
val_set_size: 0.1
num_epochs: 3
micro_batch_size: 4
gradient_accumulation_steps: 4
learning_rate: 0.0002
output_dir: ./outputs/lora-support-v1
axolotl train axolotl_config.yml
От обучения до работающего сервиса
Обученная модель в файле никому не нужна. Нужен сервис, который отвечает на запросы пользователей. Этот шаг часто пропускают в оценках сроков, и проект буксует на финале.
После дообучения нужно объединить адаптер с базовой моделью и разместить её на сервере. Этот код объединяет адаптер LoRA с базовой моделью и сохраняет итоговую версию для публикации.
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
base = AutoModelForCausalLM.from_pretrained(
"meta-llama/Meta-Llama-3-8B-Instruct",
torch_dtype=torch.bfloat16,
device_map="cpu"
)
peft_model = PeftModel.from_pretrained(base, "./outputs/lora-support-v1")
merged = peft_model.merge_and_unload()
merged.save_pretrained("./merged-model", safe_serialization=True)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
merged.push_to_hub("your-org/llama3-8b-support-v1", private=True)
tokenizer.push_to_hub("your-org/llama3-8b-support-v1", private=True)
Стоимость дообучения на облачной видеокарте A100 по цене около 1,50 доллара в час.
- 1000 примеров, 3 прохода, r=16: 30-40 минут, около 0,75 доллара.
- 10 000 примеров, 3 прохода, r=16: 4-5 часов, около 7-8 долларов.
- 50 000 примеров, 1 проход, r=32: 8-10 часов, около 12-15 долларов.
Это стоимость одного запуска. На практике потребуется 5-10 запусков для подбора параметров, итого 50-150 долларов на полный пилот.
Выравнивание по предпочтениям: DPO и ORPO
Базовое дообучение учит модели формат. Но иногда нужно подтянуть тон и стиль. Например, чтобы модель отвечала дружелюбно, а не сухо. Или давала развёрнутый анализ, а не отговорки. Это второй уровень настройки.
Дообучение по примерам (SFT, Supervised Fine-Tuning) учит модель имитировать образцы. Но иногда нужно большее: модель должна предпочитать одни ответы другим.
Для этого существуют DPO (Direct Preference Optimization - прямая настройка по предпочтениям) и ORPO (Odds Ratio Preference Optimization - более новый метод того же класса). Оба метода обучают модель на парах примеров, где один ответ помечен как лучший, а другой как худший.
ORPO стал стандартом в сообществе при работе с Llama 3 и Gemma 2. Он не требует вспомогательной модели и обучает одновременно двум целям за один проход. Это снижает стоимость обучения примерно вдвое.
Когда нужен этот шаг. Если дообученная модель отвечает технически правильно, но тон не подходит. Или слишком много отказов отвечать. Или нужна тонкая настройка под предпочтения команды.
Этот код запускает обучение DPO. Параметр beta=0.1 контролирует, насколько сильно модель отклоняется от исходного поведения.
from trl import DPOTrainer, DPOConfig
# Формат данных
# {"prompt": "...", "chosen": "хороший ответ", "rejected": "плохой ответ"}
dpo_config = DPOConfig(
beta=0.1,
max_length=1024,
output_dir="./dpo-output"
)
trainer = DPOTrainer(model=model, args=dpo_config, train_dataset=dpo_dataset)
trainer.train()
Запуск нескольких адаптеров одновременно
Если у вас несколько отделов или продуктов, не нужно держать отдельную видеокарту под каждый. Одна машина может держать одну базовую модель и несколько "специализаций" одновременно. Экономия на серверах в 3-5 раз.
Инструмент vLLM (высокопроизводительный сервер для запуска моделей) поддерживает горячую замену адаптеров LoRA. Одна базовая модель работает с несколькими адаптерами под разные отделы или продукты. Сценарий применения: один сервер обслуживает поддержку, HR и юридический отдел одновременно.
Следующие команды запускают сервер с двумя адаптерами и показывают, как выбрать нужный при запросе.
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Meta-Llama-3-8B-Instruct \
--enable-lora \
--lora-modules support-v1=./outputs/lora-support-v1 \
support-v2=./outputs/lora-support-v2 \
--max-lora-rank 64 \
--gpu-memory-utilization 0.9
import openai
client = openai.OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
response = client.chat.completions.create(
model="support-v1",
messages=[{"role": "user", "content": "Как сбросить пароль?"}]
)
Одна видеокарта A10G (24 гигабайта) держит Llama 3 8B плюс 4-8 адаптеров одновременно. Пропускная способность: 50-100 запросов в секунду при средней задержке 500 миллисекунд.
Типичные ошибки
Модель забывает общие знания. Признак: точность на вашей задаче растёт, но модель начинает хуже отвечать на общие вопросы. Решение: снизить скорость обучения, уменьшить число проходов, добавить в датасет 5-10% общих примеров.
Переобучение на малом датасете. Ошибка на обучающих данных падает к нулю, ошибка на проверочных растёт. Это значит, что модель запомнила тренировочные примеры наизусть, но не научилась обобщать. Решение: снизить ранг до 8, увеличить параметр lora_dropout до 0,1, добавить данных.
Нехватка видеопамяти. Первое, что нужно попробовать, это включить gradient checkpointing (метод экономии памяти за счёт пересчёта части данных). Это замедляет обучение на 20-30%, но экономит значительный объём видеопамяти.
Частые вопросы
Насколько QLoRA хуже полного дообучения по качеству?
QLoRA слегка уступает из-за шума при сжатии базовых весов. Разница на большинстве задач составляет 0,5-2% по метрикам. Для задач, требующих максимальной точности (математика, программный код), стоит пробовать полное дообучение в bf16, если позволяет видеокарта.
Работает ли LoRA для Mistral, Qwen, Gemma?
Да. LoRA работает для любого трансформера со стандартной архитектурой внимания. Qwen2, Gemma 2, Mistral, Phi-3 поддерживаются все. Различаются только названия слоёв: для Phi-3 это qkv_proj и o_proj вместо стандартных q_proj, v_proj.
Что выбрать: SFT, DPO или ORPO?
SFT (базовое дообучение по примерам) учит конкретному поведению и формату. Это первый шаг. DPO и ORPO нужны как следующий шаг для настройки предпочтений, когда базовое дообучение уже есть. Если начинаете с нуля, ORPO удобнее: не требует вспомогательной модели, стабильнее обучается.
Как проверить, что адаптер не сломал общие способности модели?
Запустите стандартные тесты до и после дообучения: MMLU (общие знания), GSM8K (арифметика), HumanEval (программный код). Падение больше 2-3% означает, что нужно пересмотреть данные или снизить скорость обучения.
unsloth против стандартного trl: в чём ограничения бесплатной версии?
Бесплатная версия unsloth поддерживает только одну видеокарту. Несколько карт (через FSDP или DeepSpeed) только в платной версии (от 350 долларов в месяц). Для команд с несколькими картами выбор такой: либо unsloth Pro, либо стандартный trl с accelerate.
Что дальше
Ваш следующий шаг: возьмите 500 примеров из вашей базы (договоры, ответы поддержки, прайсы) и запустите пилот на axolotl с конфигом из статьи. Затраты - около 50-150 долларов на облачную видеокарту. Если результат устраивает - выкатывайте адаптер на vLLM и подключайте отделы.
AI Компас (t.me/kosmoslab_ai) - канал для предпринимателей в РФ и СНГ, которые применяют AI в своём бизнесе без программиста. Разбираем инструменты и схемы - без курсов и теории.