Компактная модель на 50 МБ заменила Gemini Flash во внутреннем приложении с бинарной классификацией строк. Итог: 97% точности и 0,06 секунды отклика на CPU против 99% и 0,9-1,2 секунды у API. Обучение заняло около 15 минут на RTX A6000 16 ГБ, а датасет вырос с 550 реальных примеров примерно до 2500 с помощью двух фронтир-моделей. Автор кейса считает потерю 2 процентных пунктов точности приемлемой платой за 15-20-кратный выигрыш в скорости (описание кейса на r/LocalLLaMA).
Сценарий выглядит как готовый рецепт, но работает он при стечении условий: узкая задача, высокая частота вызовов, жёсткие требования к задержке. Разберём, из чего сложился такой вывод и что стоит проверить в своём проекте.
Проблема: 0,9 секунды задержки при тысяче вызовов в день
Внутреннее приложение решало одну задачу: для пары строк a и b определить, связана ли строка b со строкой a определённым образом. Ответ - булево значение, никакой генерации текста. Формулировка промпта сводилась к вопросу вида "для 'строки a' и 'строки b' связана ли строка b со строкой a 'определённым образом'?"
Почему детерминированный код не подошёл
Первым вариантом был детерминированный код на Python и JavaScript. Он отвечал за пару миллисекунд, не требовал GPU, ключей и оплаты за токены. Точность - чуть более 66%, то есть примерно каждая третья классификация неверна.
Посчитаем на масштабе приложения: 1000 запросов в день дают около 340 ошибок. Пользователь либо перепроверяет каждый ответ вручную, либо перестаёт доверять инструменту. 66% оказались порогом, ниже которого автоматизация теряет смысл.
Почему Gemini Flash не устроил по скорости
Gemini Flash с минимальным бюджетом размышления давал 99% верных ответов и задержку 0,9-1,2 секунды в большинстве случаев. По качеству вариант подходил полностью.
0,9 секунды не выглядят проблемой, пока не умножить их на частоту: 1000 вызовов - это 15-20 минут чистого ожидания за день. Автор описывает это прямо: пользователи работают быстро, и пауза почти в секунду в таком режиме не работает. Бюджет размышления уже был выставлен на минимум, то есть это не медленный режим, а обычный рабочий.
Дело не в том, что Gemini Flash плохая. Она решает задачу почти безошибочно. Проблема в несоответствии задержки сценарию, где каждая операция занимает миллисекунды и повторяется тысячи раз в день.
Когда стоит обучать свою маленькую модель вместо вызова API
Из кейса складывается чек-лист условий, при которых своя компактная модель окупается:
- Задача узкая. Бинарная классификация по фиксированному правилу, без длинного контекста и рассуждений.
- Высокая частота однотипных вызовов. Тысячи запросов в день, где задержка умножается на количество операций.
- Жёсткий лимит по отклику. Ориентир кейса - сотые доли секунды, чтобы пауза не ощущалась.
- Есть несколько сотен реальных примеров. Отправной точкой стали около 550 примеров использования.
- Допустимо падение точности на 1-3 процентных пункта. Именно такой разрыв оказался приемлемым между 99% и 97%.
- Есть причина держать данные внутри. Работа без интернета, чувствительные данные, независимость от внешнего API.
Обратные случаи встречаются чаще. Если задача меняется каждую неделю, требует широких знаний или генерации текста, обученная с нуля компактная модель проиграет фронтир-модели. Если примеров меньше пары сотен, обучать по сути не на чем. Если пользователей десятки и задержка не мешает, вызов API дешевле по времени разработки и поддержки.
Перед сравнением вариантов стоит зафиксировать метрики: качество, задержку, цену, требования к железу. Логику такой оценки описывает материал о том, как оценивать новые AI-модели без шума вокруг релизов.
Сравнение трёх подходов: код, API, локальная модель
| Подход | Точность | Задержка | Что нужно для работы |
|---|---|---|---|
| Детерминированный код на Python и JavaScript | чуть более 66% | пара миллисекунд | ничего, кроме кода |
| Gemini Flash | 99% | 0,9-1,2 с | внешний API, сеть, ключи, оплата токенов |
| Компактная модель около 50 МБ | 97% | 0,06 с на CPU | обучение на своих данных, мониторинг, дообучение |
Выбор сводится к приоритету. Нужна максимальная точность и нет ограничений по времени отклика - берите API. Нужна скорость и автономность - учите свою модель. Детерминированный код остаётся фоном: он даёт мгновенный ответ, но его точности хватает не всегда, и именно этот разрыв закрывает обученная модель.
Подготовка данных: как из 550 примеров сделать 2500
В кейсе было около 550 реальных примеров использования. Этого мало для обучения с нуля: модель либо запомнит конкретные примеры, либо не выучит закономерность. Автор расширил набор с помощью двух разных фронтир-моделей и получил примерно 2500 обучающих примеров.
Как использовать фронтир-модели для генерации примеров
Механика простая: сильная модель берёт реальный пример и создаёт похожие - перефразирует формулировки, меняет контекст, заменяет сущности, добавляет шум. Метка класса сохраняется. Две модели вместо одной нужны для разнообразия: у каждой свои шаблоны формулировок, и смесь получается менее однородной.
По смыслу это близко к дистилляции: большая модель производит разметку, компактная учится её воспроизводить на своей архитектуре. Отличие в масштабе - переносится не общее поведение модели, а решение одной узкой задачи. Механику и подводные камни дистилляции разбирает отдельный материал о сжатии моделей без потери качества.
Риски предсказуемы. Сгенерированные пары могут содержать неверные метки, если фронтир-модель ошиблась на сложном случае. Что снижает риск: выборочная ручная проверка подвыборки, фильтрация примеров с низкой уверенностью генератора, контроль баланса классов, чтобы один класс не доминировал. Автор не уточняет, как именно проверялась корректность сгенерированных данных, поэтому эту часть стоит закрывать самостоятельно.
Обучение модели: 15 минут на RTX A6000 16 ГБ
Обучение шло на GPU RTX A6000 16 ГБ и заняло около 15 минут. Итоговая модель весит около 50 МБ. Никаких кластеров и многодневных прогонов: для задачи такого размера хватает одной рабочей станции.
Деталей архитектуры и гиперпараметров автор не приводит, поэтому повторить конфигурацию один в один не получится. Но порядок цифр полезен сам по себе: 15 минут на одной GPU - это эксперимент, который можно позволить себе несколько раз за вечер.
Какое железо нужно для обучения и инференса
Для обучения нужна GPU с 16 ГБ VRAM уровня RTX A6000. Менее мощная карта справится, но обучение займёт больше времени, насколько именно - зависит от модели и датасета.
Для инференса достаточно CPU, причём старого: в кейсе это Threadripper на 3,1 ГГц. GPU в работе не участвует. Это главное практическое преимущество схемы: обучение требует ускорителя, а эксплуатация обходится обычным процессором.
0,06 секунды на CPU означают, что модель не нужно тащить в браузер через WebGPU или WASM. Автор рассчитывает, что задержка 0,1-0,2 секунды при серверном запуске окажется достаточно быстрой и позволит избежать клиентского инференса.
Оценка результата: 97% точности и 0,06 секунды на CPU
Локальный запуск на CPU (старый Threadripper 3,1 ГГц) даёт верный ответ в 97% случаев и отклик 0,06 секунды. Автор называет разницу между 99% и 97% точности полностью приемлемой для этой задачи (исходное описание кейса).
- Gemini Flash: 99% точности, 0,9-1,2 секунды на ответ.
- Локальная модель 50 МБ: 97% точности, 0,06 секунды на CPU.
На тысяче операций это превращается в 15-20 минут ожидания против одной минуты. Ошибок становится больше примерно на 20 классификаций из 1000 (те самые 2 процентных пункта), но каждая из них стоит миллисекунды и не блокирует работу пользователя.
Как понять, какое падение точности допустимо
Универсального порога нет, есть процедура. Сначала разделите ошибки на два типа и оцените их цену. Ложноположительный ответ, из-за которого пользователь сделает лишний шаг, обычно дешевле ложноотрицательного, из-за которого шаг пропустят. Затем посчитайте, сколько таких ошибок добавится на реальном объёме: 2 процентных пункта - это 20 случаев на 1000 операций. Сравните их с выигрышем в 15-20 раз по задержке. Если ошибка исправляется за пару секунд, а экономия времени измеряется минутами, обмен в пользу локальной модели.
Если ошибка ведёт к финансовым потерям, нарушениям безопасности или порче данных, ориентир другой: там 97% может оказаться недостаточно, и разумнее оставить API или добавить проверку вторым проходом. В кейсе условия мягкие, поэтому автор счёл 97% достаточными.
Проверить решение можно на живых пользователях: логировать предсказания, сравнивать их с эталоном или ручной разметкой. A/B-тест показывает, как падение точности отражается на реальных действиях, а не на метрике в отрыве от сценария.
Развёртывание и поддержка: что дальше
Автор планирует запустить модель на сервере. Серверная задержка окажется немного выше локальных 0,06 секунды, а сам сервер может быть медленнее рабочей станции. Ожидание - 0,1-0,2 секунды, и этого должно хватить без клиентского инференса.
Зачем логировать точность и сравнения
Логи решают три задачи. Первая - заметить деградацию: когда входные данные меняются, точность модели может тихо падать. Вторая - собрать новые примеры для дообучения из реальных случаев, включая те, где модель ошиблась. Третья - сравнивать предсказания с эталоном или результатом другой системы, чтобы понимать, где именно локальная модель уступает.
Автор прямо указывает, что ведёт логирование точности и сравнений, чтобы оценивать работу модели и дополнять обучение новыми данными. Для моделей в продакшене это стандартная практика: обучение заканчивается не в момент сохранения весов, а продолжается сбором данных и периодическим дообучением.
Ограничения и риски подхода
Все цифры кейса взяты из описания автора, независимого подтверждения метрик нет (первоисточник). Это стоит учитывать при переносе выводов на свой проект.
- 97% точности и 0,06 секунды относятся к локальному запуску на CPU. При серверном развёртывании задержка вырастет, а точность может отличаться.
- На момент описания решение ещё не было развёрнуто: деплой планировался на выходные, а ожидаемая задержка 0,1-0,2 секунды остаётся предположением.
- Приемлемость падения точности с 99% до 97% заявлена для конкретной задачи, а не как общее правило.
- Сгенерированные фронтир-моделями примеры могут содержать неверные метки, и это снизит качество обучения. О способе проверки автор не сообщает.
- Модель узкоспециализирована: для другой задачи понадобится новый датасет и новое обучение.
- Появляется новая зона ответственности: обновление модели, мониторинг, дообучение. API эту работу берёт на себя.
Отдельный риск - зависимость от фронтир-моделей на этапе подготовки данных. Если генератор примеров ошибается систематически, ошибка попадёт в обучающий набор и останется в модели. Сравнение закрытых API и открытых моделей по качеству и стоимости помогает понять, где локальные модели уже практичны, а где пока уступают.
Пошаговый план: как повторить этот кейс
- Проверьте задачу: она сводится к простой классификации с фиксированным правилом? Если нужны рассуждения, длинный контекст или генерация текста, маленькая обученная модель не тот инструмент.
- Соберите реальные примеры, ориентир - 500 и больше. Меньше двух сотен делает обучение лотереей.
- Расширьте датасет двумя разными фронтир-моделями до 2000-2500 примеров, сохраняя метки. Проверьте подвыборку вручную и выровняйте классы.
- Обучите компактную модель на одной GPU с 16 ГБ VRAM. Ориентир по времени - около 15 минут на RTX A6000.
- Замерьте точность и задержку на CPU, который стоит в продакшене, а не только на машине для обучения.
- Сравните с текущим решением. Если разрыв в точности 1-3 процентных пункта, а выигрыш в скорости кратный, переносите на сервер.
- Настройте логирование предсказаний и эталонных ответов, чтобы замечать деградацию и собирать данные для дообучения.
Гиперпараметры, архитектуру и способ валидации сгенерированных данных автор не раскрыл, поэтому план остаётся рамкой, а не инструкцией с точными значениями. Если задача не сводится к узкой классификации, начинать с обучения своей модели не стоит: время уйдёт на датасет и поддержку, а точность всё равно останется ниже, чем у фронтир-модели.