Zero-shot классификация текста локальной LLM: гайд 2026 | AiManual
AiManual Logo Ai / Manual.
23 Апр 2026 Гайд

Как использовать локальную LLM в качестве zero-shot классификатора текста: гайд с примерами

Научитесь классифицировать тексты без тонкой настройки и API. Используем локальную LLM (Ollama, llama.cpp) для zero-shot. Пошаговый план, примеры, ошибки.

Zero-shot классификация: почему это не магия, а математика

Вы когда-нибудь пытались обучить BERT на своем корпусе тикетов? Я — да. Это боль. Нужна разметка, GPU на неделю, валидация, переобучение, поиск гиперпараметров. И тут приходит LLM и делает то же самое без обучения — по промпту. В 2026 году zero-shot классификация с помощью локальной LLM прочно заняла нишу быстрых прототипов и даже продакшена с невысокой нагрузкой. Модели вроде Qwen3.5 (70B), Llama 4 (405B) или Mistral Large 3 (123B) выдают качество, близкое к fine-tuned решениям, при этом ваши данные не покидают локальную машину. Но дьявол, как всегда, в деталях.

Zero-shot означает, что модель видит названия классов только в промпте и не требует примеров (few-shot). Достаточно одного внятного описания.

Как LLM умудряется классифицировать без обучения?

Секрет в том, что большие языковые модели обучены предсказывать следующее слово. Когда вы пишете: «Классифицируй текст как 'спам' или 'не спам'. Текст: ...», модель вычисляет вероятности для всех токенов и выбирает наиболее правдоподобное продолжение. Классы — это просто последовательности токенов. Если модель понимает контекст, она выдаст нужный токен. Этот подход работает, потому что на этапе претрейнга LLM видела миллионы инструкций и научилась следовать шаблонам.

Но есть нюанс: модель не «думает», она вычисляет условную вероятность. Если промпт составлен коряво, она может выдать «спам, потому что» вместо просто «спам». Или начать рассуждать вслух. Ваша задача — заставить её выдать ровно один токен из разрешённого списка. Об этом дальше.

Главные грабли (и как их обойти)

Ошибка №1: Модель возвращает лишний мусор — «Категория: позитивный» вместо «позитивный». Решение: используйте параметр logprobs и берите метку по максимальной вероятности.

Ошибка №2: Модель путает синонимы классов (например, «нейтральный» и «нейтрально»). Решение: всегда используйте один канонический формат меток и просите вернуть строго одну из них.

Ошибка №3: Дрейф логики при большом количестве классов (10+). Решение: разбивайте на бинарные классификации или используйте иерархический подход.

Если вы сомневаетесь, стоит ли вообще использовать LLM для этой задачи, советую почитать чек-лист в статье «Delegation Filter: когда НЕ использовать LLM в продакшн-пайплайнах». Там разобраны сценарии, где классификация через LLM избыточна.

Рабочий рецепт за 30 минут

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

1 Выберите модель и инструмент

Для русского языка хорошо подходят Mistral Large 3 (123B) или Qwen3.5-72B. Если ресурсов мало, можно взять Llama 4 8B — он хуже, но дешевле. Запускать лучше через Ollama (последняя версия на апрель 2026 — Ollama 0.7) — это самый простой способ. Альтернативы: llama.cpp, LM Studio. Подробный разбор инструментов — в этом обзоре.

Скачать Ollama: ollama.com. Можно запустить и на облачном GPU, если нет своего — например, RunPod даёт доступ к GPU по минутам.

2 Составьте жёсткий промпт

Вот пример плохого промпта: «Классифицируй этот отзыв на категории: позитивный, негативный, нейтральный. Отзыв: ...» — модель может выдать «позитивный, потому что клиент доволен». Хороший промпт должен содержать:

  • Чёткое указание вернуть только одну метку.
  • Формат вывода: {label}.
  • Инструкцию игнорировать всё, кроме метки.
Классифицируй отзыв на one из: позитивный, негативный, нейтральный. Выведи строго одну метку в формате {label}. Никаких пояснений. Отзыв: «Товар пришёл бракованный, не советую.»

С таким промптом модель почти всегда вернёт {негативный} — и парсить просто.

3 Получите логиты (или хотя бы logprobs)

Если вы используете llama.cpp или Ollama через API, запросите logprobs. Тогда вместо обрезки строки вы можете взять вероятности для каждого из трёх токенов: «позитивный», «негативный», «нейтральный». Это даёт calibration — если вероятность меньше 0.5, лучше откинуть результат как неуверенный. Для Ollama это делается параметром options: { logprobs: true }.

4 Пакетная обработка

LLM медленнее традиционных моделей. Один запрос — от 50 мс до 2 секунд в зависимости от размера модели и GPU. Поэтому не отправляйте тексты по одному — используйте батчинг (batch = 4-8) через многопоточность. Ollama поддерживает параллельные запросы. Но не перегружайте: если ошибка памяти, убавьте параллель.

Для высоконагруженных продакшенов стоит подумать о компромиссе: можно сначала прогнать через лёгкий классификатор (типа fastText), а на LLM отправлять только пограничные случаи. Идея описана в статье про минимальный размер LLM для классификации — там предлагают метод графа для понимания, когда без большой модели не обойтись.

Пример: классификация тикетов поддержки

Допустим, у вас десятки категорий: «оплата», «доставка», «возврат», «брак», «другое». Zero-shot справится, но есть риск, что модель будет путать «возврат» и «брак». Вот что помогает:

  • Добавьте в промпт краткие дефиниции: «возврат — инициатива клиента вернуть товар, брак — дефект производства».
  • Ограничьте число классов до 7-8. Если больше — используйте дерево: сначала бинарное ветвление («проблема с деньгами» vs «проблема с товаром»), потом внутри.
  • Тестируйте на размеченном датасете хотя бы из 100 примеров. Ошибки — нормально, но если accuracy падает ниже 70% — бейте классы дальше.
💡
Не забудьте про нормализацию текста: удаляйте лишние пробелы, переводите в нижний регистр (кроме имён собственных), обрезайте до 500 токенов — LLM не бесконечна.

Что ещё почитать?

Коллекция проверенных промптов для тестирования локальных LLM есть в отдельной статье: «Коллекция промптов для тестирования и сравнительного анализа локальных LLM». Там много готовых инструкций под разные задачи.

А если захотите пойти дальше и соединить классификацию с поиском — посмотрите гайд по RAG: «RAG за 15 минут: создаем свою систему на Python с нуля». Там как раз используется локальная LLM для анализа документов.

Частые вопросы (FAQ)

Сколько текстов можно обработать за минуту на домашнем GPU?

На RTX 4090 с Qwen3.5-14B — около 200-400 запросов в минуту при батчинге 4. Mistral Large 3 на том же GPU — ~30-50 запросов. Если нужно больше — либо берите меньшую модель, либо используйте облачные GPU.

Обязательно ли использовать logprobs?

Не обязательно, но сильно повышает надёжность. Без logprobs вы можете получить мусор, который разобьёт пайплайн. Рекомендую: если вероятность метки меньше 0.4, помечайте текст как «uncertain».

Какую модель выбрать для русского языка?

Лучшие на апрель 2026: Mistral Large 3 (отлично понимает русский), Qwen3.5-72B (дешевле), Saiga (Russian Mistral) — она специально дообучена. Но zero-shot через Saiga чуть хуже из-за меньшего разнообразия претрейна.

А если я хочу классифицировать на 50 классов?

Zero-shot с 50 классами — зона риска. Используйте иерархию или fine-tuning. Или возьмите эмбеддинги от LLM и обучите линейный классификатор — это быстрее и дешевле.

В конечном счёте, zero-shot классификация локальной LLM — отличный инструмент для быстрого старта и задач с невысокой нагрузкой. Но не забывайте про сравнение с традиционными подходами — иногда старый добрый TF-IDF с логистической регрессией уделывает LLM по скорости и цене.

Подписаться на канал