Spaces:
Sleeping
Sleeping
| """Central configuration and performance knobs. | |
| Everything tunable lives here and is overridable via environment variables, so you | |
| can trade speed for accuracy without touching code (e.g. small Whisper model while | |
| developing, large-v3-turbo for the demo). | |
| """ | |
| from __future__ import annotations | |
| import os | |
| from pathlib import Path | |
| # --- Paths ------------------------------------------------------------------- | |
| ROOT = Path(__file__).resolve().parent | |
| MODELS_DIR = ROOT / "models" | |
| DATA_DIR = ROOT / "data" | |
| DB_PATH = Path(os.getenv("ASA_DB_PATH", str(DATA_DIR / "jobs.db"))) | |
| DATA_DIR.mkdir(exist_ok=True) | |
| MODELS_DIR.mkdir(exist_ok=True) | |
| # --- Whisper (faster-whisper) ------------------------------------------------ | |
| # faster-whisper runs on CTranslate2: CPU or CUDA (no Apple Metal). On Mac, "int8" | |
| # on CPU is the fast path. Use "small"/"base" while developing, "large-v3-turbo" | |
| # for the demo β near-large accuracy at a fraction of the latency. | |
| WHISPER_MODEL = os.getenv("ASA_WHISPER_MODEL", "medium") | |
| WHISPER_DEVICE = os.getenv("ASA_WHISPER_DEVICE", "auto") # auto|cpu|cuda | |
| WHISPER_COMPUTE = os.getenv("ASA_WHISPER_COMPUTE", "int8") # int8|int8_float16|float16 | |
| WHISPER_BEAM = int(os.getenv("ASA_WHISPER_BEAM", "1")) # 1 = greedy, fastest | |
| WHISPER_LANG = os.getenv("ASA_WHISPER_LANG", "en") or None # None = autodetect | |
| # --- Gemma 4 (transformers) β one multimodal model for STT + extraction ------ | |
| # E2B is the mobile-QAT checkpoint (2.3B effective params); bump to E4B for more | |
| # accuracy headroom. Gated Google model: run `huggingface-cli login` and accept the | |
| # license first. | |
| GEMMA_MODEL_ID = os.getenv("ASA_GEMMA_MODEL", "google/gemma-4-E2B-it-qat-mobile-transformers") | |
| GEMMA_DTYPE = os.getenv("ASA_GEMMA_DTYPE", "auto") # auto|bfloat16|float16 | |
| GEMMA_DEVICE_MAP = os.getenv("ASA_GEMMA_DEVICE_MAP", "auto") | |
| GEMMA_MAX_NEW_TOKENS = int(os.getenv("ASA_GEMMA_MAX_TOKENS", "1024")) | |
| # Greedy by default: deterministic, best for form-filling + transcription. The card's | |
| # recommended sampling (temp 1.0 / top_p 0.95 / top_k 64) only applies if you opt in. | |
| GEMMA_SAMPLE = os.getenv("ASA_GEMMA_SAMPLE", "0") == "1" | |
| GEMMA_TEMPERATURE = float(os.getenv("ASA_GEMMA_TEMPERATURE", "1.0")) | |
| GEMMA_TOP_P = float(os.getenv("ASA_GEMMA_TOP_P", "0.95")) | |
| GEMMA_TOP_K = int(os.getenv("ASA_GEMMA_TOP_K", "64")) | |
| # Gemma's audio path is capped at 30s; longer notes fall back to faster-whisper. | |
| GEMMA_AUDIO_MAX_SEC = float(os.getenv("ASA_GEMMA_AUDIO_MAX_SEC", "30")) | |
| # --- llama.cpp (PRIMARY): Gemma 4 GGUF β text (GBNF grammar) + audio (mtmd) --- | |
| # Preferred backend. Text extraction runs in-process via llama-cpp-python with a | |
| # grammar so JSON is always valid. Audio runs through the llama-mtmd-cli binary | |
| # (llama.cpp PR #21421); the mmproj MUST be BF16 per that PR. If the GGUF/mmproj/ | |
| # binary aren't present, the code falls back to the Gemma transformers path above. | |
| LLAMA_MODEL_PATH = Path( | |
| os.getenv("ASA_LLAMA_MODEL", str(MODELS_DIR / "gemma-4-E2B-it-Q6_K.gguf")) | |
| ) | |
| LLAMA_MMPROJ_PATH = Path( | |
| os.getenv("ASA_LLAMA_MMPROJ", str(MODELS_DIR / "mmproj-BF16.gguf")) | |
| ) | |
| LLAMA_MTMD_CLI = os.getenv("ASA_LLAMA_MTMD_CLI", "llama-mtmd-cli") # binary name/path | |
| LLAMA_CTX = int(os.getenv("ASA_LLAMA_CTX", "4096")) | |
| LLAMA_GPU_LAYERS = int(os.getenv("ASA_LLAMA_GPU_LAYERS", "-1")) # -1 = all to GPU | |
| LLAMA_THREADS = int(os.getenv("ASA_LLAMA_THREADS", str(os.cpu_count() or 4))) | |
| LLAMA_TEMPERATURE = float(os.getenv("ASA_LLAMA_TEMPERATURE", "0.0")) | |
| LLAMA_MAX_TOKENS = int(os.getenv("ASA_LLAMA_MAX_TOKENS", "1024")) | |
| # --- Business defaults ------------------------------------------------------- | |
| CURRENCY = os.getenv("ASA_CURRENCY", "$") | |
| BUSINESS_NAME = os.getenv("ASA_BUSINESS_NAME", "") # shown on invoices, optional | |