Практика · Laravel · Ollama · Qwen2.5 · CPU inference
AI-анализатор проектов работал через DeepSeek и возвращал строгий JSON из 21 поля. Мы добавили локальную Qwen2.5 7B через Ollama, проверили её на реальной нагрузке и выяснили, где CPU-модель действительно экономит ресурсы, а где облачный AI всё ещё выигрывает.
Коротко: локальная модель не стала безусловной заменой DeepSeek. Лучший результат дала каскадная схема: Ollama обрабатывает массовый первичный поток, а облачная модель подключается только к проектам, которым нужен более глубокий анализ.
Если вы проектируете похожий контур для документов, внутренних данных или автоматизации, посмотрите услугу разработки AI-агентов и RAG-систем.
В этом проекте AI встроен в backend-конвейер. Система собирает GitHub-проекты, читает описание, README, сайт и метаданные, а затем определяет тип продукта, целевую аудиторию, проблему, коммерческий потенциал, сложность реализации, доступность данных и конкуренцию.
Ответ нельзя заменить свободным текстом. Следующий этап ожидает структурированный объект: 21 обязательное поле, заданные типы данных и оценки в допустимых диапазонах. Ошибка модели здесь ломает не красоту ответа, а автоматическую обработку.
Intel Xeon E5-1650 v3, 6 физических ядер и 12 потоков, 62 ГБ RAM, два SATA SSD. Это обычный сервер приложений, а не специализированная AI-машина.
Квантованная модель занимает около 4,7 ГБ. Контекст ограничили 8192 токенами, параллельность — одним запросом.
Анализ идёт через Laravel Horizon. Пользователь не ждёт ответ в браузере, поэтому задержка CPU inference допустима.
Ollama не опубликована на 0.0.0.0:11434. Доступ разрешён только приложению через туннель и отдельную Docker-сеть.
На одном и том же ProjectAnalysisInput сравнили DeepSeek, Qwen2.5 7B и Qwen2.5 14B. Более крупная локальная модель местами давала оценки ближе к DeepSeek, но на CPU один запуск занимал больше шести минут.
| Модель | Вход | Выход | Время |
|---|---|---|---|
| DeepSeek | 2345 токенов | 1517 | 8,5 с |
| Qwen2.5 7B | 2320 | 564 | ≈159 с |
| Qwen2.5 14B | 2320 | 676 | ≈376 с |
Вывод не в том, что 14B «плохая». Для интерактивного CPU-конвейера её цена по времени оказалась выше прироста качества.
Следующий тест — ограничение числа логических CPU для одного и того же запроса. Основной прирост произошёл между четырьмя и шестью потоками. После восьми скорость почти перестала меняться.
Если отдать модели все 12 потоков, MySQL, PHP, Redis и очереди останутся без запаса, а inference не ускорится. Поэтому верхний лимит установили на 8 CPU: это не абсолютный максимум, а баланс всего production-сервера.
Сначала JSON Schema находилась прямо в prompt рядом с инструкцией, README и данными проекта. Для облачного API лишние токены почти незаметны, но локальная модель обрабатывает каждый из них на CPU.
Схему передали через нативный параметр format Ollama. После сокращения инструкции и входа лабораторное время анализа снизилось примерно со 159 до 95–100 секунд — почти на 40%, при этом ответ сохранил все обязательные поля.
Для локального inference оптимизация контекста часто выгоднее перехода на более крупную модель или выделения дополнительных CPU.
Qwen2.5 7B стабильно возвращала 21 поле без лишних ключей. Но после слишком агрессивного сокращения system prompt появилась семантическая ошибка: репозиторий книги Python Data Science Handbook модель классифицировала как ecommerce — из-за упоминания печатной версии.
Формально ответ был идеальным. Смысл — неверным. После уточнения правил классификация исправилась. Этот пример показал, что проверять замену провайдера только фразой «JSON пришёл» нельзя.
Обязательные поля, типы, диапазоны и отсутствие неожиданных ключей.
Контрольные проекты, пограничные случаи и сравнение с историческими результатами.
Timeout, повторы, очереди, логирование, нагрузка и влияние на остальные сервисы.
Интеграция уже была построена через AiProviderInterface. Мы добавили ещё одну реализацию и оставили выбор провайдера в конфигурации. Основной анализатор по-прежнему собирает вход, вызывает контракт, валидирует DTO и рассчитывает итоговые показатели.
AiProviderInterface ├── OpenAiProvider ├── DeepSeekProvider └── OllamaProvider OLLAMA_API_URL=http://…/v1 OLLAMA_MODEL=qwen2.5:7b OLLAMA_TIMEOUT=600
Ollama предоставляет OpenAI-совместимый /v1/chat/completions, поэтому инфраструктурная разница не просачивается в бизнес-логику. DeepSeekProvider остаётся доступным: провайдера и модель можно менять независимо от конвейера.
Laravel и Ollama находятся на разных физических серверах. Публично открывать inference API не стали. Между хостами работает зашифрованный SSH-туннель, а ключ отдельного системного пользователя ограничен единственным направлением permitopen="127.0.0.1:11434".
Интеграцию проверили из того же Horizon-контейнера, где работают фоновые задачи. Для реального проекта вход сформировал штатный builder, после чего был вызван именно OllamaProvider — без сохранения результата в базу.
Запрос ушёл через закрытый адрес на /v1/chat/completions, а не во внешний DeepSeek API.
HTTP 200, модель qwen2.5:7b, 2320 входных и 617 выходных токенов, длительность 164,8 секунды. База данных не изменилась.
Эксперимент начинался с вопроса «можно ли заменить облачный API?», но более полезным оказался другой вариант — распределить работу по стоимости и сложности.
Код отбрасывает проекты, которые не проходят формальные критерии.
metadata · heuristics · rulesQwen2.5 7B обрабатывает массовый поток локально и распределяет проекты по базовым категориям.
ignore · watch · interestingОблачная модель выполняет более дорогой глубокий анализ там, где качество важнее стоимости одного запроса.
investigate · buildТак стоимость облачного inference не растёт линейно с общим потоком, данные первичного анализа остаются внутри инфраструктуры, а система не становится зависимой от одного провайдера.
Локальная модель, облачный API или гибридная схема выбираются не по моде, а по объёму запросов, требованиям к данным, допустимой задержке и цене ошибки. Я проектирую такие системы целиком: от источников и очередей до валидации, логирования и рабочего интерфейса.
Laravel · Horizon · Ollama · Qwen2.5 7B · DeepSeek · Docker · SSH tunnel · Structured Output