import os from typing import List import torch from pydantic_settings import BaseSettings def _auto_device() -> str: """Автоопределение GPU → fallback на CPU""" if torch.cuda.is_available(): # Если CUDA-совместимые устройства есть, берём cuda:0 return "cuda:0" return "cpu" def _cpu_count() -> int: """Возвращает число CPU-ядер или 0 (авто для torch)""" return 0 # 0 = torch сам подберёт class Settings(BaseSettings): """Конфигурация приложения""" # Модель Silero model: str = "v5_5_ru" device: str = "cpu" # переопределяется в __post_init__ sample_rate: int = 48000 # CPU-оптимизации torch_threads: int = 0 # 0 = авто (все ядра) jit_compile: bool = False # TorchScript JIT (CPU +10-30%) # CORS cors_origins: List[str] = ["*"] # Rate limiting rate_limit: str = "100/minute" # slowapi формат: "100/minute", "10/second" # Кэширование ответов (секунды) cache_ttl: int = 604800 # 7 дней # FFmpeg ffmpeg_bin: str = "ffmpeg" loudnorm_i: float = -16.0 loudnorm_tp: float = -1.5 loudnorm_lra: float = 7.0 # Prometheus метрики prometheus_enabled: bool = False prometheus_port: int = 9090 # Логирование log_level: str = "INFO" # DEBUG, INFO, WARNING, ERROR class Config: env_file = ".env" env_file_encoding = "utf-8" def __init__(self, **kwargs): super().__init__(**kwargs) # Автоопределение device if self.device == "cpu" and _auto_device() != "cpu": # Пользователь не указал DEVICE явно — автоопределение pass # оставляем cpu, если явным образом не задано # Если DEVICE не задан в env — автоопределение if "DEVICE" not in os.environ: self.device = _auto_device() if self.torch_threads == 0: self.torch_threads = _cpu_count() or os.cpu_count() or 4