Навигация: ← Архитектура | README | Код →
МИНИМУМ (7B модель, медленно):
RAM: 8GB
Диск: 20GB свободно
CPU: x86_64, любой
ХОРОШО (14B модель, комфортно):
RAM: 16GB
Диск: 50GB свободно
CPU: AVX2 (Intel Haswell 2014+ / AMD Ryzen)
ОТЛИЧНО (70B модель):
RAM: 64GB+
Диск: 100GB свободно
CPU: AVX2, много каналов памяти
grep -o 'avx2' /proc/cpuinfo | head -1
# Если вывело "avx2" — есть. Если пусто — нет.
Ubuntu 22.04 или 24.04 (рекомендуется)
Docker 20.x+
curl, git
# Обновить систему
sudo apt-get update && sudo apt-get upgrade -y
# Установить нужные пакеты
sudo apt-get install -y \
curl \
git \
docker.io \
docker-compose \
python3-pip \
htop \
nvtop # для мониторинга GPU если есть
# Добавить текущего пользователя в группу docker
# (чтобы не писать sudo каждый раз)
sudo usermod -aG docker $USER
newgrp docker
# Запустить Docker
sudo systemctl enable docker
sudo systemctl start docker
# Проверить
docker --version
# Docker version 24.x.x — ок
# Официальный установщик (одна команда)
curl -fsSL https://ollama.com/install.sh | sh
# Ollama устанавливается как systemd сервис
# и запускается автоматически
# Проверить что запущен
curl http://localhost:11434/api/tags
# Должен ответить: {"models":[]}
# Посмотреть статус
systemctl status ollama
По умолчанию Ollama слушает только localhost.
Если нужен доступ из Docker контейнеров:
# Отредактировать systemd unit
sudo systemctl edit ollama
# Добавить в файл:
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
# Перезапустить
sudo systemctl daemon-reload
sudo systemctl restart ollama
# Основная модель — умная, для всего
ollama pull qwen2.5:14b
# Размер: ~8.1GB, время: 10-30 мин зависит от скорости
# Модель для кода
ollama pull qwen2.5-coder:7b
# Размер: ~4.5GB
# Модель для embeddings (RAG и память)
# Маленькая, только для векторов
ollama pull nomic-embed-text
# Размер: ~274MB
# Проверить что скачалось
ollama list
# NAME ID SIZE MODIFIED
# qwen2.5:14b ... 8.1 GB ...
# qwen2.5-coder:7b ... 4.5 GB ...
# nomic-embed-text:... ... 274 MB ...
# Быстрый тест — задать вопрос напрямую
ollama run qwen2.5:14b "скажи привет по-русски"
# Ответ должен появиться за 5-30 секунд
# Выйти из интерактивного чата: /bye или Ctrl+D
docker run -d \
--name open-webui \
--restart always \
-p 3000:8080 \
--add-host=host.docker.internal:host-gateway \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
-v open-webui:/app/backend/data \
ghcr.io/open-webui/open-webui:latest
# Открыть в браузере:
# http://localhost:3000
# При первом входе — создать аккаунт администратора
# (только локальный, данные нигде не передаются)
curl -s http://localhost:3000 | grep -o '<title>[^<]*</title>'
# <title>Open WebUI</title>
docker ps
# CONTAINER ID IMAGE STATUS PORTS
# abc123 ghcr.io/open-webui/open-webui Up 2 minutes 0.0.0.0:3000->8080/tcp
mkdir -p /opt/local-ai/{config,router,memory,tests}
cd /opt/local-ai
# Системный промпт (личность модели)
cat > config/system_prompt.txt << 'PROMPT'
Ты — локальный AI-ассистент.
Краткий, точный, без похвал и воды.
Отвечай на языке вопроса.
Определи тип запроса → переключись:
код/функция/баг/python/sql → отвечай как senior developer
объясни/почему/что такое → объясняй от простого к сложному
напиши/составь/письмо → структурированный текст
найди/сравни/таблица → факты в таблице или списке
план/шаги/как сделать → нумерованные шаги
Всегда:
- Сначала ответ, потом объяснение
- Код в блоках с языком (```python)
- Если неясно — задай 1 вопрос
- Не придумывай факты
PROMPT
# Конфиг моделей
cat > config/models.yaml << 'YAML'
models:
default: qwen2.5:14b
code: qwen2.5-coder:7b
heavy: qwen2.5:72b
embed: nomic-embed-text
routing:
code_keywords:
- "код"
- "функция"
- "python"
- "javascript"
- "typescript"
- "sql"
- "баг"
- "ошибка в коде"
- "class"
- "def "
- "dockerfile"
- "yaml"
- "nginx"
- "docker"
- "скрипт"
heavy_keywords:
- "проанализируй детально"
- "сравни подробно"
- "архитектура системы"
- "стратегия развития"
- "напиши большой"
YAML
# requirements.txt
cat > router/requirements.txt << 'EOF'
fastapi==0.115.0
uvicorn==0.30.0
requests==2.32.0
pyyaml==6.0.2
chromadb==0.5.0
EOF
# Dockerfile для Router
cat > router/Dockerfile << 'EOF'
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY router.py .
COPY tools.py .
CMD ["uvicorn", "router:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
EOF
# Скопировать файлы из раздела "Код"
# см. 04_CODE.md → router/router.py
# см. 04_CODE.md → router/tools.py
cat > docker-compose.yml << 'EOF'
version: '3.8'
networks:
ai-network:
driver: bridge
services:
open-webui:
image: ghcr.io/open-webui/open-webui:latest
container_name: open-webui
restart: always
ports:
- "3000:8080"
environment:
- OLLAMA_BASE_URL=http://host.docker.internal:11434
- WEBUI_SECRET_KEY=local-secret-change-me
- OPENAI_API_BASE_URL=http://router:8000/v1
volumes:
- webui-data:/app/backend/data
networks:
- ai-network
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- router
router:
build: ./router
container_name: ai-router
restart: always
ports:
- "8000:8000"
environment:
- OLLAMA_URL=http://host.docker.internal:11434
- CHROMA_URL=http://chromadb:8000
volumes:
- ./config:/config:ro
networks:
- ai-network
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- chromadb
chromadb:
image: chromadb/chroma:latest
container_name: chromadb
restart: always
ports:
- "8001:8000"
volumes:
- chroma-data:/chroma/chroma
networks:
- ai-network
volumes:
webui-data:
chroma-data:
EOF
cd /opt/local-ai
# Собрать и запустить
docker-compose up -d --build
# Посмотреть логи
docker-compose logs -f
# Проверить статус контейнеров
docker-compose ps
# Проверить Ollama
curl http://localhost:11434/api/tags
# Проверить Router
curl http://localhost:8000/health
# Проверить ChromaDB
curl http://localhost:8001/api/v1/heartbeat
# Проверить WebUI
curl -s http://localhost:3000 | grep -o '<title>[^<]*</title>'
# Запустить полный тест стека
python3 tests/test_stack.py
Ожидаемый вывод:
=== ТЕСТ СТЕКА ===
--- Ollama ---
✅ Ollama запущен
✅ Модели загружены
✅ Ollama генерирует текст
--- Роутер ---
✅ Роутер здоров
✅ Выбирает coder модель для кода
✅ Выбирает дефолт для обычных вопросов
✅ Роутер отвечает
--- ChromaDB ---
✅ ChromaDB запущен
--- Open WebUI ---
✅ WebUI доступен
=== 8/8 тестов прошло ===
# Ollama уже запускается через systemd автоматически
# Docker контейнеры с restart: always
# тоже стартуют автоматически после перезагрузки
# Проверить после перезагрузки:
sudo reboot
# ... подождать 1-2 минуты ...
curl http://localhost:3000
# Обновить конкретную модель
ollama pull qwen2.5:14b
# Посмотреть список всех моделей
ollama list
# Удалить старую модель
ollama rm qwen2.5:7b
# Обновить Open WebUI
docker-compose pull open-webui
docker-compose up -d open-webui
# Проверить статус
systemctl status ollama
# Посмотреть логи
journalctl -u ollama -n 50
# Перезапустить
sudo systemctl restart ollama
# Проверить сколько RAM свободно
free -h
# Посмотреть что загружено в Ollama
curl http://localhost:11434/api/ps
# Выгрузить все модели
curl -X POST http://localhost:11434/api/generate \
-d '{"model": "qwen2.5:14b", "keep_alive": 0}'
# Посмотреть логи
docker-compose logs router
docker-compose logs open-webui
# Пересобрать
docker-compose down
docker-compose up -d --build --force-recreate
# Проверить что Ollama слушает на 0.0.0.0
curl http://0.0.0.0:11434/api/tags
# Если нет — настроить OLLAMA_HOST
sudo systemctl edit ollama
# Добавить:
# [Service]
# Environment="OLLAMA_HOST=0.0.0.0:11434"
sudo systemctl daemon-reload
sudo systemctl restart ollama
Следующий документ: 04_CODE.md