File size: 4,374 Bytes
1d9dc1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import os
from dataclasses import dataclass
from pathlib import Path

from dotenv import load_dotenv

DEFAULT_LLM_MODEL_FILE = "Llama-3.2-1B-Instruct-Q4_K_M.gguf"


def read_int(name, default_value):
    raw_value = os.getenv(name, str(default_value)).strip()
    try:
        return int(raw_value)
    except ValueError:
        return default_value


def resolve_path(root_dir, raw_value):
    path = Path(raw_value)
    if path.is_absolute():
        return path
    return root_dir / path


def resolve_llm_model_path(models_dir, model_file):
    if model_file:
        requested_path = models_dir / model_file
        if requested_path.exists():
            return requested_path

    default_path = models_dir / DEFAULT_LLM_MODEL_FILE
    if default_path.exists():
        return default_path

    gguf_files = sorted(models_dir.glob("*.gguf"))
    if gguf_files:
        return gguf_files[0]

    return models_dir / (model_file or DEFAULT_LLM_MODEL_FILE)


def make_local_model_dir(hf_cache_dir, repo_id):
    safe_name = repo_id.replace("/", "--")
    return hf_cache_dir / "downloads" / safe_name


def resolve_hf_source(hf_cache_dir, repo_id):
    local_dir = make_local_model_dir(hf_cache_dir, repo_id)
    if local_dir.exists():
        return local_dir
    return repo_id


@dataclass(frozen=True)
class Settings:
    project_root: Path
    models_dir: Path
    hf_cache_dir: Path
    data_dir: Path
    llm_model_file: str
    llm_model_path: Path
    context_size: int
    live_asr_model_id: str
    live_asr_source: str | Path
    batch_asr_model_id: str
    batch_asr_source: str | Path
    image_model_id: str
    image_model_source: str | Path
    tts_en_model_id: str
    tts_en_source: str | Path
    tts_hi_model_id: str
    tts_hi_source: str | Path
    asr_compute_type: str
    embedding_model_id: str
    tesseract_cmd: str


def load_settings():
    project_root = Path(__file__).resolve().parent.parent
    load_dotenv(project_root / ".env")

    models_dir = resolve_path(project_root, os.getenv("EDUAI_MODELS_DIR", "models"))
    hf_cache_dir = resolve_path(project_root, os.getenv("EDUAI_HF_CACHE_DIR", "models/hf_cache"))
    data_dir = resolve_path(project_root, os.getenv("EDUAI_DATA_DIR", "data"))

    models_dir.mkdir(parents=True, exist_ok=True)
    hf_cache_dir.mkdir(parents=True, exist_ok=True)
    data_dir.mkdir(parents=True, exist_ok=True)

    os.environ.setdefault("HF_HOME", str(hf_cache_dir))
    os.environ.setdefault("HF_HUB_CACHE", str(hf_cache_dir / "hub"))
    os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")

    llm_model_file = os.getenv("EDUAI_LLM_MODEL_FILE", DEFAULT_LLM_MODEL_FILE).strip()

    live_asr_model_id = os.getenv("EDUAI_LIVE_ASR_MODEL_ID", "Systran/faster-whisper-small").strip()
    batch_asr_model_id = os.getenv("EDUAI_BATCH_ASR_MODEL_ID", "Systran/faster-whisper-large-v3").strip()
    image_model_id = os.getenv("EDUAI_IMAGE_MODEL_ID", "HuggingFaceTB/SmolVLM-256M-Instruct").strip()
    tts_en_model_id = os.getenv("EDUAI_TTS_EN_MODEL_ID", "facebook/mms-tts-eng").strip()
    tts_hi_model_id = os.getenv("EDUAI_TTS_HI_MODEL_ID", "facebook/mms-tts-hin").strip()
    embedding_model_id = os.getenv("EDUAI_EMBEDDING_MODEL_ID", "sentence-transformers/all-MiniLM-L6-v2").strip()

    return Settings(
        project_root=project_root,
        models_dir=models_dir,
        hf_cache_dir=hf_cache_dir,
        data_dir=data_dir,
        llm_model_file=llm_model_file,
        llm_model_path=resolve_llm_model_path(models_dir, llm_model_file),
        context_size=read_int("EDUAI_CONTEXT_SIZE", 8192),
        live_asr_model_id=live_asr_model_id,
        live_asr_source=resolve_hf_source(hf_cache_dir, live_asr_model_id),
        batch_asr_model_id=batch_asr_model_id,
        batch_asr_source=resolve_hf_source(hf_cache_dir, batch_asr_model_id),
        image_model_id=image_model_id,
        image_model_source=resolve_hf_source(hf_cache_dir, image_model_id),
        tts_en_model_id=tts_en_model_id,
        tts_en_source=resolve_hf_source(hf_cache_dir, tts_en_model_id),
        tts_hi_model_id=tts_hi_model_id,
        tts_hi_source=resolve_hf_source(hf_cache_dir, tts_hi_model_id),
        asr_compute_type=os.getenv("EDUAI_ASR_COMPUTE_TYPE", "int8").strip() or "int8",
        embedding_model_id=embedding_model_id,
        tesseract_cmd=os.getenv("TESSERACT_CMD", "").strip(),
    )