Deepak Yadav commited on
Commit
7d9087b
·
1 Parent(s): d31a2f9

updated new version deepseek-r1

Browse files
.DS_Store ADDED
Binary file (8.2 kB). View file
 
.gitignore ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116
+ .pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
169
+
170
+ # Ruff stuff:
171
+ .ruff_cache/
172
+
173
+ # PyPI configuration file
174
+ .pypirc
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python image
2
+ FROM python:3.10
3
+
4
+ # Install dependencies
5
+ RUN apt-get update && apt-get install -y curl
6
+
7
+ # Install Ollama
8
+ RUN curl -fsSL https://ollama.com/install.sh | sh
9
+
10
+ # Install Python dependencies
11
+ COPY requirements.txt .
12
+ RUN pip install --no-cache-dir -r requirements.txt
13
+
14
+ # Copy app files
15
+ COPY . .
16
+
17
+ # Expose Ollama API port
18
+ EXPOSE 11434
19
+
20
+ # Start Ollama in the background
21
+ RUN ollama pull deepseek-r1:1.5b
22
+
23
+ CMD ollama serve & streamlit run app.py --server.port 7860 --server.enableCORS false --server.enableXsrfProtection false
__init__.py ADDED
File without changes
app.py CHANGED
@@ -1,146 +1,35 @@
1
  import streamlit as st
2
  import os
3
- from langchain_community.document_loaders import PDFMinerLoader
4
- from langchain_community.embeddings import SentenceTransformerEmbeddings
5
- from langchain.text_splitter import RecursiveCharacterTextSplitter
6
- from langchain_community.vectorstores import FAISS
7
- from langchain.chains import RetrievalQA
8
- from langchain_community.llms import HuggingFacePipeline
9
- from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, pipeline
10
- import torch
11
 
12
- st.title("DocChatAI | Chat over PDF Doc")
 
 
13
 
14
- # Custom CSS for chat messages
15
- st.markdown("""
16
- <style>
17
- .user-message {
18
- text-align: right;
19
- background-color: #3c8ce7;
20
- color: white;
21
- padding: 10px;
22
- border-radius: 10px;
23
- margin-bottom: 10px;
24
- display: inline-block;
25
- width: fit-content;
26
- max-width: 70%;
27
- margin-left: auto;
28
- box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
29
- }
30
- .assistant-message {
31
- text-align: left;
32
- background-color: #d16ba5;
33
- color: white;
34
- padding: 10px;
35
- border-radius: 10px;
36
- margin-bottom: 10px;
37
- display: inline-block;
38
- width: fit-content;
39
- max-width: 70%;
40
- margin-right: auto;
41
- box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
42
- }
43
- </style>
44
- """, unsafe_allow_html=True)
45
 
46
- def get_file_size(file):
47
- file.seek(0, os.SEEK_END)
48
- file_size = file.tell()
49
- file.seek(0)
50
- return file_size
51
-
52
- # Add a sidebar for model selection and user details
53
- st.sidebar.write("Settings")
54
- st.sidebar.write("-----------")
55
- model_options = ["MBZUAI/LaMini-T5-738M", "google/flan-t5-base", "google/flan-t5-small"]
56
- selected_model = st.sidebar.radio("Choose Model", model_options)
57
- st.sidebar.write("-----------")
58
- uploaded_file = st.sidebar.file_uploader("Upload file", type=["pdf"])
59
- st.sidebar.write("-----------")
60
- st.sidebar.write("About Me")
61
- st.sidebar.write("Name: Deepak Yadav")
62
- st.sidebar.write("Bio: Passionate about AI and machine learning. Enjoys working on innovative projects and sharing knowledge with the community.")
63
- st.sidebar.write("[GitHub](https://github.com/deepak7376)")
64
- st.sidebar.write("[LinkedIn](https://www.linkedin.com/in/dky7376/)")
65
- st.sidebar.write("-----------")
66
-
67
- @st.cache_resource
68
- def initialize_qa_chain(filepath, CHECKPOINT):
69
- loader = PDFMinerLoader(filepath)
70
- documents = loader.load()
71
- text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=500)
72
- splits = text_splitter.split_documents(documents)
73
-
74
- # Create embeddings
75
- embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
76
- vectordb = FAISS.from_documents(splits, embeddings)
77
-
78
- # Initialize model
79
- TOKENIZER = AutoTokenizer.from_pretrained(CHECKPOINT)
80
- BASE_MODEL = AutoModelForSeq2SeqLM.from_pretrained(CHECKPOINT, device_map=torch.device('cpu'), torch_dtype=torch.float32)
81
- pipe = pipeline(
82
- 'text2text-generation',
83
- model=BASE_MODEL,
84
- tokenizer=TOKENIZER,
85
- max_length=256,
86
- do_sample=True,
87
- temperature=0.3,
88
- top_p=0.95,
89
- )
90
-
91
- llm = HuggingFacePipeline(pipeline=pipe)
92
-
93
- # Build a QA chain
94
- qa_chain = RetrievalQA.from_chain_type(
95
- llm=llm,
96
- chain_type="stuff",
97
- retriever=vectordb.as_retriever(),
98
- )
99
- return qa_chain
100
-
101
- def process_answer(instruction, qa_chain):
102
- generated_text = qa_chain.run(instruction)
103
- return generated_text
104
 
 
 
105
  if uploaded_file is not None:
106
  os.makedirs("docs", exist_ok=True)
107
  filepath = os.path.join("docs", uploaded_file.name)
 
108
  with open(filepath, "wb") as temp_file:
109
  temp_file.write(uploaded_file.read())
110
- temp_filepath = temp_file.name
111
 
112
- with st.spinner('Embeddings are in process...'):
113
- qa_chain = initialize_qa_chain(temp_filepath, selected_model)
 
114
  else:
115
- qa_chain = None
116
-
117
- # Initialize chat history
118
- if "messages" not in st.session_state:
119
- st.session_state.messages = []
120
-
121
- # Display chat messages from history on app rerun
122
- for message in st.session_state.messages:
123
- if message["role"] == "user":
124
- st.markdown(f"<div class='user-message'>{message['content']}</div>", unsafe_allow_html=True)
125
- else:
126
- st.markdown(f"<div class='assistant-message'>{message['content']}</div>", unsafe_allow_html=True)
127
-
128
- # React to user input
129
- if prompt := st.chat_input("What is up?"):
130
- # Display user message in chat message container
131
- st.markdown(f"<div class='user-message'>{prompt}</div>", unsafe_allow_html=True)
132
- # Add user message to chat history
133
- st.session_state.messages.append({"role": "user", "content": prompt})
134
 
135
- if qa_chain:
136
- # Generate response
137
- response = process_answer({'query': prompt}, qa_chain)
138
- else:
139
- # Prompt to upload a file
140
- response = "Please upload a PDF file to enable the chatbot."
141
 
142
- # Display assistant response in chat message container
143
- st.markdown(f"<div class='assistant-message'>{response}</div>", unsafe_allow_html=True)
144
-
145
- # Add assistant response to chat history
146
- st.session_state.messages.append({"role": "assistant", "content": response})
 
1
  import streamlit as st
2
  import os
3
+ from components.sidebar import render_sidebar
4
+ from components.chat_ui import display_chat
5
+ from services.llm import initialize_qa_chain, initialize_chain
6
+ from utils.helpers import get_file_size
 
 
 
 
7
 
8
+ # import subprocess
9
+ # process = subprocess.Popen("ollama serve", shell=True)
10
+ # print(process)
11
 
12
+ # App Title
13
+ st.title("DocChatAI | Chat Using Documents")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ # Sidebar - Model Selection & File Upload
16
+ selected_model, temperature, top_p, max_tokens, uploaded_file = render_sidebar()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ mode = False
19
+ # Check if a PDF file is uploaded
20
  if uploaded_file is not None:
21
  os.makedirs("docs", exist_ok=True)
22
  filepath = os.path.join("docs", uploaded_file.name)
23
+
24
  with open(filepath, "wb") as temp_file:
25
  temp_file.write(uploaded_file.read())
 
26
 
27
+ with st.spinner('Please wait...'):
28
+ qa_chain = initialize_qa_chain(filepath, selected_model, temperature, top_p, max_tokens)
29
+ mode = True
30
  else:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ qa_chain = initialize_chain(selected_model, temperature, top_p, max_tokens)
 
 
 
 
 
33
 
34
+ # Initialize and Display Chat History
35
+ display_chat(qa_chain, mode)
 
 
 
components/__init__.py ADDED
File without changes
components/chat_ui.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ # from services.llm import process_answer
3
+ import time
4
+ import re
5
+
6
+ # Custom CSS for chat styling
7
+ CHAT_CSS = """
8
+ <style>
9
+ .user-message {
10
+ text-align: right;
11
+ background-color: #3c8ce7;
12
+ color: white;
13
+ padding: 10px;
14
+ border-radius: 10px;
15
+ margin-bottom: 10px;
16
+ display: inline-block;
17
+ width: fit-content;
18
+ max-width: 70%;
19
+ margin-left: auto;
20
+ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
21
+ }
22
+ .assistant-message {
23
+ text-align: left;
24
+ background-color: #d16ba5;
25
+ color: white;
26
+ padding: 10px;
27
+ border-radius: 10px;
28
+ margin-bottom: 10px;
29
+ display: inline-block;
30
+ width: fit-content;
31
+ max-width: 70%;
32
+ margin-right: auto;
33
+ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
34
+ }
35
+ </style>
36
+ """
37
+ def extract_thoughts(response_text):
38
+ """Extracts <think>...</think> content and the main answer."""
39
+ match = re.search(r"<think>(.*?)</think>", response_text, re.DOTALL)
40
+ if match:
41
+ thinking_part = match.group(1).strip()
42
+ main_answer = re.sub(r"<think>.*?</think>", "", response_text, flags=re.DOTALL).strip()
43
+ else:
44
+ thinking_part = None
45
+ main_answer = response_text.strip()
46
+
47
+ return thinking_part, main_answer
48
+
49
+ # Streamed response emulator
50
+ def response_generator(response):
51
+ for word in response.split():
52
+ yield word + " "
53
+ time.sleep(0.05)
54
+
55
+ def display_chat(qa_chain, mode):
56
+ st.markdown(CHAT_CSS, unsafe_allow_html=True)
57
+
58
+ if "messages" not in st.session_state:
59
+ st.session_state.messages = []
60
+
61
+ for message in st.session_state.messages:
62
+ with st.chat_message(message["role"]):
63
+ st.markdown(message["content"])
64
+
65
+ if prompt := st.chat_input("Ask something..."):
66
+ st.session_state.messages.append({"role": "user", "content": prompt})
67
+ with st.chat_message("user"):
68
+ st.markdown(prompt)
69
+
70
+ # Get chat response
71
+ response = qa_chain.invoke({"input": prompt}) if mode else qa_chain.invoke({'context': prompt})
72
+ if not response: # Handle empty responses
73
+ response = {'answer': "I don't know."}
74
+
75
+ if mode is False:
76
+ response = {'answer': response}
77
+
78
+ # Extract <think> part and main answer
79
+ thinking_part, main_answer = extract_thoughts(response['answer'])
80
+
81
+ # Display assistant response
82
+ with st.chat_message("assistant"):
83
+ if thinking_part:
84
+ with st.expander("💭 Thought Process"):
85
+ st.markdown(thinking_part) # Hidden by default, expandable
86
+
87
+ response = st.write_stream(response_generator(main_answer))
88
+
89
+ st.session_state.messages.append({"role": "assistant", "content": response})
components/sidebar.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def render_sidebar():
4
+ st.sidebar.title("DocChatAI")
5
+ st.sidebar.subheader("Chat using PDF Document")
6
+ st.sidebar.write("-----------")
7
+
8
+ # Model Selection
9
+ model_options = ["deepseek-r1:1.5b"]
10
+ selected_model = st.sidebar.radio("Choose Model", model_options)
11
+
12
+ st.sidebar.write("-----------")
13
+
14
+ # Hyperparameters
15
+ temperature = st.sidebar.slider("Temperature", min_value=0.0, max_value=1.0, value=0.7, step=0.1)
16
+ top_p = st.sidebar.slider("Top-p (Nucleus Sampling)", min_value=0.0, max_value=1.0, value=0.9, step=0.05)
17
+ max_tokens = st.sidebar.number_input("Max Tokens", min_value=10, max_value=2048, value=256, step=10)
18
+
19
+ st.sidebar.write("-----------")
20
+
21
+ # File Upload
22
+ uploaded_file = st.sidebar.file_uploader("Upload Documents", type=["pdf"])
23
+
24
+ st.sidebar.write("-----------")
25
+
26
+ # About Section
27
+ st.sidebar.write("About Me")
28
+ st.sidebar.write("Name: Deepak Yadav")
29
+ st.sidebar.write("Bio: Passionate about AI and machine learning.")
30
+ st.sidebar.write("[GitHub](https://github.com/deepak7376)")
31
+ st.sidebar.write("[LinkedIn](https://www.linkedin.com/in/dky7376/)")
32
+
33
+ st.sidebar.write("-----------")
34
+
35
+ return selected_model, temperature, top_p, max_tokens, uploaded_file
doc.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ rag_chatbot/
2
+ │── app.py # Main Streamlit app
3
+ │── components/
4
+ │ ├── sidebar.py # Sidebar UI (model selection, upload, user info)
5
+ │ ├── chat_ui.py # Chat UI styling and history
6
+ │── services/
7
+ │ ├── pdf_processing.py # PDF loading and text splitting
8
+ │ ├── vector_store.py # Vector database (FAISS) setup
9
+ │ ├── llm.py # Model initialization and QA chain
10
+ │── utils/
11
+ │ ├── helpers.py # Helper functions (e.g., get_file_size)
12
+ │── docs/ # Folder for storing uploaded PDFs (created dynamically)
13
+ │── requirements.txt # Dependencies
14
+ │── README.md # Project documentation
docs/dummy.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ hello
requirements.txt CHANGED
@@ -5,4 +5,7 @@ langchain
5
  langchain-community
6
  accelerate
7
  sentence-transformers
8
- faiss-cpu
 
 
 
 
5
  langchain-community
6
  accelerate
7
  sentence-transformers
8
+ faiss-cpu
9
+ pymupdf
10
+ ollama
11
+ langchain_ollama
services/__init__.py ADDED
File without changes
services/llm.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ollama
2
+ from langchain.chains import RetrievalQA
3
+ from langchain.chains import create_retrieval_chain
4
+ from langchain_ollama import OllamaLLM
5
+ from services.pdf_processing import load_and_split_pdf
6
+ from services.vector_store import create_vector_store
7
+ from langchain.chains.combine_documents import create_stuff_documents_chain
8
+ from langchain_core.prompts import ChatPromptTemplate
9
+ from langchain.prompts import PromptTemplate
10
+ import streamlit as st
11
+
12
+ PROMPT_TEMPLATE = """Question: {context}
13
+
14
+ Answer: Let's think step by step."""
15
+
16
+ @st.cache_resource
17
+ def initialize_qa_chain(filepath, model_name, temperature, top_p, max_tokens):
18
+ # Load and split the PDF
19
+ splits = load_and_split_pdf(filepath)
20
+ vectordb = create_vector_store(splits)
21
+
22
+ # Use Ollama or Hugging Face LLM
23
+ # Configure the LLM with additional parameters
24
+ llm = OllamaLLM(
25
+ model=model_name,
26
+ temperature=temperature, # Controls randomness (0 = deterministic, 1 = max randomness)
27
+ max_tokens=max_tokens, # Limit the number of tokens in the output
28
+ top_p=top_p # Nucleus sampling for controlling diversity
29
+ )
30
+
31
+
32
+ # # Define strict retrieval-based prompting
33
+ # prompt_template = PromptTemplate(
34
+ # template=(
35
+ # "You are an AI assistant that only answers questions based on the provided document. "
36
+ # "Do not use external knowledge. If you cannot find an answer in the document, respond with: 'I don't know.'\n\n"
37
+ # "Document Context:\n{context}\n\n"
38
+ # "User Question: {query}\n\n"
39
+ # "Assistant Answer:"
40
+ # ),
41
+ # input_variables=["context", "query"]
42
+ # )
43
+
44
+ system_prompt = (
45
+ "Use the given context to answer the question. "
46
+ "If you don't know the answer, say you don't know. "
47
+ "Use three sentence maximum and keep the answer concise. "
48
+ "Context: {context}"
49
+ )
50
+ prompt = ChatPromptTemplate.from_messages(
51
+ [
52
+ ("system", system_prompt),
53
+ ("human", "{input}"),
54
+ ]
55
+ )
56
+ question_answer_chain = create_stuff_documents_chain(llm, prompt)
57
+ chain = create_retrieval_chain(vectordb.as_retriever(), question_answer_chain)
58
+
59
+ # return RetrievalQA.from_chain_type(
60
+ # llm=llm,
61
+ # chain_type="stuff",
62
+ # retriever=vectordb.as_retriever(),
63
+ # chain_type_kwargs={"prompt": prompt_template}
64
+ # )
65
+ return chain
66
+
67
+ @st.cache_resource
68
+ def initialize_chain(model_name, temperature, top_p, max_tokens):
69
+ # Use Ollama or Hugging Face LLM
70
+ # Configure the LLM with additional parameters
71
+ llm = OllamaLLM(
72
+ model=model_name,
73
+ temperature=temperature, # Controls randomness (0 = deterministic, 1 = max randomness)
74
+ max_tokens=max_tokens, # Limit the number of tokens in the output
75
+ top_p=top_p # Nucleus sampling for controlling diversity
76
+ )
77
+
78
+
79
+
80
+ prompt = ChatPromptTemplate.from_template(PROMPT_TEMPLATE)
81
+
82
+ chain = prompt | llm
83
+
84
+ return chain
85
+
86
+
services/pdf_processing.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from langchain_community.document_loaders import PyMuPDFLoader
2
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
3
+
4
+ def load_and_split_pdf(filepath):
5
+ loader = PyMuPDFLoader(filepath) # Use PyMuPDFLoader instead
6
+ documents = loader.load()
7
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
8
+ return text_splitter.split_documents(documents)
services/vector_store.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_community.vectorstores import FAISS
2
+ # from langchain_community.embeddings import SentenceTransformerEmbeddings
3
+ # from langchain_community.embeddings.ollama import OllamaEmbeddings
4
+ from langchain_huggingface import HuggingFaceEmbeddings
5
+
6
+ def create_vector_store(splits):
7
+ # embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
8
+ embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
9
+ # embeddings = OllamaEmbeddings(model="nomic-embed-text")
10
+ return FAISS.from_documents(splits, embeddings)
utils/__init__.py ADDED
File without changes
utils/helpers.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ def get_file_size(file):
4
+ file.seek(0, os.SEEK_END)
5
+ size = file.tell()
6
+ file.seek(0)
7
+ return size