SagarAtHf's picture
Update main.py
f822f95 verified
Raw
History Blame Contribute Delete
3.57 kB
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import os
import torch
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig, pipeline
app = FastAPI(title="Flykite Model Serving Engine")
class QueryRequest(BaseModel):
question: str
chunk_size: int = 1000
chunk_overlap: int = 200
k_depth: int = 3
temperature: float = 0.20
top_p: float = 0.90
# Pre-caching models on container start
embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-small-en-v1.5")
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.float16
)
model_id = "mistralai/Mistral-7B-Instruct-v0.3"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id, quantization_config=bnb_config, device_map="auto"
)
pdf_path = "Flykite Airlines_ HRP.pdf"
raw_documents = PyMuPDFLoader(pdf_path).load() if os.path.exists(pdf_path) else None
@app.get("/")
def health():
return {"status": "ready", "document_indexed": raw_documents is not None}
@app.post("/api/generate")
@app.post("/api/generate")
def generate(payload: QueryRequest):
# Checkpoint 1: Confirm payload extraction
print(f"πŸ“¬ [API RECEIVED] Incoming query captured: '{payload.question}'")
if not raw_documents:
raise HTTPException(status_code=500, detail="Handbook missing on host filesystem.")
# Checkpoint 2: Monitor the Data Engineering processing phase
print(f"πŸ”„ [DATA PROCESSING] Slicing text chunks... Size: {payload.chunk_size} | Overlap: {payload.chunk_overlap}")
splitter = RecursiveCharacterTextSplitter(chunk_size=payload.chunk_size, chunk_overlap=payload.chunk_overlap)
chunks = splitter.split_documents(raw_documents)
# Checkpoint 3: Monitor Vector Database indexing
print(f"πŸ“¦ [INDEXING] Rebuilding dynamic FAISS vector matrix with {len(chunks)} nodes...")
db = FAISS.from_documents(chunks, embeddings)
retriever = db.as_retriever(search_kwargs={"k": payload.k_depth})
# Checkpoint 4: Confirm Retrieval Success
docs = retriever.invoke(payload.question)
print(f"πŸ” [RETRIEVED] Pulling context... Extracted top {len(docs)} segments for prompt insertion.")
context = "\n\n".join([c.page_content for c in docs])
audit = [{"page": d.metadata.get("page", "unknown"), "content": d.page_content} for d in docs]
prompt = (
f"You are the official Flykite Assistant. Base answers ONLY on context.\n\n"
f"CONTEXT:\n{context}\n\nQUERY: {payload.question}\n\nRESPONSE:"
)
# Checkpoint 5: Model Inference Start Execution
print("🧠 [LLM RUNNING] Tokenizing prompt and spinning compute core via Mistral-7B...")
gen = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512,
temperature=payload.temperature, top_p=payload.top_p, do_sample=True, pad_token_id=tokenizer.eos_token_id)
response_payload = gen(prompt)[0]["generated_text"].split("RESPONSE:")[-1].strip()
# Checkpoint 6: Success confirmation
print("πŸš€ [SUCCESS] Response compiled. Shipping payload back to frontend.")
return {"answer": response_payload, "audit_trail": audit}