Новая статья про перевод aux-задач Hermes на локальные модели и отключение thinking у Qwen3
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 400" width="100%" height="auto">
|
||||||
|
<rect width="1200" height="400" fill="#0a0c10"/>
|
||||||
|
|
||||||
|
<!-- Hexagon pattern -->
|
||||||
|
<g stroke="#1a2332" stroke-width="1" fill="none" opacity="0.5">
|
||||||
|
<polygon points="100,100 130,80 160,100 160,140 130,160 100,140"/>
|
||||||
|
<polygon points="250,100 280,80 310,100 310,140 280,160 250,140"/>
|
||||||
|
<polygon points="400,100 430,80 460,100 460,140 430,160 400,140"/>
|
||||||
|
<polygon points="550,100 580,80 610,100 610,140 580,160 550,140"/>
|
||||||
|
<polygon points="700,100 730,80 760,100 760,140 730,160 700,140"/>
|
||||||
|
<polygon points="850,100 880,80 910,100 910,140 880,160 850,140"/>
|
||||||
|
<polygon points="1000,100 1030,80 1060,100 1060,140 1030,160 1000,140"/>
|
||||||
|
|
||||||
|
<polygon points="175,160 205,140 235,160 235,200 205,220 175,200"/>
|
||||||
|
<polygon points="325,160 355,140 385,160 385,200 355,220 325,200"/>
|
||||||
|
<polygon points="475,160 505,140 535,160 535,200 505,220 475,200"/>
|
||||||
|
<polygon points="625,160 655,140 685,160 685,200 655,220 625,200"/>
|
||||||
|
<polygon points="775,160 805,140 835,160 835,200 805,220 775,200"/>
|
||||||
|
<polygon points="925,160 955,140 985,160 985,200 955,220 925,200"/>
|
||||||
|
<polygon points="1075,160 1105,140 1135,160 1135,200 1105,220 1075,200"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Center text -->
|
||||||
|
<text x="600" y="175" font-family="monospace" font-size="36" fill="#58a6ff" text-anchor="middle" font-weight="bold">
|
||||||
|
Локальные aux-модели Hermes
|
||||||
|
</text>
|
||||||
|
<text x="600" y="215" font-family="monospace" font-size="20" fill="#8b949e" text-anchor="middle">
|
||||||
|
qwen3-vl · qwen3 · think:false · Ollama
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<!-- Decor line -->
|
||||||
|
<line x1="200" y1="250" x2="1000" y2="250" stroke="#30363d" stroke-width="1"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,191 @@
|
|||||||
|
---
|
||||||
|
date: '2026-08-30T12:00:00+03:00'
|
||||||
|
lastmod: '2026-08-30T12:00:00+03:00'
|
||||||
|
draft: false
|
||||||
|
title: 'Как я перевёл aux-задачи Hermes на локальные модели: экономия токенов и отключение режима размышлений у Qwen3'
|
||||||
|
slug: 'local-aux-models-hermes-qwen3'
|
||||||
|
description: 'Рассказываю, как выбрал модель для вспомогательных (auxiliary) задач агента Hermes, перевёл vision и текстовые задачи на локальную Ollama, сэкономил токены облачного провайдера и допилил отключение режима размышлений (thinking) у Qwen3.'
|
||||||
|
|
||||||
|
categories:
|
||||||
|
- 'AI'
|
||||||
|
- 'DevOps'
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- 'hermes'
|
||||||
|
- 'ollama'
|
||||||
|
- 'qwen3'
|
||||||
|
- 'llm'
|
||||||
|
- 'aux'
|
||||||
|
- 'vision'
|
||||||
|
- 'локальные-модели'
|
||||||
|
- 'экономия-токенов'
|
||||||
|
|
||||||
|
keywords:
|
||||||
|
- 'hermes'
|
||||||
|
- 'ollama'
|
||||||
|
- 'qwen3'
|
||||||
|
- 'qwen3-vl'
|
||||||
|
- 'auxiliary'
|
||||||
|
- 'thinking'
|
||||||
|
- 'reasoning'
|
||||||
|
- 'локальная модель'
|
||||||
|
- 'экономия токенов'
|
||||||
|
|
||||||
|
cover:
|
||||||
|
image: "hero.svg"
|
||||||
|
alt: "Локальные aux-модели Hermes: qwen3-vl и qwen3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Как я перевёл aux-задачи Hermes на локальные модели
|
||||||
|
|
||||||
|
У меня на домашнем сервере живёт агент [Hermes](https://hermes-agent.nousresearch.com) — он ведёт блог, следит за сертификатами, ходит в мессенджеры и выполняет кучу мелких, но важных задач. Основную модель он берёт в облаке (провайдер polza.ai, 131K контекст), а для вспомогательных задач — генерации заголовков, извлечения текста из веб-страниц, описания картинок (vision) и сжатия контекста — у него есть отдельный механизм **auxiliary**. По умолчанию все aux-задачи тоже резолвятся в облако, а значит — тратят токены и деньги.
|
||||||
|
|
||||||
|
На сервере стоит видеокарта **RTX 5060 Ti 16 GB** (да, та самая, про которую я писал в статье про зависание Ubuntu при загрузке). Раз есть GPU — почему бы не увести aux-задачи на локальные модели? Приватность, скорость, ноль затрат на API. Рассказываю, как выбирал модель, как настраивал и какой грабли встретил при отключении режима размышлений (thinking) у Qwen3.
|
||||||
|
|
||||||
|
## Что такое auxiliary-задачи в Hermes
|
||||||
|
|
||||||
|
Hermes — агент с модульной архитектурой. Кроме основной модели (которая думает и пишет ответы), он вызывает **вспомогательные (auxiliary) задачи** через отдельный клиент — `auxiliary_client.py`. В моей версии их несколько:
|
||||||
|
|
||||||
|
| Задача | Что делает | Порог контекста |
|
||||||
|
|---|---|---|
|
||||||
|
| `vision` | Описывает картинки, читает скриншоты | нет |
|
||||||
|
| `title_generation` | Генерирует заголовки диалогов | нет |
|
||||||
|
| `web_extract` | Извлекает текст из веб-страниц | нет |
|
||||||
|
| `compression` | Сжимает историю диалога (context compaction) | **64K жёсткий минимум** |
|
||||||
|
| `skills_hub`, `approval`, `mcp` и др. | Служебные | нет |
|
||||||
|
|
||||||
|
Ключевой момент: **только `compression` требует большого контекста (64K)**. Это жёсткое требование самого Hermes — для сжатия истории ему нужна модель, которая видит весь диалог. Локальные GGUF-модели до 64K не дотягивают (проверил: qwen3-8b упирается в 40960 токенов контекста, qwen2.5-coder-14b — в 32768; теги «64k/65k» в названиях моделей — маркетинг, реальный контекст меньше). Поэтому **compression я оставил в облаке**, а вот все остальные aux-задачи — кандидаты на локализацию.
|
||||||
|
|
||||||
|
## Выбор модели
|
||||||
|
|
||||||
|
Критерии были простые:
|
||||||
|
|
||||||
|
1. Модель должна уметь **vision** (для `vision`-задачи).
|
||||||
|
2. Должна влезать в 16 GB VRAM вместе с эмбеддинг-моделью `bge-m3` и основной текст-моделью.
|
||||||
|
3. Должна быстро отвечать — aux-задачи вызываются часто, ждать минуту утомительно.
|
||||||
|
4. Желательно уметь закрыть и текстовые задачи (генерация заголовков, извлечение текста) — чтобы не гонять облако вообще.
|
||||||
|
|
||||||
|
Я поставил [qwen3-vl:8b](https://ollama.com/library/qwen3-vl) — мультимодальную модель Qwen 8B с поддержкой vision. Она весит ~6.1 GB, контекст 262K (но KV cache на полный контекст — ~309 GB, так что реально держу `num_ctx=8192`). Проверил через `/api/show` — у неё есть capability `vision`, значит Hermes её увидит как vision-модель.
|
||||||
|
|
||||||
|
**Важный нюанс про qwen3-vl:** она великолепно описывает картинки (проверено E2E — отвечает «red»/«blue» на цветные картинки за 1-10 секунд), но для текстовых задач она... слишком умная. На простой вопрос «какой сегодня день недели» она генерирует 3778 токенов рассуждений и отвечает через 64 секунды! Это потому, что qwen3-модели по умолчанию включён режим reasoning/thinking. Для заголовков и извлечения текста это неприемлемо.
|
||||||
|
|
||||||
|
Поэтому я взял **две модели**:
|
||||||
|
- `qwen3-vl:8b` — для vision (картинки);
|
||||||
|
- `qwen3:8b` — для текстовых aux (title_generation, web_extract), с принудительно отключённым thinking.
|
||||||
|
|
||||||
|
## Настройка
|
||||||
|
|
||||||
|
Hermes поддерживает per-task конфигурацию auxiliary-задач в `config.yaml`. Формат:
|
||||||
|
|
||||||
|
```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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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
|
||||||
|
# и так для каждой задачи
|
||||||
|
```
|
||||||
|
|
||||||
|
Пара важных граблей:
|
||||||
|
|
||||||
|
- **`api_key` обязан быть непустым.** В коде Hermes пустой `api_key` означает «унаследовать ключ основного провайдера» — и тогда он попытается сходить в polza.ai с локальной моделью. Я поставил заглушку `ollama` (Ollama её не проверяет).
|
||||||
|
- **Ollama надо форматировать через OpenAI-совместимый эндпоинт** `/v1/chat/completions` — именно так Hermes ходит в локальные модели.
|
||||||
|
- **Для qwen3-vl держать `num_ctx` небольшим** (я использую 8192), иначе Ollama пытается зарезервировать KV cache под весь 262K контекст — это ~309 GB, runner падает с EOF.
|
||||||
|
|
||||||
|
## Допиливание отключения режима размышлений (thinking)
|
||||||
|
|
||||||
|
Самая интересная часть. Qwen3-модели (и qwen3, и qwen3-vl) по умолчанию генерируют **скрытый поток рассуждений (thinking/reasoning)** перед ответом. Для aux-задач это означает:
|
||||||
|
|
||||||
|
- Заголовок генерируется 64 секунды вместо 3-5.
|
||||||
|
- При ограниченном `max_tokens` ответ вообще **пустой** — весь бюджет съедает thinking, до `content` дело не доходит.
|
||||||
|
|
||||||
|
Я перепробовал несколько способов отключить thinking, и вот что выяснилось:
|
||||||
|
|
||||||
|
### Что НЕ работает (в Ollama)
|
||||||
|
|
||||||
|
| Способ | Результат |
|
||||||
|
|---|---|
|
||||||
|
| `/no_think` в начале сообщения | Не работает — модель всё равно думает |
|
||||||
|
| `enable_thinking: false` в `extra_body` | Не работает |
|
||||||
|
| `thinking: {type: disabled}` (как в OpenAI API Qwen) | Не работает — content пустой, reasoning продолжается |
|
||||||
|
| `system: "Не думай"` | Не работает |
|
||||||
|
|
||||||
|
Я проверил chat template модели — там есть команды `/think` и `/no_think`, но они не активируются в Ollama (флаг `IsThinkSet` не выставляется).
|
||||||
|
|
||||||
|
### Что работает
|
||||||
|
|
||||||
|
**Единственный рабочий способ — корневой параметр `think: false` в теле запроса:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:11434/api/chat -d '{
|
||||||
|
"model": "qwen3:8b",
|
||||||
|
"messages": [{"role": "user", "content": "Привет!"}],
|
||||||
|
"think": false
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Ответ приходит через **0.7 секунды** (вместо 64!), `reasoning=false`, `content` заполнен. Именно эту опцию я и прописал в `extra_body` конфига Hermes:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
extra_body:
|
||||||
|
think: false
|
||||||
|
```
|
||||||
|
|
||||||
|
В коде Hermes `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`: после текстового вызова в памяти остаются обе модели.
|
||||||
|
|
||||||
|
## Итог
|
||||||
|
|
||||||
|
- **Vision** полностью локальный — картинки описываются на сервере, в облако не уходят.
|
||||||
|
- **Текстовые aux** (заголовки, извлечение текста) — локальные, быстрые, бесплатные.
|
||||||
|
- **Compression** остался в облаке — ему нужен контекст 64K, который локально не влезает.
|
||||||
|
- Облачные токены тратятся только на основную модель и сжатие контекста — экономия существенная.
|
||||||
|
|
||||||
|
Самое ценное знание, которым делюсь: **если вы используете Qwen3 в Ollama для вспомогательных задач — не забудьте `think: false`**. Это превращает задумчивую модель, которая час думает над заголовком, в мгновенного исполнителя. И помните: `/no_think`, `enable_thinking` и `thinking: disabled` — в Ollama не работают, работает только корневой `think: false`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Полезные ссылки: [Hermes Agent](https://hermes-agent.nousresearch.com) · [Ollama qwen3-vl](https://ollama.com/library/qwen3-vl) · [Ollama qwen3](https://ollama.com/library/qwen3)*
|
||||||
Reference in New Issue
Block a user