Перейти к содержимому
30 окт. 2024 г.·8 мин чтения

Fine-tuned open-weight модель: когда она выгоднее API

Fine-tuned open-weight модель окупается не всегда: разбираем, где она даёт ниже задержку, больше контроля над данными и понятную экономику.

Fine-tuned open-weight модель: когда она выгоднее API

Почему тут легко переплатить

Переплата начинается в тот момент, когда команда смотрит только на цену за 1 млн токенов. На бумаге закрытый API может казаться дешевле, чем fine-tuned open-weight модель на своих GPU. Но в продакшене платят не только за генерацию. Платят за время пользователя, за повторные запросы и за людей, которые потом разбирают неудачные ответы.

Задержка часто бьет по бюджету сильнее, чем разница в тарифе. Если ответ приходит не за 1,5 секунды, а за 5-7, пользователь жмет кнопку еще раз, оператор уходит в ручной режим, а цепочка в бэкенде ждет дольше. В чатах поддержки это быстро превращается в лишние минуты работы. В голосовых сценариях и внутренних ассистентах такой скачок просто ломает поток.

Есть и менее заметная статья расходов - ручная проверка. Если модель отвечает нестабильно, команда добавляет фильтры, выборочную модерацию, повторный прогон через другую модель или разметку силами сотрудников. Сначала это выглядит как временная мера. Через месяц оказывается, что на проверку уходит больше денег, чем на сами вызовы API.

Поэтому считать нужно не одну цену, а весь сценарий целиком: стоимость типового запроса, среднюю и p95 задержку, долю ответов, которые уходят на ручную проверку, и разницу между пилотом и боевой нагрузкой.

Пилот почти всегда врет в лучшую сторону. На малом объеме мало длинных диалогов, почти нет пиков, кэш работает лучше, а команда следит за результатом вручную. Когда трафик вырастает в 10 раз, всплывают длинные хвосты по задержке, растет число спорных ответов, и экономика меняется.

Хороший пример - разбор обращений клиентов в банке. На тесте из 500 тикетов закрытый API может выглядеть аккуратно и недорого. На потоке в 200 000 обращений в день добавляются повторы, ночные пики, требования к журналированию и проверка спорных случаев. В этот момент своя дообученная модель иногда выигрывает не по цене токена, а по сумме всех расходов.

Если команда не считает полную стоимость сценария, она почти наверняка сравнивает не те цифры.

Когда своя модель дает заметный плюс

Своя модель выигрывает не там, где задача просто "умная", а там, где она узкая и повторяется сотни или тысячи раз в день. Если вы снова и снова просите систему извлечь поля из документа, разметить обращение, присвоить тег или проверить текст по правилам, модель начинает работать как предсказуемый рабочий инструмент, а не как дорогой универсальный собеседник.

Особенно это заметно, когда ответ нужен в строгом формате. Закрытый API часто пишет лишние пояснения, меняет структуру JSON или по-разному трактует одно и то же правило. Fine-tuned open-weight модель обычно проще приучить к короткому и стабильному выводу. Для продакшена это не мелочь. Один лишний абзац может сломать пайплайн, а одно пропущенное поле отправит документ на ручную проверку.

Такой подход особенно хорошо работает, когда задача много раз повторяется в течение дня, у команды уже есть хорошие примеры из реальной работы, ответ должен укладываться в шаблон, пользователи ждут результат за 1-2 секунды, а данные нежелательно выводить за свой контур.

Хороший пример - разбор входящих обращений. Допустим, банк получает тысячи сообщений в день и для каждого нужно определить тему, срочность, продукт и следующий шаг. Если команда уже накопила историю таких обращений, дообученная модель часто дает более ровный результат, чем внешний API общего назначения. Она отвечает короче, реже уходит в лишние пояснения и лучше держит нужные категории.

С задержкой картина тоже простая. Когда модель стоит ближе к вашим сервисам и не проходит длинную цепочку внешних вызовов, ответ обычно приходит быстрее и ровнее по времени. Для чата это просто приятно. Для голосового сценария, антифрода или интерфейса оператора это уже влияет на сам продукт.

Отдельный плюс - контроль данных. Если в запросах есть персональные данные, внутренние коды, номера договоров или служебные тексты, свой контур снимает много лишних вопросов у ИБ и юристов. Для российских команд это часто не абстракция, а обычное требование. Если модель хостится в РФ и логи остаются внутри страны, пилот согласовать проще.

Своя модель не нужна для любой задачи подряд. Но когда процесс массовый, формат строгий, а данные чувствительные, выгода быстро перестает быть теорией.

Где закрытый API остается разумным выбором

Fine-tuned open-weight модель не всегда лучший первый шаг. Закрытый API часто проще и честнее по затратам, если сама задача еще не устоялась. Когда сценарии меняются каждую неделю, своя модель быстро превращается в движущуюся цель: команде приходится заново собирать примеры, переобучать модель и ловить новые ошибки.

Это особенно заметно в продуктах, где команда еще ищет рабочий формат. Сегодня нужен краткий ответ, завтра - строгий шаблон, через месяц - новый тон и другая логика маршрутизации. В такой фазе гибкость закрытого API обычно полезнее, чем тонкая настройка своей модели.

Есть и другой частый случай: нужен не один узкий навык, а широкий круг знаний. Если ассистент отвечает и про тарифы, и про документы, и про ошибки в приложении, и про редкие вопросы вне скрипта, большая закрытая модель часто держит такой разброс лучше. Fine-tune обычно сильнее там, где поведение можно описать большим числом похожих примеров.

Экономика тоже быстро ставит все на место. При маленьком объеме запросов своя инфраструктура редко окупается. На бумаге инференс может казаться дешевым, но потом появляются GPU, мониторинг, резервный маршрут, обновления моделей и время инженеров. Если у вас сотни или даже несколько тысяч запросов в день, закрытый API часто дает более спокойную модель расходов.

Еще одна проблема - отсутствие данных и метрики качества. Без размеченного набора запросов команда обычно спорит по ощущениям: этот ответ "кажется лучше", тот "звучит увереннее". Так легко выбрать плохой путь. Сначала полезнее собрать реальные диалоги, отметить ошибки и решить, что считать хорошим результатом: точность извлечения, длину ответа, долю эскалаций или что-то еще.

Для российских команд практичный путь часто такой: сначала прогнать один и тот же набор задач через несколько API-моделей, сравнить цену, задержку и качество, а уже потом решать, нужен ли свой fine-tune. Если модельный выбор можно менять без переписывания кода, этот этап проходит заметно быстрее. И только когда задача стала стабильной, узкой и объемной, своя модель начинает выглядеть сильнее закрытого API.

Как измерить задержку честно

Средняя задержка почти всегда врет. Если сравниваете fine-tuned open-weight модель и закрытый API, одного числа недостаточно.

Смотрите хотя бы на p50 и p95. p50 показывает обычный день, а p95 быстро вскрывает хвосты, которые ломают UX и очереди в сервисе. Если есть всплески трафика, отдельно снимайте пики под нагрузкой, иначе тест получится слишком красивым.

Еще одна частая ошибка - мерить только "ответ модели". Пользователь ждет не абстрактный инференс, а весь путь запроса. Поэтому полезно раскладывать задержку на части: сеть до API и обратно, время в очереди, токенизацию и подготовку запроса, время до первого токена и полную генерацию ответа.

Так сразу видно, где именно проигрыш. Иногда сама модель отвечает быстро, но очередь перед GPU съедает секунды. Бывает и наоборот: закрытый API стабилен по очередям, но теряет время на сети и длинной генерации.

Сравнение должно быть симметричным. Гоняйте один и тот же набор промптов, одинаковый лимит ответа и одинаковые настройки температуры, если она влияет на длину текста. Иначе вы сравниваете не модели, а разные сценарии.

Отдельно проверьте холодный старт. Для своей модели это может быть загрузка воркера, прогрев кэша или подъем редкого маршрута. Для внешнего API холодный старт тоже встречается, просто команда часто не видит его напрямую и списывает скачок на "плохую сеть".

Нагрузочные тесты на одном запросе почти бесполезны. Берите рабочий поток. Например, в банке один пользовательский диалог может включать классификацию обращения, извлечение полей, короткое резюме для оператора и финальный ответ клиенту. Если мерить только последний шаг, реальную задержку цепочки вы не увидите.

Нормальный тест выглядит скучно, и это хорошо. Один и тот же клиентский код, один и тот же формат запросов, несколько уровней нагрузки и длинная серия прогонов, чтобы поймать редкие провалы. Если вы тестируете через OpenAI-совместимый шлюз вроде RU LLM, удобно держать один SDK и менять только маршрут модели. Так разница в цифрах ближе к правде, а не к особенностям обвязки.

Ориентир тут простой: если p50 красивый, а p95 и пики плохие, сервис уже будет раздражать людей. Решение принимают не по лучшему ответу из теста, а по тому, как система ведет себя в обычный вторник в 11:30.

Как посчитать окупаемость по шагам

Проверьте контур под 152-ФЗ
Если важен 152-ФЗ, держите логи и бэкапы на серверах в РФ.

Считать лучше не "модель против модели", а один конкретный сценарий. Например, авторазбор входящих обращений, где у вас уже есть понятный поток запросов каждый день. Если смешать в один расчет чат, поиск, суммаризацию и проверку документов, цифры быстро станут бесполезными.

Сначала зафиксируйте базу за обычный день или неделю: сколько запросов приходит, сколько токенов уходит на вход, сколько модель генерирует на выходе и как часто система делает повторы. Повторы почти всегда недооценивают. Если 12% запросов отправляются заново из-за таймаутов, неудачных ответов или лишних проверок, это уже заметно меняет экономику.

Дальше раскладывайте расходы по понятным блокам. Для закрытого API посчитайте цену входных и выходных токенов, а затем прибавьте повторы и ретраи. Для своей модели посчитайте аренду или стоимость GPU в пересчете на час, среднюю пропускную способность, хранение, мониторинг и поддержку. Fine-tune тоже добавляйте в расчет, но не целиком за один месяц, а как амортизацию на тот срок, в течение которого вы реально планируете использовать модель. Отдельной строкой внесите цену ошибок: ручные правки, повторную обработку, потерянное время операторов и случаи, где слабый ответ запускает второй запрос.

На практике это выглядит просто. Если API стоит 900 рублей в день при вашем объеме, а своя модель обходится в 600 рублей GPU и еще в 150 рублей на сопровождение, разница уже видна. Но если своя модель еще и дает на 8% меньше ошибок и экономит команде два часа ручной правки, она окупается быстрее, чем кажется по одной только цене токенов.

Точку окупаемости ищут так: делят фиксированные затраты на fine-tune и запуск на разницу в переменной стоимости одного запроса. Если закрытый API обходится в 0,9 рубля за запрос, а fine-tuned open-weight модель - в 0,45 рубля, то каждый запрос экономит 0,45 рубля. При затратах на запуск 450 000 рублей окупаемость начинается примерно с 1 млн запросов.

Если у вас уже стоит OpenAI-совместимый шлюз, например RU LLM, не берите усредненные оценки из презентаций. Возьмите реальные логи по токенам, повторам и маршрутам моделей. Обычно именно там и прячется настоящая экономика.

Что дает контроль кроме цены

Когда команда держит модель под своим управлением, она получает не только другую экономику. Она убирает часть случайности из продакшена. Для сервисов с очередями, SLA и проверками это часто важнее, чем разница в цене за токен.

Первое, что меняется, - вы фиксируете версию модели. Закрытый API может внезапно начать отвечать чуть иначе: поменяется стиль, структура JSON, длина ответа или качество на узком кейсе. Для демо это терпимо. Для скоринга заявок, разбора обращений или маршрутизации тикетов это уже риск. Если модель настроена и закреплена на вашей стороне, вы сами решаете, когда обновляться и что тестировать перед релизом.

Второй плюс - формат ответа. Многие команды теряют время не на сам инференс, а на разбор того, что модель вернула. Если процесс требует строгую схему, поля confidence, причины решения и короткое объяснение для оператора, свою fine-tuned open-weight модель проще приучить к этому поведению. Тогда приложение меньше чинит ответ после модели, а пайплайн ломается реже.

Отдельная история - персональные данные. Когда маскирование стоит рядом с приложением и рядом же идет инференс, поток данных проще контролировать. Вы заранее скрываете ФИО, телефоны, номера договоров и отправляете в модель уже очищенный текст. В российском контуре это особенно заметно: меньше лишних передач, проще описать процесс для ИБ и комплаенса, легче показать, где именно лежат логи и бэкапы. Если команде нужен единый API-слой с хранением логов в РФ и встроенными аудит-трейлами, такие требования можно закрывать через RU LLM без смены привычного SDK.

Контроль хорошо виден в тестах. Когда модель, промпт, температура и схема ответа зафиксированы, вы можете честно сравнивать релизы между собой. Это уже не спор в стиле "кажется, стало лучше". Это таблица, где видно, на каких классах запросов качество выросло, где упала точность и сколько ошибок дает новая настройка.

Обычно команде достаточно держать под контролем четыре вещи: версию модели, шаблон ответа, правила маскирования PII и набор регрессионных тестов. Такой набор не делает систему идеальной, зато делает ее предсказуемой. А в продакшене предсказуемость почти всегда полезнее, чем редкий всплеск качества на чужом закрытом API.

Пример: разбор обращений в банке

Держите откат под рукой
Оставьте один клиент и переключайте трафик между внешними API и open-weight моделями.

У банка чат поддержки редко начинается с длинного описания проблемы. Чаще клиент пишет 5-10 слов: "не пришел перевод", "списали два раза", "не могу войти", "карта заблокирована". Для такой очереди не нужен большой универсальный ответчик. Нужна модель, которая быстро и одинаково раскладывает поток по понятным классам.

Если банк уже знает, что почти все сообщения попадают примерно в два десятка категорий, задача становится очень прикладной. Модель должна определить класс, срочность и следующий маршрут. Иногда ей нужно еще понять, хватает ли данных для ответа.

В этом месте закрытый API часто дает хорошую точность, но у него есть неприятная черта: в пиковые часы время ответа прыгает. Утром после зарплатного дня, в конце месяца или во время сбоя в мобильном приложении это видно сразу. Оператор ждет дольше, очередь растет, а часть диалогов уходит на ручную сортировку.

Fine-tuned open-weight модель обычно выигрывает не "умом вообще", а предсказуемостью. Если дообучить ее на обезличенной истории обращений и жестко задать формат вывода, она стабильно возвращает класс обращения, уровень приоритета, очередь для маршрутизации и короткую причину выбора.

Для банка это удобно еще и потому, что формат не плывет. Интеграция в CRM проще, а проверки работают без лишней логики. Если команде нужен контур внутри РФ, такую модель можно держать на своей инфраструктуре или на хостинге open-weight моделей в российских ЦОДах.

Экономия появляется не на редких запросах, а на плотном потоке в течение всего дня. Если банк обрабатывает тысячи коротких сообщений в час, цена каждого вызова и задержка инференса быстро становятся заметны в бюджете поддержки. Затраты на дообучение и сопровождение окупаются быстрее, потому что запросы короткие, классы стабильные, а формат ответа один и тот же.

Такой сценарий не требует самой сильной модели на рынке. Он требует модели, которая не ломает JSON, не думает лишние две секунды и не меняет ответ на одинаковых сообщениях. Для первичной сортировки в банке это часто лучше, чем более умный, но менее ровный закрытый API.

Где команды ошибаются

Fine-tuned open-weight модель часто проигрывает не потому, что сам подход плохой, а потому что команда ошибается в постановке задачи. Самый частый промах простой: берут модель слишком большого класса "на вырост". Для короткой классификации писем, тегирования диалогов или извлечения полей 7B или 14B нередко хватает, а 70B только поднимает цену, требования к GPU и задержку.

Еще одна частая ошибка - начинать дообучение до того, как есть baseline и понятная метрика. Команда собирает датасет, запускает обучение, тратит неделю, а потом не может честно ответить, стало ли лучше. Сначала нужен простой ориентир: хороший промпт, несколько примеров в контексте, один закрытый API для сравнения и метрика под задачу. Для банка это может быть F1 по классам обращений, а не общее "модель вроде отвечает лучше".

Проблемы начинаются и там, где в один контур пытаются засунуть сразу несколько разных задач: поиск по базе знаний, классификацию и генерацию ответа. Тогда трудно понять, что именно сломалось и где тратятся деньги. Если retriever находит слабые документы, дообучение генеративной модели не спасет. Если задача вообще решается обычным классификатором, дорогая генерация только мешает.

С данными команды тоже часто спешат. Они не чистят дубли, оставляют шумные примеры, тащат противоречивую разметку из разных источников. В итоге модель запоминает мусор и ведет себя неровно. Одинаковые обращения в датасете могут искусственно поднять метрику на валидации, а в проде качество потом резко падает.

Перед запуском пилота стоит проверить простые вещи: какая самая маленькая модель уже держит нужное качество, есть ли baseline на промптах или закрытом API, разделены ли поиск, классификация и генерация по этапам, почищены ли дубли и спорная разметка, а также посчитаны ли не только GPU, но и работа команды.

Последний пункт недооценивают чаще всего. В экономику LLM входят не только серверы. Нужно считать разметку, обучение, A/B-тесты, мониторинг качества, хранение логов, обновление моделей, дежурства инженеров и откат релизов. Если этого нет в расчете, своя модель почти всегда кажется дешевле, чем есть на самом деле.

Для команд с российским контуром это заметно особенно хорошо. Если модель работает внутри РФ, вы выигрываете в контроле данных и задержке. Но выгода появляется только тогда, когда задача узкая, метрика ясная, а расчет сделан полностью, без логики в духе "железо стоит недорого, значит все окупится".

Быстрая проверка перед пилотом

Запустите open-weight в РФ
Если нужен свой контур, используйте open-weight модели на GPU в российских ЦОДах.

Пилот имеет смысл не для любой задачи. Лучше всего он работает там, где запросы похожи друг на друга и повторяются каждый день. Если у вас десятки сценариев с разной логикой, вы не поймете, модель не тянет задачу или команда смешала слишком много условий в одном тесте.

Хороший кандидат выглядит просто: одна операция, много однотипных входов, понятный результат. В банке это может быть разбор входящих обращений по темам и извлечение пары полей из текста. В таком случае fine-tuned open-weight модель часто дает честный сигнал уже на пилоте.

Перед стартом полезно проверить пять вещей. Задача должна быть узкой, а повторы - частыми. У вас должно быть хотя бы несколько сотен хороших примеров, не сырых логов, а данных после чистки и с внятной разметкой. Команда должна заранее выбрать метрику: для одной задачи это accuracy, для другой F1, для третьей доля ответов без опасных ошибок. Нужна понятная цель по задержке и по пику нагрузки, а не просто ощущение, что модель отвечает "быстро". И наконец, нужен план отката: если качество просело или очередь на инференс выросла, трафик должен уйти на внешний API без ручной паники.

С данными команды ошибаются чаще всего. Пятьсот примеров могут хватить для пилота, если они чистые и покрывают реальные случаи. Те же пятьсот примеров бесполезны, если половина разметки спорная, а редкие, но дорогие ошибки никто не отметил.

Метрику тоже стоит привязать к бизнесу. Если модель сортирует обращения, допустимая ошибка одна. Если она пишет ответ клиенту, порог обычно жестче. Полезно сразу записать, какой результат вы считаете проходным, а какой закрывает пилот.

План отката лучше продумать до первого теста. Если у вас есть OpenAI-совместимый слой вроде RU LLM, такой откат можно сделать через конфиг и маршрут, без переписывания клиента. На бумаге это выглядит мелочью. На практике именно это часто спасает пилот, когда нагрузка в пике оказывается выше прогноза.

Что делать дальше

Не начинайте с большой миграции. Возьмите одну задачу, где результат легко проверить: разбор обращений, извлечение полей из документов, классификацию диалогов или короткие ответы по базе знаний. Для первого прогона хватит одной метрики, например доли правильной классификации или p95 по задержке.

Сначала сравните 2-3 open-weight модели без fine-tune. Это скучный, но полезный шаг. Команды часто сразу идут в дообучение, а потом выясняют, что базовая модель уже закрывала задачу на приемлемом уровне. Fine-tuned open-weight модель окупается лучше только там, где прирост заметен в реальной работе, а не на красивом демо.

После этого дайте моделям настоящий трафик хотя бы на коротком пилоте. Не считайте экономику по таблице с примерными токенами. Смотрите на живые запросы: среднюю длину входа и выхода, пики нагрузки, долю повторов, ошибки маршрутизации и время ответа под очередью. Именно здесь часто меняется вся картина по цене и задержке.

Дальше решение обычно простое. Если после теста закрытый API все еще дешевле или точнее, оставьте его для этой задачи. Если своя модель дает меньшую задержку, стабильный формат ответа, более понятную работу с данными и предсказуемый счет, тогда есть смысл двигаться дальше.

Для команд, которым нужен российский контур, RU LLM может быть удобной точкой входа: один OpenAI-совместимый endpoint, возможность менять маршрут моделей без переписывания SDK и хостинг open-weight моделей в российских ЦОДах. Для пилота это часто практичнее, чем сразу собирать весь контур своими силами.

Часто задаваемые вопросы

Когда своя fine-tuned модель реально выгоднее закрытого API?

Своя модель обычно окупается на узкой и массовой задаче. Если вы тысячи раз в день классифицируете обращения, извлекаете поля или отдаете ответ в строгом JSON, fine-tune часто снижает задержку, число повторов и объем ручной проверки.

На малом трафике или в сыром сценарии закрытый API чаще выходит проще и дешевле.

Какие задачи лучше всего подходят для fine-tune?

Лучше всего подходят повторяющиеся операции с понятным результатом. Это разбор обращений, тегирование диалогов, извлечение данных из документов, проверка текста по правилам и короткие ответы по шаблону.

Если задача требует широкий круг знаний и часто меняется, универсальный API обычно держится лучше.

Почему цена за токен не показывает реальную стоимость?

Смотрите не только на тариф, а на весь путь запроса. Деньги съедают повторы, таймауты, длинная генерация, ручные правки и время операторов.

Иногда модель с более высокой ценой за токен дает меньший общий счет, потому что отвечает быстрее и ломает меньше сценариев.

Почему пилот часто показывает слишком хороший результат?

Пилот почти всегда выглядит лучше боевой нагрузки. На тесте меньше длинных диалогов, реже приходят пики, кэш помогает сильнее, а команда сама следит за спорными ответами.

Проверяйте модель на рабочем потоке, а не на маленькой красивой выборке.

Как честно сравнить задержку двух моделей?

Не смотрите только на среднее время ответа. Снимайте хотя бы p50 и p95, меряйте время до первого токена и полную генерацию, а также проверяйте поведение на пике.

Гоняйте один и тот же набор промптов с одинаковыми настройками. Иначе вы сравните разные режимы, а не модели.

Сколько данных нужно для первого пилота?

Для первого пилота часто хватает нескольких сотен чистых и размеченных примеров. Этого достаточно, чтобы увидеть, держит ли модель формат, категории и нужную скорость.

Сырые логи без чистки пользы почти не дают. Лучше меньше данных, но с понятной разметкой и реальными ошибками.

Как посчитать окупаемость по шагам?

Берите один сценарий и считайте стоимость одного запроса целиком. Внесите токены, GPU или аренду, повторы, мониторинг, поддержку, ручную проверку и цену ошибок.

Потом сравните переменную стоимость запроса и разделите затраты на запуск на экономию с одного вызова. Так вы увидите порог окупаемости без догадок.

Что свой контур дает кроме экономии?

Вы сами фиксируете версию модели, формат ответа и правила маскирования данных. Это убирает случайные изменения, из-за которых вчерашний JSON работал, а сегодня ломает пайплайн.

Для команд с персональными данными такой подход еще и упрощает разговор с ИБ и юристами.

Когда лучше оставить закрытый API?

Если сценарий меняется каждую неделю, лучше не спешить со своей моделью. Закрытый API удобнее там, где команда еще ищет формат, пробует разные промпты и не накопила нормальный датасет.

Он же часто выигрывает на маленьком объеме запросов, когда своя инфраструктура еще не успевает окупиться.

Как запустить пилот и не сломать продакшен?

Не тащите сразу весь трафик на новую модель. Возьмите одну задачу, задайте проходную метрику, подготовьте откат на внешний API и дайте пилоту короткий, но живой поток.

Если вы работаете через OpenAI-совместимый слой вроде RU LLM, можно менять маршрут модели без переписывания клиента. Это сильно упрощает тест и откат.