AdarshDRC commited on
Commit
08bcc6f
·
verified ·
1 Parent(s): fd67f33

Create config.py

Browse files
Files changed (1) hide show
  1. src/config.py +172 -0
src/config.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ src/config.py — Single source of truth for every constant and environment variable.
3
+
4
+ Rules:
5
+ - No magic numbers anywhere else in the codebase.
6
+ - Every threshold, dimension, and limit is documented here with the reason it exists.
7
+ - Environment variables are loaded once at startup; never call os.getenv() elsewhere.
8
+ """
9
+
10
+ import os
11
+ from dotenv import load_dotenv
12
+
13
+ load_dotenv()
14
+
15
+
16
+ # ════════════════════════════════════════════════════════════════════
17
+ # ENVIRONMENT VARIABLES
18
+ # ════════════════════════════════════════════════════════════════════
19
+
20
+ DEFAULT_PINECONE_KEY = os.getenv("DEFAULT_PINECONE_KEY", "")
21
+ DEFAULT_CLOUDINARY_URL = os.getenv("DEFAULT_CLOUDINARY_URL", "")
22
+ SUPABASE_URL = os.getenv("SUPABASE_URL", "")
23
+ SUPABASE_SERVICE_KEY = os.getenv("SUPABASE_SERVICE_KEY", "")
24
+ HF_TOKEN = os.getenv("HF_TOKEN", "")
25
+
26
+ # Set ENABLE_ADAFACE=1 to enable full ArcFace+AdaFace 1024-D fusion.
27
+ # When disabled, ArcFace(512) + zeros(512) = 1024-D (fully functional,
28
+ # zero-padding is cosine-neutral and doesn't corrupt similarity scores).
29
+ ENABLE_ADAFACE = os.getenv("ENABLE_ADAFACE", "0").strip() == "1"
30
+
31
+ # InsightFace ONNX runtime is NOT thread-safe. Keep at 1 unless you
32
+ # switch to a thread-safe inference backend (e.g. Triton, torchserve).
33
+ MAX_CONCURRENT_INFERENCES = int(os.getenv("MAX_CONCURRENT_INFERENCES", "1"))
34
+
35
+
36
+ # ════════════════════════════════════════════════════════════════════
37
+ # PINECONE INDEX NAMES
38
+ # ════════════════════════════════════════════════════════════════════
39
+
40
+ IDX_FACES = "enterprise-faces"
41
+ IDX_OBJECTS = "enterprise-objects"
42
+
43
+
44
+ # ════════════════════════════════════════════════════════════════════
45
+ # VECTOR DIMENSIONS
46
+ # These MUST match the Pinecone index dimensions.
47
+ # If you change a dimension you MUST reset the corresponding index.
48
+ # ════════════════════════════════════════════════════════════════════
49
+
50
+ FACE_DIM = 512 # ArcFace-R100 raw output
51
+ ADAFACE_DIM = 512 # AdaFace IR-50 raw output
52
+ FUSED_FACE_DIM = 1024 # concat(ArcFace, AdaFace) → stored in enterprise-faces
53
+
54
+ SIGLIP_DIM = 768 # google/siglip-base-patch16-224 output
55
+ DINOV2_DIM = 768 # facebook/dinov2-base CLS token output
56
+ FUSED_OBJ_DIM = 1536 # concat(SigLIP, DINOv2) → stored in enterprise-objects
57
+
58
+ # Allow env-var overrides in case the index was created at different dims
59
+ IDX_FACES_DIM = int(os.getenv("IDX_FACES_DIM", str(FUSED_FACE_DIM)))
60
+ IDX_OBJECTS_DIM = int(os.getenv("IDX_OBJECTS_DIM", str(FUSED_OBJ_DIM)))
61
+
62
+
63
+ # ════════════════════════════════════════════════════════════════════
64
+ # OBJECT LANE — YOLO + EMBEDDING
65
+ # ════════════════════════════════════════════════════════════════════
66
+
67
+ # Longest edge of an image before embedding.
68
+ # 640px balances accuracy vs GPU memory; SigLIP/DINOv2 were pretrained at 224px
69
+ # so going above ~640 yields diminishing returns.
70
+ MAX_IMAGE_SIZE = 640
71
+
72
+ # Max YOLO segmentation crops per image (full image is always crop 0).
73
+ # Beyond ~6 crops the embeddings become redundant and slow down inference.
74
+ MAX_CROPS = 6
75
+
76
+ YOLO_PERSON_CLASS_ID = 0 # COCO class 0 = "person"
77
+ YOLO_MIN_CROP_PX = 30 # ignore detections smaller than 30×30 px
78
+ YOLO_CONF_THRESHOLD = 0.5 # YOLO confidence gate
79
+
80
+
81
+ # ════════════════════════════════════════════════════════════════════
82
+ # FACE LANE — DETECTION
83
+ # ════════════════════════════════════════════════════════════════════
84
+
85
+ # Multi-scale pyramid: SCRFD runs at each resolution, results are merged
86
+ # and deduplicated by IoU. Larger scales catch smaller faces.
87
+ # DET_SIZE_PRIMARY is the InsightFace prep() size; the others are used
88
+ # by temporarily overriding det_model.input_size mid-pipeline.
89
+ DET_SIZE_PRIMARY = (1280, 1280)
90
+ DET_SIZE_SECONDARY = (960, 960)
91
+ DET_SIZE_FALLBACK = (640, 640)
92
+ DET_SCALES = [DET_SIZE_PRIMARY, DET_SIZE_SECONDARY, DET_SIZE_FALLBACK]
93
+
94
+ # Suppress duplicate detections across scales/flips.
95
+ # IoU > 0.45 → same face detected twice; keep the higher-confidence one.
96
+ IOU_DEDUP_THRESHOLD = 0.45
97
+
98
+
99
+ # ════════════════════════════════════════════════════════════════════
100
+ # FACE LANE — QUALITY GATES (applied during detection/encoding)
101
+ # ════════════════════════════════════════════════════════════════════
102
+
103
+ # Faces smaller than this (in either dimension) carry too little information
104
+ # for a reliable 512-D embedding.
105
+ MIN_FACE_SIZE = 20 # px
106
+
107
+ # Hard limit on faces stored per source image.
108
+ MAX_FACES_PER_IMAGE = 12
109
+
110
+ # InsightFace det_score gate. Lowered from 0.60 to accept partially
111
+ # occluded faces, angles, sunglasses, and smiles.
112
+ FACE_QUALITY_GATE = 0.35
113
+
114
+
115
+ # ════════════════════════════════════════════════════════════════════
116
+ # FACE LANE — SEARCH THRESHOLDS (applied to Pinecone cosine scores)
117
+ # These are separate from FACE_QUALITY_GATE (which gates detection).
118
+ # These gate how similar a stored face must be to the query face.
119
+ # ════════════════════════════════════════════════════════════════════
120
+
121
+ # det_score ≥ 0.85 → high-quality frontal face → use stricter match threshold
122
+ FACE_DET_SCORE_HQ_SPLIT = 0.85
123
+ FACE_THRESHOLD_HIGH = 0.40 # for high-quality faces
124
+ FACE_THRESHOLD_LOW = 0.32 # for lower-quality faces
125
+
126
+ FACE_TOP_K_FETCH = 50 # fetch more candidates then filter; multi-face merge needs headroom
127
+
128
+
129
+ # ════════════════════════════════════════════════════════════════════
130
+ # OBJECT LANE — SEARCH THRESHOLDS
131
+ # ════════════════════════════════════════════════════════════════════
132
+
133
+ OBJECT_SCORE_THRESHOLD = 0.45
134
+ OBJECT_TOP_K = 10
135
+
136
+
137
+ # ════════════════════════════════════════════════════════════════════
138
+ # FACE CROP THUMBNAILS
139
+ # Stored in Pinecone metadata as base64 JPEG for UI display.
140
+ # ════════════════════════════════════════════════════════════════════
141
+
142
+ FACE_CROP_THUMB_SIZE = 112 # px — matches face model input size
143
+ FACE_CROP_QUALITY = 80 # JPEG quality; balances size vs clarity
144
+ FACE_CROP_PADDING = 0.20 # 20% padding around tight bbox for UI legibility
145
+ ADAFACE_CROP_PADDING = 0.10 # 10% padding for model input (wants tight crop)
146
+
147
+
148
+ # ════════════════════════════════════════════════════════════════════
149
+ # API LIMITS
150
+ # ════════════════════════════════════════════════════════════════════
151
+
152
+ # Hard cap on files per upload request. Each file spawns concurrent
153
+ # Cloudinary + AI tasks; uncapped batches can exhaust RAM.
154
+ MAX_FILES_PER_UPLOAD = 20
155
+
156
+
157
+ # ════════════════════════════════════════════════════════════════════
158
+ # LRU PINECONE CLIENT POOL
159
+ # ════════════════════════════════════════════════════════════════════
160
+
161
+ # Each Pinecone() client holds open TCP connections.
162
+ # Too many exhaust file descriptors; 64 covers typical multi-tenant load.
163
+ PINECONE_POOL_MAX = 64
164
+
165
+
166
+ # ════════════════════════════════════════════════════════════════════
167
+ # IN-MEMORY INFERENCE CACHE
168
+ # ═══════════════════════════════════════════════════════════���════════
169
+
170
+ # Cache keyed by (file_hash, detect_faces). 128 entries ≈ last ~128 unique
171
+ # images; prevents re-running multi-second AI inference on duplicate uploads.
172
+ INFERENCE_CACHE_SIZE = 128