GeorgiosIoannouCoder commited on
Commit
77cd2ef
1 Parent(s): c924850

Create Fall_2024_Ioannou_Georgios_RAG_tutorial_11_05_2024.ipynb

Browse files
Fall_2024_Ioannou_Georgios_RAG_tutorial_11_05_2024.ipynb ADDED
@@ -0,0 +1,677 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {
6
+ "id": "NgfYnPJIcitW"
7
+ },
8
+ "source": [
9
+ "---\n",
10
+ "\n",
11
+ "# Ioannou_Georgios\n"
12
+ ]
13
+ },
14
+ {
15
+ "cell_type": "markdown",
16
+ "metadata": {
17
+ "id": "BAdncZ1Ccmn_"
18
+ },
19
+ "source": [
20
+ "## Copyright © 2024 by Georgios Ioannou\n"
21
+ ]
22
+ },
23
+ {
24
+ "cell_type": "markdown",
25
+ "metadata": {
26
+ "id": "vxYZpoi3dgfL"
27
+ },
28
+ "source": [
29
+ "---\n",
30
+ "\n",
31
+ "<h1 align=\"center\"> RAG Question Answering Application Using TXT Files, MongoDB As The Vector Database, HuggingFace Embedding Model, HuggingFace LLM, and Gradio </h1>\n"
32
+ ]
33
+ },
34
+ {
35
+ "cell_type": "markdown",
36
+ "source": [
37
+ "<h2 align=\"center\"> HuggingFace Embedding Model Used: <a href=\"https://huggingface.co/sentence-transformers/all-mpnet-base-v2\"> all-mpnet-base-v2 </a> </h2>\n"
38
+ ],
39
+ "metadata": {
40
+ "id": "MWzJLfMsCrqt"
41
+ }
42
+ },
43
+ {
44
+ "cell_type": "markdown",
45
+ "source": [
46
+ "<h2 align=\"center\"> HuggingFace LLM Model Used: <a href=\"https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct\"> Qwen2.5-1.5B-Instruct </a> </h2>\n"
47
+ ],
48
+ "metadata": {
49
+ "id": "0l8WK80uC9WZ"
50
+ }
51
+ },
52
+ {
53
+ "cell_type": "markdown",
54
+ "metadata": {
55
+ "id": "xXdDSfrtzW10"
56
+ },
57
+ "source": [
58
+ "---\n",
59
+ "\n",
60
+ "<h2 align=\"center\"> Install Libraries </h2>\n"
61
+ ]
62
+ },
63
+ {
64
+ "cell_type": "code",
65
+ "execution_count": null,
66
+ "metadata": {
67
+ "id": "wEoN-qN9cxjt"
68
+ },
69
+ "outputs": [],
70
+ "source": [
71
+ "!pip install gradio pymongo langchain-community transformers"
72
+ ]
73
+ },
74
+ {
75
+ "cell_type": "code",
76
+ "execution_count": null,
77
+ "metadata": {
78
+ "id": "oXSlapLqeXoJ"
79
+ },
80
+ "outputs": [],
81
+ "source": [
82
+ "# Import libraries.\n",
83
+ "# Gradio.\n",
84
+ "import gradio as gr\n",
85
+ "\n",
86
+ "# File loading and environment variables.\n",
87
+ "import os\n",
88
+ "import sys\n",
89
+ "\n",
90
+ "# File loading and environment variables.\n",
91
+ "from getpass import getpass\n",
92
+ "from google.colab import userdata\n",
93
+ "from google.colab import drive\n",
94
+ "\n",
95
+ "# Gradio.\n",
96
+ "from gradio.themes.base import Base\n",
97
+ "\n",
98
+ "# HuggingFace LLM.\n",
99
+ "from huggingface_hub import InferenceClient\n",
100
+ "\n",
101
+ "# Langchain.\n",
102
+ "from langchain.document_loaders import TextLoader\n",
103
+ "from langchain.prompts import PromptTemplate\n",
104
+ "from langchain.schema.runnable import RunnablePassthrough, RunnableLambda\n",
105
+ "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
106
+ "from langchain_community.vectorstores import MongoDBAtlasVectorSearch\n",
107
+ "from langchain_community.embeddings import HuggingFaceInferenceAPIEmbeddings\n",
108
+ "\n",
109
+ "# MongoDB.\n",
110
+ "from pymongo import MongoClient\n",
111
+ "\n",
112
+ "# Function type hints.\n",
113
+ "from typing import Dict, Any"
114
+ ]
115
+ },
116
+ {
117
+ "cell_type": "markdown",
118
+ "metadata": {
119
+ "id": "qNMAqdpWf5Iq"
120
+ },
121
+ "source": [
122
+ "## Step 1: Data Sourcing and Preparation\n"
123
+ ]
124
+ },
125
+ {
126
+ "cell_type": "code",
127
+ "execution_count": null,
128
+ "metadata": {
129
+ "id": "PRKmpcMWjXeg"
130
+ },
131
+ "outputs": [],
132
+ "source": [
133
+ "# For Google Colab.\n",
134
+ "# Mount (connect) your Google Drive to your Colab environment.\n",
135
+ "# This will establish a connection to your Google Drive, making it accessible from your Colab notebook.\n",
136
+ "\n",
137
+ "drive.mount(\"/content/drive/\")"
138
+ ]
139
+ },
140
+ {
141
+ "cell_type": "code",
142
+ "execution_count": null,
143
+ "metadata": {
144
+ "id": "V_YnoLTkjXek"
145
+ },
146
+ "outputs": [],
147
+ "source": [
148
+ "# For Google Colab.\n",
149
+ "! ls \"/content/drive/My Drive/zoom-transcripts/\""
150
+ ]
151
+ },
152
+ {
153
+ "cell_type": "code",
154
+ "execution_count": null,
155
+ "metadata": {
156
+ "id": "qGXN8pAWjXen"
157
+ },
158
+ "outputs": [],
159
+ "source": [
160
+ "# For Google Colab.\n",
161
+ "# Append your directory path to the Python system path.\n",
162
+ "directory_path = \"/content/drive/My Drive/zoom-transcripts/\"\n",
163
+ "\n",
164
+ "sys.path.append(directory_path)\n",
165
+ "\n",
166
+ "# Print the updated system path to the console.\n",
167
+ "print(\"sys.path =\", sys.path)"
168
+ ]
169
+ },
170
+ {
171
+ "cell_type": "code",
172
+ "execution_count": null,
173
+ "metadata": {
174
+ "id": "xwnzuw0NjXeq"
175
+ },
176
+ "outputs": [],
177
+ "source": [
178
+ "# Get all the filenames under our directory path.\n",
179
+ "my_txts = os.listdir(directory_path)\n",
180
+ "my_txts"
181
+ ]
182
+ },
183
+ {
184
+ "cell_type": "code",
185
+ "execution_count": null,
186
+ "metadata": {
187
+ "id": "ggS61lmnjXer"
188
+ },
189
+ "outputs": [],
190
+ "source": [
191
+ "# Load the TXT.\n",
192
+ "\n",
193
+ "loaders = []\n",
194
+ "for my_txt in my_txts:\n",
195
+ " my_txt_path = os.path.join(directory_path, my_txt)\n",
196
+ " loaders.append(TextLoader(my_txt_path))\n",
197
+ "\n",
198
+ "print(\"len(loaders) =\", len(loaders))\n",
199
+ "\n",
200
+ "loaders"
201
+ ]
202
+ },
203
+ {
204
+ "cell_type": "code",
205
+ "execution_count": null,
206
+ "metadata": {
207
+ "id": "H9g8SGTGjXes"
208
+ },
209
+ "outputs": [],
210
+ "source": [
211
+ "# Load the TXT.\n",
212
+ "\n",
213
+ "data = []\n",
214
+ "for loader in loaders:\n",
215
+ " data.append(loader.load())\n",
216
+ "\n",
217
+ "print(\"len(data) =\", len(data), \"\\n\")\n",
218
+ "\n",
219
+ "# First TXT file.\n",
220
+ "data[0]"
221
+ ]
222
+ },
223
+ {
224
+ "cell_type": "code",
225
+ "execution_count": null,
226
+ "metadata": {
227
+ "id": "SSZOD3M8jXey"
228
+ },
229
+ "outputs": [],
230
+ "source": [
231
+ "# Initialize the text splitter\n",
232
+ "# Uses a text splitter to split the data into smaller documents.\n",
233
+ "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)"
234
+ ]
235
+ },
236
+ {
237
+ "cell_type": "code",
238
+ "execution_count": null,
239
+ "metadata": {
240
+ "id": "fAqdCPx8jXez"
241
+ },
242
+ "outputs": [],
243
+ "source": [
244
+ "# Split the TXT documents into chunks.\n",
245
+ "docs = []\n",
246
+ "for doc in data:\n",
247
+ " chunk = text_splitter.split_documents(doc)\n",
248
+ " docs.append(chunk)\n",
249
+ "\n",
250
+ "# # Debugging purposes to print the number of documents in each chunk.\n",
251
+ "# # Print the number of total documents to be stored in the vector database.\n",
252
+ "# total = 0\n",
253
+ "# for i in range(len(docs)):\n",
254
+ "# if i == len(docs) - 1:\n",
255
+ "# print(len(docs[i]), end=\"\")\n",
256
+ "# else:\n",
257
+ "# print(len(docs[i]), \"+ \", end=\"\")\n",
258
+ "# total += len(docs[i])\n",
259
+ "# print(\" =\", total, \" total documents\\n\")\n",
260
+ "\n",
261
+ "# # Print the first document.\n",
262
+ "# print(docs[0], \"\\n\\n\\n\")\n",
263
+ "\n",
264
+ "# # Print the total number of TXT files.\n",
265
+ "# # docs is a list of lists where each list stores all the documents for one TXT file.\n",
266
+ "# print(len(docs), \"chunks in docs list\")\n",
267
+ "\n",
268
+ "# docs"
269
+ ]
270
+ },
271
+ {
272
+ "cell_type": "code",
273
+ "execution_count": null,
274
+ "metadata": {
275
+ "id": "CRdD2CQXjXe0"
276
+ },
277
+ "outputs": [],
278
+ "source": [
279
+ "# Merge the documents into a single list to be embededed so that they can be stored them in the vector database.\n",
280
+ "merged_documents = []\n",
281
+ "\n",
282
+ "for doc in docs:\n",
283
+ " merged_documents.extend(doc)\n",
284
+ "\n",
285
+ "# Print the merged list of all the documents.\n",
286
+ "print(\"len(merged_documents) =\", len(merged_documents))\n",
287
+ "print(merged_documents)"
288
+ ]
289
+ },
290
+ {
291
+ "cell_type": "markdown",
292
+ "source": [
293
+ "## Step 2: Vector Database Setup\n"
294
+ ],
295
+ "metadata": {
296
+ "id": "amLFTvEUrYHR"
297
+ }
298
+ },
299
+ {
300
+ "cell_type": "code",
301
+ "source": [
302
+ "# Connect to MongoDB Atlas cluster using the connection string.\n",
303
+ "MONGO_URI = getpass(\"MONGO_URI:\")\n",
304
+ "cluster = MongoClient(MONGO_URI)\n",
305
+ "\n",
306
+ "# Define the MongoDB database and collection name.\n",
307
+ "DB_NAME = \"txts\"\n",
308
+ "COLLECTION_NAME = \"txts_collection\"\n",
309
+ "\n",
310
+ "# Connect to the specific collection in the database.\n",
311
+ "MONGODB_COLLECTION = cluster[DB_NAME][COLLECTION_NAME]\n",
312
+ "\n",
313
+ "vector_search_index = \"vector_index\""
314
+ ],
315
+ "metadata": {
316
+ "id": "vcYEWk7Dnoz_"
317
+ },
318
+ "execution_count": null,
319
+ "outputs": []
320
+ },
321
+ {
322
+ "cell_type": "code",
323
+ "source": [
324
+ "# Delete any existing records in the collection.\n",
325
+ "# Clear the collection.\n",
326
+ "MONGODB_COLLECTION.delete_many({})"
327
+ ],
328
+ "metadata": {
329
+ "id": "wEabWPjmnrWc"
330
+ },
331
+ "execution_count": null,
332
+ "outputs": []
333
+ },
334
+ {
335
+ "cell_type": "markdown",
336
+ "source": [
337
+ "## Step 3: Generate Embeddings and Data Ingestion Into MongoDB"
338
+ ],
339
+ "metadata": {
340
+ "id": "poyFalAIrd3g"
341
+ }
342
+ },
343
+ {
344
+ "cell_type": "code",
345
+ "source": [
346
+ "HF_TOKEN = getpass(\"HF_TOKEN:\")\n",
347
+ "# https://python.langchain.com/docs/integrations/text_embedding/huggingfacehub/#hugging-face-inference-api\n",
348
+ "embedding_model = HuggingFaceInferenceAPIEmbeddings(\n",
349
+ " api_key=HF_TOKEN, model_name=\"sentence-transformers/all-mpnet-base-v2\"\n",
350
+ ")"
351
+ ],
352
+ "metadata": {
353
+ "id": "qBMpZjK_rrSi"
354
+ },
355
+ "execution_count": null,
356
+ "outputs": []
357
+ },
358
+ {
359
+ "cell_type": "code",
360
+ "source": [
361
+ "# Initialize the MongoDB Atlas vector search with the document segments.\n",
362
+ "# Create a vector store (vecgtor database) from the documents.\n",
363
+ "vector_search = MongoDBAtlasVectorSearch.from_documents(\n",
364
+ " documents=merged_documents, # The sample documents to store in the vector database.\n",
365
+ " embedding=embedding_model, # HuggingFace's embedding model as the model used to convert text into vector embeddings for the embedding field.\n",
366
+ " collection=MONGODB_COLLECTION, # pdfs.pdfs_collection as the Atlas collection to store the documents.\n",
367
+ " index_name=vector_search_index # vector_index as the index to use for querying the vector store.\n",
368
+ ")\n",
369
+ "\n",
370
+ "# At this point, 'docs' are split and indexed in MongoDB Atlas, enabling text search capabilities."
371
+ ],
372
+ "metadata": {
373
+ "id": "fVEp3QfHnc3l"
374
+ },
375
+ "execution_count": null,
376
+ "outputs": []
377
+ },
378
+ {
379
+ "cell_type": "code",
380
+ "source": [
381
+ "# Connect to an existing vector store (database).\n",
382
+ "# ONLY RUN IT IF YOU HAVE AN EXISITNG VECTOR STORE AND YOU JUST NEED TO CONNECT TO IT.\n",
383
+ "vector_search = MongoDBAtlasVectorSearch.from_connection_string(\n",
384
+ " connection_string=MONGO_URI,\n",
385
+ " namespace=f\"{DB_NAME}.{COLLECTION_NAME}\",\n",
386
+ " embedding=embedding_model,\n",
387
+ " index_name=vector_search_index,\n",
388
+ ")"
389
+ ],
390
+ "metadata": {
391
+ "id": "kj8wfTv38zAG"
392
+ },
393
+ "execution_count": null,
394
+ "outputs": []
395
+ },
396
+ {
397
+ "cell_type": "markdown",
398
+ "metadata": {
399
+ "id": "DGlA_MrqpSkQ"
400
+ },
401
+ "source": [
402
+ "## Step 4: Vector Search\n"
403
+ ]
404
+ },
405
+ {
406
+ "cell_type": "code",
407
+ "source": [
408
+ "# Semantic Search.\n",
409
+ "query = \"Who is Georgios?\"\n",
410
+ "results = vector_search.similarity_search(query=query, k=10) # 10 most similar documents.\n",
411
+ "\n",
412
+ "print(\"\\n\")\n",
413
+ "print(results)\n",
414
+ "# # Better looking output.\n",
415
+ "# from pprint import pprint\n",
416
+ "# pprint(results)"
417
+ ],
418
+ "metadata": {
419
+ "id": "K4-w_1Q7r85B"
420
+ },
421
+ "execution_count": null,
422
+ "outputs": []
423
+ },
424
+ {
425
+ "cell_type": "code",
426
+ "source": [
427
+ "# Filter on metadata.\n",
428
+ "# Semantic search with filtering.\n",
429
+ "query = \"Who is Georgios?\"\n",
430
+ "\n",
431
+ "results = vector_search.similarity_search_with_score(\n",
432
+ " query = query,\n",
433
+ " k = 10, # 10 most similar documents.\n",
434
+ " pre_filter = { \"source\": { \"$eq\": \"/content/drive/My Drive/zoom-transcripts/Week-01-Setup-Pandas-Tuesday-2024-08-27.vtt\" } } # Filtering on the source.\n",
435
+ ")\n",
436
+ "\n",
437
+ "print(results)\n",
438
+ "# # Better looking output.\n",
439
+ "# from pprint import pprint\n",
440
+ "# pprint(results)"
441
+ ],
442
+ "metadata": {
443
+ "id": "rxEssV0uuKNk"
444
+ },
445
+ "execution_count": null,
446
+ "outputs": []
447
+ },
448
+ {
449
+ "cell_type": "code",
450
+ "source": [
451
+ "# Basic RAG.\n",
452
+ "# k to search for only the 10 most relevant documents.\n",
453
+ "# score_threshold to use only documents with a relevance score above 0.80.\n",
454
+ "retriever_1 = vector_search.as_retriever(\n",
455
+ " search_type = \"similarity\", # similarity, mmr, similarity_score_threshold. https://api.python.langchain.com/en/latest/vectorstores/langchain_core.vectorstores.VectorStore.html#langchain_core.vectorstores.VectorStore.as_retriever\n",
456
+ " search_kwargs = {\"k\": 10, \"score_threshold\": 0.85}\n",
457
+ ")"
458
+ ],
459
+ "metadata": {
460
+ "id": "f0GIVNFpuQnP"
461
+ },
462
+ "execution_count": null,
463
+ "outputs": []
464
+ },
465
+ {
466
+ "cell_type": "code",
467
+ "source": [
468
+ "# RAG with Filtering.\n",
469
+ "# k to search for only the 10 most relevant documents.\n",
470
+ "# score_threshold to use only documents with a relevance score above 0.89.\n",
471
+ "# pre_filter to filter documents where the source is equal to \"/content/drive/My Drive/zoom-transcripts/Week-01-Setup-Pandas-Tuesday-2024-08-27.vtt\".\n",
472
+ "retriever_2 = vector_search.as_retriever(\n",
473
+ " search_type = \"similarity\", # similarity, mmr, similarity_score_threshold. https://api.python.langchain.com/en/latest/vectorstores/langchain_core.vectorstores.VectorStore.html#langchain_core.vectorstores.VectorStore.as_retriever\n",
474
+ " search_kwargs = {\n",
475
+ " \"k\": 10,\n",
476
+ " \"score_threshold\": 0.89,\n",
477
+ " \"pre_filter\": { \"source\": { \"$eq\": \"/content/drive/My Drive/zoom-transcripts/Week-01-Setup-Pandas-Tuesday-2024-08-27.vtt\" } }\n",
478
+ " }\n",
479
+ ")"
480
+ ],
481
+ "metadata": {
482
+ "id": "E0GMWmBqxK6D"
483
+ },
484
+ "execution_count": null,
485
+ "outputs": []
486
+ },
487
+ {
488
+ "cell_type": "markdown",
489
+ "metadata": {
490
+ "id": "NBS7TGJoE-tb"
491
+ },
492
+ "source": [
493
+ "## Step 5: LLM\n"
494
+ ]
495
+ },
496
+ {
497
+ "cell_type": "code",
498
+ "source": [
499
+ "# Formatting the retrieved documents beofre inserting them in the system prompt template.\n",
500
+ "def format_docs(docs):\n",
501
+ " return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
502
+ "\n",
503
+ "def generate_response(input_dict: Dict[str, Any]) -> str:\n",
504
+ " formatted_prompt = prompt.format(**input_dict)\n",
505
+ " # print(formatted_prompt)\n",
506
+ " response = hf_client.chat.completions.create(\n",
507
+ " model=\"Qwen/Qwen2.5-1.5B-Instruct\",\n",
508
+ " messages=[{\n",
509
+ " \"role\": \"system\",\n",
510
+ " \"content\": formatted_prompt\n",
511
+ " },{\n",
512
+ " \"role\": \"user\",\n",
513
+ " \"content\": input_dict[\"question\"]\n",
514
+ " }],\n",
515
+ " max_tokens=1000,\n",
516
+ " temperature=0.2,\n",
517
+ " )\n",
518
+ "\n",
519
+ " return response.choices[0].message.content\n",
520
+ "\n",
521
+ "# Initialize Hugging Face client\n",
522
+ "hf_client = InferenceClient(api_key=HF_TOKEN)\n",
523
+ "\n",
524
+ "# Define the prompt template\n",
525
+ "prompt = PromptTemplate.from_template(\n",
526
+ " \"\"\"Use the following pieces of context to answer the question at the end.\n",
527
+ "\n",
528
+ " START OF CONTEXT:\n",
529
+ " {context}\n",
530
+ " END OF CONTEXT:\n",
531
+ "\n",
532
+ " START OF QUESTION:\n",
533
+ " {question}\n",
534
+ " END OF QUESTION:\n",
535
+ "\n",
536
+ " If you do not know the answer, just say that you do not know.\n",
537
+ " NEVER assume things.\n",
538
+ " \"\"\"\n",
539
+ ")\n",
540
+ "\n",
541
+ "# Build the chain with retriever_1.\n",
542
+ "rag_chain = (\n",
543
+ " {\"context\": retriever_1 | RunnableLambda(format_docs), \"question\": RunnablePassthrough()}\n",
544
+ " | RunnableLambda(generate_response)\n",
545
+ ")\n",
546
+ "\n",
547
+ "# Example usage.\n",
548
+ "query = \"Who is Georgios?\"\n",
549
+ "answer = rag_chain.invoke(query)\n",
550
+ "\n",
551
+ "print(\"\\nQuestion:\", query)\n",
552
+ "print(\"Answer:\", answer)\n",
553
+ "\n",
554
+ "# Get source documents related to the query.\n",
555
+ "documents = retriever_1.invoke(query)\n",
556
+ "print(\"\\nSource documents:\")\n",
557
+ "# Better looking output.\n",
558
+ "from pprint import pprint\n",
559
+ "pprint(results)"
560
+ ],
561
+ "metadata": {
562
+ "id": "fTTCikzK4-Ct"
563
+ },
564
+ "execution_count": null,
565
+ "outputs": []
566
+ },
567
+ {
568
+ "cell_type": "code",
569
+ "source": [
570
+ "# # For debugging purposes to look into the chain more in-depth.\n",
571
+ "# from langchain_core.tracers.stdout import ConsoleCallbackHandler\n",
572
+ "# answer = rag_chain.invoke(query, config={'callbacks': [ConsoleCallbackHandler()]})"
573
+ ],
574
+ "metadata": {
575
+ "id": "eGvev04J7yUJ"
576
+ },
577
+ "execution_count": null,
578
+ "outputs": []
579
+ },
580
+ {
581
+ "cell_type": "code",
582
+ "source": [
583
+ "# Does the LLM already has the knowledge or not?\n",
584
+ "client = InferenceClient(api_key=HF_TOKEN )\n",
585
+ "\n",
586
+ "messages = [\n",
587
+ "\t{\n",
588
+ "\t\t\"role\": \"user\",\n",
589
+ "\t\t\"content\": \"Who is Harpreet?\"\n",
590
+ "\t}\n",
591
+ "]\n",
592
+ "\n",
593
+ "stream = client.chat.completions.create(\n",
594
+ " model=\"Qwen/Qwen2.5-1.5B-Instruct\",\n",
595
+ "\tmessages=messages,\n",
596
+ "\tmax_tokens=500,\n",
597
+ "\tstream=True\n",
598
+ ")\n",
599
+ "\n",
600
+ "for chunk in stream:\n",
601
+ " print(chunk.choices[0].delta.content, end=\"\")"
602
+ ],
603
+ "metadata": {
604
+ "id": "xHkgODNYOyjW"
605
+ },
606
+ "execution_count": null,
607
+ "outputs": []
608
+ },
609
+ {
610
+ "cell_type": "markdown",
611
+ "source": [
612
+ "## Step 5: Gradio\n"
613
+ ],
614
+ "metadata": {
615
+ "id": "7NFmu95wH1rP"
616
+ }
617
+ },
618
+ {
619
+ "cell_type": "code",
620
+ "source": [
621
+ "# Input : query.\n",
622
+ "# Output: answer.\n",
623
+ "\n",
624
+ "def get_response(query):\n",
625
+ " return rag_chain.invoke(query)"
626
+ ],
627
+ "metadata": {
628
+ "id": "e2d4id4tH3MW"
629
+ },
630
+ "execution_count": null,
631
+ "outputs": []
632
+ },
633
+ {
634
+ "cell_type": "code",
635
+ "source": [
636
+ "# Gradio application.\n",
637
+ "with gr.Blocks(theme=Base(), title=\"RAG Question Answering App Using .txt Files, MongoDB Vector Database, HuggingFace, and Gradio\") as demo:\n",
638
+ " gr.Markdown(\n",
639
+ " \"\"\"\n",
640
+ " # RAG Question Answering App Using .txt Files, MongoDB Vector Database, HuggingFace, and Gradio\n",
641
+ " \"\"\")\n",
642
+ " textbox = gr.Textbox(label=\"Question:\")\n",
643
+ " with gr.Row():\n",
644
+ " button = gr.Button(\"Submit\", variant=\"primary\")\n",
645
+ " with gr.Column():\n",
646
+ " output1 = gr.Textbox(lines=1, max_lines=10, label=\"Answer:\")\n",
647
+ "\n",
648
+ "\n",
649
+ "# Call get_response function upon clicking the Submit button.\n",
650
+ " button.click(get_response, textbox, outputs=[output1])\n",
651
+ "\n",
652
+ "demo.launch(share=True)"
653
+ ],
654
+ "metadata": {
655
+ "id": "MMbeOhixICrw"
656
+ },
657
+ "execution_count": null,
658
+ "outputs": []
659
+ }
660
+ ],
661
+ "metadata": {
662
+ "accelerator": "GPU",
663
+ "colab": {
664
+ "gpuType": "T4",
665
+ "provenance": []
666
+ },
667
+ "kernelspec": {
668
+ "display_name": "Python 3",
669
+ "name": "python3"
670
+ },
671
+ "language_info": {
672
+ "name": "python"
673
+ }
674
+ },
675
+ "nbformat": 4,
676
+ "nbformat_minor": 0
677
+ }