chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<a target="_blank" href="https://lightning.ai/akshay-ddods/studios/rag-using-llama-3-3-by-meta-ai">
|
||||
<img src="https://pl-bolts-doc-images.s3.us-east-2.amazonaws.com/app-2/studio-badge.svg" alt="Open In Studio"/>
|
||||
</a>
|
||||
|
||||
# LLama3.3-RAG application
|
||||
|
||||
This project leverages a locally Llama 3.3 to build a RAG application to **chat with your docs** and Streamlit to build the UI.
|
||||
|
||||
## Demo
|
||||
|
||||
Watch the demo video:
|
||||
|
||||
[](https://www.youtube.com/watch?v=ZgNJMWipirk)
|
||||
|
||||
|
||||
## Installation and setup
|
||||
|
||||
**Setup Ollama**:
|
||||
```bash
|
||||
# setup ollama on linux
|
||||
curl -fsSL https://ollama.com/install.sh | sh
|
||||
# pull llama 3.3:70B
|
||||
ollama pull llama3.3
|
||||
```
|
||||
**Setup Qdrant VectorDB**
|
||||
```bash
|
||||
docker run -p 6333:6333 -p 6334:6334 \
|
||||
-v $(pwd)/qdrant_storage:/qdrant/storage:z \
|
||||
qdrant/qdrant
|
||||
```
|
||||
|
||||
**Install Dependencies**:
|
||||
Ensure you have Python 3.11 or later installed.
|
||||
```bash
|
||||
pip install streamlit ollama llama-index-vector-stores-qdrant
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📬 Stay Updated with Our Newsletter!
|
||||
**Get a FREE Data Science eBook** 📖 with 150+ essential lessons in Data Science when you subscribe to our newsletter! Stay in the loop with the latest tutorials, insights, and exclusive resources. [Subscribe now!](https://join.dailydoseofds.com)
|
||||
|
||||
[](https://join.dailydoseofds.com)
|
||||
|
||||
---
|
||||
|
||||
## Contribution
|
||||
|
||||
Contributions are welcome! Please fork the repository and submit a pull request with your improvements.
|
||||
@@ -0,0 +1,170 @@
|
||||
# Adapted from https://docs.streamlit.io/knowledge-base/tutorials/build-conversational-apps#build-a-simple-chatbot-gui-with-streaming
|
||||
import os
|
||||
|
||||
import base64
|
||||
import gc
|
||||
import random
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from IPython.display import Markdown, display
|
||||
|
||||
from llama_index.core import Settings
|
||||
from llama_index.llms.ollama import Ollama
|
||||
from llama_index.core import PromptTemplate
|
||||
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
|
||||
from llama_index.core import VectorStoreIndex, ServiceContext, SimpleDirectoryReader
|
||||
|
||||
import streamlit as st
|
||||
|
||||
if "id" not in st.session_state:
|
||||
st.session_state.id = uuid.uuid4()
|
||||
st.session_state.file_cache = {}
|
||||
|
||||
session_id = st.session_state.id
|
||||
client = None
|
||||
|
||||
|
||||
|
||||
@st.cache_resource
|
||||
def load_llm():
|
||||
llm = Ollama(model="llama3.3", request_timeout=120.0)
|
||||
return llm
|
||||
|
||||
def reset_chat():
|
||||
st.session_state.messages = []
|
||||
st.session_state.context = None
|
||||
gc.collect()
|
||||
|
||||
|
||||
def display_pdf(file):
|
||||
# Opening file from file path
|
||||
|
||||
st.markdown("### PDF Preview")
|
||||
base64_pdf = base64.b64encode(file.read()).decode("utf-8")
|
||||
|
||||
# Embedding PDF in HTML
|
||||
pdf_display = f"""<iframe src="data:application/pdf;base64,{base64_pdf}" width="400" height="100%" type="application/pdf"
|
||||
style="height:100vh; width:100%"
|
||||
>
|
||||
</iframe>"""
|
||||
|
||||
# Displaying File
|
||||
st.markdown(pdf_display, unsafe_allow_html=True)
|
||||
|
||||
|
||||
with st.sidebar:
|
||||
st.header(f"Add your documents!")
|
||||
|
||||
uploaded_file = st.file_uploader("Choose your `.pdf` file", type="pdf")
|
||||
|
||||
if uploaded_file:
|
||||
try:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
file_path = os.path.join(temp_dir, uploaded_file.name)
|
||||
|
||||
with open(file_path, "wb") as f:
|
||||
f.write(uploaded_file.getvalue())
|
||||
|
||||
file_key = f"{session_id}-{uploaded_file.name}"
|
||||
st.write("Indexing your document...")
|
||||
|
||||
if file_key not in st.session_state.get('file_cache', {}):
|
||||
|
||||
if os.path.exists(temp_dir):
|
||||
loader = SimpleDirectoryReader(
|
||||
input_dir = temp_dir,
|
||||
required_exts=[".pdf"],
|
||||
recursive=True
|
||||
)
|
||||
else:
|
||||
st.error('Could not find the file you uploaded, please check again...')
|
||||
st.stop()
|
||||
|
||||
docs = loader.load_data()
|
||||
|
||||
# setup llm & embedding model
|
||||
llm=load_llm()
|
||||
embed_model = HuggingFaceEmbedding( model_name="BAAI/bge-large-en-v1.5", trust_remote_code=True)
|
||||
# Creating an index over loaded data
|
||||
Settings.embed_model = embed_model
|
||||
index = VectorStoreIndex.from_documents(docs, show_progress=True)
|
||||
|
||||
# Create the query engine, where we use a cohere reranker on the fetched nodes
|
||||
Settings.llm = llm
|
||||
query_engine = index.as_query_engine(streaming=True)
|
||||
|
||||
# ====== Customise prompt template ======
|
||||
qa_prompt_tmpl_str = (
|
||||
"Context information is below.\n"
|
||||
"---------------------\n"
|
||||
"{context_str}\n"
|
||||
"---------------------\n"
|
||||
"Given the context information above I want you to think step by step to answer the query in a crisp manner, incase case you don't know the answer say 'I don't know!'.\n"
|
||||
"Query: {query_str}\n"
|
||||
"Answer: "
|
||||
)
|
||||
qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)
|
||||
|
||||
query_engine.update_prompts(
|
||||
{"response_synthesizer:text_qa_template": qa_prompt_tmpl}
|
||||
)
|
||||
|
||||
st.session_state.file_cache[file_key] = query_engine
|
||||
else:
|
||||
query_engine = st.session_state.file_cache[file_key]
|
||||
|
||||
# Inform the user that the file is processed and Display the PDF uploaded
|
||||
st.success("Ready to Chat!")
|
||||
display_pdf(uploaded_file)
|
||||
except Exception as e:
|
||||
st.error(f"An error occurred: {e}")
|
||||
st.stop()
|
||||
|
||||
col1, col2 = st.columns([6, 1])
|
||||
|
||||
with col1:
|
||||
st.header(f"Chat with Docs using Llama-3.3")
|
||||
|
||||
with col2:
|
||||
st.button("Clear ↺", on_click=reset_chat)
|
||||
|
||||
# Initialize chat history
|
||||
if "messages" not in st.session_state:
|
||||
reset_chat()
|
||||
|
||||
|
||||
# Display chat messages from history on app rerun
|
||||
for message in st.session_state.messages:
|
||||
with st.chat_message(message["role"]):
|
||||
st.markdown(message["content"])
|
||||
|
||||
|
||||
# Accept user input
|
||||
if prompt := st.chat_input("What's up?"):
|
||||
# Add user message to chat history
|
||||
st.session_state.messages.append({"role": "user", "content": prompt})
|
||||
# Display user message in chat message container
|
||||
with st.chat_message("user"):
|
||||
st.markdown(prompt)
|
||||
|
||||
# Display assistant response in chat message container
|
||||
with st.chat_message("assistant"):
|
||||
message_placeholder = st.empty()
|
||||
full_response = ""
|
||||
|
||||
# Simulate stream of response with milliseconds delay
|
||||
streaming_response = query_engine.query(prompt)
|
||||
|
||||
for chunk in streaming_response.response_gen:
|
||||
full_response += chunk
|
||||
message_placeholder.markdown(full_response + "▌")
|
||||
|
||||
# full_response = query_engine.query(prompt)
|
||||
|
||||
message_placeholder.markdown(full_response)
|
||||
# st.session_state.context = ctx
|
||||
|
||||
# Add assistant response to chat history
|
||||
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
||||
Binary file not shown.
@@ -0,0 +1,363 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RAG using Meta AI Llama-3\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<img src=\"./resources/rag_architecture.png\" width=800px>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"from dotenv import load_dotenv\n",
|
||||
"from IPython.display import Markdown, display\n",
|
||||
"\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"from llama_index.llms.ollama import Ollama\n",
|
||||
"from llama_index.core import PromptTemplate\n",
|
||||
"from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
|
||||
"from llama_index.core import VectorStoreIndex, ServiceContext, SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"from llama_index.vector_stores.qdrant import QdrantVectorStore\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"import qdrant_client"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# allows nested access to the event loop\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# add your documents in this directory, you can drag & drop\n",
|
||||
"input_dir_path = '/teamspace/studios/this_studio/test-dir'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"collection_name=\"chat_with_docs\"\n",
|
||||
"\n",
|
||||
"client = qdrant_client.QdrantClient(\n",
|
||||
" host=\"localhost\",\n",
|
||||
" port=6333\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def create_index(documents):\n",
|
||||
" vector_store = QdrantVectorStore(client=client, collection_name=collection_name)\n",
|
||||
" storage_context = StorageContext.from_defaults(vector_store=vector_store)\n",
|
||||
" index = VectorStoreIndex.from_documents(\n",
|
||||
" documents,\n",
|
||||
" storage_context=storage_context,\n",
|
||||
" )\n",
|
||||
" return index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "7b4ba9e36b4e47b982be21b95b24a181",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"config.json: 0%| | 0.00/779 [00:00<?, ?B/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "bf2ebc67bf4a4caf8c6292b80f869b7c",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"model.safetensors: 0%| | 0.00/1.34G [00:00<?, ?B/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "8e41ff80db1a44a1ac3dc99fc477a819",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"tokenizer_config.json: 0%| | 0.00/366 [00:00<?, ?B/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "17460d4930c241c8a7af9208b82d1310",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"vocab.txt: 0%| | 0.00/232k [00:00<?, ?B/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "1418bcfbba844062a80299a82f04d21d",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"tokenizer.json: 0%| | 0.00/711k [00:00<?, ?B/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "f73ccdc9f6be4b9e9e5d69d3de936ec1",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"special_tokens_map.json: 0%| | 0.00/125 [00:00<?, ?B/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\n",
|
||||
"# setup llm & embedding model\n",
|
||||
"llm=Ollama(model=\"llama3.3\", request_timeout=120.0)\n",
|
||||
"# embed_model = HuggingFaceEmbedding( model_name=\"Snowflake/snowflake-arctic-embed-m\", trust_remote_code=True)\n",
|
||||
"embed_model = HuggingFaceEmbedding( model_name=\"BAAI/bge-large-en-v1.5\", trust_remote_code=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "b9f486b6a1da4f15bb0e43469fa8c420",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Parsing nodes: 0%| | 0/17 [00:00<?, ?it/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "363a055481fb4d808da9551727ee5307",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Generating embeddings: 0%| | 0/26 [00:00<?, ?it/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# load data\n",
|
||||
"loader = SimpleDirectoryReader(\n",
|
||||
" input_dir = input_dir_path,\n",
|
||||
" required_exts=[\".pdf\"],\n",
|
||||
" recursive=True\n",
|
||||
" )\n",
|
||||
"docs = loader.load_data()\n",
|
||||
"\n",
|
||||
"# Creating an index over loaded data\n",
|
||||
"Settings.embed_model = embed_model\n",
|
||||
"try:\n",
|
||||
" index = create_index(docs)\n",
|
||||
" print('Using Qdrant collection')\n",
|
||||
"except:\n",
|
||||
" index = VectorStoreIndex.from_documents(docs, show_progress=True)\n",
|
||||
"\n",
|
||||
"# Create the query engine, where we use a cohere reranker on the fetched nodes\n",
|
||||
"Settings.llm = llm\n",
|
||||
"query_engine = index.as_query_engine()\n",
|
||||
"\n",
|
||||
"# ====== Customise prompt template ======\n",
|
||||
"qa_prompt_tmpl_str = (\n",
|
||||
"\"Context information is below.\\n\"\n",
|
||||
"\"---------------------\\n\"\n",
|
||||
"\"{context_str}\\n\"\n",
|
||||
"\"---------------------\\n\"\n",
|
||||
"\"Given the context information above I want you to think step by step to answer the query in a crisp manner, incase case you don't know the answer say 'I don't know!'.\\n\"\n",
|
||||
"\"Query: {query_str}\\n\"\n",
|
||||
"\"Answer: \"\n",
|
||||
")\n",
|
||||
"qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)\n",
|
||||
"\n",
|
||||
"query_engine.update_prompts(\n",
|
||||
" {\"response_synthesizer:text_qa_template\": qa_prompt_tmpl}\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Generate the response\n",
|
||||
"response = query_engine.query(\"What exactly is DSPy?\",)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"DSPy is a framework for programmatically solving advanced tasks with language and retrieval models through composing and declaring modules. It aims to replace brittle \"prompt engineering\" tricks with composable modules and automatic optimizers, allowing developers to define signatures that specify what a language model (LM) needs to do declaratively."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"display(Markdown(str(response)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### ❗️❗️ Make sure you clear GPU memory by clicking on Restart button above, if you want to use Streamlit from here"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n",
|
||||
"To disable this warning, you can either:\n",
|
||||
"\t- Avoid using `tokenizers` before the fork if possible\n",
|
||||
"\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Sat Dec 7 08:31:49 2024 \n",
|
||||
"+---------------------------------------------------------------------------------------+\n",
|
||||
"| NVIDIA-SMI 535.216.03 Driver Version: 535.216.03 CUDA Version: 12.2 |\n",
|
||||
"|-----------------------------------------+----------------------+----------------------+\n",
|
||||
"| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |\n",
|
||||
"| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |\n",
|
||||
"| | | MIG M. |\n",
|
||||
"|=========================================+======================+======================|\n",
|
||||
"| 0 NVIDIA L4 Off | 00000000:35:00.0 Off | 0 |\n",
|
||||
"| N/A 36C P0 31W / 72W | 19895MiB / 23034MiB | 0% Default |\n",
|
||||
"| | | N/A |\n",
|
||||
"+-----------------------------------------+----------------------+----------------------+\n",
|
||||
" \n",
|
||||
"+---------------------------------------------------------------------------------------+\n",
|
||||
"| Processes: |\n",
|
||||
"| GPU GI CI PID Type Process name GPU Memory |\n",
|
||||
"| ID ID Usage |\n",
|
||||
"|=======================================================================================|\n",
|
||||
"+---------------------------------------------------------------------------------------+\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# check GPU usage\n",
|
||||
"\n",
|
||||
"!nvidia-smi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RAG using Meta AI Llama-3.2\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<img src=\"./resources/rag_architecture.png\" width=800px>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"from IPython.display import Markdown, display\n",
|
||||
"\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"from llama_index.llms.ollama import Ollama\n",
|
||||
"from llama_index.core import PromptTemplate\n",
|
||||
"from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
|
||||
"from llama_index.core import VectorStoreIndex, ServiceContext, SimpleDirectoryReader, StorageContext\n",
|
||||
"from llama_index.core.postprocessor import SentenceTransformerRerank\n",
|
||||
"from llama_index.vector_stores.qdrant import QdrantVectorStore\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"import qdrant_client"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# allows nested access to the event loop\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# add your documents in this directory, you can drag & drop\n",
|
||||
"input_dir_path = './docs'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"collection_name=\"chat_with_docs\"\n",
|
||||
"\n",
|
||||
"client = qdrant_client.QdrantClient(\n",
|
||||
" host=\"localhost\",\n",
|
||||
" port=6333\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def create_index(documents):\n",
|
||||
" vector_store = QdrantVectorStore(client=client, collection_name=collection_name)\n",
|
||||
" storage_context = StorageContext.from_defaults(vector_store=vector_store)\n",
|
||||
" index = VectorStoreIndex.from_documents(\n",
|
||||
" documents,\n",
|
||||
" storage_context=storage_context,\n",
|
||||
" )\n",
|
||||
" return index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"# setup llm & embedding model and reranker\n",
|
||||
"llm=Ollama(model=\"llama3.2:1b\", request_timeout=120.0)\n",
|
||||
"embed_model = HuggingFaceEmbedding( model_name=\"BAAI/bge-large-en-v1.5\", trust_remote_code=True)\n",
|
||||
"rerank = SentenceTransformerRerank(\n",
|
||||
" model=\"cross-encoder/ms-marco-MiniLM-L-2-v2\", top_n=3\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Parsing nodes: 100%|██████████| 32/32 [00:00<00:00, 369.47it/s]\n",
|
||||
"Generating embeddings: 100%|██████████| 45/45 [00:25<00:00, 1.77it/s]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# load data\n",
|
||||
"loader = SimpleDirectoryReader(\n",
|
||||
" input_dir = input_dir_path,\n",
|
||||
" required_exts=[\".pdf\"],\n",
|
||||
" recursive=True\n",
|
||||
" )\n",
|
||||
"docs = loader.load_data()\n",
|
||||
"\n",
|
||||
"# Creating an index over loaded data\n",
|
||||
"Settings.embed_model = embed_model\n",
|
||||
"try:\n",
|
||||
" index = create_index(docs)\n",
|
||||
" print('Using Qdrant collection')\n",
|
||||
"except:\n",
|
||||
" index = VectorStoreIndex.from_documents(docs, show_progress=True)\n",
|
||||
"\n",
|
||||
"# Create the query engine, where we use a cohere reranker on the fetched nodes\n",
|
||||
"Settings.llm = llm\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10, node_postprocessors=[rerank]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# ====== Customise prompt template ======\n",
|
||||
"qa_prompt_tmpl_str = (\n",
|
||||
"\"Context information is below.\\n\"\n",
|
||||
"\"---------------------\\n\"\n",
|
||||
"\"{context_str}\\n\"\n",
|
||||
"\"---------------------\\n\"\n",
|
||||
"\"Given the context information above I want you to think step by step to answer the query in a crisp manner, incase case you don't know the answer say 'I don't know!'.\\n\"\n",
|
||||
"\"Query: {query_str}\\n\"\n",
|
||||
"\"Answer: \"\n",
|
||||
")\n",
|
||||
"qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)\n",
|
||||
"\n",
|
||||
"query_engine.update_prompts(\n",
|
||||
" {\"response_synthesizer:text_qa_template\": qa_prompt_tmpl}\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Generate the response\n",
|
||||
"response = query_engine.query(\"What exactly is DSPy?\",)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"DSPy stands for \"Deep Semantic Prompting and Parameterized Yield\". It is a programming model developed by Stanford Natural Language Processing Group that translates prompting techniques into parameterized declarative modules, which can be used to build complex natural language processing (NLP) systems. Specifically, DSPy allows users to define natural language signatures, or prompts, using a shorthand notation, and then uses these signatures to abstract and automate the task of prompting large language models, such as those used in transformer-based architectures like GPT-3.5."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"display(Markdown(str(response)))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 284 KiB |
Reference in New Issue
Block a user