Sai809701 commited on
Commit
2cba8eb
Β·
1 Parent(s): fce0e0f

updated main.py

Browse files
Files changed (2) hide show
  1. Dockerfile +27 -3
  2. main.py +36 -32
Dockerfile CHANGED
@@ -1,12 +1,36 @@
 
1
  FROM python:3.10-slim
2
 
 
3
  WORKDIR /app
4
 
 
5
  COPY requirements.txt .
6
- RUN pip install --no-cache-dir --upgrade pip
7
- RUN pip install --no-cache-dir -r requirements.txt
8
 
 
 
 
 
 
9
  COPY . .
10
 
 
 
 
 
11
  EXPOSE 7860
12
- CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use official Python image
2
  FROM python:3.10-slim
3
 
4
+ # Set working directory
5
  WORKDIR /app
6
 
7
+ # Copy requirements and install dependencies
8
  COPY requirements.txt .
 
 
9
 
10
+ # Upgrade pip and install pinned dependencies
11
+ RUN pip install --no-cache-dir --upgrade pip \
12
+ && pip install --no-cache-dir -r requirements.txt
13
+
14
+ # Copy all code and model files
15
  COPY . .
16
 
17
+ # Set Transformers cache to a writable folder
18
+ ENV TRANSFORMERS_CACHE=/tmp/hf_cache
19
+
20
+ # Expose FastAPI port
21
  EXPOSE 7860
22
+
23
+ # Precompute embeddings at build time (optional: adjust if dataset is large)
24
+ RUN python -c "\
25
+ import os, torch, pandas as pd;\
26
+ from sentence_transformers import SentenceTransformer;\
27
+ model = SentenceTransformer('./muril_combined_multilingual_model');\
28
+ df = pd.read_csv('./muril_multilingual_dataset.csv').dropna(subset=['question','answer']);\
29
+ answers = df['answer'].tolist();\
30
+ embeddings = model.encode(answers, convert_to_tensor=True);\
31
+ torch.save(embeddings, './answer_embeddings.pt');\
32
+ print('βœ… Precomputed embeddings saved');\
33
+ "
34
+
35
+ # Run FastAPI with uvicorn
36
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "]()
main.py CHANGED
@@ -1,33 +1,37 @@
1
  import os
2
- os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf_cache"
 
3
  import torch
4
- from fastapi import FastAPI, Query
 
5
  from pydantic import BaseModel
6
  from sentence_transformers import SentenceTransformer, util
7
- import pandas as pd
8
- from langdetect import detect, DetectorFactory
9
-
10
- # Fix langdetect randomness
11
- DetectorFactory.seed = 0
12
 
13
  # --- Configuration ---
14
  MODEL_PATH = './muril_combined_multilingual_model'
15
  CSV_PATH = './muril_multilingual_dataset.csv'
 
16
 
17
  # --- Load MuRIL Model and Dataset ---
18
  def load_resources():
19
  try:
20
  model = SentenceTransformer(MODEL_PATH)
21
- df = pd.read_csv(CSV_PATH).dropna(subset=['question', 'answer'])
22
- # Precompute embeddings for all answers
23
- df['embedding'] = list(model.encode(df['answer'].tolist(), convert_to_tensor=True))
24
- print("βœ… Resources loaded successfully!")
25
- return model, df
 
 
 
 
 
26
  except Exception as e:
27
  print(f"❌ Error loading resources: {e}")
28
- return None, None
29
 
30
- model, df = load_resources()
31
 
32
  # --- Initialize FastAPI ---
33
  app = FastAPI(title="MuRIL Multilingual QA API")
@@ -35,7 +39,7 @@ app = FastAPI(title="MuRIL Multilingual QA API")
35
  # --- API Data Models ---
36
  class QueryRequest(BaseModel):
37
  question: str
38
- lang: str = None # Optional language filter (en/hi/mr/...)
39
 
40
  class QAResponse(BaseModel):
41
  answer: str
@@ -47,28 +51,28 @@ def get_answer_endpoint(request: QueryRequest):
47
  return {"answer": "Model not loaded."}
48
 
49
  question_text = request.question
50
- question_lang = None
51
- try:
52
- question_lang = detect(question_text)
53
- except:
54
- question_lang = None
55
 
56
- question_emb = model.encode(question_text, convert_to_tensor=True)
 
 
 
 
 
57
 
58
- # Filter dataframe by requested language if provided
59
  filtered_df = df
60
- if request.lang:
61
- filtered_df = df[df['answer'].apply(lambda x: detect(x) == request.lang)]
62
-
63
- if filtered_df.empty:
64
- filtered_df = df # fallback to all answers
65
-
66
- # Compute cosine similarity
67
- answer_embeddings = torch.stack(filtered_df['embedding'].to_list())
68
- cosine_scores = util.pytorch_cos_sim(question_emb, answer_embeddings)
69
  best_idx = torch.argmax(cosine_scores).item()
70
  answer = filtered_df.iloc[best_idx]['answer']
71
-
72
  return {"answer": answer}
73
 
74
  @app.get("/")
 
1
  import os
2
+ os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf_cache" # MUST be before importing SentenceTransformer
3
+
4
  import torch
5
+ import pandas as pd
6
+ from fastapi import FastAPI
7
  from pydantic import BaseModel
8
  from sentence_transformers import SentenceTransformer, util
9
+ from langdetect import detect
 
 
 
 
10
 
11
  # --- Configuration ---
12
  MODEL_PATH = './muril_combined_multilingual_model'
13
  CSV_PATH = './muril_multilingual_dataset.csv'
14
+ EMBEDDINGS_PATH = './answer_embeddings.pt'
15
 
16
  # --- Load MuRIL Model and Dataset ---
17
  def load_resources():
18
  try:
19
  model = SentenceTransformer(MODEL_PATH)
20
+ df = pd.read_csv(CSV_PATH).dropna(subset=['question','answer'])
21
+ if os.path.exists(EMBEDDINGS_PATH):
22
+ answer_embeddings = torch.load(EMBEDDINGS_PATH)
23
+ print("βœ… Loaded precomputed embeddings")
24
+ else:
25
+ answers = df['answer'].tolist()
26
+ answer_embeddings = model.encode(answers, convert_to_tensor=True)
27
+ torch.save(answer_embeddings, EMBEDDINGS_PATH)
28
+ print("βœ… Computed and saved embeddings")
29
+ return model, df, answer_embeddings
30
  except Exception as e:
31
  print(f"❌ Error loading resources: {e}")
32
+ return None, None, None
33
 
34
+ model, df, answer_embeddings = load_resources()
35
 
36
  # --- Initialize FastAPI ---
37
  app = FastAPI(title="MuRIL Multilingual QA API")
 
39
  # --- API Data Models ---
40
  class QueryRequest(BaseModel):
41
  question: str
42
+ lang: str = None # optional language filter, e.g., "en", "hi", "mr"
43
 
44
  class QAResponse(BaseModel):
45
  answer: str
 
51
  return {"answer": "Model not loaded."}
52
 
53
  question_text = request.question
54
+ lang_filter = request.lang
 
 
 
 
55
 
56
+ # Detect language if no filter provided
57
+ if not lang_filter:
58
+ try:
59
+ lang_filter = detect(question_text)
60
+ except:
61
+ lang_filter = None
62
 
63
+ # Filter dataset by language if specified
64
  filtered_df = df
65
+ filtered_embeddings = answer_embeddings
66
+ if lang_filter:
67
+ if 'lang' in df.columns:
68
+ mask = df['lang'] == lang_filter
69
+ filtered_df = df[mask]
70
+ filtered_embeddings = torch.tensor([answer_embeddings[i] for i, m in enumerate(mask) if m])
71
+
72
+ question_emb = model.encode(question_text, convert_to_tensor=True)
73
+ cosine_scores = util.pytorch_cos_sim(question_emb, filtered_embeddings)
74
  best_idx = torch.argmax(cosine_scores).item()
75
  answer = filtered_df.iloc[best_idx]['answer']
 
76
  return {"answer": answer}
77
 
78
  @app.get("/")