Free-LLMs

Как дообучить небольшую LLM на знаниях своей предметной области

План LoRA и QLoRA: выбор базы, данные, параметры, оценка и ограничения дообучения.

Domain
Дообучение под домен
🤖
Мониторинг бесплатных моделей в Telegram Бот @freellms_bot присылает новые бесплатные модели и AI-акции.
→

Небольшую LLM на 0,5-8 млрд параметров дообучают на своей предметной области через LoRA или QLoRA: берут Instruct-модель, готовят несколько сотен или тысяч примеров «запрос и правильный ответ» в нужном вам формате и терминологии, обучают адаптер на одной видеокарте и сравнивают результат с базовой моделью на отложенных вопросах. Важная оговорка: так модель учится говорить на языке вашей области (формат, термины, структура ответа, классификация), а не запоминает базу фактов. Для фактов, которые меняются и требуют ссылок на источник, нужен поиск, то есть RAG. Ниже план из семи шагов, выбор параметров и рабочий скрипт.

Что дообучение даст, а что нет

Исследования расставляют границы довольно чётко. В работе Gekhman и соавторов (EMNLP 2024) примеры с новыми для модели фактами усваивались заметно медленнее остальных, а по мере усвоения линейно повышали склонность к галлюцинациям; авторы делают вывод, что знания модель получает на предобучении, а дообучение учит ими пользоваться. Сравнение Ovadia и соавторов показало, что RAG стабильно превосходит неконтролируемое дообучение и на знакомых моделью темах, и на новых. Исследование «LoRA Learns Less and Forgets Less» добавляет: при типичных настройках LoRA уступает полному дообучению на целевой области (программирование, математика), зато лучше сохраняет возможности модели за её пределами.

Задача предметной областиДообучение небольшой моделиЧто использовать
Ответы строго в вашем формате (JSON, шаблон письма, разметка)ПодходитLoRA на примерах формата
Классификация и маршрутизация по вашим категориямПодходитLoRA или маленький классификатор (сравнение)
Терминология и стиль отраслиПодходитLoRA на экспертных ответах
Ответы по документам, прайсам, регламентамПлохо: факты устаревают и забываютсяRAG, при необходимости плюс LoRA на формат ответа
Данные, которые меняются каждую неделюНе подходитRAG или вызов функции (как обновлять знания)

Если сомневаетесь, нужно ли обучение вообще, пройдите дерево решений из статьи промпт, RAG или fine-tuning.

План из семи шагов

  1. Сформулируйте задачу и метрику. «Знает нашу область» не измеряется. Измеряется «в 90 процентах вопросов из тестового набора ответ содержит нужные поля и не противоречит эталону». Метрику выбирайте до обучения.
  2. Соберите оценочный набор и отложите его. 50-100 типичных запросов с эталонными ответами, которые не попадут в обучение. Методика замера описана в статье как сравнить LLM на своих задачах.
  3. Замерьте базовую модель с хорошим промптом. Если промпт с примерами уже даёт нужное качество, обучение не нужно. Если нет, у вас есть отправная точка для сравнения.
  4. Подготовьте обучающие примеры (подробности в статье про датасет для fine-tuning).
  5. Обучите адаптер LoRA или QLoRA.
  6. Сравните с базой на оценочном наборе и проверьте, что общие способности не просели (протокол проверки).
  7. Выложите адаптер или слитую модель и сохраните версию данных и параметров, чтобы эксперимент можно было повторить.

Выбор базовой модели

  • Instruct или Base. Для узких задач с несколькими сотнями примеров проще стартовать с Instruct-версии: она уже умеет вести диалог и следовать инструкциям, а вы корректируете формат и терминологию. Base-модель имеет смысл, если у вас десятки тысяч примеров и вы сами задаёте весь стиль ответов.
  • Размер. Для первого цикла берите 0,5-4B: обучение занимает минуты или десятки минут, а ошибки в данных видны сразу. Затем сравните с 7-8B. Как оценить память под веса и обучение, разобрано в статье про выбор размера LLM.
  • Лицензия. Проверьте карточку модели: допускает ли она коммерческое использование и выкладку производных весов. Для адаптеров это те же условия, что у базы.
  • Поддержка русского. Если задача на русском, посмотрите, заявлен ли он в карточке модели, и проверьте на своих примерах, а не по общему описанию.
  • MoE-модели. Они обучаются сложнее: в обзоре Hugging Face отмечено, что MoE исторически плохо обобщаются при дообучении и склонны к переобучению. Для первого эксперимента берите плотную модель (см. статью про MoE).

Параметры LoRA: с чего начать

LoRA замораживает веса модели и обучает небольшие матрицы малого ранга, добавленные к слоям (Hu и соавторы). QLoRA дополнительно хранит замороженную базу в 4-битном формате NF4, что позволило авторам дообучать модель на 65 млрд параметров на одной карте с 48 ГБ. Параметры, которые стоит знать:

ПараметрЧто делаетПрактический ориентир
r (ранг)Ёмкость адаптераСтартуйте с 16-32; если данных много и качество упирается в потолок, поднимайте
lora_alphaМасштаб вклада адаптераЧасто берут равным r или 2 × r; в примерах документации TRL r=32, lora_alpha=16
target_modulesК каким слоям добавлять адаптер"all-linear": исследование LoRA Without Regret показало, что адаптеры на всех матрицах, особенно на MLP, работают лучше, чем только на внимании, даже при том же числе параметров
learning_rateШаг обученияДля адаптеров выше, чем при полном обучении: документация TRL приводит ориентир порядка 10 раз выше; начинайте с 1e-4 - 2e-4 и подбирайте
ЭпохиСколько раз пройти датасет1-3; следите за ошибкой на отложенной выборке

В той же работе Thinking Machines отмечено, что на небольших датасетах LoRA сопоставима с полным дообучением, а на датасетах, превышающих ёмкость адаптера, проигрывает по эффективности обучения. Для типичной доменной задачи на сотни и тысячи примеров это означает: ранга 16-64 обычно достаточно, а если качество упёрлось, сначала улучшайте данные, потом поднимайте ранг.

Скрипт обучения

Формат данных: файл train.jsonl, по одной записи на строку. Используем формат prompt-completion с ролями: для него SFTTrainer по умолчанию считает потери только на ответе, как описано в документации SFT Trainer, и сам применяет чат-шаблон модели.

{"prompt": [{"role": "system", "content": "Ты помощник службы поддержки интернет-магазина. Отвечай по шаблону: вывод, шаги, что приложить."},
            {"role": "user", "content": "Курьер привёз заказ с вмятиной на коробке, что делать?"}],
 "completion": [{"role": "assistant", "content": "Вывод: заказ можно вернуть или обменять.\nШаги: 1) сфотографируйте упаковку и товар; 2) подайте заявку в разделе «Мои заказы»; 3) дождитесь решения.\nПриложить: фото упаковки и накладную."}]}

Установка (Linux или WSL, видеокарта NVIDIA, Python 3.11 и новее) и скрипт train_lora.py:

pip install torch
pip install -U trl peft bitsandbytes datasets
import torch
from datasets import load_dataset
from peft import LoraConfig
from transformers import BitsAndBytesConfig
from trl import SFTConfig, SFTTrainer

MODEL = "Qwen/Qwen3-0.6B"   # для проверки пайплайна; затем замените на свою базу

data = load_dataset("json", data_files={"train": "train.jsonl", "eval": "eval.jsonl"})

bnb = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True,
    bnb_4bit_compute_dtype=torch.bfloat16,
)  # для обычной LoRA уберите эту конфигурацию и quantization_config ниже

lora = LoraConfig(
    r=32, lora_alpha=64, lora_dropout=0.05,
    target_modules="all-linear", task_type="CAUSAL_LM",
)

args = SFTConfig(
    output_dir="./out/domain-lora",
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=1e-4,
    num_train_epochs=2,
    max_length=2048,
    bf16=True,
    gradient_checkpointing=True,
    logging_steps=10,
    eval_strategy="steps",
    eval_steps=50,
    save_strategy="epoch",
)

trainer = SFTTrainer(
    model=MODEL,
    args=args,
    train_dataset=data["train"],
    eval_dataset=data["eval"],
    peft_config=lora,
    quantization_config=bnb,
)
trainer.train()
trainer.save_model("./out/domain-lora/adapter")

Названия некоторых полей SFTConfig (например, max_length и параметры оценки) меняются между релизами, поэтому закрепите версии библиотек в requirements.txt и сверяйтесь с документацией установленной версии. Сравнение инструментов (TRL, Unsloth, Axolotl) и пример YAML-конфига есть в статье про инструменты дообучения.

Как читать кривые обучения

  • Ошибка на обучающей выборке падает, на отложенной растёт: началось переобучение. Остановитесь раньше, уменьшите число эпох или добавьте разнообразия в данные.
  • Обе кривые почти не двигаются: проверьте формат (применён ли чат-шаблон модели, не обучается ли она на шаблоне вместо ответа), скорость обучения и качество данных.
  • Ошибка хорошая, а ответы плохие: метрика потерь не измеряет качество задачи. Вернитесь к оценочному набору и сравнивайте реальные ответы.
  • Модель стала хуже на общих вопросах: уменьшите число эпох или ранг, добавьте в обучение часть универсальных диалогов. Работа об эмпирическом изучении катастрофического забывания фиксирует, что при последовательном дообучении LLM от 1 до 7 млрд параметров забывание наблюдается в целом.

Результат: адаптер или слитая модель

Адаптер весит мало и подключается к базовой модели при загрузке, так что на одной базе можно держать несколько адаптеров для разных задач. Для запуска в Ollama или llama.cpp адаптер сливают с базой и конвертируют в GGUF (про форматы):

from peft import AutoPeftModelForCausalLM

model = AutoPeftModelForCausalLM.from_pretrained("./out/domain-lora/adapter")
merged = model.merge_and_unload()
merged.save_pretrained("./out/merged")

Дальше модель можно поднять как сервис по инструкции из статьи как развернуть небольшую LLM как API.

Итого

  • Дообучение небольшой модели учит формату, терминологии, стилю и классификации. Изменяющиеся факты держите в индексе или базе.
  • Сначала оценочный набор и базовая линия с хорошим промптом, потом обучение.
  • Для старта: Instruct-модель 0,5-4B, QLoRA, all-linear, r 16-32, скорость обучения около 1e-4, 1-3 эпохи.
  • Качество данных важнее количества: сначала правьте их, потом поднимайте ранг и размер модели.
  • После обучения сравните адаптер с базой и проверьте общие способности.
FL
Редакция Free-LLMsКоманда каталога бесплатных LLM API. Проверяем лимиты провайдеров и тестируем модели и инструменты руками.

Читайте также