У любого инженера, работающего с вендорскими системами, есть личная боль: сотни PDF — спецификации протоколов, мануалы, интеграционные описания. Поиск по ним — это «открой семь документов и Ctrl+F в каждом». Отдавать такие документы в облачные LLM нельзя. Решение — полностью локальный RAG: свои модели, свои документы, ничего не покидает домашнюю сеть.
Здесь — моя рабочая конфигурация: RTX 3060 12 ГБ, Ollama, OpenWebUI, ~200 увесистых PDF, и три неочевидных настройки, без которых на моделях 7B RAG просто не работает.
Архитектура
Хост — Proxmox VE (обычный Debian под капотом) с RTX 3060 12 ГБ. Схема сознательно простая:
- Ollama — нативно на хосте. Никаких VM и контейнеров: пакет ставится прямо на Proxmox-хост, видит GPU напрямую через обычный драйвер NVIDIA. Ноль возни с passthrough, IOMMU и nvidia-container-runtime — для одной карты и одного потребителя это самый короткий путь;
- OpenWebUI — в Docker Compose там же: интерфейс, управление коллекциями документов, RAG-конвейер. К Ollama ходит по HTTP;
- SearXNG — в том же compose: локальный метапоиск; OpenWebUI использует его для web-поиска, когда ответа в документах нет. Наружу уходят только поисковые запросы к обычным поисковикам — сами документы никуда не уезжают.
Минимальный compose:
| |
Один нюанс: Ollama по умолчанию слушает только localhost — чтобы контейнер до неё
достучался, в systemd-юните задаётся Environment="OLLAMA_HOST=0.0.0.0:11434"
(и файрволом закрывается всё, кроме docker-сети и localhost).
Модели
На 12 ГБ VRAM выбор прагматичный:
| Роль | Модель | Зачем |
|---|---|---|
| Генерация ответов | qwen2.5:7b-instruct | лучший на момент сборки баланс качества/размера для инструкций и работы с контекстом; влезает в VRAM с приличным контекстом |
| Эмбеддинги | bge-m3 | мультиязычные эмбеддинги (документация — смесь английского и русского), длинные чанки |
| Reranker | bge-reranker-v2-m3 | пересортировка найденных чанков по релевантности — заметно поднимает точность попадания |
| |
Скорость на 3060 субъективно: 7B-модель отвечает в темпе чтения — для интерактивной работы с документацией этого достаточно. Гнаться за моделями крупнее на этом железе смысла нет: они уже не помещаются в VRAM целиком, и скорость падает в разы.
Загрузка документов
В OpenWebUI документы живут в Knowledge-коллекциях: создаёте коллекцию, заливаете PDF,
дальше она подключается к чату (#имя-коллекции или привязкой к модели). Я залил
порядка 200 объёмных PDF — спецификации, мануалы, интеграционные описания.
На таком объёме и вылезают грабли, о которых молчат туториалы с тремя файлами.
Три граблины, без которых ничего не работает
1. Native function calling ломает RAG на маленьких моделях
Симптом: коллекция подключена, а модель отвечает «в документах ничего не найдено» или игнорирует документы вовсе. Причина: в режиме native function calling OpenWebUI ожидает, что модель сама вызовет инструмент поиска по базе — а модели уровня 7B делают это нестабильно: не вызывают, вызывают с пустым запросом, ломают формат вызова.
Лечение: в настройках модели (Admin → Models → ваша модель → Advanced Params) переключить Function Calling: Native → Default (legacy). В legacy-режиме OpenWebUI сам достаёт релевантные чанки и кладёт их в промпт — модели остаётся только читать. Для 7B-моделей это единственный надёжный режим RAG.
2. Эмбеддинги валятся с 503 на большом объёме документов
Симптом: при индексации большой коллекции — ошибки 503 от Ollama, часть документов не индексируется. Причина: OpenWebUI по умолчанию шлёт эмбеддинг-запросы крупными батчами, и Ollama на одной GPU захлёбывается.
Лечение: Admin → Settings → Documents → Embedding Batch Size уменьшить (с дефолтного до 8–16 — подобрать по своему железу), после чего переиндексировать коллекцию. Индексация 200 PDF занимает время — это разовая плата.
3. Гибридный поиск + reranker
Чисто векторный поиск по технической документации промахивается на точных вещах: номера полей, имена параметров, коды ошибок — то, что инженеру нужно чаще всего. Векторная близость находит «похожее по смыслу», а нужно «ровно это».
Лечение: Admin → Settings → Documents:
- включить Hybrid Search — к векторному поиску добавляется полнотекстовый (BM25), и точные термины начинают находиться;
- указать Reranking Model:
bge-reranker-v2-m3— кандидаты из обоих поисков пересортировываются кросс-энкодером, в промпт уходят действительно релевантные чанки.
Из этих трёх настроек и складывается разница между «игрушка, которая галлюцинирует» и «инструмент, которым пользуешься каждый день».
Что получилось на практике
Хорошо работает: «в каком разделе описано X», «какие значения принимает параметр Y», «что означает ошибка Z» — вопросы, где ответ находится в одном-двух местах во всей базе документов. С указанием источника — OpenWebUI показывает, из каких документов взяты чанки, и это критично: ответу LLM по документации нельзя верить без проверки по первоисточнику.
Слабые места, о которых честно:
- таблицы — PDF-парсер разбирает сложные многостраничные таблицы посредственно, ответы «по табличным данным» надо перепроверять всегда;
- схемы и диаграммы — текстовый RAG их не видит в принципе;
- обобщение по всем документам сразу («сравни, как это сделано в пяти документах») — не для 7B-модели с ограниченным контекстом; это инструмент точечного поиска, не аналитик.
Итог
Полностью локальный RAG на скромной GPU — рабочая вещь, если принять два решения: простая архитектура (Ollama нативно, обвязка в Docker) и честная настройка под маленькую модель (legacy function calling, гибридный поиск, reranker). Дальше он просто тихо экономит время: вопрос к 200 PDF стал занимать полминуты вместо получаса раскопок.