← LLM fine-tuning: LoRA, QLoRA, and when not to do it
07 / 07 · 60 min

Capstone: a code-review specialist from a small model

The full cycle: a dataset of diffs with seeded bugs, QLoRA SFT and DPO pairs of found versus missed, acceptance against pre-committed criteria — and a quantized endpoint with a model card.

Lesson content is currently available in Russian.

What you will learn

  • →Собирать датасет диффов и ревью с жёсткой структурой выхода и бесспорным ground truth.
  • →Проводить цикл SFT + DPO с фиксацией конфигов, seed и хэшей данных для воспроизводимости.
  • →Принимать модель по заранее заданным критериям и выкатывать её как сервис с модельной картой.

Постановка и данные: диффы с известными багами

Капстоун: превратить 7B-модель (хорошая база — Qwen2.5-Coder-7B-Instruct) в специалиста по код-ревью, который получает unified diff и возвращает структурированное ревью: JSON со списком находок — severity, файл и строка, объяснение, предлагаемая правка. Малая модель не обгонит фронтирную в общем программировании, но на узком жанре «найди проблемы в диффе и оформи по нашему стандарту» это реалистично.

Данные собираем из трёх слоёв. Первый — история ваших PR: диффы плюс комментарии ревьюеров; фильтруйте жёстко, оставляя только комментарии, которые привели к правке (значит, нашли реальную проблему). Второй — публичные ревью из OSS-проектов вашего стека с той же фильтрацией. Третий и самый ценный для оценки — синтетика с посаженными багами: берёте чистый код, детерминированно вносите баг известного класса (off-by-one, утечка ресурса, неэкранированный ввод, гонка) и получаете пример, где эталонное ревью известно точно. Такие примеры дают то, чего нет у «живых» данных, — бесспорный ground truth для метрики recall.

Целевой объём: 800–2000 обучающих примеров, сбалансированных по языкам и классам проблем, плюс 100 отложенных диффов с посаженными багами для приёмки. Каждый пример — диалог в chat-формате: system с правилами ревью и схемой JSON, user с диффом, assistant с эталонным ревью. Весь конвейер второго урока — дедупликация, деконтаминация, проверка шаблона — применяется без скидок.

Тренировка: SFT, затем DPO по глубине

Первый этап — QLoRA SFT по рецепту третьего урока: r=16, alpha=32, target_modules="all-linear", learning rate 2e-4, две эпохи, чекпойнт после каждой. После обучения — ручная проверка: двадцать генераций на held-out диффах, глазами. Типичные болезни первой итерации: невалидный JSON на длинных диффах (лечится примерами длинных диффов в данных), находки без номера строки, пропуск багов в конце диффа — сигнал обрезки по max_seq_length, проверьте распределение длин.

Второй этап — DPO, и здесь он ложится идеально, потому что у ревью есть естественная ось предпочтений: глубина. Сэмплируйте по два ревью из SFT-модели на каждый дифф с посаженным багом (temperature 0,8). Chosen — ревью, которое нашло посаженный баг и не намусорило ложными срабатываниями; rejected — которое баг пропустило или утопило его в общих словах про стиль. Такое ранжирование почти автоматическое: наличие бага в находках проверяется скриптом. 300–500 пар, beta 0,1, learning rate 5e-7, одна эпоха.

Всё фиксируется для воспроизводимости: конфиги обучения в репозитории, seed, хэш датасета, версии библиотек. Через три месяца, когда стек изменится и понадобится ретрейн, «как мы это обучали» должно восстанавливаться командой, а не археологией.

Приёмка: критерии до обучения

Критерии приёмки фиксируются до первого прогона — это защита от подгонки под результат. Рабочий набор для ревьюера:

  • Recall посаженных багов: на 100 отложенных диффах модель находит не менее чем на 15 п.п. больше багов, чем база с лучшим промптом.
  • Шум: не более одного ложного срабатывания на дифф в среднем — ревьюера, который спамит, отключат через неделю.
  • Контракт формата: валидный JSON по схеме в 99%+ ответов, включая диффы вне обучающего распределения.
  • Win rate по полезности: side-by-side с откалиброванным судьёй против базы с лучшим промптом — не ниже 60%, доверительный интервал не накрывает 50%.
  • Регрессии: просадка на HumanEval не более 2 п.п. — ревьюер не должен разучиться понимать код.

Протокол — из пятого урока: рандомизация позиций, калибровка судьи на 30 парах против ваших вердиктов, интервалы по win rate. Отдельно прочитайте двадцать транскриптов: типичный скрытый провал — модель научилась триггериться на класс бага из синтетики и видит его там, где его нет.

Если приёмка не прошла — это нормальный исход первой итерации. Диагноз почти всегда в данных: recall низкий — мало примеров этого класса багов; шум высокий — в chosen попали многословные ревью; формат ломается — не хватает длинных и грязных диффов в обучении. Одна итерация по данным обычно даёт больше, чем любой перебор гиперпараметров.

Сервинг, интеграция и модельная карта

Финал — по маршруту шестого урока: мёрж в bf16, квантизация AWQ (GPU-сервинг) или GGUF Q5_K_M (локально/CPU), повторный прогон приёмочного eval на квантованном артефакте, vLLM-эндпоинт со смоук-тестом chat-шаблона.

Интеграция в процесс — GitHub Action: на каждый PR воркфлоу отправляет дифф на эндпоинт, полученный JSON превращает в inline-комментарии. Два продуктовых правила, которые решают судьбу инструмента: ревьюер комментирует только изменённые строки (не устраивает аудит всего файла) и молчит, когда находок нет, — доверие убивается шумом быстрее, чем пропусками.

Последний артефакт — модельная карта в репозитории: базовая модель и её лицензия, происхождение данных (сколько из логов, сколько синтетики, какие классы багов посажены), конфиги SFT и DPO, все числа приёмки с интервалами, известные ограничения (языки и фреймворки, которых модель не видела) и план ретрейна — при смене стека или падении онлайн-метрик ниже порога.

Этот цикл — данные → SFT → DPO → честная приёмка → квантованный сервинг → карта — и есть содержание курса. Он повторяется для любого следующего специалиста: суммаризатора инцидентов, генератора миграций, классификатора тикетов. Меняется датасет — рецепт остаётся.

Practice

Капстоун: ревьюер в проде

Пройдите полный цикл: датасет диффов с фильтрацией и посаженными багами, QLoRA SFT, DPO-пары «нашёл баг / пропустил», приёмка по зафиксированным критериям против базы с лучшим промптом, квантованный эндпоинт и модельная карта.

Deliverable

Репозиторий: скрипты данных, конфиги SFT/DPO, адаптер, отчёт приёмки с интервалами, работающий эндпоинт, отвечающий на реальный PR, и модельная карта.

Checkpoint

Представьте капстоун как релиз: покажите цифры приёмки, продемонстрируйте эндпоинт на живом диффе и защитите план ретрейна.

  • ✓ Критерии приёмки зафиксированы до обучения и включают recall багов, шум, формат и регрессии.
  • ✓ Цикл воспроизводим: конфиги, seed и хэш датасета в репозитории, приёмка прогнана на квантованном артефакте.
  • ✓ Эндпоинт отвечает на реальный дифф валидным JSON, модельная карта описывает данные, ограничения и план ретрейна.

Check yourself

Зачем в датасете ревьюера синтетические диффы с посаженными багами?

01Зачем в датасете ревьюера синтетические диффы с посаженными багами?

Как формируются пары для DPO ревьюера?

02Как формируются пары для DPO ревьюера?

Почему критерии приёмки фиксируются до обучения?

03Почему критерии приёмки фиксируются до обучения?

Приёмка не прошла по recall багов. Первый шаг?

04Приёмка не прошла по recall багов. Первый шаг?

Что обязательно входит в модельную карту?

05Что обязательно входит в модельную карту?

Sources

Capstone: a code-review specialist from a small model · LLM fine-tuning: LoRA, QLoRA, and when not to do it · VORCL