"""Константная матрица уровней AI (`min`/`medium`/`max`) — ADR-004. Единственный источник моделей/квантов/параметров генерации/требований железа — `docs/architecture/adr/004-ai-tier-matrix.md`; этот модуль переводит матрицу ADR в структуры, которыми пользуются `services/ai_levels.py` (детект доступности уровня) и `services/instance_settings.py::load_effective_config` (подмена `transcriber`/`summarizer` эффективной конфигурации для `medium`/`max` — `min` продолжает использовать дефолты `plugins.yaml`/правки администратора). Пути моделей на дисковых томах (`model_files`, `options.download_root`, `options.tokenizer_path`) — контракт с инсталлятором (`deploy/llm/download-model.sh` и его аналог для faster-whisper): скрипты обязаны скачивать модели именно по этим путям, иначе детект доступности уровня будет ошибочно считать модель нескачанной. """ from pydantic import BaseModel from core.plugins.config import AiLevel, SummarizerConfig, TranscriberConfig WHISPER_MODELS_ROOT = "/models/whisper" """Корень тома с моделями faster-whisper; каждый уровень хранит свою модель в одноимённом (модели, не уровню) подкаталоге — общий volume `whisper-cache`.""" QWEN_MODELS_ROOT = "/models/qwen" """Корень тома с GGUF-квантами и токенизаторами Qwen — общий volume `llm-models`.""" _LLM_BASE_URL_CPU = "http://llm:8080/v1" """CPU-сервер llama.cpp (compose-сервис `llm`) — уровни `min`/`medium`.""" _LLM_BASE_URL_GPU = "http://llm-gpu:8080/v1" """GPU-сервер llama.cpp (compose-сервис `llm-gpu`, образ `...:server-cuda`) — уровень `max` (`requires_gpu=True`, GPU обязателен).""" class TierSpec(BaseModel): """Полная конфигурация одного уровня AI: плагины, требования железа, модели.""" transcriber: TranscriberConfig summarizer: SummarizerConfig min_ram_mb: int requires_gpu: bool min_vram_mb: int | None = None model_files: list[str] TIERS: dict[AiLevel, TierSpec] = { "min": TierSpec( transcriber=TranscriberConfig( provider="faster_whisper_cpu", model="small", options={"download_root": f"{WHISPER_MODELS_ROOT}/small"}, ), summarizer=SummarizerConfig( provider="qwen_local", model="qwen3.5-4b-instruct-q4_k_m", chunk_minutes=20, options={ "base_url": _LLM_BASE_URL_CPU, "tokenizer_path": f"{QWEN_MODELS_ROOT}/qwen3.5-4b-instruct.tokenizer.json", "temperature": 0.2, "max_tokens_map": 1024, "max_tokens_reduce": 1536, }, ), min_ram_mb=16 * 1024, requires_gpu=False, min_vram_mb=None, model_files=[ f"{WHISPER_MODELS_ROOT}/small", f"{QWEN_MODELS_ROOT}/qwen3.5-4b-instruct-q4_k_m.gguf", f"{QWEN_MODELS_ROOT}/qwen3.5-4b-instruct.tokenizer.json", ], ), "medium": TierSpec( transcriber=TranscriberConfig( provider="faster_whisper_cpu", model="medium", options={"download_root": f"{WHISPER_MODELS_ROOT}/medium"}, ), summarizer=SummarizerConfig( provider="qwen_local", model="qwen3.5-9b-instruct-q4_k_m", chunk_minutes=20, options={ "base_url": _LLM_BASE_URL_CPU, "tokenizer_path": f"{QWEN_MODELS_ROOT}/qwen3.5-9b-instruct.tokenizer.json", "temperature": 0.2, "max_tokens_map": 1024, "max_tokens_reduce": 2048, }, ), min_ram_mb=32 * 1024, # GPU опционален на этом уровне (ADR-004: полный offload от ~8 ГБ # VRAM ускоряет, но не требуется) — константная матрица держит # безопасный CPU-вариант `faster_whisper_cpu`/CPU llama.cpp; # GPU-ускорение уровня `medium` — ручная настройка администратора # поверх этой матрицы (вне детекта доступности). requires_gpu=False, min_vram_mb=8 * 1024, model_files=[ f"{WHISPER_MODELS_ROOT}/medium", f"{QWEN_MODELS_ROOT}/qwen3.5-9b-instruct-q4_k_m.gguf", f"{QWEN_MODELS_ROOT}/qwen3.5-9b-instruct.tokenizer.json", ], ), "max": TierSpec( transcriber=TranscriberConfig( provider="faster_whisper_gpu", model="large-v3", options={ "download_root": f"{WHISPER_MODELS_ROOT}/large-v3", "compute_type": "float16", }, ), summarizer=SummarizerConfig( provider="qwen_local", model="qwen3.5-35b-a3b-instruct-q4_k_m", chunk_minutes=20, options={ "base_url": _LLM_BASE_URL_GPU, "tokenizer_path": f"{QWEN_MODELS_ROOT}/qwen3.5-35b-a3b-instruct.tokenizer.json", "temperature": 0.2, "max_tokens_map": 1536, "max_tokens_reduce": 2560, }, ), min_ram_mb=64 * 1024, requires_gpu=True, min_vram_mb=16 * 1024, model_files=[ f"{WHISPER_MODELS_ROOT}/large-v3", f"{QWEN_MODELS_ROOT}/qwen3.5-35b-a3b-instruct-q4_k_m.gguf", f"{QWEN_MODELS_ROOT}/qwen3.5-35b-a3b-instruct.tokenizer.json", ], ), }