AlirezaHSZ commited on
Commit
9baa100
·
verified ·
1 Parent(s): de16065

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -108
app.py CHANGED
@@ -4,15 +4,24 @@ import streamlit as st
4
  from langchain.text_splitter import RecursiveCharacterTextSplitter
5
  from langchain.vectorstores import FAISS
6
  from langchain.embeddings import HuggingFaceEmbeddings
7
- from transformers import AutoTokenizer, AutoModelForCausalLM
8
- import torch
9
 
10
  # Configuration
11
  EMBEDDING_MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2"
12
- LLM_MODEL_NAME = "TheBloke/Llama-2-7B-GGUF"
13
- DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
14
 
15
- # Text Splitting
 
 
 
 
 
 
 
 
 
16
  def get_pdf_text(pdf_docs):
17
  text = ""
18
  for pdf in pdf_docs:
@@ -22,135 +31,113 @@ def get_pdf_text(pdf_docs):
22
  return text
23
 
24
  def get_text_chunks(text):
25
- splitter = RecursiveCharacterTextSplitter(chunk_size=10000, chunk_overlap=1000)
26
  return splitter.split_text(text)
27
 
28
  # Vector Store
29
  def get_vector_store(chunks):
30
- try:
31
- embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME)
32
- vector_store = FAISS.from_texts(chunks, embedding=embeddings)
33
- vector_store.save_local("faiss_index")
34
- except Exception as e:
35
- raise RuntimeError(f"Error processing embeddings: {e}")
36
 
37
- # Load Model with Caching
38
  @st.cache_resource
39
- def load_model():
40
- try:
41
- tokenizer = AutoTokenizer.from_pretrained(LLM_MODEL_NAME, cache_dir="./cache", trust_remote_code=True)
42
- model = AutoModelForCausalLM.from_pretrained(
43
- LLM_MODEL_NAME,
44
- torch_dtype=torch.float16 if DEVICE == "cuda" else torch.float32,
45
- low_cpu_mem_usage=True,
46
- cache_dir="./cache",
47
- trust_remote_code=True
48
- ).to(DEVICE)
49
- return tokenizer, model
50
- except Exception as e:
51
- raise RuntimeError(f"Error loading DeepSeek model: {e}")
52
 
53
  # Response Generation
54
- class DeepSeekChat:
55
  def __init__(self):
56
- self.tokenizer, self.model = load_model()
57
 
58
  def generate(self, context, question):
59
- try:
60
- prompt_template = """Answer based on context:
61
- Context: {context}
62
- Question: {question}
63
- Answer:"""
64
-
65
- prompt = prompt_template.format(context=context, question=question)
66
- print("Prompt:", prompt)
67
-
68
- inputs = self.tokenizer(prompt, return_tensors="pt").to(DEVICE)
69
- print("Inputs:", inputs)
70
-
71
- outputs = self.model.generate(
72
- inputs.input_ids,
73
- max_new_tokens=200,
74
- temperature=0.3,
75
- do_sample=True
76
- )
77
- print("Outputs:", outputs)
78
-
79
- response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
80
- print("Response:", response)
81
-
82
- return response
83
- except Exception as e:
84
- raise RuntimeError(f"Error generating response: {e}")
85
-
86
- # Streamlit App
87
- def clear_chat_history():
88
- st.session_state.messages = [{"role": "assistant", "content": "در خدمتیم"}]
89
 
 
90
  def main():
91
- st.set_page_config(page_title="Chatbot", layout="wide", initial_sidebar_state="expanded")
92
 
93
- st.markdown("""
94
- <style>
95
- body { background-color: #000000; color: #ffffff; }
96
- .main { background-color: #333333; padding: 20px; border-radius: 10px; }
97
- </style>
98
- """, unsafe_allow_html=True)
99
-
100
  if "uploaded" not in st.session_state:
101
  st.session_state.uploaded = False
 
 
102
 
 
103
  if not st.session_state.uploaded:
104
- st.title("A Personal Assistant for your Standards ...")
105
- pdf_docs = st.file_uploader("فایل مورد نظر راآپلود کنید", accept_multiple_files=True)
106
- if st.button("تایید"):
 
107
  if pdf_docs:
108
- with st.spinner("در حال پردازش..."):
 
109
  raw_text = get_pdf_text(pdf_docs)
 
 
110
  text_chunks = get_text_chunks(raw_text)
 
 
111
  get_vector_store(text_chunks)
 
112
  st.session_state.uploaded = True
113
- st.success("پردازش موفق")
114
  else:
115
- st.error("لطفا حداقل یک فایل را آپلود کنید")
116
- else:
117
- st.title("Assistant ready ...")
118
- st.write("میتونین سوالتونو بپرسین")
119
- st.button('حذف مکالمه', on_click=clear_chat_history)
120
-
121
- if "messages" not in st.session_state:
122
- st.session_state.messages = [{"role": "assistant", "content": "در خدمتیم"}]
123
-
124
- for message in st.session_state.messages:
125
- with st.chat_message(message["role"]):
126
- st.write(message["content"])
127
 
128
- if prompt := st.chat_input():
 
 
 
 
 
 
 
 
 
 
 
 
129
  st.session_state.messages.append({"role": "user", "content": prompt})
130
- with st.chat_message("user"):
131
- st.write(prompt)
132
-
133
- if st.session_state.messages[-1]["role"] != "assistant":
134
- with st.spinner("در حال پاسخگویی..."):
135
- try:
136
- embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME)
137
- db = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
138
- docs = db.similarity_search(prompt, k=4)
139
- print("Retrieved Documents:", docs)
140
-
141
- context = "\n".join([d.page_content for d in docs])
142
- print("Context:", context)
143
-
144
- chat_model = DeepSeekChat()
145
- response = chat_model.generate(context, prompt)
146
- print("Generated Response:", response)
147
-
148
- with st.chat_message("assistant"):
149
- st.write(response)
150
- st.session_state.messages.append({"role": "assistant", "content": response})
151
- except Exception as e:
152
- st.error(f"خطا: {str(e)}")
153
- print("Error during response generation:", str(e))
154
 
155
  if __name__ == "__main__":
156
  main()
 
4
  from langchain.text_splitter import RecursiveCharacterTextSplitter
5
  from langchain.vectorstores import FAISS
6
  from langchain.embeddings import HuggingFaceEmbeddings
7
+ from llama_cpp import Llama
8
+ from huggingface_hub import hf_hub_download # Add this import
9
 
10
  # Configuration
11
  EMBEDDING_MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2"
12
+ MODEL_REPO = "TheBloke/Llama-2-7B-GGUF"
13
+ MODEL_FILE = "llama-2-7b.Q4_K_M.gguf" # Specific quantization file
14
 
15
+ # Download model from Hugging Face Hub
16
+ @st.cache_resource
17
+ def download_model():
18
+ return hf_hub_download(
19
+ repo_id=MODEL_REPO,
20
+ filename=MODEL_FILE,
21
+ cache_dir="models"
22
+ )
23
+
24
+ # Text Processing
25
  def get_pdf_text(pdf_docs):
26
  text = ""
27
  for pdf in pdf_docs:
 
31
  return text
32
 
33
  def get_text_chunks(text):
34
+ splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
35
  return splitter.split_text(text)
36
 
37
  # Vector Store
38
  def get_vector_store(chunks):
39
+ embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME)
40
+ vector_store = FAISS.from_texts(chunks, embedding=embeddings)
41
+ vector_store.save_local("faiss_index")
 
 
 
42
 
43
+ # Model Loading
44
  @st.cache_resource
45
+ def load_llama():
46
+ model_path = download_model()
47
+ return Llama(
48
+ model_path=model_path,
49
+ n_ctx=2048,
50
+ n_threads=4,
51
+ n_gpu_layers=20 # Adjust based on your GPU capacity
52
+ )
 
 
 
 
 
53
 
54
  # Response Generation
55
+ class LlamaChat:
56
  def __init__(self):
57
+ self.llm = load_llama()
58
 
59
  def generate(self, context, question):
60
+ prompt = f"""Answer based on this context:
61
+ {context}
62
+
63
+ Question: {question}
64
+ Answer:"""
65
+
66
+ response = self.llm(
67
+ prompt,
68
+ max_tokens=256,
69
+ temperature=0.3,
70
+ top_p=0.95,
71
+ repeat_penalty=1.2
72
+ )
73
+
74
+ return response['choices'][0]['text'].strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
+ # Streamlit UI
77
  def main():
78
+ st.set_page_config(page_title="Llama-2 PDF Assistant", layout="wide")
79
 
80
+ # Initialize session state
 
 
 
 
 
 
81
  if "uploaded" not in st.session_state:
82
  st.session_state.uploaded = False
83
+ if "messages" not in st.session_state:
84
+ st.session_state.messages = [{"role": "assistant", "content": "Ask me about your documents!"}]
85
 
86
+ # File Upload Section
87
  if not st.session_state.uploaded:
88
+ st.title("PDF Document Assistant")
89
+ pdf_docs = st.file_uploader("Upload PDF files", accept_multiple_files=True, type="pdf")
90
+
91
+ if st.button("Process Documents"):
92
  if pdf_docs:
93
+ with st.status("Processing documents..."):
94
+ st.write("Extracting text...")
95
  raw_text = get_pdf_text(pdf_docs)
96
+
97
+ st.write("Chunking text...")
98
  text_chunks = get_text_chunks(raw_text)
99
+
100
+ st.write("Creating vector store...")
101
  get_vector_store(text_chunks)
102
+
103
  st.session_state.uploaded = True
104
+ st.rerun()
105
  else:
106
+ st.error("Please upload at least one PDF file")
 
 
 
 
 
 
 
 
 
 
 
107
 
108
+ # Chat Interface
109
+ else:
110
+ st.title("Document Chat Assistant")
111
+ st.button("Clear Chat", on_click=lambda: st.session_state.update(
112
+ messages=[{"role": "assistant", "content": "Ask me about your documents!"}]
113
+ ))
114
+
115
+ # Display chat messages
116
+ for msg in st.session_state.messages:
117
+ st.chat_message(msg["role"]).write(msg["content"])
118
+
119
+ # Handle user input
120
+ if prompt := st.chat_input("Your question:"):
121
  st.session_state.messages.append({"role": "user", "content": prompt})
122
+ st.chat_message("user").write(prompt)
123
+
124
+ with st.spinner("Thinking..."):
125
+ try:
126
+ # Retrieve relevant context
127
+ embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME)
128
+ db = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
129
+ docs = db.similarity_search(prompt, k=4)
130
+ context = "\n".join([d.page_content for d in docs])
131
+
132
+ # Generate response
133
+ chat_model = LlamaChat()
134
+ response = chat_model.generate(context, prompt)
135
+
136
+ st.session_state.messages.append({"role": "assistant", "content": response})
137
+ st.chat_message("assistant").write(response)
138
+
139
+ except Exception as e:
140
+ st.error(f"Error: {str(e)}")
 
 
 
 
 
141
 
142
  if __name__ == "__main__":
143
  main()