Files
dedinit.ru/docs/local-aux-models.md
T

7.7 KiB
Raw Blame History

Опыт: локальные 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)

Грабли

  1. api_key обязан быть непустым. Пустой api_key = «унаследовать ключ основного провайдера» → попытка сходить в polza.ai с локальной моделью. Заглушка ollama подходит (Ollama её не проверяет).
  2. Ollama подключается через OpenAI-совместимый эндпоинт /v1/chat/completions (именно так Hermes ходит в локальные модели).
  3. qwen3-vl:8b: держать num_ctx небольшим (8192). Полный контекст 262K → KV cache ~309 GB, runner падает с EOF (EOF on 127.0.0.1:45579).
  4. 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.