Skip to content

Commit ce6127f

Browse files
committed
feat: Resolving RAG Issues
1 parent f6b70e3 commit ce6127f

File tree

12 files changed

+13096
-13052
lines changed

12 files changed

+13096
-13052
lines changed

.dockerignore

Lines changed: 0 additions & 16 deletions
This file was deleted.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
faiss_index/
44
mlruns/
55
mlartifacts/
6-
my_model/
6+
models/hf_cache/
77

88
# Byte-compiled / optimized / DLL files
99
__pycache__/

data/processed/test_set.csv

Lines changed: 2582 additions & 2582 deletions
Large diffs are not rendered by default.

data/processed/train_set.csv

Lines changed: 10325 additions & 10325 deletions
Large diffs are not rendered by default.

docker-compose.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ services:
1616
- ./src:/app/src
1717
- ./models:/app/models
1818
- ./faiss_index:/app/faiss_index
19-
- ./my_model:/app/my_model
2019
dns:
2120
- 8.8.8.8
2221
- 8.8.4.4
2322
environment:
2423
- GROQ_API_KEY=${GROQ_API_KEY}
25-
- EMBED_MODEL_PATH=/app/my_model
26-
- HF_HUB_OFFLINE=1
27-
- TRANSFORMERS_OFFLINE=1
24+
- HF_HOME=./models/hf_cache
25+
- EMBED_MODEL_PATH=sentence-transformers/all-MiniLM-L6-v2
26+
- HF_HUB_OFFLINE=0
27+
- TRANSFORMERS_OFFLINE=0
2828
networks:
2929
- monitoring-net
3030

mlflow.db

440 KB
Binary file not shown.

models/model.joblib

4.42 MB
Binary file not shown.

models/scaler.joblib

1.14 KB
Binary file not shown.

src/app/main.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import json
55
from fastapi import FastAPI, HTTPException
66
from pydantic import BaseModel, ConfigDict
7-
import numpy as np
87
import os
98
from typing import List
109
from dotenv import load_dotenv
@@ -66,6 +65,14 @@ def ask_rag(query):
6665
print("Error: model_columns.json not found.")
6766
model_columns = []
6867

68+
# Load scaler
69+
try:
70+
scaler = joblib.load("models/scaler.joblib")
71+
print("Scaler loaded successfully.")
72+
except FileNotFoundError:
73+
print("Error: scaler.joblib not found.")
74+
scaler = None
75+
6976

7077
# Define Input Data Shape (Pydantic BaseModel) ---
7178
class ProductFeatures(BaseModel):
@@ -143,7 +150,15 @@ def health():
143150

144151
@app.post("/predict", response_model=PredictionOut)
145152
def predict(features: ProductFeatures):
153+
if model is None or not model_columns or scaler is None:
154+
raise HTTPException(
155+
status_code=500, detail="Model, columns, or scaler not loaded."
156+
)
157+
158+
# Convert Pydantic object → dict
146159
data_dict = features.model_dump()
160+
161+
# Rename to match training columns
147162
data_dict_renamed = {
148163
"Original Price": data_dict["Original_Price"],
149164
"Discount Price": data_dict["Discount_Price"],
@@ -156,17 +171,38 @@ def predict(features: ProductFeatures):
156171
"Delivery Type": data_dict["Delivery_Type"],
157172
"Flagship Store": data_dict["Flagship_Store"],
158173
}
174+
175+
# Make a DataFrame
159176
input_df = pd.DataFrame([data_dict_renamed])
177+
178+
# --- SCALE NUMERIC FEATURES (NEW) ---
179+
numeric_features = [
180+
"Original Price",
181+
"Discount Price",
182+
"Number of Ratings",
183+
"Positive Seller Ratings",
184+
"Ship On Time",
185+
"Chat Response Rate",
186+
"No. of products to be sold",
187+
]
188+
189+
input_df[numeric_features] = scaler.transform(input_df[numeric_features])
190+
191+
# --- ENCODE CATEGORICALS ---
160192
input_df_encoded = pd.get_dummies(input_df, drop_first=True)
193+
194+
# --- ALIGN COLUMNS ---
161195
input_df_aligned = input_df_encoded.reindex(columns=model_columns, fill_value=0)
162196

163-
if model is None or not model_columns:
164-
return {"error": "Model or columns not loaded."}
197+
# --- PREDICT ---
198+
raw_pred = model.predict(input_df_aligned)[0]
199+
200+
# Clip output to between 1–100
201+
prediction = float(raw_pred)
165202

166-
prediction = np.clip(model.predict(input_df_aligned)[0], 1, 100)
167-
observe_prediction()
203+
observe_prediction() # D4 metric
168204

169-
return {"predicted_success_score": float(prediction)}
205+
return {"predicted_success_score": prediction}
170206

171207

172208
# D2 RAG Chatbot Endpoint (Updated with Guardrails)

src/ingest.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,45 @@
66
from llama_index.llms.groq import Groq
77
from llama_index.core.node_parser import SentenceSplitter
88

9-
# 1. Setup
10-
print("Starting Ingestion...")
11-
Settings.embed_model = HuggingFaceEmbedding(
12-
model_name="sentence-transformers/all-MiniLM-L6-v2"
9+
# 1. Setup Hugging Face cache & Embedding
10+
hf_cache_dir = os.getenv("HF_HOME", "models/hf_cache")
11+
os.makedirs(hf_cache_dir, exist_ok=True)
12+
13+
embed_model_name = os.getenv(
14+
"EMBED_MODEL_PATH", "sentence-transformers/all-MiniLM-L6-v2"
1315
)
16+
print(f"Using embedding model: {embed_model_name}")
17+
18+
Settings.embed_model = HuggingFaceEmbedding(model_name=embed_model_name)
1419
Settings.llm = Groq(model="llama-3.1-8b-instant", api_key=os.getenv("GROQ_API_KEY"))
1520

16-
# 2. Load Data
17-
# CHECK THIS PATH: Make sure your CSV is actually inside data/raw/
21+
# 2. Load CSV
1822
file_path = os.path.join("data", "raw", "daraz-code-mixed-product-reviews.csv")
19-
2023
if not os.path.exists(file_path):
21-
print(f" Error: File not found at {file_path}")
22-
print(" Please move your CSV to 'data/raw/' or update the path.")
23-
exit()
24+
raise FileNotFoundError(
25+
f"CSV not found at {file_path}. Please move it there or update the path."
26+
)
2427

2528
df = pd.read_csv(file_path)
2629
documents = []
2730

28-
print(f" Processing {len(df)} rows...")
31+
print(f"Processing {len(df)} rows...")
2932
for _, row in df.iterrows():
30-
review_text = str(row["Reviews"]) # Ensure string
33+
review_text = str(row["Reviews"])
3134
sentiment_value = str(row.get("Sentiments", "unknown"))
3235

3336
text = f"Review: {review_text}\nSentiment: {sentiment_value}"
34-
35-
# Metadata helps the LLM filter if needed
36-
metadata = {
37-
"sentiment": sentiment_value,
38-
}
37+
metadata = {"sentiment": sentiment_value}
3938
documents.append(Document(text=text, metadata=metadata))
4039

4140
# 3. Chunking
4241
parser = SentenceSplitter(chunk_size=512, chunk_overlap=50)
4342
nodes = parser.get_nodes_from_documents(documents)
4443

45-
# 4. Build & Save (Default LlamaIndex Storage - Compatible with your query.py)
46-
print("Building Index...")
44+
# 4. Build & Save Index
4745
index = VectorStoreIndex(nodes, show_progress=True)
46+
faiss_dir = "faiss_index"
47+
os.makedirs(faiss_dir, exist_ok=True)
48+
index.storage_context.persist(persist_dir=faiss_dir)
4849

49-
print("Saving to 'faiss_index'...")
50-
index.storage_context.persist(persist_dir="faiss_index")
51-
52-
print("SUCCESS: Index built! Now run 'make run' or 'python main.py'")
50+
print(f"SUCCESS: Index built and saved to '{faiss_dir}'")

0 commit comments

Comments
 (0)