138 lines
6.0 KiB
Python
138 lines
6.0 KiB
Python
"""Константная матрица уровней 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",
|
||
],
|
||
),
|
||
}
|