MVPilgrim commited on
Commit
9d1f3d8
·
1 Parent(s): 82f7507
Files changed (1) hide show
  1. app.py +425 -420
app.py CHANGED
@@ -21,437 +21,442 @@ import streamlit as st
21
  import subprocess
22
 
23
 
24
-
25
- if 'logging' not in st.session_state:
26
- weaviate_logger = logging.getLogger("httpx")
27
- weaviate_logger.setLevel(logging.WARNING)
28
- logger = logging.getLogger(__name__)
29
- logging.basicConfig(level=logging.INFO)
30
- st.session_state.weaviate_logger = weaviate_logger
31
- st.session_state.logger = logger
32
- else:
33
- weaviate_logger = st.session_state.weaviate_logger
34
- logger = st.session_state.logger
35
-
36
-
37
- def runStartup():
38
- logger.info("### Running startup.sh")
39
- result = ""
40
- try:
41
- result = subprocess.run("bash startup.sh &",shell=True,capture_output=True,text=True,timeout=120)
42
- logger.info(f"startup.sh stdout: {result.stdout}")
43
- logger.info(f"startup.sh stderr: {result.stderr}")
44
- logger.info(f"Return code: {result.returncode}")
45
- except:
46
- logger.error(f"subprocess.run() encountered error.")
47
- logger.info("### Running startup.sh complete")
48
- if 'runStartup' not in st.session_state:
49
- st.session_state.runStartup = True
50
- runStartup()
51
-
52
-
53
-
54
- ######################################################################
55
- # MAINLINE
56
- #
57
- logger.info("#### MAINLINE ENTERED.")
58
-
59
- # Function to load the CSS file
60
- def load_css(file_name):
61
- with open(file_name) as f:
62
- st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
63
-
64
- # Load the custom CSS
65
- if 'load_css' not in st.session_state:
66
- load_css(".streamlit/main.css")
67
- st.session_state.load_css = True
68
-
69
- st.markdown("<h1 style='text-align: center; color: #666666;'>Vector Database RAG Proof of Concept</h1>", unsafe_allow_html=True)
70
- st.markdown("<h6 style='text-align: center; color: #666666;'>V1</h6>", unsafe_allow_html=True)
71
-
72
- #pathString = "/Users/660565/KPSAllInOne/ProgramFilesX86/WebCopy/DownloadedWebSites/LLMPOC_HTML"
73
- pathString = "/app/inputDocs"
74
- chunks = []
75
- webpageDocNames = []
76
- page_contentArray = []
77
- webpageChunks = []
78
- webpageTitles = []
79
- webpageChunksDocNames = []
80
-
81
- ######################################################
82
- # Connect to the Weaviate vector database.
83
- #if 'client' not in st.session_state:
84
- logger.info("#### Create Weaviate db client connection.")
85
- client = weaviate.WeaviateClient(
86
- connection_params=ConnectionParams.from_params(
87
- http_host="localhost",
88
- http_port="8080",
89
- http_secure=False,
90
- grpc_host="localhost",
91
- grpc_port="50051",
92
- grpc_secure=False
93
- ),
94
- additional_config=AdditionalConfig(
95
- timeout=Timeout(init=60, query=1800, insert=1800), # Values in seconds
 
96
  )
97
- )
98
- client.connect()
99
- # st.session_state.client = client
100
- #else:
101
- # client = st.session_state.client
102
-
103
-
104
- #######################################################
105
- # Read each text input file, parse it into a document,
106
- # chunk it, collect chunks and document name.
107
- if not client.collections.exists("Documents") or not client.collections.exists("Documents") :
108
- logger.info("#### Read and chunk input text files.")
109
- for filename in os.listdir(pathString):
110
- logger.info(filename)
111
- path = Path(pathString + "/" + filename)
112
- filename = filename.rstrip(".html")
113
- webpageDocNames.append(filename)
114
- htmlLoader = BSHTMLLoader(path,"utf-8")
115
- htmlData = htmlLoader.load()
116
-
117
- title = htmlData[0].metadata['title']
118
- page_content = htmlData[0].page_content
119
-
120
- # Clean data. Remove multiple newlines, etc.
121
- page_content = re.sub(r'\n+', '\n',page_content)
122
-
123
- page_contentArray.append(page_content);
124
- webpageTitles.append(title)
125
- max_tokens = 1000
126
- tokenizer = Tokenizer.from_pretrained("bert-base-uncased")
127
- logger.debug(f"### tokenizer: {tokenizer}")
128
- splitter = HuggingFaceTextSplitter(tokenizer, trim_chunks=True)
129
- chunksOnePage = splitter.chunks(page_content, chunk_capacity=50)
130
-
131
- chunks = []
132
- for chnk in chunksOnePage:
133
- logger.debug(f"#### chnk in file: {chnk}")
134
- chunks.append(chnk)
135
- logger.debug(f"chunks: {chunks}")
136
- webpageChunks.append(chunks)
137
- webpageChunksDocNames.append(filename + "Chunks")
138
-
139
- logger.debug(f"### filename, title: {filename}, {title}")
140
- logger.debug(f"### webpageDocNames: {webpageDocNames}")
141
-
142
-
143
-
144
- ######################################################
145
- # Create database webpage and chunks collections.
146
- #wpCollection = createWebpageCollection()
147
- #wpChunkCollection = createChunksCollection()
148
- if not client.collections.exists("Documents"):
149
- logger.info("#### createWebpageCollection() entered.")
150
- #client.collections.delete("Documents")
151
- class_obj = {
152
- "class": "Documents",
153
- "description": "For first attempt at loading a Weviate database.",
154
- "vectorizer": "text2vec-transformers",
155
- "moduleConfig": {
156
- "text2vec-transformers": {
157
- "vectorizeClassName": False
158
- }
159
- },
160
- "vectorIndexType": "hnsw",
161
- "vectorIndexConfig": {
162
- "distance": "cosine",
163
- },
164
- "properties": [
165
- {
166
- "name": "title",
167
- "dataType": ["text"],
168
- "description": "HTML doc title.",
169
- "vectorizer": "text2vec-transformers",
170
- "moduleConfig": {
171
- "text2vec-transformers": {
172
- "vectorizePropertyName": True,
173
- "skip": False,
174
- "tokenization": "lowercase"
 
 
 
 
 
 
175
  }
176
  },
177
- "invertedIndexConfig": {
178
- "bm25": {
179
- "b": 0.75,
180
- "k1": 1.2
181
- },
182
- }
183
- },
184
- {
185
- "name": "content",
186
- "dataType": ["text"],
187
- "description": "HTML page content.",
188
- "moduleConfig": {
189
- "text2vec-transformers": {
190
- "vectorizePropertyName": True,
191
- "tokenization": "whitespace"
192
  }
193
  }
194
- }
195
- ]
196
- }
197
- wpCollection = client.collections.create_from_dict(class_obj)
198
-
199
-
200
- if not client.collections.exists("Chunks"):
201
- logger.info("#### createChunksCollection() entered.")
202
- #client.collections.delete("Chunks")
203
- class_obj = {
204
- "class": "Chunks",
205
- "description": "Collection for document chunks.",
206
- "vectorizer": "text2vec-transformers",
207
- "moduleConfig": {
208
- "text2vec-transformers": {
209
- "vectorizeClassName": True
210
- }
211
- },
212
- "vectorIndexType": "hnsw",
213
- "vectorIndexConfig": {
214
- "distance": "cosine",
215
- },
216
- "properties": [
217
- {
218
- "name": "chunk",
219
- "dataType": ["text"],
220
- "description": "Single webpage chunk.",
221
- "vectorizer": "text2vec-transformers",
222
- "moduleConfig": {
223
- "text2vec-transformers": {
224
- "vectorizePropertyName": False,
225
- "skip": False,
226
- "tokenization": "lowercase"
227
- }
228
  }
229
  },
230
- {
231
- "name": "chunk_index",
232
- "dataType": ["int"]
233
  },
234
- {
235
- "name": "webpage",
236
- "dataType": ["Documents"],
237
- "description": "Webpage content chunks.",
238
-
239
- "invertedIndexConfig": {
240
- "bm25": {
241
- "b": 0.75,
242
- "k1": 1.2
 
 
 
243
  }
244
- }
245
- }
246
- ]
247
- }
248
- wpChunkCollection = client.collections.create_from_dict(class_obj)
249
-
250
-
251
- ###########################################################
252
- # Create document and chunks objects in the database.
253
- if not client.collections.exists("Documents") :
254
- logger.info("#### Create page/doc db objects.")
255
- for i, className in enumerate(webpageDocNames):
256
- title = webpageTitles[i]
257
- logger.debug(f"## className, title: {className}, {title}")
258
- # Create Webpage Object
259
- page_content = page_contentArray[i]
260
- # Insert the document.
261
- wpCollectionObj_uuid = wpCollection.data.insert(
262
- {
263
- "name": className,
264
- "title": title,
265
- "content": page_content
266
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  )
268
-
269
- if not client.collections.exists("Chunks") :
270
- logger.info("#### Create chunk db objects.")
271
- # Insert the chunks for the document.
272
- for i2, chunk in enumerate(webpageChunks[i]):
273
- chunk_uuid = wpChunkCollection.data.insert(
274
- {
275
- "title": title,
276
- "chunk": chunk,
277
- "chunk_index": i2,
278
- "references":
279
- {
280
- "webpage": wpCollectionObj_uuid
281
- }
282
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  )
284
-
285
-
286
- #################################################################
287
- # Initialize the LLM.
288
- model_path = "/app/llama-2-7b-chat.Q4_0.gguf"
289
- if 'llm' not in st.session_state:
290
- llm = Llama(model_path,
291
- #*,
292
- n_gpu_layers=0,
293
- split_mode=llama_cpp.LLAMA_SPLIT_MODE_LAYER,
294
- main_gpu=0,
295
- tensor_split=None,
296
- vocab_only=False,
297
- use_mmap=True,
298
- use_mlock=False,
299
- kv_overrides=None,
300
- seed=llama_cpp.LLAMA_DEFAULT_SEED,
301
- n_ctx=512,
302
- n_batch=512,
303
- n_threads=8,
304
- n_threads_batch=16,
305
- rope_scaling_type=llama_cpp.LLAMA_ROPE_SCALING_TYPE_UNSPECIFIED,
306
- pooling_type=llama_cpp.LLAMA_POOLING_TYPE_UNSPECIFIED,
307
- rope_freq_base=0.0,
308
- rope_freq_scale=0.0,
309
- yarn_ext_factor=-1.0,
310
- yarn_attn_factor=1.0,
311
- yarn_beta_fast=32.0,
312
- yarn_beta_slow=1.0,
313
- yarn_orig_ctx=0,
314
- logits_all=False,
315
- embedding=False,
316
- offload_kqv=True,
317
- last_n_tokens_size=64,
318
- lora_base=None,
319
- lora_scale=1.0,
320
- lora_path=None,
321
- numa=False,
322
- chat_format=None,
323
- chat_handler=None,
324
- draft_model=None,
325
- tokenizer=None,
326
- type_k=None,
327
- type_v=None,
328
- verbose=True
329
- )
330
- st.session_state.llm = llm
331
- else:
332
- llm = st.session_state.llm
333
-
334
- def getRagData(promptText):
335
- logger.info("#### getRagData() entered.")
336
- ###############################################################################
337
- # Initial the the sentence transformer and encode the query prompt.
338
- logger.info(f"#### Encode text query prompt to create vectors. {text}")
339
- model = SentenceTransformer('/app/multi-qa-MiniLM-L6-cos-v1')
340
-
341
- vector = model.encode(promptText)
342
- vectorList = []
343
-
344
- logger.debug("#### Print vectors.")
345
- for vec in vector:
346
- vectorList.append(vec)
347
- logger.debug(f"vectorList: {vectorList[2]}")
348
-
349
- # Fetch chunks and print chunks.
350
- logger.info("#### Retrieve semchunks from db using vectors from prompt.")
351
- semChunks = wpChunkCollection.query.near_vector(
352
- near_vector=vectorList,
353
- distance=0.7,
354
- limit=3
355
- )
356
- logger.debug(f"### semChunks[0]: {semChunks}")
357
-
358
- # Print chunks, corresponding document and document title.
359
- ragData = ""
360
- logger.info("#### Print individual retrieved chunks.")
361
- for chunk in enumerate(semChunks.objects):
362
- logger.info(f"#### chunk: {chunk}")
363
- ragData = ragData + "\n" + chunk[0]
364
- webpage_uuid = chunk[1].properties['references']['webpage']
365
- logger.info(f"webpage_uuid: {webpage_uuid}")
366
- wpFromChunk = wpCollection.query.fetch_object_by_id(webpage_uuid)
367
- logger.info(f"### wpFromChunk title: {wpFromChunk.properties['title']}")
368
- #collection = client.collections.get("Chunks")
369
- return ragData
370
-
371
-
372
- # Display UI
373
- col1, col2 = st.columns(2)
374
-
375
- with col1:
376
- if "sysTA" not in st.session_state:
377
- st.session_state.sysTA = st.text_area(label="sysTA",value="fdsaf fsdafdsa")
378
- elif "sysTAtext" in st.session_state:
379
- st.session_state.sysTA = st.text_area(label="sysTA",value=st.session_state.sysTAtext)
380
- else:
381
- st.session_state.sysTA = st.text_area(label="sysTA",value=st.session_state.sysTA)
382
 
383
- if "userpTA" not in st.session_state:
384
- userTextArea = st.text_area(label="userpTA",value="fdsaf fsdafdsa")
385
- elif "userpTAtext" in st.session_state:
386
- st.session_state.userpTA = st.text_area(label="userpTA",value=st.session_state.userpTAtext)
387
- else:
388
- st.session_state.userpTA = st.text_area(label="userpTA",value=st.session_state.userpTA)
 
389
 
390
- with col2:
391
- if "ragpTA" not in st.session_state:
392
- ragPromptTextArea = st.text_area(label="ragpTA",value="fdsaf fsdafdsa")
393
- elif "ragpTAtext" in st.session_state:
394
- st.session_state.ragpTA = st.text_area(label="ragpTA",value=st.session_state.ragpTAtext)
395
- else:
396
- st.session_state.ragTA = st.text_area(label="ragTA",value=st.session_state.ragTA)
397
 
398
- if "rspTA" not in st.session_state:
399
- responseTextArea = st.text_area(label="rspTA",value="fdsaf fsdafdsa")
400
- elif "rspTAtext" in st.session_state:
401
- st.session_state.rspTA = st.text_area(label="rspTA",value=st.session_state.rspTAtext)
402
- else:
403
- st.session_state.rspTA = st.text_area(label="rspTA",value=st.session_state.rspTA)
404
-
405
- def runLLM(prompt):
406
- max_tokens = 1000
407
- temperature = 0.3
408
- top_p = 0.1
409
- echo = True
410
- stop = ["Q", "\n"]
411
-
412
- modelOutput = llm(
413
- prompt,
414
- max_tokens=max_tokens,
415
- temperature=temperature,
416
- top_p=top_p,
417
- echo=echo,
418
- stop=stop,
419
- )
420
- result = modelOutput["choices"][0]["text"].strip()
421
- return(result)
422
-
423
- def setPrompt(pprompt,ragFlag):
424
- logger(f"\n### setPrompt() entered. ragFlag: {ragFlag}")
425
- if ragFlag:
426
- ragPrompt = getRagData(pprompt)
427
- userPrompt = pprompt + "\n" + ragPrompt
428
- prompt = userPrompt
429
- userPrompt = "Using this information: " + ragPrompt \
430
- + "process the following statement or question and produce a a response" \
431
- + intialPrompt
432
- else:
433
- userPrompt = pprompt
434
- #prompt = f""" <s> [INST] <<SYS>> {systemTextArea.value} </SYS>> Q: {userPrompt} A: [/INST]"""
435
- return userPrompt
436
-
437
-
438
- def on_submitButton_clicked():
439
- logger = st.session_state.logger
440
- logger.debug("\n### on_submitButton_clicked")
441
- st.session_state.sysTAtext = st.session_state.sysTA
442
- logger.info(f"sysTAtext: {st.session_state.sysTAtext}")
443
-
444
- st.session_state.userpTAtext = setPrompt("","")
445
- st.session_state.userpTA = st.session_state.userpTAtext
446
- logger.info(f"userpTAtext: {st.session_state.userpTAtext}")
447
-
448
- st.session_state.rspTAtext = runLLM(st.session_state.userpTAtext)
449
- st.session_state.rspTA = st.session_state.rspTAtext
450
- logger.info(f"rspTAtext: {st.session_state.rspTAtext}")
451
-
452
-
453
- with st.sidebar:
454
- st.selectRag = st.checkbox("Enable Query With RAG",value=False,key="selectRag",help=None,on_change=None,args=None,kwargs=None,disabled=False,label_visibility="visible")
455
- st.submitButton = st.button("Run LLM Query",key=None,help=None,on_click=on_submitButton_clicked,args=None,kwargs=None,type="secondary",disabled=False,use_container_width=False)
456
-
457
- logger.info("#### semsearch.py terminating.")
 
21
  import subprocess
22
 
23
 
24
+ try:
25
+ if 'logging' not in st.session_state:
26
+ weaviate_logger = logging.getLogger("httpx")
27
+ weaviate_logger.setLevel(logging.WARNING)
28
+ logger = logging.getLogger(__name__)
29
+ logging.basicConfig(level=logging.INFO)
30
+ st.session_state.weaviate_logger = weaviate_logger
31
+ st.session_state.logger = logger
32
+ else:
33
+ weaviate_logger = st.session_state.weaviate_logger
34
+ logger = st.session_state.logger
35
+
36
+
37
+ def runStartup():
38
+ logger.info("### Running startup.sh")
39
+ result = ""
40
+ try:
41
+ result = subprocess.run("bash startup.sh 2>1 > /app/startup.log &",shell=True,capture_output=True,text=True,timeout=120)
42
+ logger.info(f"startup.sh stdout: {result.stdout}")
43
+ logger.info(f"startup.sh stderr: {result.stderr}")
44
+ logger.info(f"Return code: {result.returncode}")
45
+ except:
46
+ logger.error(f"subprocess.run() encountered error.")
47
+ logger.info("### Running startup.sh complete")
48
+ if 'runStartup' not in st.session_state:
49
+ st.session_state.runStartup = True
50
+ runStartup()
51
+
52
+
53
+
54
+ ######################################################################
55
+ # MAINLINE
56
+ #
57
+ logger.info("#### MAINLINE ENTERED.")
58
+
59
+ # Function to load the CSS file
60
+ def load_css(file_name):
61
+ with open(file_name) as f:
62
+ st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
63
+
64
+ # Load the custom CSS
65
+ if 'load_css' not in st.session_state:
66
+ load_css(".streamlit/main.css")
67
+ st.session_state.load_css = True
68
+
69
+ st.markdown("<h1 style='text-align: center; color: #666666;'>Vector Database RAG Proof of Concept</h1>", unsafe_allow_html=True)
70
+ st.markdown("<h6 style='text-align: center; color: #666666;'>V1</h6>", unsafe_allow_html=True)
71
+
72
+ #pathString = "/Users/660565/KPSAllInOne/ProgramFilesX86/WebCopy/DownloadedWebSites/LLMPOC_HTML"
73
+ pathString = "/app/inputDocs"
74
+ chunks = []
75
+ webpageDocNames = []
76
+ page_contentArray = []
77
+ webpageChunks = []
78
+ webpageTitles = []
79
+ webpageChunksDocNames = []
80
+
81
+ ######################################################
82
+ # Connect to the Weaviate vector database.
83
+ #if 'client' not in st.session_state:
84
+ logger.info("#### Create Weaviate db client connection.")
85
+ client = weaviate.WeaviateClient(
86
+ connection_params=ConnectionParams.from_params(
87
+ http_host="localhost",
88
+ http_port="8080",
89
+ http_secure=False,
90
+ grpc_host="localhost",
91
+ grpc_port="50051",
92
+ grpc_secure=False
93
+ ),
94
+ additional_config=AdditionalConfig(
95
+ timeout=Timeout(init=60, query=1800, insert=1800), # Values in seconds
96
+ )
97
  )
98
+ client.connect()
99
+ # st.session_state.client = client
100
+ #else:
101
+ # client = st.session_state.client
102
+
103
+
104
+ #######################################################
105
+ # Read each text input file, parse it into a document,
106
+ # chunk it, collect chunks and document name.
107
+ if not client.collections.exists("Documents") or not client.collections.exists("Documents") :
108
+ logger.info("#### Read and chunk input text files.")
109
+ for filename in os.listdir(pathString):
110
+ logger.info(filename)
111
+ path = Path(pathString + "/" + filename)
112
+ filename = filename.rstrip(".html")
113
+ webpageDocNames.append(filename)
114
+ htmlLoader = BSHTMLLoader(path,"utf-8")
115
+ htmlData = htmlLoader.load()
116
+
117
+ title = htmlData[0].metadata['title']
118
+ page_content = htmlData[0].page_content
119
+
120
+ # Clean data. Remove multiple newlines, etc.
121
+ page_content = re.sub(r'\n+', '\n',page_content)
122
+
123
+ page_contentArray.append(page_content);
124
+ webpageTitles.append(title)
125
+ max_tokens = 1000
126
+ tokenizer = Tokenizer.from_pretrained("bert-base-uncased")
127
+ logger.debug(f"### tokenizer: {tokenizer}")
128
+ splitter = HuggingFaceTextSplitter(tokenizer, trim_chunks=True)
129
+ chunksOnePage = splitter.chunks(page_content, chunk_capacity=50)
130
+
131
+ chunks = []
132
+ for chnk in chunksOnePage:
133
+ logger.debug(f"#### chnk in file: {chnk}")
134
+ chunks.append(chnk)
135
+ logger.debug(f"chunks: {chunks}")
136
+ webpageChunks.append(chunks)
137
+ webpageChunksDocNames.append(filename + "Chunks")
138
+
139
+ logger.debug(f"### filename, title: {filename}, {title}")
140
+ logger.debug(f"### webpageDocNames: {webpageDocNames}")
141
+
142
+
143
+
144
+ ######################################################
145
+ # Create database webpage and chunks collections.
146
+ #wpCollection = createWebpageCollection()
147
+ #wpChunkCollection = createChunksCollection()
148
+ if not client.collections.exists("Documents"):
149
+ logger.info("#### createWebpageCollection() entered.")
150
+ #client.collections.delete("Documents")
151
+ class_obj = {
152
+ "class": "Documents",
153
+ "description": "For first attempt at loading a Weviate database.",
154
+ "vectorizer": "text2vec-transformers",
155
+ "moduleConfig": {
156
+ "text2vec-transformers": {
157
+ "vectorizeClassName": False
158
+ }
159
+ },
160
+ "vectorIndexType": "hnsw",
161
+ "vectorIndexConfig": {
162
+ "distance": "cosine",
163
+ },
164
+ "properties": [
165
+ {
166
+ "name": "title",
167
+ "dataType": ["text"],
168
+ "description": "HTML doc title.",
169
+ "vectorizer": "text2vec-transformers",
170
+ "moduleConfig": {
171
+ "text2vec-transformers": {
172
+ "vectorizePropertyName": True,
173
+ "skip": False,
174
+ "tokenization": "lowercase"
175
+ }
176
+ },
177
+ "invertedIndexConfig": {
178
+ "bm25": {
179
+ "b": 0.75,
180
+ "k1": 1.2
181
+ },
182
  }
183
  },
184
+ {
185
+ "name": "content",
186
+ "dataType": ["text"],
187
+ "description": "HTML page content.",
188
+ "moduleConfig": {
189
+ "text2vec-transformers": {
190
+ "vectorizePropertyName": True,
191
+ "tokenization": "whitespace"
192
+ }
 
 
 
 
 
 
193
  }
194
  }
195
+ ]
196
+ }
197
+ wpCollection = client.collections.create_from_dict(class_obj)
198
+
199
+
200
+ if not client.collections.exists("Chunks"):
201
+ logger.info("#### createChunksCollection() entered.")
202
+ #client.collections.delete("Chunks")
203
+ class_obj = {
204
+ "class": "Chunks",
205
+ "description": "Collection for document chunks.",
206
+ "vectorizer": "text2vec-transformers",
207
+ "moduleConfig": {
208
+ "text2vec-transformers": {
209
+ "vectorizeClassName": True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
  },
212
+ "vectorIndexType": "hnsw",
213
+ "vectorIndexConfig": {
214
+ "distance": "cosine",
215
  },
216
+ "properties": [
217
+ {
218
+ "name": "chunk",
219
+ "dataType": ["text"],
220
+ "description": "Single webpage chunk.",
221
+ "vectorizer": "text2vec-transformers",
222
+ "moduleConfig": {
223
+ "text2vec-transformers": {
224
+ "vectorizePropertyName": False,
225
+ "skip": False,
226
+ "tokenization": "lowercase"
227
+ }
228
  }
229
+ },
230
+ {
231
+ "name": "chunk_index",
232
+ "dataType": ["int"]
233
+ },
234
+ {
235
+ "name": "webpage",
236
+ "dataType": ["Documents"],
237
+ "description": "Webpage content chunks.",
238
+
239
+ "invertedIndexConfig": {
240
+ "bm25": {
241
+ "b": 0.75,
242
+ "k1": 1.2
243
+ }
244
+ }
245
+ }
246
+ ]
247
+ }
248
+ wpChunkCollection = client.collections.create_from_dict(class_obj)
249
+
250
+
251
+ ###########################################################
252
+ # Create document and chunks objects in the database.
253
+ if not client.collections.exists("Documents") :
254
+ logger.info("#### Create page/doc db objects.")
255
+ for i, className in enumerate(webpageDocNames):
256
+ title = webpageTitles[i]
257
+ logger.debug(f"## className, title: {className}, {title}")
258
+ # Create Webpage Object
259
+ page_content = page_contentArray[i]
260
+ # Insert the document.
261
+ wpCollectionObj_uuid = wpCollection.data.insert(
262
+ {
263
+ "name": className,
264
+ "title": title,
265
+ "content": page_content
266
+ }
267
+ )
268
+
269
+ if not client.collections.exists("Chunks") :
270
+ logger.info("#### Create chunk db objects.")
271
+ # Insert the chunks for the document.
272
+ for i2, chunk in enumerate(webpageChunks[i]):
273
+ chunk_uuid = wpChunkCollection.data.insert(
274
+ {
275
+ "title": title,
276
+ "chunk": chunk,
277
+ "chunk_index": i2,
278
+ "references":
279
+ {
280
+ "webpage": wpCollectionObj_uuid
281
+ }
282
+ }
283
+ )
284
+
285
+
286
+ #################################################################
287
+ # Initialize the LLM.
288
+ model_path = "/app/llama-2-7b-chat.Q4_0.gguf"
289
+ if 'llm' not in st.session_state:
290
+ llm = Llama(model_path,
291
+ #*,
292
+ n_gpu_layers=0,
293
+ split_mode=llama_cpp.LLAMA_SPLIT_MODE_LAYER,
294
+ main_gpu=0,
295
+ tensor_split=None,
296
+ vocab_only=False,
297
+ use_mmap=True,
298
+ use_mlock=False,
299
+ kv_overrides=None,
300
+ seed=llama_cpp.LLAMA_DEFAULT_SEED,
301
+ n_ctx=512,
302
+ n_batch=512,
303
+ n_threads=8,
304
+ n_threads_batch=16,
305
+ rope_scaling_type=llama_cpp.LLAMA_ROPE_SCALING_TYPE_UNSPECIFIED,
306
+ pooling_type=llama_cpp.LLAMA_POOLING_TYPE_UNSPECIFIED,
307
+ rope_freq_base=0.0,
308
+ rope_freq_scale=0.0,
309
+ yarn_ext_factor=-1.0,
310
+ yarn_attn_factor=1.0,
311
+ yarn_beta_fast=32.0,
312
+ yarn_beta_slow=1.0,
313
+ yarn_orig_ctx=0,
314
+ logits_all=False,
315
+ embedding=False,
316
+ offload_kqv=True,
317
+ last_n_tokens_size=64,
318
+ lora_base=None,
319
+ lora_scale=1.0,
320
+ lora_path=None,
321
+ numa=False,
322
+ chat_format=None,
323
+ chat_handler=None,
324
+ draft_model=None,
325
+ tokenizer=None,
326
+ type_k=None,
327
+ type_v=None,
328
+ verbose=True
329
+ )
330
+ st.session_state.llm = llm
331
+ else:
332
+ llm = st.session_state.llm
333
+
334
+ def getRagData(promptText):
335
+ logger.info("#### getRagData() entered.")
336
+ ###############################################################################
337
+ # Initial the the sentence transformer and encode the query prompt.
338
+ logger.info(f"#### Encode text query prompt to create vectors. {text}")
339
+ model = SentenceTransformer('/app/multi-qa-MiniLM-L6-cos-v1')
340
+
341
+ vector = model.encode(promptText)
342
+ vectorList = []
343
+
344
+ logger.debug("#### Print vectors.")
345
+ for vec in vector:
346
+ vectorList.append(vec)
347
+ logger.debug(f"vectorList: {vectorList[2]}")
348
+
349
+ # Fetch chunks and print chunks.
350
+ logger.info("#### Retrieve semchunks from db using vectors from prompt.")
351
+ semChunks = wpChunkCollection.query.near_vector(
352
+ near_vector=vectorList,
353
+ distance=0.7,
354
+ limit=3
355
  )
356
+ logger.debug(f"### semChunks[0]: {semChunks}")
357
+
358
+ # Print chunks, corresponding document and document title.
359
+ ragData = ""
360
+ logger.info("#### Print individual retrieved chunks.")
361
+ for chunk in enumerate(semChunks.objects):
362
+ logger.info(f"#### chunk: {chunk}")
363
+ ragData = ragData + "\n" + chunk[0]
364
+ webpage_uuid = chunk[1].properties['references']['webpage']
365
+ logger.info(f"webpage_uuid: {webpage_uuid}")
366
+ wpFromChunk = wpCollection.query.fetch_object_by_id(webpage_uuid)
367
+ logger.info(f"### wpFromChunk title: {wpFromChunk.properties['title']}")
368
+ #collection = client.collections.get("Chunks")
369
+ return ragData
370
+
371
+
372
+ # Display UI
373
+ col1, col2 = st.columns(2)
374
+
375
+ with col1:
376
+ if "sysTA" not in st.session_state:
377
+ st.session_state.sysTA = st.text_area(label="sysTA",value="fdsaf fsdafdsa")
378
+ elif "sysTAtext" in st.session_state:
379
+ st.session_state.sysTA = st.text_area(label="sysTA",value=st.session_state.sysTAtext)
380
+ else:
381
+ st.session_state.sysTA = st.text_area(label="sysTA",value=st.session_state.sysTA)
382
+
383
+ if "userpTA" not in st.session_state:
384
+ userTextArea = st.text_area(label="userpTA",value="fdsaf fsdafdsa")
385
+ elif "userpTAtext" in st.session_state:
386
+ st.session_state.userpTA = st.text_area(label="userpTA",value=st.session_state.userpTAtext)
387
+ else:
388
+ st.session_state.userpTA = st.text_area(label="userpTA",value=st.session_state.userpTA)
389
+
390
+ with col2:
391
+ if "ragpTA" not in st.session_state:
392
+ ragPromptTextArea = st.text_area(label="ragpTA",value="fdsaf fsdafdsa")
393
+ elif "ragpTAtext" in st.session_state:
394
+ st.session_state.ragpTA = st.text_area(label="ragpTA",value=st.session_state.ragpTAtext)
395
+ else:
396
+ st.session_state.ragTA = st.text_area(label="ragTA",value=st.session_state.ragTA)
397
+
398
+ if "rspTA" not in st.session_state:
399
+ responseTextArea = st.text_area(label="rspTA",value="fdsaf fsdafdsa")
400
+ elif "rspTAtext" in st.session_state:
401
+ st.session_state.rspTA = st.text_area(label="rspTA",value=st.session_state.rspTAtext)
402
+ else:
403
+ st.session_state.rspTA = st.text_area(label="rspTA",value=st.session_state.rspTA)
404
+
405
+ def runLLM(prompt):
406
+ max_tokens = 1000
407
+ temperature = 0.3
408
+ top_p = 0.1
409
+ echo = True
410
+ stop = ["Q", "\n"]
411
+
412
+ modelOutput = llm(
413
+ prompt,
414
+ max_tokens=max_tokens,
415
+ temperature=temperature,
416
+ top_p=top_p,
417
+ echo=echo,
418
+ stop=stop,
419
  )
420
+ result = modelOutput["choices"][0]["text"].strip()
421
+ return(result)
422
+
423
+ def setPrompt(pprompt,ragFlag):
424
+ logger(f"\n### setPrompt() entered. ragFlag: {ragFlag}")
425
+ if ragFlag:
426
+ ragPrompt = getRagData(pprompt)
427
+ userPrompt = pprompt + "\n" + ragPrompt
428
+ prompt = userPrompt
429
+ userPrompt = "Using this information: " + ragPrompt \
430
+ + "process the following statement or question and produce a a response" \
431
+ + intialPrompt
432
+ else:
433
+ userPrompt = pprompt
434
+ #prompt = f""" <s> [INST] <<SYS>> {systemTextArea.value} </SYS>> Q: {userPrompt} A: [/INST]"""
435
+ return userPrompt
436
+
437
+
438
+ def on_submitButton_clicked():
439
+ logger = st.session_state.logger
440
+ logger.debug("\n### on_submitButton_clicked")
441
+ st.session_state.sysTAtext = st.session_state.sysTA
442
+ logger.info(f"sysTAtext: {st.session_state.sysTAtext}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
 
444
+ st.session_state.userpTAtext = setPrompt("","")
445
+ st.session_state.userpTA = st.session_state.userpTAtext
446
+ logger.info(f"userpTAtext: {st.session_state.userpTAtext}")
447
+
448
+ st.session_state.rspTAtext = runLLM(st.session_state.userpTAtext)
449
+ st.session_state.rspTA = st.session_state.rspTAtext
450
+ logger.info(f"rspTAtext: {st.session_state.rspTAtext}")
451
 
 
 
 
 
 
 
 
452
 
453
+ with st.sidebar:
454
+ st.selectRag = st.checkbox("Enable Query With RAG",value=False,key="selectRag",help=None,on_change=None,args=None,kwargs=None,disabled=False,label_visibility="visible")
455
+ st.submitButton = st.button("Run LLM Query",key=None,help=None,on_click=on_submitButton_clicked,args=None,kwargs=None,type="secondary",disabled=False,use_container_width=False)
456
+
457
+ logger.info("#### semsearch.py terminating.")
458
+ except Exception as e:
459
+ logger.error("#### EXCEPTION. e: {str(e)})
460
+ with open("/app/startup.log", "r") as file:
461
+ content = file.read()
462
+ print(content)