File size: 5,006 Bytes
2758540
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
001c84a
2758540
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""
config.py - Central configuration for Multimodal Surveillance Intelligence System
"""
import os
import torch
from pathlib import Path
from pydantic_settings import BaseSettings
from pydantic import Field
from loguru import logger


class Settings(BaseSettings):
    # ── App ───────────────────────────────────────────────
    APP_NAME: str = "Multimodal Surveillance Intelligence System"
    APP_VERSION: str = "1.0.0"
    DEBUG: bool = False
    HOST: str = "0.0.0.0"
    PORT: int = 8000

    # ── Database (NeonDB PostgreSQL) ───────────────────────
    DATABASE_URL: str = Field(
        default="postgresql+asyncpg://user:password@hostname/dbname?ssl=require",
        description="Database connection URL"
    )
    DB_ECHO: bool = False

    # ── Security ───────────────────────────────────────────
    SECRET_KEY: str = Field(default="change-in-production-super-secret-key", env="SECRET_KEY")
    API_KEY: str = Field(default="surveillance-api-key-2024", env="API_KEY")

    # ── Model Paths / Cache ───────────────────────────────
    MODEL_CACHE_DIR: str = Field(default="./model_cache", env="HF_HOME")

    # ── Vision Models ─────────────────────────────────────
    DETECTION_MODEL: str = "facebook/detr-resnet-50"
    REID_MODEL: str = "google/vit-base-patch16-224"
    CLIP_MODEL: str = "openai/clip-vit-base-patch32"
    DETECTION_CONFIDENCE: float = 0.7
    DETECTION_BATCH_SIZE: int = 4

    # ── NLP Models ────────────────────────────────────────
    SEMANTIC_SEARCH_MODEL: str = "sentence-transformers/all-MiniLM-L6-v2"
    QA_MODEL: str = "deepset/roberta-base-squad2"
    REPORT_MODEL: str = "google/flan-t5-base"
    SUMMARIZER_MODEL: str = "facebook/bart-large-cnn"

    # ── Audio Models (Optional) ───────────────────────────
    WHISPER_MODEL: str = "openai/whisper-small"
    AUDIO_CLASS_MODEL: str = "superb/wav2vec2-base-superb-ks"
    TTS_MODEL: str = "microsoft/speecht5_tts"
    ENABLE_AUDIO: bool = False

    # ── FAISS ─────────────────────────────────────────────
    FAISS_INDEX_PATH: str = "./faiss_indexes"
    REID_EMBEDDING_DIM: int = 768   # ViT-base hidden size
    CLIP_EMBEDDING_DIM: int = 512   # CLIP embedding size
    SEARCH_EMBEDDING_DIM: int = 384  # MiniLM embedding size
    FAISS_NPROBE: int = 10

    # ── Tracking ──────────────────────────────────────────
    TRACKER_TYPE: str = "bytetrack"   # "bytetrack" or "deepsort"
    TRACK_THRESH: float = 0.5
    TRACK_BUFFER: int = 30
    MATCH_THRESH: float = 0.8

    # ── WebSocket / Cameras ───────────────────────────────
    MAX_CAMERAS: int = 16
    FRAME_QUEUE_SIZE: int = 30
    FPS_TARGET: int = 30

    # ── Anomaly Detection ─────────────────────────────────
    ANOMALY_THRESHOLD: float = 0.75

    # ── CORS ──────────────────────────────────────────────
    CORS_ORIGINS: list = ["*"]

    class Config:
        env_file = ".env"
        env_file_encoding = "utf-8"
        case_sensitive = False


settings = Settings()

# ── Device Detection ──────────────────────────────────────────
def get_device() -> torch.device:
    if torch.cuda.is_available():
        device = torch.device("cuda")
        logger.info(f"πŸš€ GPU detected: {torch.cuda.get_device_name(0)} | VRAM: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")
    else:
        device = torch.device("cpu")
        logger.warning("⚠️  No GPU detected β€” running on CPU. Performance may be degraded.")
    return device


DEVICE = get_device()

# ── Paths ─────────────────────────────────────────────────────
BASE_DIR = Path(__file__).resolve().parent
FAISS_DIR = BASE_DIR / settings.FAISS_INDEX_PATH
MODEL_CACHE = BASE_DIR / settings.MODEL_CACHE_DIR
FAISS_DIR.mkdir(parents=True, exist_ok=True)
MODEL_CACHE.mkdir(parents=True, exist_ok=True)

# Set HuggingFace cache
os.environ["HF_HOME"] = str(MODEL_CACHE)
os.environ["TRANSFORMERS_CACHE"] = str(MODEL_CACHE)