harshrawat18 commited on
Commit
f23cb25
Β·
1 Parent(s): 41800f5

feat: complete sprint 10 (Nomic 768-dim model upgrade and schema migration)

Browse files
Files changed (3) hide show
  1. api.py +13 -6
  2. requirements.txt +1 -1
  3. scripts/reembed_all.py +72 -0
api.py CHANGED
@@ -89,9 +89,13 @@ reranker_model = None
89
  def get_embedding_model():
90
  global embedding_model
91
  if embedding_model is None:
92
- print("⏳ Loading Embedding Model on first request...")
93
- embedding_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
94
- print("βœ… Embedding Model loaded")
 
 
 
 
95
  return embedding_model
96
 
97
  def get_reranker_model():
@@ -148,7 +152,7 @@ async def health_check():
148
  checks = {}
149
  try:
150
  model = get_embedding_model()
151
- test_vec = model.encode("test", normalize_embeddings=True)
152
  checks["embedding_model"] = {"status": "ok", "dims": len(test_vec)}
153
  except Exception as e:
154
  checks["embedding_model"] = {"status": "error", "detail": str(e)}
@@ -188,7 +192,9 @@ async def ingest_document(request: IngestRequest, admin_key: str = ""):
188
  doc_hash = hashlib.sha256(request.text.encode()).hexdigest()[:16]
189
  chunks = chunk_text(request.text)
190
  model = get_embedding_model()
191
- embeddings = model.encode(chunks, normalize_embeddings=True, batch_size=32, show_progress_bar=False).tolist()
 
 
192
  rows = []
193
  for i, (chunk, embedding) in enumerate(zip(chunks, embeddings)):
194
  rows.append({
@@ -221,7 +227,8 @@ async def rag_query(request: Request, query: SearchQuery):
221
 
222
  # --- STEP 2: EMBED THE ENGLISH QUERY ---
223
  model = get_embedding_model()
224
- query_numbers = model.encode(english_query, normalize_embeddings=True).tolist()
 
225
 
226
  # --- STEP 3: SEMANTIC CACHE LOOKUP ---
227
  cache_result = supabase.rpc("check_query_cache", {
 
89
  def get_embedding_model():
90
  global embedding_model
91
  if embedding_model is None:
92
+ print("⏳ Loading Nomic Embedding Model (768-dim)...")
93
+ # PENDING: Run 003_upgrade_embeddings_768.sql in Supabase before this goes live
94
+ embedding_model = SentenceTransformer(
95
+ 'nomic-ai/nomic-embed-text-v1',
96
+ trust_remote_code=True
97
+ )
98
+ print("βœ… Nomic Model loaded")
99
  return embedding_model
100
 
101
  def get_reranker_model():
 
152
  checks = {}
153
  try:
154
  model = get_embedding_model()
155
+ test_vec = model.encode("search_query: test", normalize_embeddings=True)
156
  checks["embedding_model"] = {"status": "ok", "dims": len(test_vec)}
157
  except Exception as e:
158
  checks["embedding_model"] = {"status": "error", "detail": str(e)}
 
192
  doc_hash = hashlib.sha256(request.text.encode()).hexdigest()[:16]
193
  chunks = chunk_text(request.text)
194
  model = get_embedding_model()
195
+ # Nomic requires search_document prefix for schemes/documents
196
+ prefixed_chunks = [f"search_document: {c}" for c in chunks]
197
+ embeddings = model.encode(prefixed_chunks, normalize_embeddings=True, batch_size=32, show_progress_bar=False).tolist()
198
  rows = []
199
  for i, (chunk, embedding) in enumerate(zip(chunks, embeddings)):
200
  rows.append({
 
227
 
228
  # --- STEP 2: EMBED THE ENGLISH QUERY ---
229
  model = get_embedding_model()
230
+ # Nomic requires search_query prefix for citizens' questions
231
+ query_numbers = model.encode(f"search_query: {english_query}", normalize_embeddings=True).tolist()
232
 
233
  # --- STEP 3: SEMANTIC CACHE LOOKUP ---
234
  cache_result = supabase.rpc("check_query_cache", {
requirements.txt CHANGED
@@ -1,7 +1,7 @@
1
  fastapi
2
  uvicorn[standard]
3
  torch>=2.2.0
4
- sentence-transformers
5
  huggingface-hub
6
  groq
7
  supabase
 
1
  fastapi
2
  uvicorn[standard]
3
  torch>=2.2.0
4
+ sentence-transformers>=2.7.0
5
  huggingface-hub
6
  groq
7
  supabase
scripts/reembed_all.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ GovBridge India β€” Full Re-embedding Script
3
+ Run AFTER: Supabase migration 003 is executed
4
+ Purpose: Re-embed all documents with nomic-embed-text-v1 (768-dim)
5
+ Usage: python3 gov_backend/scripts/reembed_all.py
6
+ """
7
+ import os
8
+ import time
9
+ from supabase import create_client
10
+ from sentence_transformers import SentenceTransformer
11
+
12
+ # Load environment variables
13
+ SUPABASE_URL = os.environ.get('SUPABASE_URL')
14
+ SUPABASE_KEY = os.environ.get('SUPABASE_KEY')
15
+ BATCH_SIZE = 50
16
+
17
+ def main():
18
+ if not SUPABASE_URL or not SUPABASE_KEY:
19
+ print("❌ Missing SUPABASE_URL or SUPABASE_KEY")
20
+ return
21
+
22
+ print("⏳ Loading nomic-embed-text-v1 model...")
23
+ model = SentenceTransformer(
24
+ 'nomic-ai/nomic-embed-text-v1',
25
+ trust_remote_code=True
26
+ )
27
+ print("βœ… Model loaded")
28
+
29
+ supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
30
+
31
+ # Fetch all chunks where embedding is null
32
+ result = supabase.table('document_chunks') \
33
+ .select('id, chunk_text, scheme_title') \
34
+ .is_('embedding', 'null') \
35
+ .limit(1000) \
36
+ .execute()
37
+
38
+ chunks = result.data or []
39
+ if not chunks:
40
+ print("πŸŽ‰ No chunks found needing re-embedding.")
41
+ return
42
+
43
+ print(f"Found {len(chunks)} chunks to embed. Starting migration...")
44
+
45
+ for i in range(0, len(chunks), BATCH_SIZE):
46
+ batch = chunks[i:i+BATCH_SIZE]
47
+ # Use Nomic task prefix for documents
48
+ texts = [
49
+ f"search_document: {c.get('chunk_text', '') or c.get('scheme_title', '')}"
50
+ for c in batch
51
+ ]
52
+
53
+ print(f"πŸ”„ Processing batch {i//BATCH_SIZE + 1}...")
54
+ embeddings = model.encode(
55
+ texts,
56
+ normalize_embeddings=True,
57
+ show_progress_bar=False
58
+ ).tolist()
59
+
60
+ for chunk, embedding in zip(batch, embeddings):
61
+ supabase.table('document_chunks') \
62
+ .update({'embedding': embedding}) \
63
+ .eq('id', chunk['id']) \
64
+ .execute()
65
+
66
+ print(f"βœ… Batch {i//BATCH_SIZE + 1} complete.")
67
+ time.sleep(0.5)
68
+
69
+ print("πŸŽ‰ All document chunks have been re-embedded with 768 dimensions.")
70
+
71
+ if __name__ == '__main__':
72
+ main()