Suprito commited on
Commit
9026f71
·
verified ·
1 Parent(s): bc18fa6

Upload 15 files

Browse files
.dockerignore ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ venv/
2
+ __pycache__/
3
+ .env
4
+ .ipynb_checkpoints/
5
+ *.pyc
6
+
7
+ # Exclude any local model weights if you accidentally put them in the folder
8
+ *.bin
9
+ *.bin.*
10
+ *.pth
11
+ *.pt
12
+ model/
13
+ checkpoint/
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ chroma_db/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text
37
+ data/MedicalBook.pdf filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ venv/
2
+ .env
3
+ chroma_db/
4
+ __pycache__/
Dockerfile ADDED
File without changes
app.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests # Standard library for sending API requests
3
+
4
+ st.set_page_config(page_title="Medical AI Assistant", layout="centered")
5
+ st.title("⚕️ General Medicine Chatbot")
6
+
7
+ # This is the address of your FastAPI "Brain"
8
+ API_URL = "http://127.0.0.1:8000/ask"
9
+
10
+ # Initialize chat history
11
+ if "messages" not in st.session_state:
12
+ st.session_state.messages = []
13
+
14
+ # Display previous messages
15
+ for message in st.session_state.messages:
16
+ with st.chat_message(message["role"]):
17
+ st.markdown(message["content"])
18
+
19
+ if prompt := st.chat_input("Ask a medical question..."):
20
+ # 1. Display user message
21
+ st.chat_message("user").markdown(prompt)
22
+ st.session_state.messages.append({"role": "user", "content": prompt})
23
+
24
+ # 2. Call the API
25
+ with st.chat_message("assistant"):
26
+ with st.spinner("Thinking..."):
27
+ try:
28
+ # We send the query to your FastAPI server
29
+ # Note: 'query' must match the Pydantic model in main.py
30
+ payload = {"query": prompt}
31
+ response = requests.post(API_URL, json=payload)
32
+
33
+ if response.status_code == 200:
34
+ answer = response.json().get("answer", "No answer found.")
35
+ st.markdown(answer)
36
+ st.session_state.messages.append({"role": "assistant", "content": answer})
37
+ else:
38
+ st.error(f"API Error {response.status_code}: {response.text}")
39
+
40
+ except Exception as e:
41
+ st.error(f"Could not connect to the API. Is Uvicorn running? Error: {e}")
chroma_db/3680a8e6-9770-4cfc-9ae4-18ad2a369d9b/data_level0.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a7d011826d12a6ecb524c46ede71a830b5c48fd6f1cce9fccc4769ab833c3f7a
3
+ size 30484764
chroma_db/3680a8e6-9770-4cfc-9ae4-18ad2a369d9b/header.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4cc1e2b6bdf1eee6eeddf6cb9aa7e20c69033a8a929d902cd56859392e703544
3
+ size 100
chroma_db/3680a8e6-9770-4cfc-9ae4-18ad2a369d9b/index_metadata.pickle ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9cddbf2ed05e967b82f0aa08af3fc6d86d674784c779fc12911e6b4c0513a534
3
+ size 1673588
chroma_db/3680a8e6-9770-4cfc-9ae4-18ad2a369d9b/length.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8e94d1a8852d94aa7c25b56188ab929e437a50bcce95ffd81eacfc29596156ec
3
+ size 72756
chroma_db/3680a8e6-9770-4cfc-9ae4-18ad2a369d9b/link_lists.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4a0204e0094ab2daaecd241d7808b915e3c05cf6f38abed8cba205a33303304e
3
+ size 156260
chroma_db/chroma.sqlite3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:004ed53cdb169fca6e2874342756070a0d218cf9d3856ddd4395176bb58f83c9
3
+ size 118001664
data/MedicalBook.pdf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cef47d2bcde526111d3d29f77876ab139efdf7d7e5e3180838fff9c335c64dc1
3
+ size 10764110
engine.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from operator import itemgetter
2
+ import os
3
+ from dotenv import load_dotenv
4
+ from langchain_community.embeddings import HuggingFaceEmbeddings
5
+ from langchain_huggingface import HuggingFaceEmbeddings
6
+ from langchain_chroma import Chroma
7
+
8
+ from utils import load_docs, split_docs
9
+ from langchain_huggingface import HuggingFaceEmbeddings
10
+ from langchain_core.prompts import ChatPromptTemplate
11
+ from langchain_core.output_parsers import StrOutputParser
12
+ from langchain_core.runnables import RunnablePassthrough
13
+ from langchain_huggingface import ChatHuggingFace
14
+
15
+ import torch
16
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
17
+ from langchain_huggingface import HuggingFacePipeline
18
+
19
+
20
+ import warnings
21
+ warnings.filterwarnings("ignore", category=UserWarning)
22
+
23
+ load_dotenv()
24
+ HF_TOKEN = os.getenv("HF_TOKEN")
25
+ file_path = "data/MedicalBook.pdf"
26
+
27
+ def downlode_hugging_face_embeddings():
28
+ embeddings=HuggingFaceEmbeddings(model_name='sentence-transformers/msmarco-MiniLM-L6-v3')
29
+ return embeddings
30
+
31
+ CHROMA_PATH="chroma_db"
32
+ #embeddings = downlode_hugging_face_embeddings()
33
+
34
+ def create_vectorstore(embeddings):
35
+ if os.path.exists(CHROMA_PATH):
36
+ print(f"--- Loading existing Vector DB from {CHROMA_PATH}... ---")
37
+ # FIX: To LOAD, use Chroma() directly. Do NOT use .from_documents()
38
+ return Chroma(
39
+ persist_directory=CHROMA_PATH,
40
+ embedding_function=embeddings
41
+ )
42
+ else:
43
+ print("Creating a new one...")
44
+ documents = load_docs(file_path)
45
+ text_chunks = split_docs(documents)
46
+ # Use .from_documents ONLY when you have new text_chunks to process
47
+ return Chroma.from_documents(
48
+ documents=text_chunks,
49
+ embedding=embeddings,
50
+ persist_directory=CHROMA_PATH
51
+ )
52
+
53
+ # vector_db=create_vectorstore()
54
+ # retriever=vector_db.as_retriever(search_kwargs={"k": 3})
55
+
56
+ def get_llm():
57
+ # The correct ID for the 1B Instruct model
58
+ model_path = "ibm-granite/granite-3.0-1b-a400m-instruct"
59
+
60
+ device = -1 # Force CPU
61
+ print(f"--- Loading local model: {model_path} ---")
62
+
63
+ tokenizer = AutoTokenizer.from_pretrained(model_path)
64
+
65
+ # We use low_cpu_mem_usage to keep the RAM footprint small
66
+ model = AutoModelForCausalLM.from_pretrained(
67
+ model_path,
68
+ torch_dtype=torch.float32,
69
+ low_cpu_mem_usage=True,
70
+ device_map=None
71
+ )
72
+
73
+ gen_pipeline = pipeline(
74
+ "text-generation",
75
+ model=model,
76
+ tokenizer=tokenizer,
77
+ max_new_tokens=256,
78
+ temperature=0.3,
79
+ do_sample=True,
80
+ return_full_text=False
81
+ )
82
+
83
+ llm = HuggingFacePipeline(pipeline=gen_pipeline)
84
+ return ChatHuggingFace(llm=llm)
85
+
86
+
87
+ def get_llm_response(user_input, retriever, llm):
88
+ prompt = ChatPromptTemplate.from_messages([
89
+ ("system", "You are a medical specialist. Use the context to answer. If you don't know, say 'I don't know'."),
90
+ ("human", "Context: {context}\n\nQuestion: {input}")
91
+ ])
92
+
93
+ chain = (
94
+ {
95
+ "context": itemgetter("input") | retriever,
96
+ "input": itemgetter("input"),
97
+ }
98
+ | prompt
99
+ | llm
100
+ | StrOutputParser()
101
+ )
102
+ return chain.invoke({"input": user_input})
103
+
104
+ def load_system():
105
+ """
106
+ Orchestrates the loading of the full RAG pipeline.
107
+ This can be called by both FastAPI and Streamlit.
108
+ """
109
+ print("--- Initializing Medical AI System ---")
110
+ embeddings = downlode_hugging_face_embeddings()
111
+ vector_db = create_vectorstore(embeddings)
112
+ retriever = vector_db.as_retriever(search_kwargs={"k": 3})
113
+ llm = get_llm()
114
+ print("--- System Ready ---")
115
+ return retriever, llm
116
+
117
+ if __name__=="__main__":
118
+
119
+ embeddings = downlode_hugging_face_embeddings()
120
+ vector_db=create_vectorstore(embeddings)
121
+ retriever=vector_db.as_retriever(search_kwargs={"k": 3})
122
+ llm=get_llm()
123
+
124
+ # print("\n -- LLM Testing -- \n")
125
+ # while True:
126
+ # User_query=input("User: ")
127
+ # if User_query.lower() in ["quit","exit","q"]:
128
+ # print("Exiting..")
129
+ # break
130
+ # response=get_llm_response(User_query, retriever, llm)
131
+ # print(f"Assistant: {response}")
132
+
133
+
134
+
135
+
main.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel
3
+ from engine import load_system, get_llm_response
4
+
5
+
6
+ app=FastAPI(
7
+ title="Medical RAG API",
8
+ description="Backend API for IBM Granite chat model",
9
+ version="1.0.0")
10
+
11
+ #gloabal model loading
12
+ print("Loading Medical AI Engine... Please wait.")
13
+ retriever, llm = load_system()
14
+ print("AI loaded successfully.")
15
+
16
+ class ChatRequest(BaseModel):
17
+ query: str
18
+
19
+ class ChatResponse(BaseModel):
20
+ answer: str
21
+
22
+ @app.get("/")
23
+ def read_root():
24
+ return {"status":"online","message": "Medical API is Ready"}
25
+
26
+ @app.post("/ask", response_model=ChatResponse)
27
+ async def ask_question(request: ChatRequest):
28
+ try:
29
+ # Using the globally loaded retriever and llm
30
+ response = get_llm_response(request.query, retriever, llm)
31
+ return ChatResponse(answer=response)
32
+ except Exception as e:
33
+ # Standard API error handling
34
+ raise HTTPException(status_code=500, detail=str(e))
requirements.txt ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ Pydentic
4
+ python-dotenv
5
+
6
+ langchain
7
+ langchain-community
8
+ langchain-huggingface
9
+ sentence-transformers
10
+
11
+ pypdf
12
+ langchain-chroma
13
+ streamlit
14
+
15
+ requests
16
+ torch --index-url https://download.pytorch.org/whl/cpu
17
+ transformers
18
+ accelerate
start.sh ADDED
File without changes