7.7 KiB
Опыт: локальные auxiliary-модели для Hermes (RTX 5060 Ti 16 GB)
Дата: 2026-08-30 · Автор: Стороженко Евгений (kpa39l) · Среда: bigbox, RTX 5060 Ti 16 GB, Ubuntu Связанная статья:
content/posts/20260830 - local aux models hermes/index.md
Этот документ — техническая копия опыта, описанного в статье блога. Здесь — точные конфиги, команды, замеры и грабли, чтобы можно было повторить настройку без повторного исследования.
Проблема
Агент Hermes (/opt/hermes/.hermes/hermes-agent/) помимо основной модели вызывает вспомогательные (auxiliary) задачи через auxiliary_client.py:
vision— описание картинок/скриншотовtitle_generation— генерация заголовков диалоговweb_extract— извлечение текста из веб-страницcompression— сжатие истории диалога (context compaction), жёсткий минимум контекста 64K токеновskills_hub,approval,mcp,triage_specifier,kanban_decomposer,profile_describer,curator— служебные
По умолчанию все они резолвятся в облачного провайдера (polza.ai) — тратят токены и деньги. Цель: увести на локальную Ollama то, что не требует 64K контекста.
Выбор модели
Критерии: уметь vision, влезать в 16 GB VRAM вместе с bge-m3 (эмбеддинги), быстро отвечать (aux-задачи вызываются часто), желательно закрыть и текстовые задачи.
- qwen3-vl:8b (~6.1 GB, контекст 262K, умеет vision) — для
vision. Проверено: отвечает «red»/«blue» на цветные картинки 256x256 за 1–10 сек. - qwen3:8b (~5.2 GB, чисто текстовая) — для текстовых aux (
title_generation,web_extract). На простой вопрос qwen3-vl генерит 3778 токенов reasoning и отвечает 64 сек — для текста непригодна.
compression осталась на polza.ai: ей нужен контекст 64K+, а локальные GGUF не дотягивают:
- qwen3-8b: реальный контекст 40960 (тег «64k» в названии — маркетинг)
- qwen2.5-coder-14b: реально 32768 (тег «32k» честный)
Настройка
Рабочий конфиг в /opt/hermes/.hermes/config.yaml:
auxiliary:
vision:
provider: custom
model: qwen3-vl:8b
base_url: http://localhost:11434/v1
api_key: ollama
title_generation:
provider: custom
model: qwen3:8b
base_url: http://localhost:11434/v1
api_key: ollama
extra_body:
think: false
web_extract:
provider: custom
model: qwen3:8b
base_url: http://localhost:11434/v1
api_key: ollama
extra_body:
think: false
Команды CLI:
hermes config set auxiliary.vision.provider custom
hermes config set auxiliary.vision.model qwen3-vl:8b
hermes config set auxiliary.vision.base_url http://localhost:11434/v1
hermes config set auxiliary.vision.api_key ollama
# ...аналогично для title_generation и web_extract (model qwen3:8b + extra_body think:false)
Грабли
api_keyобязан быть непустым. Пустойapi_key= «унаследовать ключ основного провайдера» → попытка сходить в polza.ai с локальной моделью. Заглушкаollamaподходит (Ollama её не проверяет).- Ollama подключается через OpenAI-совместимый эндпоинт
/v1/chat/completions(именно так Hermes ходит в локальные модели). - qwen3-vl:8b: держать
num_ctxнебольшим (8192). Полный контекст 262K → KV cache ~309 GB, runner падает с EOF (EOF on 127.0.0.1:45579). session_search— НЕ auxiliary-задача (это tool). Переопределениеauxiliary.session_search.*из конфига нужно удалить.
Допиливание: отключение режима размышлений (thinking) у Qwen3
Qwen3-модели по умолчанию генерируют скрытый поток reasoning перед ответом. Для aux это катастрофа: 64 сек на заголовок, пустой content при ограниченном max_tokens (весь бюджет съедает thinking).
Что НЕ работает (проверено на Ollama)
| Способ | Результат |
|---|---|
/no_think в начале сообщения |
Модель всё равно думает |
enable_thinking: false в extra_body |
Не работает |
thinking: {type: disabled} (как в OpenAI API Qwen) |
Не работает — reasoning продолжается |
| System prompt «не думай» | Не работает |
В chat template qwen3 есть команды /think и /no_think, но в Ollama они не активируются (флаг IsThinkSet не выставляется).
Что работает
Единственный способ — корневой параметр think: false в теле запроса (HTTP-уровень):
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:8b",
"messages": [{"role": "user", "content": "Привет!"}],
"think": false
}'
Результат: ответ через 0.7 сек (вместо 64), reasoning=false, content заполнен.
В Hermes это передаётся через extra_body: {think: false} в конфиге — в коде auxiliary_client.py effective_extra_body уходит в корень JSON-тела запроса, ровно туда, куда Ollama ждёт think.
E2E-замеры (реальные вызовы через Hermes call_llm)
| Задача | Время | Результат |
|---|---|---|
title_generation |
11.3 сек | «Настройка Ollama: локальные модели» |
web_extract |
7.5 сек | Извлёк главную мысль |
vision (картинка 256x256) |
7.6 сек | «blue» |
VRAM / память
RTX 5060 Ti 16 GB, держатся одновременно:
qwen3-vl:8b— ~7.2 GB (vision)qwen3:8b— ~6.1 GB (текст)bge-m3— ~1.2 GB (эмбеддинги)
Итого ~14.5 GB — влезает, переключение vision↔текст без выгрузки (проверено через /api/ps).
Откат
hermes config set auxiliary.<task>.provider auto
hermes config set auxiliary.<task>.model ""
docker exec ollama ollama stop qwen3-vl:8b
docker exec ollama ollama stop qwen3:8b
Сопутствующий фикс Hugo
При сборке репозитория современным Hugo (0.145+) возникала ошибка:
config value "en" for defaultContentLanguage does not match any language definition.
Решение (коммит 1bda9e2): добавить в hugo.toml:
defaultContentLanguage = 'ru'
Потому что в [languages] объявлен только ru, а Hugo по умолчанию считает язык en.