Один из самых частых вопросов, которые прилетают в IT-отдел после запуска локального AI-сервиса: «а почему модель плохо пишет код» или «почему она такая тупая в аналитике». Обычно ответ прост — для задачи выбрана не та модель. Open-source LLM сегодня развились настолько, что универсального победителя на все случаи жизни не существует: одна модель отлично пишет код, но слабовата в свободном диалоге, другая прекрасно поддерживает разговор, но путается в математике. Разберём, какие модели на практике стоит ставить на srv-ai01 под конкретные задачи компании — кодинг, поддержку клиентов и аналитику данных.

Кодинг: Qwen2.5-Coder и DeepSeek-Coder

Для задач, связанных с генерацией и ревью кода, специализированные кодовые модели стабильно обходят модели общего назначения того же размера. Два лидера в open-source сегменте на конец 2025 года:

  • Qwen2.5-Coder-32B-Instruct — сильный выбор для смешанных стеков (Python, JS/TS, Go), хорошо держит длинный контекст при код-ревью, разумно себя ведёт при рефакторинге больших файлов;
  • DeepSeek-Coder-V2 — особенно силён в алгоритмических задачах и competitive-programming стиле, чуть тяжелее по требованиям к VRAM, но даёт заметно более точные ответы на сложные архитектурные вопросы.
# для команды разработки на srv-ai01
vllm serve /models/qwen2.5-coder-32b-instruct \
  --port 8000 \
  --max-model-len 32768 \
  --gpu-memory-utilization 0.85 \
  --served-model-name coding-assistant

Если GPU-ресурсы ограничены, квантованная версия Qwen2.5-Coder-14B в GPTQ или AWQ формате даёт неплохой компромисс между качеством и объёмом VRAM — разница в качестве с 32B заметна в основном на сложных многофайловых задачах, для точечных вопросов «почему падает этот тест» разницы почти нет.

Поддержка клиентов: Llama 3.1/3.3 и Mistral

Для саппорта важнее не глубина рассуждений, а естественность диалога, следование тону компании и устойчивость к попыткам вывести модель за рамки скрипта (см. статью про prompt injection). Здесь хорошо себя показывают:

  • Llama 3.3-70B — качественный follow-instructions, стабильно держит заданный тон и формат ответа, хорошо работает с RAG поверх базы знаний компании;
  • Mistral Small / Mistral Large — заметно быстрее по латентности при сопоставимом качестве диалога, что важно для интерактивного чата, где пользователь ждёт ответ здесь и сейчас, а не через 15 секунд;
  • Qwen2.5-32B-Instruct — неплохой универсальный вариант, если нужно и немного кода в ответах поддержки (например, помощь с настройкой API), и обычный диалог.

Для саппорта латентность часто важнее пиковой точности, поэтому здесь имеет смысл жертвовать размером модели ради скорости первого токена — клиент, ждущий ответ 20 секунд, воспринимает сервис как медленный, даже если сам ответ отличный.

# для отдела поддержки — приоритет на латентность
vllm serve /models/mistral-small-24b-instruct \
  --port 8001 \
  --max-model-len 16384 \
  --gpu-memory-utilization 0.4 \
  --served-model-name support-assistant

Аналитика данных: DeepSeek-V3 и Qwen2.5-72B

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

  • DeepSeek-V3 — один из сильнейших open-source вариантов по качеству рассуждений на момент выхода, особенно хорош там, где нужно несколько шагов логического вывода поверх табличных данных;
  • Qwen2.5-72B-Instruct — надёжный выбор при работе с длинными отчётами и большим контекстом, стабильно следует структуре запроса (например, «выведи ответ строго в виде таблицы»);
  • DeepSeek-R1 (или его дистиллированные версии) — если аналитика требует явного пошагового рассуждения перед ответом, reasoning-модели этого типа заметно снижают число фактических ошибок ценой более медленного ответа.

Для аналитики почти всегда стоит связывать модель с code-интерпретатором (см. статью про плагины Open WebUI) — вместо того чтобы модель «в уме» считала агрегаты по таблице, она должна писать и выполнять код, который считает точно.

Как выбирать, если ресурсы srv-ai01 ограничены

Если железо не позволяет держать три полноценные модели одновременно в памяти, практичная стратегия — держать одну сильную универсальную модель (например, Qwen2.5-32B-Instruct) как модель по умолчанию, и догружать специализированные модели по требованию через динамическую загрузку vLLM или llama.cpp с выгрузкой неиспользуемых моделей по таймауту простоя.

# пример конфигурации с ленивой загрузкой в LiteLLM
model_list:
  - model_name: coding-assistant
    litellm_params:
      model: openai/qwen2.5-coder-32b
      api_base: http://srv-ai01.itpages.lab.local:8000/v1
  - model_name: support-assistant
    litellm_params:
      model: openai/mistral-small-24b
      api_base: http://srv-ai01.itpages.lab.local:8001/v1
  - model_name: analytics-assistant
    litellm_params:
      model: openai/deepseek-v3
      api_base: http://srv-ai01.itpages.lab.local:8002/v1

Такая настройка позволяет пользователям и интеграциям обращаться к моделям по смысловому имени (coding-assistant, support-assistant), не зная деталей о том, какая конкретно модель и на каком порту стоит за этим именем — это также упрощает будущие обновления моделей по схеме blue-green.

Методика сравнения моделей на своих данных

Общие бенчмарки (MMLU, HumanEval, MT-Bench) полезны для первичного отбора кандидатов, но плохо предсказывают, как модель поведёт себя на специфичных задачах твоей компании. Разумная методика — собрать 30-50 реальных примеров запросов из каждой категории (код, поддержка, аналитика) и прогнать через каждого кандидата с одинаковыми параметрами генерации.

# упрощённый скрипт сравнения моделей на своём наборе примеров
import json

candidates = ["qwen2.5-coder-32b", "deepseek-coder-v2", "llama3.3-70b"]
test_set = json.load(open("test_prompts/coding_tasks.json"))

results = {}
for model in candidates:
    correct = 0
    for task in test_set:
        response = query_model(model, task["prompt"])
        if evaluate_response(response, task["expected_criteria"]):
            correct += 1
    results[model] = correct / len(test_set)

print(results)

Оценку ответов лучше не полностью автоматизировать — для кода можно проверять автотестами, но для поддержки и аналитики финальную оценку 20-30 ответов стоит поручить живому эксперту из соответствующего отдела, который знает, что такое «хороший ответ» в контексте конкретных задач компании.

Требования к железу для разных моделей

Перед тем как выбирать модель по качеству, стоит трезво оценить, помещается ли она в VRAM srv-ai01. Ориентировочные требования при использовании квантования (4-bit AWQ/GPTQ):

Модель                          Параметры    VRAM (4-bit)    Скорость (примерно)
Mistral Small                   24B          ~16 GB          быстрая
Qwen2.5-Coder / Qwen2.5          14B          ~10 GB          быстрая
Qwen2.5-Coder / Qwen2.5          32B          ~20 GB          средняя
Llama 3.3                        70B          ~40 GB          средняя-медленная
DeepSeek-V3 (MoE, активных ~37B) 671B total   ~40-45 GB       средняя за счёт MoE

Модели с архитектурой Mixture-of-Experts (как DeepSeek-V3) особенно интересны для ограниченного железа — при огромном общем числе параметров на каждый конкретный запрос активируется лишь часть экспертов, что даёт качество, близкое к куда более крупной плотной модели, при разумных требованиях к VRAM и вычислениям.

Обновление модельного ландшафта: план ревью

Open-source модели развиваются быстро — то, что было лучшим выбором для кодинга полгода назад, может уже уступать новому релизу. Разумно не гнаться за каждым новым релизом, но и не консервировать выбор навсегда. Практичный ритм — ежеквартальный обзор доступных моделей с прогоном того же набора тестов, что использовался при первоначальном выборе, и решением, стоит ли мигрировать.

# чек-лист квартального ревью моделей
1. Есть ли новая версия текущей модельной линейки (например,
   Qwen3 вместо Qwen2.5)?
2. Прогнать новую версию на своём test_set из статьи выше
3. Сравнить с текущими метриками качества и латентности
4. Если прирост качества > 10% или прирост скорости > 20% -
   планировать миграцию через blue-green
5. Если прироста нет - оставить текущую версию, зафиксировать
   дату следующего ревью

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

Частые ошибки и как их избежать

  • Одна модель на все задачи «для простоты». Экономит время на настройке, но заметно снижает качество там, где нужна специализация — особенно в коде и аналитике. Начни хотя бы с двух моделей: кодовой и универсальной.
  • Выбор модели по бенчмаркам без проверки на своих задачах. Общие лидерборды не отражают специфику твоих промптов и данных компании. Всегда прогоняй кандидатов на реальных примерах из своих задач, прежде чем катить в прод.
  • Игнорирование латентности при выборе модели для интерактивного чата. Самая точная модель бесполезна, если сотрудники перестают ей пользоваться из-за долгого ожидания ответа. Для чата в реальном времени латентность first-token часто важнее пары процентов точности.

Специализация внутри одной категории задач

Даже внутри одной широкой категории вроде «кодинг» разумно учитывать более узкую специализацию под стек технологий компании. Модель, отлично справляющаяся с Python и JavaScript, не обязательно так же хороша в узкоспециализированных языках или фреймворках — например, в написании Terraform-конфигураций, PL/SQL или встраиваемого C для микроконтроллеров.

# пример специализированного теста под конкретный стек
test_prompts_terraform = [
    "Напиши модуль Terraform для VPC с публичной и приватной подсетью",
    "Исправь ошибку в этом ресурсе aws_security_group: ...",
    "Объясни разницу между count и for_each в этом файле",
]
# прогони через кандидатов и сравни с ожидаемым результатом от senior-инженера

Если основной стек компании — что-то нишевое, иногда практичнее взять модель среднего размера с хорошими общими навыками кода и до-обучить (fine-tune) её на внутренней кодовой базе компании через LoRA, чем искать готовую модель, идеально закрывающую именно эту нишу. Это отдельная, более сложная тема, но её стоит держать в уме как альтернативу бесконечному перебору готовых моделей.

Гибридный подход: маршрутизация запросов между моделями

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

def route_request(user_message: str) -> str:
    if contains_code_block(user_message) or re.search(r"(?i)напиши код|debug|исправь ошибку", user_message):
        return "coding-assistant"
    if re.search(r"(?i)посчитай|проанализируй таблицу|сводка по данным", user_message):
        return "analytics-assistant"
    return "support-assistant"

Такой роутинг снижает нагрузку на самую тяжёлую модель (аналитическую или кодовую), направляя туда только действительно релевантные запросы, а рутинные вопросы обрабатывает более лёгкая и быстрая модель по умолчанию.

Что дальше

Безопасность и эксплуатация AI-инфраструктуры — вот с чем ещё стоит разобраться: