Замена LLM локальной моделью: как автор сэкономил на анализе Reddit-комментариев
Hacker News · оригинал
Материал подготовлен автоматизированной редакционной системой. Факты можно сверить по указанному первоисточнику.

Разработчик автоматизировал извлечение названий ножевых брендов и сталей из Reddit, обучив компактную модель GLiNER на метках, сгенерированных Gemini. Проект обошелся в $11.50 и позволил снизить затраты на API-вызовы при сохранении высокой точности.
Ценность: Кейс демонстрирует практический подход к снижению издержек на LLM: вместо постоянного обращения к дорогому API используется разовая генерация обучающих данных для локальной специализированной модели. Это актуально для задач, где объем данных растет линейно, а требования к латентности и стоимости критичны.
Автор проекта, увлеченный коллекционированием ножей, столкнулся с проблемой растущих расходов на API-вызовы Gemini 3.1 Pro. Изначально он использовал большую языковую модель для извлечения названий брендов, моделей и сталей из тысяч комментариев на Reddit. Хотя качество распознавания было высоким, стоимость росла пропорционально объему обсуждений, а единственный способ ограничить расходы — пропускать часть комментариев, что снижало полноту данных.
В качестве альтернативы автор рассмотрел открытую модель named-entity recognition (NER) GLiNER. В режиме zero-shot она демонстрировала точность около 0.65 F1, что было недостаточно для замены Gemini. Однако возник вопрос: можно ли обучить GLiNER на метках, сгенерированных Gemini один раз, чтобы закрыть этот разрыв в качестве и сделать работу модели бесплатной?
Ключевым решением в процессе подготовки данных стало требование к Gemini возвращать точные подстроки, а не позиции символов. Автор отметил, что LLM плохо считает индексы, часто ошибаясь на несколько позиций. Поэтому код на TypeScript самостоятельно находил смещения строк в тексте. Также в датасет были добавлены негативные примеры — комментарии со словами-триггерами (например, «углерод» или «рукоятка»), но без упоминания конкретных продуктов, чтобы модель научилась отличать категории от сущностей.
Самым сложным этапом стала отладка процесса обучения. Пять из десяти попыток завершились неудачей. Три провала были связаны с конфигурацией, а два — с ошибкой в тензоре words_mask. Автор заполнял его единицами и нулями, как обычную attention mask, не подозревая, что для GLiNER это индексы слов. Из-за этого модель пыталась найти сущности внутри одного гигантского токена, что приводило к плоской кривой потерь без ошибок в логах.
После исправления ошибки с words_mask шестая попытка обучения прошла успешно. Модель GLiNER large v2.5 (459M параметров) достигла точности 0.83 F1 на валидационном наборе из 225 комментариев, которые не участвовали в обучении. Обучение заняло 24 минуты на GPU Tesla T4. Общие затраты составили $9 за генерацию меток и около $2.50 за вычислительное время.
Автор подчеркивает важность проверки входных тензоров при работе с фреймворками вроде Hugging Face Trainer. Плоская кривая потерь может быть следствием как сложных данных, так и скрытых ошибок в коде препроцессинга. В данном случае проблема была именно в неверном понимании структуры входных данных модели.
Итогом проекта стала локальная модель, которая работает значительно дешевле LLM и способна корректно обрабатывать нюансы, такие как различие между «углеродистой сталью» как категорией и конкретными марками стали. Проект демонстрирует, что для узких задач NER специализированные компактные модели, обученные на синтетических данных от LLM, могут быть эффективным и экономичным решением.