Skip to content

Commit fc854e7

Browse files
authored
Version 1.4.1 files.
Version 1.4.1 files.
1 parent b270562 commit fc854e7

File tree

9 files changed

+65
-39
lines changed

9 files changed

+65
-39
lines changed

config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ DOCUMENT_MAP:
2626
.txt: TextLoader
2727
.xls: UnstructuredExcelLoader
2828
.xlsx: UnstructuredExcelLoader
29-
EMBEDDING_MODEL_NAME: C:/PATH/Scripts/LM Search Vector Database_v1_working/Embedding_Models/BAAI--bge-base-en
29+
EMBEDDING_MODEL_NAME: C:/PATH/Scripts/LM Search Vector Database_v1_4 - working/Embedding_Models/hkunlp--instructor-large

document_chunker.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from langchain.text_splitter import RecursiveCharacterTextSplitter
22

33
def split_documents(documents):
4-
54
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1200, chunk_overlap=400)
65
texts = text_splitter.split_documents(documents)
6+
77
return texts
8-

document_loader.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,29 @@ def load_single_document(file_path: str) -> Document:
4141
return loader.load()[0]
4242

4343
def load_document_batch(filepaths):
44+
4445
with ThreadPoolExecutor(len(filepaths)) as exe:
4546
futures = [exe.submit(load_single_document, name) for name in filepaths]
4647
data_list = [future.result() for future in futures]
47-
return (data_list, filepaths)
48+
49+
return (data_list, filepaths)
4850

4951
def load_documents(source_dir: str) -> list[Document]:
52+
5053
all_files = os.listdir(source_dir)
5154
paths = [os.path.join(source_dir, file_path) for file_path in all_files if os.path.splitext(file_path)[1] in DOCUMENT_MAP.keys()]
5255

5356
n_workers = min(INGEST_THREADS, max(len(paths), 1))
5457
chunksize = round(len(paths) / n_workers)
5558
docs = []
59+
5660
with ProcessPoolExecutor(n_workers) as executor:
5761
futures = [executor.submit(load_document_batch, paths[i : (i + chunksize)]) for i in range(0, len(paths), chunksize)]
5862
for future in as_completed(futures):
5963
contents, _ = future.result()
6064
docs.extend(contents)
61-
65+
6266
return docs
67+
68+
if __name__ == "__main__":
69+
load_documents(SOURCE_DIRECTORY)

example.png

-2.51 KB
Loading

gui.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import tkinter as tk
2+
from tkinter import font as tkfont
23
from gui_table import create_table
34
import threading
45
from nvml import CudaVramLogic
@@ -41,9 +42,17 @@ def __init__(self, root):
4142
self.create_chromadb_button.pack(pady=5)
4243

4344
create_table(left_frame)
44-
45-
self.cuda_info_label = tk.Label(left_frame, text="CUDA & VRAM Info", font=("Segoe UI Historic", 10))
46-
self.cuda_info_label.pack(pady=5)
45+
46+
# GPU label
47+
self.gpu_info_label = tk.Label(left_frame, font=("Segoe UI Semibold", 16), foreground='green')
48+
self.gpu_info_label.pack(pady=1)
49+
50+
# VRAM label
51+
self.vram_info_label = tk.Label(left_frame, font=("Segoe UI Semibold", 16), foreground='blue')
52+
self.vram_info_label.pack(pady=1)
53+
54+
# Adjust CudaVramLogic initialization:
55+
self.cuda_logic = CudaVramLogic(self.vram_info_label, self.gpu_info_label, self.root)
4756

4857
main_pane.add(left_frame)
4958

@@ -75,8 +84,6 @@ def __init__(self, root):
7584
scroll2.pack(side=tk.RIGHT, fill=tk.Y)
7685
self.read_only_text.config(yscrollcommand=scroll2.set)
7786

78-
self.cuda_logic = CudaVramLogic(self.cuda_info_label, self.root)
79-
8087
self.center_window(root)
8188

8289
def center_window(self, root):

gui_logic.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from server_connector import interact_with_chat
99
import subprocess
1010
import server_connector
11+
import threading
1112

1213
def load_config():
1314
with open("config.yaml", 'r') as stream:
@@ -54,10 +55,13 @@ def download_embedding_model(self):
5455

5556
if selected_model:
5657
model_url = f"https://huggingface.co/{selected_model}"
57-
5858
target_directory = os.path.join("Embedding_Models", selected_model.replace("/", "--"))
5959

60-
subprocess.run(["git", "clone", model_url, target_directory])
60+
def download_model():
61+
subprocess.run(["git", "clone", model_url, target_directory])
62+
63+
download_thread = threading.Thread(target=download_model)
64+
download_thread.start()
6165

6266
def select_embedding_model_directory(self):
6367
initial_dir = 'Embedding_Models' if os.path.exists('Embedding_Models') else os.path.expanduser("~")
@@ -101,7 +105,12 @@ def create_chromadb(self):
101105

102106
if response:
103107
embedding_model_path = getattr(self, "embedding_model_directory", "")
104-
os.system(f'python ingest_improved.py "{embedding_model_path}"')
108+
109+
def run_create_chromadb(embedding_model_path):
110+
os.system(f'python ingest_improved.py "{embedding_model_path}"')
111+
112+
create_chromadb_thread = threading.Thread(target=run_create_chromadb, args=(embedding_model_path,))
113+
create_chromadb_thread.start()
105114

106115
def submit_query(self):
107116
current_dir = os.path.dirname(os.path.realpath(__file__))
@@ -120,14 +129,21 @@ def submit_query(self):
120129
return
121130

122131
query = self.gui.text_input.get("1.0", tk.END).strip()
123-
answer = interact_with_chat(query)
124-
self.gui.read_only_text.config(state=tk.NORMAL)
125-
self.gui.read_only_text.delete("1.0", tk.END)
126-
self.gui.read_only_text.insert(tk.END, answer)
127-
self.gui.read_only_text.config(state=tk.DISABLED)
132+
133+
# Move the chat interaction logic to a separate function
134+
def interact_with_chat_and_update_gui(query):
135+
answer = interact_with_chat(query)
136+
self.gui.read_only_text.config(state=tk.NORMAL)
137+
self.gui.read_only_text.delete("1.0", tk.END)
138+
self.gui.read_only_text.insert(tk.END, answer)
139+
self.gui.read_only_text.config(state=tk.DISABLED)
140+
141+
# Create a thread for chat interaction and GUI update
142+
chat_thread = threading.Thread(target=interact_with_chat_and_update_gui, args=(query,))
143+
chat_thread.start()
128144

129145
if __name__ == "__main__":
130146
root = tk.Tk()
131147
app = DocQA_GUI(root)
132148
logic = DocQA_Logic(app)
133-
root.mainloop()
149+
root.mainloop()

gui_table.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ def create_table(parent_frame):
3131

3232
pro_tip_text = (
3333
"DO NOT have LM Studio running when creating the vector database. The VRAM numbers above refer to when creating "
34-
"the database. After it's created, run LM Studio and load your LLM (remember only Llama2-based models work "
35-
"currently when querying the database). To query the database, the embedding model will use about half the VRAM "
36-
"it used when creating it. Use the LARGEST embedding model you can possibly fit into VRAM while the LLM is loaded "
37-
"into LM Studio (remembering the half rule above). The quality of the embedding model is ACTUALLY MORE important "
38-
"than the size of the LLM. Experiment with low-quality LLMs and high-quality embedding models. EXAMPLE: q3_k_3 "
39-
"model + instructor-xl worked just fine together."
34+
"the database, which attempts to use multithreading, hence more VRAM used. After it's created, run LM Studio and "
35+
" load your LLM (remember only Llama2-based models work currently when querying the database). To query the database, "
36+
" the embedding model uses much less VRAM. Use the LARGEST embedding model you can possibly fit into VRAM while the "
37+
" LLM is loaded into LM Studio. The quality of the embedding model is ACTUALLY MORE important than the size of the LLM. "
38+
" Experiment with low-quality LLMs and high-quality embedding models. For example, q3_k_3 model + instructor-xl worked "
39+
" just fine together. If your text has a lot of technical jargon, a larger LLM might be better, but for everyday usage, "
40+
" strive to use as large of an embedding model as possible with as large of an LLM with the remaining VRAM."
4041
)
4142

4243
pro_tip_description = tk.Label(parent_frame, text=pro_tip_text, wraplength=400, justify="left")

ingest_improved.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import logging
22
import os
3-
import sys
43
import shutil
54
import torch
65
import yaml
@@ -45,7 +44,7 @@ def main():
4544
model_kwargs={"device": COMPUTE_DEVICE},
4645
)
4746

48-
# Delete current vector database before creating new one
47+
# Delete the current vector database before creating a new one
4948
if os.path.exists(PERSIST_DIRECTORY):
5049
shutil.rmtree(PERSIST_DIRECTORY)
5150
os.makedirs(PERSIST_DIRECTORY)
@@ -63,4 +62,5 @@ def main():
6362
logging.basicConfig(
6463
format="%(asctime)s - %(levelname)s - %(filename)s:%(lineno)s - %(message)s", level=logging.INFO
6564
)
65+
6666
main()

nvml.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from pynvml import *
22
from multiprocessing import Process, Pipe, Event
33
import time
4-
import tkinter as tk
54

65
def monitor_nvml(pipe, stop_event):
76
nvmlInit()
@@ -35,23 +34,20 @@ def stop_monitoring(p, stop_event):
3534
p.join()
3635

3736
class CudaVramLogic:
38-
def __init__(self, label, root):
39-
self.cuda_info_label = label
37+
def __init__(self, vram_label, gpu_label, root):
38+
self.vram_label = vram_label
39+
self.gpu_label = gpu_label
4040
self.root = root
4141
self.parent_conn, self.process, self.stop_event = start_monitoring()
42-
self.update_cuda_info()
42+
self.update_info()
4343

44-
def update_cuda_info(self):
44+
def update_info(self):
4545
if self.parent_conn.poll():
4646
memory_used_str, gpu_utilization = self.parent_conn.recv()
47-
info_text = f"Memory Used: {memory_used_str} | GPU Utilization: {gpu_utilization}"
48-
self.cuda_info_label.config(text=info_text)
49-
self.root.after(500, self.update_cuda_info)
47+
self.vram_label.config(text=f"VRAM: {memory_used_str}")
48+
self.gpu_label.config(text=f"GPU: {gpu_utilization}")
49+
self.root.after(500, self.update_info)
5050

5151
def stop_and_exit(self):
5252
stop_monitoring(self.process, self.stop_event)
5353
self.root.quit()
54-
55-
# If the script is executed directly, it will just run without outputting any metrics.
56-
if __name__ == "__main__":
57-
pass

0 commit comments

Comments
 (0)