chore: import upstream snapshot with attribution
Build Package / build (ubuntu-latest) (push) Failing after 1s
CodeQL / Analyze (python) (push) Failing after 1s
Core Typecheck / core-typecheck (push) Failing after 1s
Linting / lint (push) Failing after 1s
llama-dev tests / test-llama-dev (push) Failing after 1s
Publish Sub-Package to PyPI if Needed / publish_subpackage_if_needed (push) Has been skipped
Sync Docs to Developer Hub / sync-docs (push) Failing after 0s
Build Package / build (windows-latest) (push) Has been cancelled
Build Package / build (ubuntu-latest) (push) Failing after 1s
CodeQL / Analyze (python) (push) Failing after 1s
Core Typecheck / core-typecheck (push) Failing after 1s
Linting / lint (push) Failing after 1s
llama-dev tests / test-llama-dev (push) Failing after 1s
Publish Sub-Package to PyPI if Needed / publish_subpackage_if_needed (push) Has been skipped
Sync Docs to Developer Hub / sync-docs (push) Failing after 0s
Build Package / build (windows-latest) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/drive/1N4agIVU1NTEHaO5mLPa-bGBNpY17AxsO#scrollTo=8n2pDnW7521g\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# AIMon Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%capture\n",
|
||||
"!pip install llama-index\n",
|
||||
"!pip install llama-index-postprocessor-aimon-rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.response.pprint_utils import pprint_response"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"An OpenAI and AIMon API key is required for this notebook. Import the AIMon and OpenAI API keys from Colab Secrets"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# Import Colab Secrets userdata module.\n",
|
||||
"from google.colab import userdata\n",
|
||||
"\n",
|
||||
"os.environ[\"AIMON_API_KEY\"] = userdata.get(\"AIMON_API_KEY\")\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = userdata.get(\"OPENAI_API_KEY\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2025-03-10 18:01:07-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt\n",
|
||||
"Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ...\n",
|
||||
"Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 75042 (73K) [text/plain]\n",
|
||||
"Saving to: ‘data/paul_graham/paul_graham_essay.txt’\n",
|
||||
"\n",
|
||||
"data/paul_graham/pa 100%[===================>] 73.28K --.-KB/s in 0.03s \n",
|
||||
"\n",
|
||||
"2025-03-10 18:01:08 (2.59 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Generate documents and build an index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()\n",
|
||||
"\n",
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(documents=documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Define a task definition for the AIMon reranker and instantiate an instance of the AIMonRerank class. The [task definition](https://docs.aimon.ai/retrieval#task-definition) serves as an explicit instruction to the system, defining what the reranking evaluation should focus on."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from llama_index.postprocessor.aimon_rerank import AIMonRerank\n",
|
||||
"\n",
|
||||
"task_definition = \"Your task is to assess the actions of an individual specified in the user query against the context documents supplied.\"\n",
|
||||
"\n",
|
||||
"aimon_rerank = AIMonRerank(\n",
|
||||
" top_n=2,\n",
|
||||
" api_key=userdata.get(\"AIMON_API_KEY\"),\n",
|
||||
" task_definition=task_definition,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Directly retrieve top 2 most similar nodes (i.e., without using a reranker)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(similarity_top_k=2)\n",
|
||||
"response = query_engine.query(\"What did Sam Altman do in this essay?\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: Sam Altman was asked to become the president of Y\n",
|
||||
"Combinator, initially declined the offer to pursue starting a startup\n",
|
||||
"focused on nuclear reactors, but eventually agreed to take over\n",
|
||||
"starting with the winter 2014 batch.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: 2940ea4a-69ec-4fc4-9dd4-8ed54a9d4f1b\n",
|
||||
"Similarity: 0.8305926707169754\n",
|
||||
"Text: When I was dealing with some urgent problem during YC, there was\n",
|
||||
"about a 60% chance it had to do with HN, and a 40% chance it had do\n",
|
||||
"with everything else combined. [17] As well as HN, I wrote all of\n",
|
||||
"YC's internal software in Arc. But while I continued to work a good\n",
|
||||
"deal in Arc, I gradually stopped working on Arc, partly because I\n",
|
||||
"didn't have t...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: 2f043635-e4ce-4054-92f3-b624fd90ae04\n",
|
||||
"Similarity: 0.8239262662012308\n",
|
||||
"Text: Up till that point YC had been controlled by the original LLC we\n",
|
||||
"four had started. But we wanted YC to last for a long time, and to do\n",
|
||||
"that it couldn't be controlled by the founders. So if Sam said yes,\n",
|
||||
"we'd let him reorganize YC. Robert and I would retire, and Jessica and\n",
|
||||
"Trevor would become ordinary partners. When we asked Sam if he wanted\n",
|
||||
"to...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieve top 10 most relevant nodes, but then rerank with AIMon Reranker"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src=\"https://raw.githubusercontent.com/devvratbhardwaj/images/refs/heads/main/AIMon_Reranker.svg\" alt=\"Diagram depicting working of AIMon reranker\"/>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Explanation of the reranking process:\n",
|
||||
"\n",
|
||||
"The diagram illustrates how a reranker refines document retrieval for a more accurate response.\n",
|
||||
"\n",
|
||||
"1. **Initial Retrieval (Vector DB)**: \n",
|
||||
" - A query is sent to the vector database. \n",
|
||||
" - The system retrieves the **top 10 most relevant records** based on similarity scores (`top_k = 10`). \n",
|
||||
"\n",
|
||||
"2. **Reranking with AIMon**: \n",
|
||||
" - Instead of using only the highest-scoring records directly, these 10 records are reranked using the **AIMon Reranker**. \n",
|
||||
" - The reranker evaluates the documents based on their actual relevance to the query, rather than just raw similarity scores. \n",
|
||||
" - During this step, a **task definition** is applied, serving as an explicit instruction that defines what the reranking evaluation should focus on. \n",
|
||||
" - This ensures that the selected records are not just statistically similar but also **contextually relevant** to the intended task. \n",
|
||||
"\n",
|
||||
"3. **Final Selection (`top_n = 2`)**: \n",
|
||||
" - After reranking, the system selects the **top 2 most contextually relevant records** for response generation. \n",
|
||||
" - The **task definition ensures** that these records align with the query’s intent, leading to a **more precise and informative response**."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total number of batches formed: 1\n",
|
||||
"Processing batch 1/1 with 10 context documents.\n",
|
||||
"Finished processing. Total batches sent to AIMon reranker: 1\n",
|
||||
"Top 2 nodes selected after reranking.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10, node_postprocessors=[aimon_rerank]\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\"What did Sam Altman do in this essay?\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: Sam Altman was asked to become the president of Y\n",
|
||||
"Combinator, initially declined the offer to pursue starting a startup\n",
|
||||
"focused on nuclear reactors, but eventually agreed to take over as\n",
|
||||
"president starting with the winter 2014 batch.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: 2940ea4a-69ec-4fc4-9dd4-8ed54a9d4f1b\n",
|
||||
"Similarity: 0.48260445005911023\n",
|
||||
"Text: When I was dealing with some urgent problem during YC, there was\n",
|
||||
"about a 60% chance it had to do with HN, and a 40% chance it had do\n",
|
||||
"with everything else combined. [17] As well as HN, I wrote all of\n",
|
||||
"YC's internal software in Arc. But while I continued to work a good\n",
|
||||
"deal in Arc, I gradually stopped working on Arc, partly because I\n",
|
||||
"didn't have t...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: 0baaf5af-6e6b-4889-8407-e49d1753980c\n",
|
||||
"Similarity: 0.48151918284717965\n",
|
||||
"Text: As Jessica and I were walking home from dinner on March 11, at\n",
|
||||
"the corner of Garden and Walker streets, these three threads\n",
|
||||
"converged. Screw the VCs who were taking so long to make up their\n",
|
||||
"minds. We'd start our own investment firm and actually implement the\n",
|
||||
"ideas we'd been talking about. I'd fund it, and Jessica could quit her\n",
|
||||
"job and work for ...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Conclusion\n",
|
||||
"\n",
|
||||
"The AIMon reranker, using task definition, shifted retrieval focus from general YC leadership changes to Sam Altman’s specific actions. Initially, high-similarity documents lacked his decision-making details. After reranking, lower-similarity but contextually relevant documents highlighted his reluctance and timeline, ensuring a more accurate, task-aligned response over purely similarity-based retrieval."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/CohereRerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Cohere Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.3.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install llama-index > /dev/null\n",
|
||||
"%pip install llama-index-postprocessor-cohere-rerank > /dev/null"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.response.pprint_utils import pprint_response"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2024-05-09 17:56:26-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt\n",
|
||||
"Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 2606:50c0:8003::154, 2606:50c0:8000::154, 2606:50c0:8002::154, ...\n",
|
||||
"Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|2606:50c0:8003::154|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 75042 (73K) [text/plain]\n",
|
||||
"Saving to: ‘data/paul_graham/paul_graham_essay.txt’\n",
|
||||
"\n",
|
||||
"data/paul_graham/pa 100%[===================>] 73.28K --.-KB/s in 0.009s \n",
|
||||
"\n",
|
||||
"2024-05-09 17:56:26 (7.81 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()\n",
|
||||
"\n",
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(documents=documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieve top 10 most relevant nodes, then filter with Cohere Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from llama_index.postprocessor.cohere_rerank import CohereRerank\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"api_key = os.environ[\"COHERE_API_KEY\"]\n",
|
||||
"cohere_rerank = CohereRerank(api_key=api_key, top_n=2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10,\n",
|
||||
" node_postprocessors=[cohere_rerank],\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: Sam Altman was asked if he wanted to be the president\n",
|
||||
"of Y Combinator. Initially, he declined as he wanted to start a\n",
|
||||
"startup focused on making nuclear reactors. However, after persistent\n",
|
||||
"persuasion, he eventually agreed to become the president of Y\n",
|
||||
"Combinator starting with the winter 2014 batch.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: 7ecf4eb2-215d-45e4-ba08-44d9219c7fa6\n",
|
||||
"Similarity: 0.93033177\n",
|
||||
"Text: When I was dealing with some urgent problem during YC, there was\n",
|
||||
"about a 60% chance it had to do with HN, and a 40% chance it had do\n",
|
||||
"with everything else combined. [17] As well as HN, I wrote all of\n",
|
||||
"YC's internal software in Arc. But while I continued to work a good\n",
|
||||
"deal in Arc, I gradually stopped working on Arc, partly because I\n",
|
||||
"didn't have t...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: 88be17e9-e0a0-49e1-9ff8-f2b7aa7493ed\n",
|
||||
"Similarity: 0.86269903\n",
|
||||
"Text: Up till that point YC had been controlled by the original LLC we\n",
|
||||
"four had started. But we wanted YC to last for a long time, and to do\n",
|
||||
"that it couldn't be controlled by the founders. So if Sam said yes,\n",
|
||||
"we'd let him reorganize YC. Robert and I would retire, and Jessica and\n",
|
||||
"Trevor would become ordinary partners. When we asked Sam if he wanted\n",
|
||||
"to...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Directly retrieve top 2 most similar nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=2,\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Retrieved context is irrelevant and response is hallucinated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: Sam Altman was asked to become the president of Y\n",
|
||||
"Combinator, initially declined the offer to pursue starting a startup\n",
|
||||
"focused on nuclear reactors, but eventually agreed to take over\n",
|
||||
"starting with the winter 2014 batch.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: 7ecf4eb2-215d-45e4-ba08-44d9219c7fa6\n",
|
||||
"Similarity: 0.8308840369082053\n",
|
||||
"Text: When I was dealing with some urgent problem during YC, there was\n",
|
||||
"about a 60% chance it had to do with HN, and a 40% chance it had do\n",
|
||||
"with everything else combined. [17] As well as HN, I wrote all of\n",
|
||||
"YC's internal software in Arc. But while I continued to work a good\n",
|
||||
"deal in Arc, I gradually stopped working on Arc, partly because I\n",
|
||||
"didn't have t...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: 88be17e9-e0a0-49e1-9ff8-f2b7aa7493ed\n",
|
||||
"Similarity: 0.8230144027954406\n",
|
||||
"Text: Up till that point YC had been controlled by the original LLC we\n",
|
||||
"four had started. But we wanted YC to last for a long time, and to do\n",
|
||||
"that it couldn't be controlled by the founders. So if Sam said yes,\n",
|
||||
"we'd let him reorganize YC. Robert and I would retire, and Jessica and\n",
|
||||
"Trevor would become ordinary partners. When we asked Sam if he wanted\n",
|
||||
"to...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,292 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/ColbertRerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Colbert Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"[Colbert](https://github.com/stanford-futuredata/ColBERT): ColBERT is a fast and accurate retrieval model, enabling scalable BERT-based search over large text collections in tens of milliseconds.\n",
|
||||
"\n",
|
||||
"This example shows how we use Colbert-V2 model as a reranker."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index\n",
|
||||
"!pip install llama-index-core\n",
|
||||
"!pip install --quiet transformers torch\n",
|
||||
"!pip install llama-index-embeddings-openai\n",
|
||||
"!pip install llama-index-llms-openai\n",
|
||||
"!pip install llama-index-postprocessor-colbert-rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import (\n",
|
||||
" VectorStoreIndex,\n",
|
||||
" SimpleDirectoryReader,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()\n",
|
||||
"\n",
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(documents=documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieve top 10 most relevant nodes, then filter with Colbert Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.colbert_rerank import ColbertRerank\n",
|
||||
"\n",
|
||||
"colbert_reranker = ColbertRerank(\n",
|
||||
" top_n=5,\n",
|
||||
" model=\"colbert-ir/colbertv2.0\",\n",
|
||||
" tokenizer=\"colbert-ir/colbertv2.0\",\n",
|
||||
" keep_retrieval_score=True,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10,\n",
|
||||
" node_postprocessors=[colbert_reranker],\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"50157136-f221-4468-83e1-44e289f44cd5\n",
|
||||
"When I was dealing with some urgent problem during YC, there was about a 60% chance it had to do with HN, and a 40% chan\n",
|
||||
"reranking score: 0.6470144987106323\n",
|
||||
"retrieval score: 0.8309200279065135\n",
|
||||
"**********\n",
|
||||
"87f0d691-b631-4b21-8123-8f71d383046b\n",
|
||||
"Now that I could write essays again, I wrote a bunch about topics I'd had stacked up. I kept writing essays through 2020\n",
|
||||
"reranking score: 0.6377773284912109\n",
|
||||
"retrieval score: 0.8053000783543145\n",
|
||||
"**********\n",
|
||||
"10234ad9-46b1-4be5-8034-92392ac242ed\n",
|
||||
"It's not that unprestigious types of work are good per se. But when you find yourself drawn to some kind of work despite\n",
|
||||
"reranking score: 0.6301894187927246\n",
|
||||
"retrieval score: 0.7975032272825491\n",
|
||||
"**********\n",
|
||||
"bc269bc4-49c7-4804-8575-cd6db47d70b8\n",
|
||||
"It was as weird as it sounds. I resumed all my old patterns, except now there were doors where there hadn't been. Now wh\n",
|
||||
"reranking score: 0.6282549500465393\n",
|
||||
"retrieval score: 0.8026253284729862\n",
|
||||
"**********\n",
|
||||
"ebd7e351-64fc-4627-8ddd-2681d1ac33f8\n",
|
||||
"As Jessica and I were walking home from dinner on March 11, at the corner of Garden and Walker streets, these three thre\n",
|
||||
"reranking score: 0.6245909929275513\n",
|
||||
"retrieval score: 0.7965812262372882\n",
|
||||
"**********\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for node in response.source_nodes:\n",
|
||||
" print(node.id_)\n",
|
||||
" print(node.node.get_content()[:120])\n",
|
||||
" print(\"reranking score: \", node.score)\n",
|
||||
" print(\"retrieval score: \", node.node.metadata[\"retrieval_score\"])\n",
|
||||
" print(\"**********\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Sam Altman became the second president of Y Combinator after Paul Graham decided to step back from running the organization.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"Which schools did Paul attend?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"6942863e-dfc5-4a99-b642-967b99b71343\n",
|
||||
"I didn't want to drop out of grad school, but how else was I going to get out? I remember when my friend Robert Morris g\n",
|
||||
"reranking score: 0.6333063840866089\n",
|
||||
"retrieval score: 0.7964996889742813\n",
|
||||
"**********\n",
|
||||
"477c5de0-8e05-494e-95cc-e221881fb5c1\n",
|
||||
"What I Worked On\n",
|
||||
"\n",
|
||||
"February 2021\n",
|
||||
"\n",
|
||||
"Before college the two main things I worked on, outside of school, were writing and pro\n",
|
||||
"reranking score: 0.5930159091949463\n",
|
||||
"retrieval score: 0.7771872700578062\n",
|
||||
"**********\n",
|
||||
"0448df5c-7950-483d-bc63-15e9110da3bc\n",
|
||||
"[15] We got 225 applications for the Summer Founders Program, and we were surprised to find that a lot of them were from\n",
|
||||
"reranking score: 0.5160146951675415\n",
|
||||
"retrieval score: 0.7782554326959897\n",
|
||||
"**********\n",
|
||||
"83af8efd-e992-4fd3-ada4-3c4c6f9971a1\n",
|
||||
"Much to my surprise, the time I spent working on this stuff was not wasted after all. After we started Y Combinator, I w\n",
|
||||
"reranking score: 0.5005874633789062\n",
|
||||
"retrieval score: 0.7800375923908894\n",
|
||||
"**********\n",
|
||||
"bc269bc4-49c7-4804-8575-cd6db47d70b8\n",
|
||||
"It was as weird as it sounds. I resumed all my old patterns, except now there were doors where there hadn't been. Now wh\n",
|
||||
"reranking score: 0.4977223873138428\n",
|
||||
"retrieval score: 0.782688582042514\n",
|
||||
"**********\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for node in response.source_nodes:\n",
|
||||
" print(node.id_)\n",
|
||||
" print(node.node.get_content()[:120])\n",
|
||||
" print(\"reranking score: \", node.score)\n",
|
||||
" print(\"retrieval score: \", node.node.metadata[\"retrieval_score\"])\n",
|
||||
" print(\"**********\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Paul attended Cornell University for his graduate studies and later applied to RISD (Rhode Island School of Design) in the US.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,363 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "c9c30403",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/SentenceTransformerRerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cd1f531c-303c-4d19-9a6a-1259def23c07",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Rerank can speed up an LLM query without sacrificing accuracy (and in fact, probably improving it). It does so by pruning away irrelevant nodes from the context."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "2d21a258",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "73807bd4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-embeddings-huggingface\n",
|
||||
"%pip install llama-index-llms-openai\n",
|
||||
"%pip install llama-index-postprocessor-flag-embedding-reranker"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c65114dc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index\n",
|
||||
"!pip install git+https://github.com/FlagOpen/FlagEmbedding.git"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ae5c7d2f-ad2f-4d42-8d05-7441f7d344d9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "caee0963",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2479d058",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8ebc1aa4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"OPENAI_API_KEY = \"sk-\"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2fcb92e6-f1e2-4ba5-9ccb-d69a2c959197",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4fbd38ae-0821-465d-b422-80fd9901213b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.llm = OpenAI(model=\"gpt-3.5-turbo\")\n",
|
||||
"Settings.embed_model = HuggingFaceEmbedding(\n",
|
||||
" model_name=\"BAAI/bge-small-en-v1.5\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "06f4a1c6-7320-4252-89ff-81e15a8eadae",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(documents=documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "85f21b3c-43c6-4fde-b60f-e464ee3e435f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.flag_embedding_reranker import (\n",
|
||||
" FlagEmbeddingReranker,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"rerank = FlagEmbeddingReranker(model=\"BAAI/bge-reranker-large\", top_n=5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4027f9c4-044e-48f5-8231-820e91fab20d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"First, we try with reranking. We time the query to see how long it takes to process the output from the retrieved context."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "51abb86b-43c3-49ad-b262-311b8159fe4e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from time import time"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "740d20ab-cd91-4bc4-ba64-170f23fdadfc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Elapsed: 5.37s\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10, node_postprocessors=[rerank]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"now = time()\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"Which grad schools did the author apply for and why?\",\n",
|
||||
")\n",
|
||||
"print(f\"Elapsed: {round(time() - now, 2)}s\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e07f98ac-df41-445f-a050-66d4a193a603",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The author applied to three grad schools: MIT, Yale, and Harvard. The reason for applying to these schools was because they were renowned for AI at the time and the author wanted to pursue a career in artificial intelligence.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cb808169-b7bb-4ed7-9bf0-c3091afbaf0b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: f7e7f522-40ae-416a-917e-a70e59979105): I didn't want to drop out of grad school, but how else was I going to get out? I remember when my friend Robert Morris got kicked out of Cornell for writing the internet worm of 1988, I was envious...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: df6c6b73-b488-4506-9ab1-ae5e8d499d44): So I looked around to see what I could salvage from the wreckage of my plans, and there was Lisp. I knew from experience that Lisp was interesting for its own sake and not just for its association ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 8ee64ca0-3a8d-49d2-a41d-cbf1e10216fd): [15] We got 225 applications for the Summer Founders Program, and we were surprised to find that a lot of them were from people who'd already graduated, or were about to that spring. Already this S...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: e95b6077-628a-4422-baad-765638cb6978): It was as weird as it sounds. I resumed all my old patterns, except now there were doors where there hadn't been. Now when I was tired of walking, all I had to do was raise my hand, and (unless it ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 6c54f961-c5ff-466e-861a-66f5c1c25e36): I couldn't have put this into words when I was 18. All I knew at the time was that I kept taking philosophy courses and they kept being boring. So I decided to switch to AI.\n",
|
||||
"\n",
|
||||
"AI was in the air in t...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.get_formatted_sources(length=200))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8de93bda-09f1-44cf-87ee-0b249758a28d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next, we try without rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "655f975d-69db-470c-9388-5736b1ca6d0f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Elapsed: 10.35s\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(similarity_top_k=10)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"now = time()\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"Which grad schools did the author apply for and why?\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(f\"Elapsed: {round(time() - now, 2)}s\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b4a57135-9944-4154-a100-22c80cc94a87",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The author applied to three grad schools: MIT, Yale, and Harvard. They chose these schools based on their strong reputations in the field of AI at the time. Additionally, Harvard was appealing because it was where Bill Woods, the inventor of the parser used in the author's SHRDLU clone, was located.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "30d2da74-ec2b-4f8f-90fb-9b0685ded447",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: f7e7f522-40ae-416a-917e-a70e59979105): I didn't want to drop out of grad school, but how else was I going to get out? I remember when my friend Robert Morris got kicked out of Cornell for writing the internet worm of 1988, I was envious...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 6c54f961-c5ff-466e-861a-66f5c1c25e36): I couldn't have put this into words when I was 18. All I knew at the time was that I kept taking philosophy courses and they kept being boring. So I decided to switch to AI.\n",
|
||||
"\n",
|
||||
"AI was in the air in t...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: d258db84-0975-4de0-a19b-752f529d9e5a): What I Worked On\n",
|
||||
"\n",
|
||||
"February 2021\n",
|
||||
"\n",
|
||||
"Before college the two main things I worked on, outside of school, were writing and programming. I didn't write essays. I wrote what beginning writers were supposed...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 04582ebe-239a-432a-9304-611676593c66): It's not that unprestigious types of work are good per se. But when you find yourself drawn to some kind of work despite its current lack of prestige, it's a sign both that there's something real t...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 8ee64ca0-3a8d-49d2-a41d-cbf1e10216fd): [15] We got 225 applications for the Summer Founders Program, and we were surprised to find that a lot of them were from people who'd already graduated, or were about to that spring. Already this S...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: d46b4c41-05f8-4492-b978-0ce1863a0f00): Now that I could write essays again, I wrote a bunch about topics I'd had stacked up. I kept writing essays through 2020, but I also started to think about other things I could work on. How should ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: df6c6b73-b488-4506-9ab1-ae5e8d499d44): So I looked around to see what I could salvage from the wreckage of my plans, and there was Lisp. I knew from experience that Lisp was interesting for its own sake and not just for its association ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: d91c08cf-6f7d-4ac5-8cf0-d8bcba4e77ff): It was missing a lot of things you'd want in a programming language. So these had to be added, and when they were, they weren't defined using McCarthy's original axiomatic approach. That wouldn't h...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: e95b6077-628a-4422-baad-765638cb6978): It was as weird as it sounds. I resumed all my old patterns, except now there were doors where there hadn't been. Now when I was tired of walking, all I had to do was raise my hand, and (unless it ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 027ba923-2307-4e28-8e6b-53be8e4db8ec): But Interleaf still had a few years to live yet. [5]\n",
|
||||
"\n",
|
||||
"Interleaf had done something pretty bold. Inspired by Emacs, they'd added a scripting language, and even made the scripting language a dialect ...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.get_formatted_sources(length=200))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "858826fa-d9a9-45b6-be57-3ec7f25704ce",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"As we can see, the query engine with reranking produced a much more concise output in much lower time (6s v.s. 10s). While both responses were essentially correct, the query engine without reranking included a lot of irrelevant information - a phenomenon we could attribute to \"pollution of the context window\"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/JinaRerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Jina Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index-postprocessor-jinaai-rerank\n",
|
||||
"!pip install llama-index-embeddings-jinaai\n",
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from llama_index.core import (\n",
|
||||
" VectorStoreIndex,\n",
|
||||
" SimpleDirectoryReader,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.embeddings.jinaai import JinaEmbedding\n",
|
||||
"\n",
|
||||
"api_key = os.environ[\"JINA_API_KEY\"]\n",
|
||||
"jina_embeddings = JinaEmbedding(api_key=api_key)\n",
|
||||
"\n",
|
||||
"# load documents\n",
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"url = \"https://niketeam-asset-download.nike.net/catalogs/2024/2024_Nike%20Kids_02_09_24.pdf?cb=09302022\"\n",
|
||||
"response = requests.get(url)\n",
|
||||
"with open(\"Nike_Catalog.pdf\", \"wb\") as f:\n",
|
||||
" f.write(response.content)\n",
|
||||
"reader = SimpleDirectoryReader(input_files=[\"Nike_Catalog.pdf\"])\n",
|
||||
"documents = reader.load_data()\n",
|
||||
"\n",
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents=documents, embed_model=jina_embeddings\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieve top 10 most relevant nodes, without using a reranker"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(similarity_top_k=10)\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What is the best jersey by Nike in terms of fabric?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"56\n",
|
||||
"Sustainable MaterialsNIKE KIDS SOCCER – GOALKEEPER\n",
|
||||
"KIDS NIKE DRY LS US PARK IV GK JERSEY \n",
|
||||
"CJ6073 $42.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 04/01/20\n",
|
||||
"END DATE: 12/31/25\n",
|
||||
"Goal keepers jersey with graphic print on sleeves and across upper back panel, mesh back for breathability, \n",
|
||||
"slim fit with soft hand feel, shoulder seams rolled forward for better graphic visibility, straight seam across \n",
|
||||
"back, mesh back for breathability – gameday graphic print inspired by retro campos gk design . \n",
|
||||
"Body width: 16.3\", Body length: 22\" (size medium).\n",
|
||||
"010 Black/White/(White) 012 Wolf Grey/White/(Black) 702 Volt/White/(Black)\n",
|
||||
"KIDS NIKE DRY PARK III SHORT \n",
|
||||
"BV6866 $20.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 04/01/20\n",
|
||||
"END DATE: 12/31/25\n",
|
||||
"Dri-FIT angled side seam short (slim fit) with soft hand feel updated fit for better mobility/comfort . \n",
|
||||
"Hip width: 16.9\", Inseam length: 7\" (size medium).\n",
|
||||
"010 Black/White/(White) 012 Wolf Grey/Black/(Black) 702 Volt/(Black)\n",
|
||||
"NIKE ACADEMY OTC SOCK (UNISEX) \n",
|
||||
"SX5728 $12.00\n",
|
||||
"Sold in prepacks of 6.\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 93% nylon/6% polyester/1% spandex.\n",
|
||||
"OFFER DATE: 01/01/17\n",
|
||||
"END DATE: 12/31/23\n",
|
||||
"Game day sock with fold-over cuff, articulated foot specific footbed for superior fit and contrast Swoosh \n",
|
||||
"design trademark at ankle. Sold in prepacks of 6.\n",
|
||||
"010 Black/(White) 018 Wolf Grey/(Black) 702 Volt/(Black)\n",
|
||||
"Sustainable Materials 0.8641328028479249\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"NIKE KIDS SOCCER – STOCK42\n",
|
||||
"Sustainable Materials\n",
|
||||
"KIDS NIKE DRI-FIT US SS \n",
|
||||
"CHALLENGE IV JERSEY\n",
|
||||
"DH8368 $42.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 01/01/22\n",
|
||||
"END DATE: 12/31/23\n",
|
||||
"The Nike Dri-FIT Challenge IV Jersey brings subtle style and modern performance to the field. Sweat-\n",
|
||||
"wicking fabric helps keep you dry and comfortable from the first whistle to the last minute.\n",
|
||||
"010 Black/Black/White/(White) 012 Wolf Grey/Wolf Grey/Black/(Black)\n",
|
||||
"100 White/White/White/(Black) 341 Gorge Green/Gorge Green/White/(White)\n",
|
||||
"419 College Navy/College Navy/White/(White) 448 Valor Blue/Valor Blue/White/(White)\n",
|
||||
"480 Game Royal/Game Royal/White/(White) 657 University Red/University Red/White/(White)\n",
|
||||
"692 Team Maroon/Team Maroon/White/(White) 702 Volt/Volt/Black/(Black)\n",
|
||||
"891 Team Orange/Team Orange/Black/(Black)\n",
|
||||
"NEW\n",
|
||||
"KIDS NIKE DRI-FIT CHALLENGE V JERSEY \n",
|
||||
"SS US\n",
|
||||
"FD7427 $47.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 01/01/24\n",
|
||||
"END DATE: 12/31/25\n",
|
||||
"The Nike Dri-FIT Challenge Jersey V is designed to keep your players cool and comfortable through 90 \n",
|
||||
"minutes and beyond. Mesh on the back and side panels offer breathability where athletes need it most. \n",
|
||||
"Body and sleeves are a Nike Dri-FIT knit fabric that moves sweat away to help keep players dry. This top \n",
|
||||
"is made with 100% recycled material. Side panel construction uses a more efficient pattern to help reduce \n",
|
||||
"material waste. Slim fit for a tailored look and feel.\n",
|
||||
"010 Black/White/(White) 012 Wolf Grey/Black/(Black) 100 White/Black/(Black)\n",
|
||||
"341 Gorge Green/White/(White) 419 College Navy/White/(White) 448 Valor Blue/White/(White)\n",
|
||||
"480 Game Royal/White/(White) 657 University Red/White/(White) 692 Team Maroon/White/(White)\n",
|
||||
"702 Volt/Black/(Black) 891 Team Orange/Black/(Black)\n",
|
||||
"BACK VIEW 0.863721033128725\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.source_nodes[0].text, response.source_nodes[0].score)\n",
|
||||
"print(\"\\n\")\n",
|
||||
"print(response.source_nodes[1].text, response.source_nodes[1].score)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieve top 10 most relevant nodes, but then rerank using Jina Reranker"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"By employing a reranker model, the prompt can be given more relevant context. This will lead to a more accurate response by the LLM."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from llama_index.postprocessor.jinaai_rerank import JinaRerank\n",
|
||||
"\n",
|
||||
"jina_rerank = JinaRerank(api_key=api_key, top_n=2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10, node_postprocessors=[jina_rerank]\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What is the best jersey by Nike in terms of fabric?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"NIKE KIDS SOCCER – STOCK41Sustainable Materials\n",
|
||||
"Sustainable Materials\n",
|
||||
"KIDS DRI-FIT ADV VAPOR IV JERSEY US SS\n",
|
||||
"DR0837 $77.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 01/01/23\n",
|
||||
"END DATE: 12/31/24\n",
|
||||
"Step on to the field ready for fast-paced play in the Nike Dri-FIT ADV Vapor Jersey. Engineered for \n",
|
||||
"optimal breathability, its moisture-wicking design helps keep you dry and cool under match-day pressure. \n",
|
||||
"Lightweight fabric in a relaxed, easy fit combats cling so you can focus on being the first to the ball. Lower \n",
|
||||
"insets line up perfectly with design details on the Nike Dri-FIT ADV Vapor IV Shorts to create an on-field \n",
|
||||
"look worthy of pro-level play. \n",
|
||||
"010 Black/Black/Black/(White) 100 White/White/White/(Black)\n",
|
||||
"419 College Navy/College Navy/Game Royal/(White) 480 Game Royal/Game Royal/College Navy/(White)\n",
|
||||
"657 University Red/University Red/Bright Crimson/(White)\n",
|
||||
"BACK VIEW\n",
|
||||
"GRAPHIC KNIT DETAIL\n",
|
||||
"KIDS NIKE DRI-FIT US SS STRIKE III JERSEY\n",
|
||||
"DR0913 $50.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 01/01/23\n",
|
||||
"END DATE: 12/31/24\n",
|
||||
"Take the field in match-ready style in the lightweight Nike Strike Jersey. A relaxed, easy fit ensures that \n",
|
||||
"nothing comes between you and the ball, and sweat-wicking fabric works with breathable mesh to help \n",
|
||||
"keep you cool and composed during fast-paced play. Ribbed insets stretch with you to let you move without \n",
|
||||
"restrictions. Embroidered Swoosh design trademark. \n",
|
||||
"010 Black/Black/Black/(White) 011 Black/Volt/Volt/(White)\n",
|
||||
"012 Wolf Grey/Black/Black/(White) 100 White/White/White/(Black)\n",
|
||||
"419 College Navy/College Navy/Game Royal/(White) 448 Valor Blue/College Navy/College Navy/(White)\n",
|
||||
"480 Game Royal/College Navy/College Navy/(White) 657 University Red/Bright Crimson/Bright Crimson/(White)\n",
|
||||
"GRAPHIC KNIT DETAIL 0.3603765070438385\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"NIKE KIDS SOCCER – STOCK45\n",
|
||||
"Sustainable MaterialsKIDS NIKE DRI-FIT US LS TIEMPO\n",
|
||||
"PREMIER II JERSEY\n",
|
||||
"DH8407 $32.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 01/01/22\n",
|
||||
"END DATE: 12/31/26\n",
|
||||
"The Nike Dri-FIT Tiempo Premier II Jersey brings you the cool performance of sweat-wicking fabric and a \n",
|
||||
"mesh back panel kick in when the game heats up.\n",
|
||||
"010 Black/White/(White) 100 White/White/(Black) 419 College Navy/White/(White)\n",
|
||||
"480 Game Royal/White/(White) 657 University Red/White/(White)\n",
|
||||
"KIDS NIKE DRI-FIT US SS TIEMPO\n",
|
||||
"PREMIER II JERSEY\n",
|
||||
"DH8390 $27.00\n",
|
||||
"SIZES: XS, S, M, L, XL\n",
|
||||
"FABRIC: 100% polyester.\n",
|
||||
"OFFER DATE: 01/01/22\n",
|
||||
"END DATE: 12/31/26\n",
|
||||
"The Nike Dri-FIT Tiempo Premier II Jersey brings you the cool performance of sweat-wicking fabric and a \n",
|
||||
"mesh back panel kick in when the game heats up.\n",
|
||||
"010 Black/White/(White) 012 Wolf Grey/Black/(Black) 100 White/White/(Black)\n",
|
||||
"341 Gorge Green/White/(White) 419 College Navy/White/(White) 448 Valor Blue/White/(White)\n",
|
||||
"480 Game Royal/White/(White) 547 Court Purple/White/(White) 616 Vivid Pink/Black/(Black)\n",
|
||||
"657 University Red/White/(White) 692 Team Maroon/White/(White) 702 Volt/Black/(Black)\n",
|
||||
"891 Team Orange/Black/(Black)\n",
|
||||
"Sustainable Materials 0.35767972469329834\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.source_nodes[0].text, response.source_nodes[0].score)\n",
|
||||
"print(\"\\n\")\n",
|
||||
"print(response.source_nodes[1].text, response.source_nodes[1].score)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,638 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "f1b23ffc-22d8-4414-b2e4-66d45a03523d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LLM Reranker Demonstration (Great Gatsby)\n",
|
||||
"\n",
|
||||
"This tutorial showcases how to do a two-stage pass for retrieval. Use embedding-based retrieval with a high top-k value\n",
|
||||
"in order to maximize recall and get a large set of candidate items. Then, use LLM-based retrieval\n",
|
||||
"to dynamically select the nodes that are actually relevant to the query."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1bd392e1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-llms-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ab68a3ee-f4c1-4830-856a-9c37f7a42364",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8c16404b-db81-4ee6-9c0f-cc4cdf3cb147",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import logging\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
|
||||
"logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))\n",
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import LLMRerank\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from IPython.display import Markdown, display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "8a5b0ac6-ec9c-40e1-9120-d20e33c37f80",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data, Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b785b75a-cf4d-4799-8fd2-970e5c39727c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"# LLM (gpt-3.5-turbo)\n",
|
||||
"Settings.llm = OpenAI(temperature=0, model=\"gpt-3.5-turbo\")\n",
|
||||
"Settings.chunk_size = 512"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9b689e92-fc55-48b5-859f-2a2c1394c872",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"../../../examples/gatsby/data\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1a01180d-67c8-4664-a4ee-ceab1367cb78",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"documents"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d8555b6d-5289-4803-bced-6b2f85dea3da",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total embedding token usage: 49266 tokens\n",
|
||||
"> [build_index_from_nodes] Total embedding token usage: 49266 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "805847d9-a2c1-4930-98a9-98126e730000",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Retrieval"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ace86835-832e-4964-a025-428891aa2c8b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/1r/c3h91d9s49xblwfvz79s78_c0000gn/T/ipykernel_44297/3519340226.py:7: FutureWarning: Passing a negative integer is deprecated in version 1.0 and will not be supported in future version. Instead, use None to not limit the column width.\n",
|
||||
" pd.set_option('display.max_colwidth', -1)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.retrievers import VectorIndexRetriever\n",
|
||||
"from llama_index.core import QueryBundle\n",
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"pd.set_option(\"display.max_colwidth\", -1)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_retrieved_nodes(\n",
|
||||
" query_str, vector_top_k=10, reranker_top_n=3, with_reranker=False\n",
|
||||
"):\n",
|
||||
" query_bundle = QueryBundle(query_str)\n",
|
||||
" # configure retriever\n",
|
||||
" retriever = VectorIndexRetriever(\n",
|
||||
" index=index,\n",
|
||||
" similarity_top_k=vector_top_k,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = retriever.retrieve(query_bundle)\n",
|
||||
"\n",
|
||||
" if with_reranker:\n",
|
||||
" # configure reranker\n",
|
||||
" reranker = LLMRerank(\n",
|
||||
" choice_batch_size=5,\n",
|
||||
" top_n=reranker_top_n,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = reranker.postprocess_nodes(\n",
|
||||
" retrieved_nodes, query_bundle\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return retrieved_nodes\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def pretty_print(df):\n",
|
||||
" return display(HTML(df.to_html().replace(\"\\\\n\", \"<br>\")))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def visualize_retrieved_nodes(nodes) -> None:\n",
|
||||
" result_dicts = []\n",
|
||||
" for node in nodes:\n",
|
||||
" result_dict = {\"Score\": node.score, \"Text\": node.node.get_text()}\n",
|
||||
" result_dicts.append(result_dict)\n",
|
||||
"\n",
|
||||
" pretty_print(pd.DataFrame(result_dicts))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "20993200-b725-403e-8a79-e2571dab2ebc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total embedding token usage: 10 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 10 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Who was driving the car that hit Myrtle?\",\n",
|
||||
" vector_top_k=3,\n",
|
||||
" with_reranker=False,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9dd3bc25-6ef1-46b7-869e-247c83af9d4d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.828844</td>\n",
|
||||
" <td>and some garrulous man telling over and over what<br>had happened, until it became less and less real even to him and he<br>could tell it no longer, and Myrtle Wilson’s tragic achievement was<br>forgotten. Now I want to go back a little and tell what happened at<br>the garage after we left there the night before.<br><br>They had difficulty in locating the sister, Catherine. She must have<br>broken her rule against drinking that night, for when she arrived she<br>was stupid with liquor and unable to understand that the ambulance had<br>already gone to Flushing. When they convinced her of this, she<br>immediately fainted, as if that was the intolerable part of the<br>affair. Someone, kind or curious, took her in his car and drove her in<br>the wake of her sister’s body.<br><br>Until long after midnight a changing crowd lapped up against the front<br>of the garage, while George Wilson rocked himself back and forth on<br>the couch inside. For a while the door of the office was open, and<br>everyone who came into the garage glanced irresistibly through it.<br>Finally someone said it was a shame, and closed the door. Michaelis<br>and several other men were with him; first, four or five men, later<br>two or three men. Still later Michaelis had to ask the last stranger<br>to wait there fifteen minutes longer, while he went back to his own<br>place and made a pot of coffee. After that, he stayed there alone with<br>Wilson until dawn.<br><br>About three o’clock the quality of Wilson’s incoherent muttering<br>changed—he grew quieter and began to talk about the yellow car. He<br>announced that he had a way of finding out whom the yellow car<br>belonged to, and then he blurted out that a couple of months ago his<br>wife had come from the city with her face bruised and her nose<br>swollen.<br><br>But when he heard himself say this, he flinched and began to cry “Oh,<br>my God!” again in his groaning voice. Michaelis made a clumsy</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.827754</td>\n",
|
||||
" <td>she rushed out into the dusk, waving her hands and<br>shouting—before he could move from his door the business was over.<br><br>The “death car” as the newspapers called it, didn’t stop; it came out<br>of the gathering darkness, wavered tragically for a moment, and then<br>disappeared around the next bend. Mavro Michaelis wasn’t even sure of<br>its colour—he told the first policeman that it was light green. The<br>other car, the one going toward New York, came to rest a hundred yards<br>beyond, and its driver hurried back to where Myrtle Wilson, her life<br>violently extinguished, knelt in the road and mingled her thick dark<br>blood with the dust.<br><br>Michaelis and this man reached her first, but when they had torn open<br>her shirtwaist, still damp with perspiration, they saw that her left<br>breast was swinging loose like a flap, and there was no need to listen<br>for the heart beneath. The mouth was wide open and ripped a little at<br>the corners, as though she had choked a little in giving up the<br>tremendous vitality she had stored so long.<br><br>------------------------------------------------------------------------<br><br>We saw the three or four automobiles and the crowd when we were still<br>some distance away.<br><br>“Wreck!” said Tom. “That’s good. Wilson’ll have a little business at<br>last.”<br><br>He slowed down, but still without any intention of stopping, until, as<br>we came nearer, the hushed, intent faces of the people at the garage<br>door made him automatically put on the brakes.<br><br>“We’ll take a look,” he said doubtfully, “just a look.”<br><br>I became aware now of a hollow, wailing sound which issued incessantly<br>from the garage, a sound which as we got out of the coupé and walked<br>toward the door resolved itself into the words “Oh, my God!” uttered<br>over and over in a gasping</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.826390</td>\n",
|
||||
" <td>went on, “and left the car in<br>my garage. I don’t think anybody saw us, but of course I can’t be<br>sure.”<br><br>I disliked him so much by this time that I didn’t find it necessary to<br>tell him he was wrong.<br><br>“Who was the woman?” he inquired.<br><br>“Her name was Wilson. Her husband owns the garage. How the devil did<br>it happen?”<br><br>“Well, I tried to swing the wheel—” He broke off, and suddenly I<br>guessed at the truth.<br><br>“Was Daisy driving?”<br><br>“Yes,” he said after a moment, “but of course I’ll say I was. You see,<br>when we left New York she was very nervous and she thought it would<br>steady her to drive—and this woman rushed out at us just as we were<br>passing a car coming the other way. It all happened in a minute, but<br>it seemed to me that she wanted to speak to us, thought we were<br>somebody she knew. Well, first Daisy turned away from the woman toward<br>the other car, and then she lost her nerve and turned back. The second<br>my hand reached the wheel I felt the shock—it must have killed her<br>instantly.”<br><br>“It ripped her open—”<br><br>“Don’t tell me, old sport.” He winced. “Anyhow—Daisy stepped on it. I<br>tried to make her stop, but she couldn’t, so I pulled on the emergency<br>brake. Then she fell over into my lap and I drove on.<br><br>“She’ll be all right tomorrow,” he said presently. “I’m just going to<br>wait here and see if he tries to bother her about that unpleasantness<br>this afternoon. She’s locked herself into her room, and if he tries<br>any brutality she’s going to turn the light out and on again.”<br><br>“He won’t touch</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0ad7d62b-dba9-45d5-896f-4baa9a40edba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Who was driving the car that hit Myrtle?\",\n",
|
||||
" vector_top_k=10,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ae22d297-dd3b-4a71-a890-faceafab4e1a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>went on, “and left the car in<br>my garage. I don’t think anybody saw us, but of course I can’t be<br>sure.”<br><br>I disliked him so much by this time that I didn’t find it necessary to<br>tell him he was wrong.<br><br>“Who was the woman?” he inquired.<br><br>“Her name was Wilson. Her husband owns the garage. How the devil did<br>it happen?”<br><br>“Well, I tried to swing the wheel—” He broke off, and suddenly I<br>guessed at the truth.<br><br>“Was Daisy driving?”<br><br>“Yes,” he said after a moment, “but of course I’ll say I was. You see,<br>when we left New York she was very nervous and she thought it would<br>steady her to drive—and this woman rushed out at us just as we were<br>passing a car coming the other way. It all happened in a minute, but<br>it seemed to me that she wanted to speak to us, thought we were<br>somebody she knew. Well, first Daisy turned away from the woman toward<br>the other car, and then she lost her nerve and turned back. The second<br>my hand reached the wheel I felt the shock—it must have killed her<br>instantly.”<br><br>“It ripped her open—”<br><br>“Don’t tell me, old sport.” He winced. “Anyhow—Daisy stepped on it. I<br>tried to make her stop, but she couldn’t, so I pulled on the emergency<br>brake. Then she fell over into my lap and I drove on.<br><br>“She’ll be all right tomorrow,” he said presently. “I’m just going to<br>wait here and see if he tries to bother her about that unpleasantness<br>this afternoon. She’s locked herself into her room, and if he tries<br>any brutality she’s going to turn the light out and on again.”<br><br>“He won’t touch</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4e540fb6-189f-4a54-98d6-852e561f39ee",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total embedding token usage: 14 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 14 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What did Gatsby want Daisy to do in front of Tom?\",\n",
|
||||
" vector_top_k=3,\n",
|
||||
" with_reranker=False,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3b82380c-e29f-4e9e-a46d-038ca1469904",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"****Score****: 0.8647796939111776\n",
|
||||
"****Node text****\n",
|
||||
": got to make your house into a pigsty in order to have any\n",
|
||||
"friends—in the modern world.”\n",
|
||||
"\n",
|
||||
"Angry as I was, as we all were, I was tempted to laugh whenever he\n",
|
||||
"opened his mouth. The transition from libertine to prig was so\n",
|
||||
"complete.\n",
|
||||
"\n",
|
||||
"“I’ve got something to tell you, old sport—” began Gatsby. But Daisy\n",
|
||||
"guessed at his intention.\n",
|
||||
"\n",
|
||||
"“Please don’t!” she interrupted helplessly. “Please let’s all go\n",
|
||||
"home. Why don’t we all go home?”\n",
|
||||
"\n",
|
||||
"“That’s a good idea,” I got up. “Come on, Tom. Nobody wants a drink.”\n",
|
||||
"\n",
|
||||
"“I want to know what Mr. Gatsby has to tell me.”\n",
|
||||
"\n",
|
||||
"“Your wife doesn’t love you,” said Gatsby. “She’s never loved you.\n",
|
||||
"She loves me.”\n",
|
||||
"\n",
|
||||
"“You must be crazy!” exclaimed Tom automatically.\n",
|
||||
"\n",
|
||||
"Gatsby sprang to his feet, vivid with excitement.\n",
|
||||
"\n",
|
||||
"“She never loved you, do you hear?” he cried. “She only married you\n",
|
||||
"because I was poor and she was tired of waiting for me. It was a\n",
|
||||
"terrible mistake, but in her heart she never loved anyone except me!”\n",
|
||||
"\n",
|
||||
"At this point Jordan and I tried to go, but Tom and Gatsby insisted\n",
|
||||
"with competitive firmness that we remain—as though neither of them had\n",
|
||||
"anything to conceal and it would be a privilege to partake vicariously\n",
|
||||
"of their emotions.\n",
|
||||
"\n",
|
||||
"“Sit down, Daisy,” Tom’s voice groped unsuccessfully for the paternal\n",
|
||||
"note. “What’s been going on? I want to hear all about it.”\n",
|
||||
"\n",
|
||||
"“I told you what’s been going on,” said Gatsby. “Going on for five\n",
|
||||
"years—and you didn’t know.”\n",
|
||||
"\n",
|
||||
"Tom turned to Daisy\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"****Score****: 0.8609230717744326\n",
|
||||
"****Node text****\n",
|
||||
": to keep your\n",
|
||||
"shoes dry?” There was a husky tenderness in his tone … “Daisy?”\n",
|
||||
"\n",
|
||||
"“Please don’t.” Her voice was cold, but the rancour was gone from it.\n",
|
||||
"She looked at Gatsby. “There, Jay,” she said—but her hand as she tried\n",
|
||||
"to light a cigarette was trembling. Suddenly she threw the cigarette\n",
|
||||
"and the burning match on the carpet.\n",
|
||||
"\n",
|
||||
"“Oh, you want too much!” she cried to Gatsby. “I love you now—isn’t\n",
|
||||
"that enough? I can’t help what’s past.” She began to sob\n",
|
||||
"helplessly. “I did love him once—but I loved you too.”\n",
|
||||
"\n",
|
||||
"Gatsby’s eyes opened and closed.\n",
|
||||
"\n",
|
||||
"“You loved me too?” he repeated.\n",
|
||||
"\n",
|
||||
"“Even that’s a lie,” said Tom savagely. “She didn’t know you were\n",
|
||||
"alive. Why—there’s things between Daisy and me that you’ll never know,\n",
|
||||
"things that neither of us can ever forget.”\n",
|
||||
"\n",
|
||||
"The words seemed to bite physically into Gatsby.\n",
|
||||
"\n",
|
||||
"“I want to speak to Daisy alone,” he insisted. “She’s all excited\n",
|
||||
"now—”\n",
|
||||
"\n",
|
||||
"“Even alone I can’t say I never loved Tom,” she admitted in a pitiful\n",
|
||||
"voice. “It wouldn’t be true.”\n",
|
||||
"\n",
|
||||
"“Of course it wouldn’t,” agreed Tom.\n",
|
||||
"\n",
|
||||
"She turned to her husband.\n",
|
||||
"\n",
|
||||
"“As if it mattered to you,” she said.\n",
|
||||
"\n",
|
||||
"“Of course it matters. I’m going to take better care of you from now\n",
|
||||
"on.”\n",
|
||||
"\n",
|
||||
"“You don’t understand,” said Gatsby, with a touch of panic. “You’re\n",
|
||||
"not going to take care of her any more.”\n",
|
||||
"\n",
|
||||
"“I’m not?” Tom opened his eyes wide and\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"****Score****: 0.8555028907426916\n",
|
||||
"****Node text****\n",
|
||||
": shadowed well with awnings, was dark and cool. Daisy and\n",
|
||||
"Jordan lay upon an enormous couch, like silver idols weighing down\n",
|
||||
"their own white dresses against the singing breeze of the fans.\n",
|
||||
"\n",
|
||||
"“We can’t move,” they said together.\n",
|
||||
"\n",
|
||||
"Jordan’s fingers, powdered white over their tan, rested for a moment\n",
|
||||
"in mine.\n",
|
||||
"\n",
|
||||
"“And Mr. Thomas Buchanan, the athlete?” I inquired.\n",
|
||||
"\n",
|
||||
"Simultaneously I heard his voice, gruff, muffled, husky, at the hall\n",
|
||||
"telephone.\n",
|
||||
"\n",
|
||||
"Gatsby stood in the centre of the crimson carpet and gazed around with\n",
|
||||
"fascinated eyes. Daisy watched him and laughed, her sweet, exciting\n",
|
||||
"laugh; a tiny gust of powder rose from her bosom into the air.\n",
|
||||
"\n",
|
||||
"“The rumour is,” whispered Jordan, “that that’s Tom’s girl on the\n",
|
||||
"telephone.”\n",
|
||||
"\n",
|
||||
"We were silent. The voice in the hall rose high with annoyance: “Very\n",
|
||||
"well, then, I won’t sell you the car at all … I’m under no obligations\n",
|
||||
"to you at all … and as for your bothering me about it at lunch time, I\n",
|
||||
"won’t stand that at all!”\n",
|
||||
"\n",
|
||||
"“Holding down the receiver,” said Daisy cynically.\n",
|
||||
"\n",
|
||||
"“No, he’s not,” I assured her. “It’s a bona-fide deal. I happen to\n",
|
||||
"know about it.”\n",
|
||||
"\n",
|
||||
"Tom flung open the door, blocked out its space for a moment with his\n",
|
||||
"thick body, and hurried into the room.\n",
|
||||
"\n",
|
||||
"“Mr. Gatsby!” He put out his broad, flat hand with well-concealed\n",
|
||||
"dislike. “I’m glad to see you, sir … Nick …”\n",
|
||||
"\n",
|
||||
"“Make us a cold drink,” cried Daisy.\n",
|
||||
"\n",
|
||||
"As he left the room again she got up and went over to Gatsby and\n",
|
||||
"pulled his face\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "aec75734-52e4-4b7e-9b6d-d0b7306ae5d8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total embedding token usage: 14 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 14 tokens\n",
|
||||
"Doc: 2, Relevance: 10\n",
|
||||
"No relevant documents found. Please provide a different question.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What did Gatsby want Daisy to do in front of Tom?\",\n",
|
||||
" vector_top_k=10,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "89e5408e-bf4b-483f-9144-fc5ac4fb48e8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"****Score****: 10.0\n",
|
||||
"****Node text****\n",
|
||||
": to keep your\n",
|
||||
"shoes dry?” There was a husky tenderness in his tone … “Daisy?”\n",
|
||||
"\n",
|
||||
"“Please don’t.” Her voice was cold, but the rancour was gone from it.\n",
|
||||
"She looked at Gatsby. “There, Jay,” she said—but her hand as she tried\n",
|
||||
"to light a cigarette was trembling. Suddenly she threw the cigarette\n",
|
||||
"and the burning match on the carpet.\n",
|
||||
"\n",
|
||||
"“Oh, you want too much!” she cried to Gatsby. “I love you now—isn’t\n",
|
||||
"that enough? I can’t help what’s past.” She began to sob\n",
|
||||
"helplessly. “I did love him once—but I loved you too.”\n",
|
||||
"\n",
|
||||
"Gatsby’s eyes opened and closed.\n",
|
||||
"\n",
|
||||
"“You loved me too?” he repeated.\n",
|
||||
"\n",
|
||||
"“Even that’s a lie,” said Tom savagely. “She didn’t know you were\n",
|
||||
"alive. Why—there’s things between Daisy and me that you’ll never know,\n",
|
||||
"things that neither of us can ever forget.”\n",
|
||||
"\n",
|
||||
"The words seemed to bite physically into Gatsby.\n",
|
||||
"\n",
|
||||
"“I want to speak to Daisy alone,” he insisted. “She’s all excited\n",
|
||||
"now—”\n",
|
||||
"\n",
|
||||
"“Even alone I can’t say I never loved Tom,” she admitted in a pitiful\n",
|
||||
"voice. “It wouldn’t be true.”\n",
|
||||
"\n",
|
||||
"“Of course it wouldn’t,” agreed Tom.\n",
|
||||
"\n",
|
||||
"She turned to her husband.\n",
|
||||
"\n",
|
||||
"“As if it mattered to you,” she said.\n",
|
||||
"\n",
|
||||
"“Of course it matters. I’m going to take better care of you from now\n",
|
||||
"on.”\n",
|
||||
"\n",
|
||||
"“You don’t understand,” said Gatsby, with a touch of panic. “You’re\n",
|
||||
"not going to take care of her any more.”\n",
|
||||
"\n",
|
||||
"“I’m not?” Tom opened his eyes wide and\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "23dcdac6-f4dd-469e-9f47-d030f27bacda",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Query Engine"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "94f6531d-953a-41c6-9bcc-9c293550f8c4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10,\n",
|
||||
" node_postprocessors=[\n",
|
||||
" LLMRerank(\n",
|
||||
" choice_batch_size=5,\n",
|
||||
" top_n=2,\n",
|
||||
" )\n",
|
||||
" ],\n",
|
||||
" response_mode=\"tree_summarize\",\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do during his time at Y Combinator?\",\n",
|
||||
")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_index_v2",
|
||||
"language": "python",
|
||||
"name": "llama_index_v2"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "93e3f84f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/LLMReranker-Lyft-10k.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "11b52622-f38a-4b3a-a916-c73619babb48",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LLM Reranker Demonstration (2021 Lyft 10-k)\n",
|
||||
"\n",
|
||||
"This tutorial showcases how to do a two-stage pass for retrieval. Use embedding-based retrieval with a high top-k value\n",
|
||||
"in order to maximize recall and get a large set of candidate items. Then, use LLM-based retrieval\n",
|
||||
"to dynamically select the nodes that are actually relevant to the query."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e66e4c0c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-llms-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "91b61e96-864c-4ed2-80d6-0ebfdbb57d5c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f630346f-fedd-40f2-8fb3-e052e219a873",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import logging\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
|
||||
"logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))\n",
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import LLMRerank\n",
|
||||
"\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from IPython.display import Markdown, display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "231c4418",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "36f2294f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mkdir -p 'data/10k/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/lyft_2021.pdf' -O 'data/10k/lyft_2021.pdf'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "8a8fdeb2-939c-49dd-b8e6-0139d53a4fb6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data, Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ee132733-b525-4aaf-81db-7eed19ded815",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"# LLM (gpt-3.5-turbo)\n",
|
||||
"Settings.llm = OpenAI(temperature=0, model=\"gpt-3.5-turbo\")\n",
|
||||
"\n",
|
||||
"Settings.chunk_overlap = 0\n",
|
||||
"Settings.chunk_size = 128"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "88344ea2-540c-4b46-8a66-ed78870cb80a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\n",
|
||||
" input_files=[\"./data/10k/lyft_2021.pdf\"]\n",
|
||||
").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d478f416-8e85-49ae-9817-e4d78122a120",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total embedding token usage: 226241 tokens\n",
|
||||
"> [build_index_from_nodes] Total embedding token usage: 226241 tokens\n",
|
||||
"> [build_index_from_nodes] Total embedding token usage: 226241 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "7e3d5f23-dfcd-458d-a9d3-dd66de0ab054",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Retrieval Comparisons"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "47480c6d-8914-4562-a789-fd53a99a7afb",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/1r/c3h91d9s49xblwfvz79s78_c0000gn/T/ipykernel_58458/2502541873.py:8: FutureWarning: Passing a negative integer is deprecated in version 1.0 and will not be supported in future version. Instead, use None to not limit the column width.\n",
|
||||
" pd.set_option('display.max_colwidth', -1)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.retrievers import VectorIndexRetriever\n",
|
||||
"from llama_index.core import QueryBundle\n",
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"from copy import deepcopy\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"pd.set_option(\"display.max_colwidth\", -1)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_retrieved_nodes(\n",
|
||||
" query_str, vector_top_k=10, reranker_top_n=3, with_reranker=False\n",
|
||||
"):\n",
|
||||
" query_bundle = QueryBundle(query_str)\n",
|
||||
" # configure retriever\n",
|
||||
" retriever = VectorIndexRetriever(\n",
|
||||
" index=index,\n",
|
||||
" similarity_top_k=vector_top_k,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = retriever.retrieve(query_bundle)\n",
|
||||
"\n",
|
||||
" if with_reranker:\n",
|
||||
" # configure reranker\n",
|
||||
" reranker = LLMRerank(\n",
|
||||
" choice_batch_size=5,\n",
|
||||
" top_n=reranker_top_n,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = reranker.postprocess_nodes(\n",
|
||||
" retrieved_nodes, query_bundle\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return retrieved_nodes\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def pretty_print(df):\n",
|
||||
" return display(HTML(df.to_html().replace(\"\\\\n\", \"<br>\")))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def visualize_retrieved_nodes(nodes) -> None:\n",
|
||||
" result_dicts = []\n",
|
||||
" for node in nodes:\n",
|
||||
" node = deepcopy(node)\n",
|
||||
" node.node.metadata = None\n",
|
||||
" node_text = node.node.get_text()\n",
|
||||
" node_text = node_text.replace(\"\\n\", \" \")\n",
|
||||
"\n",
|
||||
" result_dict = {\"Score\": node.score, \"Text\": node_text}\n",
|
||||
" result_dicts.append(result_dict)\n",
|
||||
"\n",
|
||||
" pretty_print(pd.DataFrame(result_dicts))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b8bedc4f-444b-4233-9b72-728e3cfbe056",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What is Lyft's response to COVID-19?\", vector_top_k=5, with_reranker=False\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e85e656b-9377-4640-a10d-a6655afd82bd",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.863554</td>\n",
|
||||
" <td>Rentals. Further, COVID-19 has and may continue to negatively impact Lyft’s ability to conduct rental operationsthrough the Express Drive program and Lyft Rentals as a result of restrictions on travel, mandated closures, limited staffing availability, and other factors relatedto COVID-19. For example, in 2020, Lyft Rentals temporarily ceased operations, closing its rental locations, as a result of COVID-19. Further, while ExpressDrive rental periods</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.854175</td>\n",
|
||||
" <td>pandemic, including sales, marketing and costs relating to our efforts to mitigate the impact of the COVID-19 pandemic. Furthermore, we have expanded overtime to include more asset-intensive offerings such as our network of Light Vehicles, Flexdrive, Lyft Rentals and Lyft Auto Care. We are also expanding the supportavailable to drivers at our Driver Hubs, our driver-centric service centers and community spaces, Driver Centers, our vehicle service centers, Mobile Services,</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.852866</td>\n",
|
||||
" <td>requested to quarantine by a medical professional, which it continues to do at this time. Further, Lyft Rentals and Flexdrive have facedsignificantly higher cos ts in transporting, repossessing, cleaning, and17</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>0.847151</td>\n",
|
||||
" <td>the transport ation needs of customers, employees and other constituents.• Grow Active Riders. We see opportunities to continue to recoup and grow our rider base amid the continuing COVID-19 pandemic. We may make incrementalinvestments in our brand and in growth marketing to maintain and drive increasing consumer preference for Lyft. We may also offer discounts for first-time ridersto try Lyft or provide incentives to existing riders to encourage increased ride frequency. We</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>0.841177</td>\n",
|
||||
" <td>day one, we have worked continuousl y to enhance the safety of our platform and the ridesharing industry by developing innovative products, policiesand processes. Business Lyft is evolving how businesses large and small take care of their people’s transportation needs across sectors including corporate, healthcare, auto, education andgovernment. Our comprehensive set of solutions allows clients to design, manage and pay for ground</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8ba150e2-c4e7-4404-b8e1-1603c2b346d3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 11 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What is Lyft's response to COVID-19?\",\n",
|
||||
" vector_top_k=20,\n",
|
||||
" reranker_top_n=5,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7541606f-6424-470b-987c-a986ac0a7cf8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>inunrestricted cash and cash equivalents and short-term investments as of December 31, 2021, we believe we have sufficient liquidity to continue business operations and totake action we determine to be in the best interests of our employees, stockholders, stakeholders and of drivers and riders on the Lyft Platform. For more information onrisks associated with the COVID-19 pandem ic, see the section titled “Risk Factors” in Item 1A of Part I.Recent Developments Transaction</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>COVID-19, may continue to develop or persist over time and further contribute to thisadverse effect. • Changes in driver behavior during the COVID-19 pandemic have led to reduced levels of driver availability on our platform relative to rider demand in certainmarkets. This imbalance fluctuates for various reasons, and to the extent that driver availability is limited, our service levels have been and may be negativelyimpacted and we have increased prices or provided additional incentives and may need to continue to do so, which</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>estimated.In response to the COVID-19 pandemic, we have adopted multiple measures, including, but not limited, to establishing new health and safety requirements forridesharing and updating workplace policies. We also made adjustments to our expenses and cash flow to correlate with declines in revenues including headcountreductions in 2020. 56</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>opportunities for drivers on our platform. Our business continues to be impacted by the COVID-19pandemic. Although we have seen some signs of demand improving, particularly compared to the demand levels at the start of the pandemic, demand levels continue to beaffected by the impact of variants and changes in case counts. The exact timing and pace of the recovery remain uncertain. The extent to which our operations will continueto be impacted by the pandemic will depend largely on future</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>does not perceive ridesharing or our other offerings as beneficial, or chooses not to adopt them as a result of concerns regarding public health or safety, affordability or forother reasons, whether as a result of incidents on our platform or on our competitors’ platforms, the COVID-19 pandemic, or otherwise, then the market for our offeringsmay not further develop, may develop more slowly than we expect or may not achieve the growth potential we expect. Additionally,</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "eb88c0bb-4d3f-4426-b2be-66b0d5635abb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What initiatives are the company focusing on independently of COVID-19?\",\n",
|
||||
" vector_top_k=5,\n",
|
||||
" with_reranker=False,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3c4b3962-2873-40b3-9f50-58cf7685454a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.819209</td>\n",
|
||||
" <td>businesses to contain the pandemic or respond to its impact and altered consumer behavior, amongother things. The Company has adopted a number of measures in response to the COVID-19 pandemic including, but not limited to, establishing new health and safetyrequirements for ridesharing and updating workplace policies. The Company also made adjustments to its expenses and cash flow to correlate with declines in revenuesincluding headcount reductions in 2020. Refer to Note 17 “Restructuring” to the</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.813341</td>\n",
|
||||
" <td>business;• manage our platform and our business assets and expenses in light of the COVID-19 pandemic and related public health measures issued by various jurisdictions,including travel bans, travel restrictions and shelter-in-place orders, as well as maintain demand for and confidence in the safety of our platform during andfollowing the COVID-19 pandemic; • plan for and manage capital</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.809412</td>\n",
|
||||
" <td>pandemic, including sales, marketing and costs relating to our efforts to mitigate the impact of the COVID-19 pandemic. Furthermore, we have expanded overtime to include more asset-intensive offerings such as our network of Light Vehicles, Flexdrive, Lyft Rentals and Lyft Auto Care. We are also expanding the supportavailable to drivers at our Driver Hubs, our driver-centric service centers and community spaces, Driver Centers, our vehicle service centers, Mobile Services,</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>0.809215</td>\n",
|
||||
" <td>COVID-19 pandemic in March 2020. We have adoptedmultiple measures in response to the COVID-19 pandemic. We cannot be certain that these actions will mitigate some or all of the negative effects of the pandemic on ourbusiness. In light of the evolving and unpredictable effects of COVID-19, we are not currently in a position to forecast the expected impact of COVID-19 on our financialand operating results in fu ture periods.Revenue Recognition Revenue</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>0.808421</td>\n",
|
||||
" <td>estimated.In response to the COVID-19 pandemic, we have adopted multiple measures, including, but not limited, to establishing new health and safety requirements forridesharing and updating workplace policies. We also made adjustments to our expenses and cash flow to correlate with declines in revenues including headcountreductions in 2020. 56</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1dcc798a-3940-4426-8110-d9a3f7dc5a68",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What initiatives are the company focusing on independently of COVID-19?\",\n",
|
||||
" vector_top_k=40,\n",
|
||||
" reranker_top_n=5,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "38bae391-7dca-4f8d-a90e-ada1beddcd2e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>remotely, as well as permanent return to workarrangements and workplac e strategies;• the inability to achieve adherence to our internal policies and core values, including our diversity, equity and inclusion practices and initiatives;• competitive pressures to move in directions that may divert us from our mission, vision and values;• the continued challenges of a rapidly-evolving industry;• the increasing need to develop expertise in new areas of business that</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>9.0</td>\n",
|
||||
" <td>platfor m and scaled user network.Notwithstanding the impact of COVID-19, we are continuing to invest in the future, both organically and through acquisitions of complementary businesses. Wealso continue to invest in the expansion of our network of Light Vehicles and Lyft Autonomous, which focuses on the deployment and scaling of third-party self-drivingtechnology on the Lyft network. Our strategy is to always be at the forefront of transportation innovation, and we believe that through these</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>9.0</td>\n",
|
||||
" <td>the transport ation needs of customers, employees and other constituents.• Grow Active Riders. We see opportunities to continue to recoup and grow our rider base amid the continuing COVID-19 pandemic. We may make incrementalinvestments in our brand and in growth marketing to maintain and drive increasing consumer preference for Lyft. We may also offer discounts for first-time ridersto try Lyft or provide incentives to existing riders to encourage increased ride frequency. We</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>8.0</td>\n",
|
||||
" <td>to grow our business and improve ourofferings, we will face challenges related to providing quality support services at scale. If we grow our international rider base and the number of international drivers onour platform, our support organization will face additional challenges, including those associated with delivering support in languages other than English. Furthermore, theCOVID-19 pandemic may impact our ability to provide effective and timely support, including as a result of a decrease in the availability of service providers and increasein</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>6.0</td>\n",
|
||||
" <td>pandemic and responsive measures;• natural disasters, economic downturns, public health crises or political crises;• general macroeconomic conditions;Operational factors • our limited operating history;• our financial performance and any inability to achieve or maintain profitability in the future;• competition in our industries;• the unpredictability of our results of operations;• uncertainty regarding the growth of the ridesharing and other markets;• our ability to attract and</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_index_v2",
|
||||
"language": "python",
|
||||
"name": "llama_index_v2"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/LongContextReorder.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LongContextReorder\n",
|
||||
"\n",
|
||||
"Models struggle to access significant details found in the center of extended contexts. [A study](https://arxiv.org/abs/2307.03172) observed that the best performance typically arises when crucial data is positioned at the start or conclusion of the input context. Additionally, as the input context lengthens, performance drops notably, even in models designed for long contexts.\n",
|
||||
"\n",
|
||||
"This module will re-order the retrieved nodes, which can be helpful in cases where a large top-k is needed. The reordering process works as follows:\n",
|
||||
"\n",
|
||||
"1. Input nodes are sorted based on their relevance scores.\n",
|
||||
"2. Sorted nodes are then reordered in an alternating pattern:\n",
|
||||
" - Even-indexed nodes are placed at the beginning of the new list.\n",
|
||||
" - Odd-indexed nodes are placed at the end of the new list.\n",
|
||||
"\n",
|
||||
"This approach ensures that the highest-scored (most relevant) nodes are positioned at the beginning and end of the list, with lower-scored nodes in the middle."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-embeddings-huggingface\n",
|
||||
"%pip install llama-index-llms-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import openai\n",
|
||||
"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/loganm/miniconda3/envs/llama-index/lib/python3.11/site-packages/torch/cuda/__init__.py:546: UserWarning: Can't initialize NVML\n",
|
||||
" warnings.warn(\"Can't initialize NVML\")\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.llm = OpenAI(model=\"gpt-3.5-turbo-instruct\", temperature=0.1)\n",
|
||||
"Settings.embed_model = HuggingFaceEmbedding(model_name=\"BAAI/bge-base-en-v1.5\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex.from_documents(documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Run Query"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.postprocessor import LongContextReorder\n",
|
||||
"\n",
|
||||
"reorder = LongContextReorder()\n",
|
||||
"\n",
|
||||
"reorder_engine = index.as_query_engine(\n",
|
||||
" node_postprocessors=[reorder], similarity_top_k=5\n",
|
||||
")\n",
|
||||
"base_engine = index.as_query_engine(similarity_top_k=5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"**`Final Response:`** Yes, the author met Sam Altman when they asked him to be the president of Y Combinator. This was during the time when the author was in a PhD program in computer science and also pursuing their passion for art. They were applying to art schools and eventually ended up attending RISD."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.response.notebook_utils import display_response\n",
|
||||
"\n",
|
||||
"base_response = base_engine.query(\"Did the author meet Sam Altman?\")\n",
|
||||
"display_response(base_response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"**`Final Response:`** Yes, the author met Sam Altman when they asked him to be the president of Y Combinator. This meeting occurred at a party at the author's house, where they were introduced by a mutual friend, Jessica Livingston. Jessica later went on to compile a book of interviews with startup founders, and the author shared their thoughts on the flaws of venture capital with her during her job search at a Boston VC firm."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"reorder_response = reorder_engine.query(\"Did the author meet Sam Altman?\")\n",
|
||||
"display_response(reorder_response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Inspect Order Diffrences"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: 81bc66bb-2c45-4697-9f08-9f848bd78b12): [17]\n",
|
||||
"\n",
|
||||
"As well as HN, I wrote all of YC's internal software in Arc. But while I continued to work ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: bd660905-e4e0-4d02-a113-e3810b59c5d1): [19] One way to get more precise about the concept of invented vs discovered is to talk about spa...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 3932e4a4-f17e-4dd2-9d25-5f0e65910dc5): Not so much because it was badly written as because the problem is so convoluted. When you're wor...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 0d801f0a-4a99-475d-aa7c-ad5d601947ea): [10]\n",
|
||||
"\n",
|
||||
"Wow, I thought, there's an audience. If I write something and put it on the web, anyone can...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: bf726802-4d0d-4ee5-ab2e-ffa8a5461bc4): I was briefly tempted, but they were so slow by present standards; what was the point? No one els...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(base_response.get_formatted_sources())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: 81bc66bb-2c45-4697-9f08-9f848bd78b12): [17]\n",
|
||||
"\n",
|
||||
"As well as HN, I wrote all of YC's internal software in Arc. But while I continued to work ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 3932e4a4-f17e-4dd2-9d25-5f0e65910dc5): Not so much because it was badly written as because the problem is so convoluted. When you're wor...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: bf726802-4d0d-4ee5-ab2e-ffa8a5461bc4): I was briefly tempted, but they were so slow by present standards; what was the point? No one els...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 0d801f0a-4a99-475d-aa7c-ad5d601947ea): [10]\n",
|
||||
"\n",
|
||||
"Wow, I thought, there's an audience. If I write something and put it on the web, anyone can...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: bd660905-e4e0-4d02-a113-e3810b59c5d1): [19] One way to get more precise about the concept of invented vs discovered is to talk about spa...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(reorder_response.get_formatted_sources())"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-index",
|
||||
"language": "python",
|
||||
"name": "llama-index"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,891 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/MetadataReplacementDemo.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Metadata Replacement + Node Sentence Window\n",
|
||||
"\n",
|
||||
"In this notebook, we use the `SentenceWindowNodeParser` to parse documents into single sentences per node. Each node also contains a \"window\" with the sentences on either side of the node sentence.\n",
|
||||
"\n",
|
||||
"Then, after retrieval, before passing the retrieved sentences to the LLM, the single sentences are replaced with a window containing the surrounding sentences using the `MetadataReplacementNodePostProcessor`.\n",
|
||||
"\n",
|
||||
"This is most useful for large documents/indexes, as it helps to retrieve more fine-grained details.\n",
|
||||
"\n",
|
||||
"By default, the sentence window is 5 sentences on either side of the original sentence.\n",
|
||||
"\n",
|
||||
"In this case, chunk size settings are not used, in favor of following the window settings."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-embeddings-openai\n",
|
||||
"%pip install llama-index-embeddings-huggingface\n",
|
||||
"%pip install llama-index-llms-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%load_ext autoreload\n",
|
||||
"%autoreload 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
|
||||
"from llama_index.core.node_parser import SentenceWindowNodeParser\n",
|
||||
"from llama_index.core.node_parser import SentenceSplitter\n",
|
||||
"\n",
|
||||
"# create the sentence window node parser w/ default settings\n",
|
||||
"node_parser = SentenceWindowNodeParser.from_defaults(\n",
|
||||
" window_size=3,\n",
|
||||
" window_metadata_key=\"window\",\n",
|
||||
" original_text_metadata_key=\"original_text\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# base node parser is a sentence splitter\n",
|
||||
"text_splitter = SentenceSplitter()\n",
|
||||
"\n",
|
||||
"llm = OpenAI(model=\"gpt-3.5-turbo\", temperature=0.1)\n",
|
||||
"embed_model = HuggingFaceEmbedding(\n",
|
||||
" model_name=\"sentence-transformers/all-mpnet-base-v2\", max_length=512\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.llm = llm\n",
|
||||
"Settings.embed_model = embed_model\n",
|
||||
"Settings.text_splitter = text_splitter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data, Build the Index\n",
|
||||
"\n",
|
||||
"In this section, we load data and build the vector index."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Load Data\n",
|
||||
"\n",
|
||||
"Here, we build an index using chapter 3 of the recent IPCC climate report."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" % Total % Received % Xferd Average Speed Time Time Time Current\n",
|
||||
" Dload Upload Total Spent Left Speed\n",
|
||||
" 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: www..ch\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!curl https://www.ipcc.ch/report/ar6/wg2/downloads/report/IPCC_AR6_WGII_Chapter03.pdf --output IPCC_AR6_WGII_Chapter03.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"documents = SimpleDirectoryReader(\n",
|
||||
" input_files=[\"./IPCC_AR6_WGII_Chapter03.pdf\"]\n",
|
||||
").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Extract Nodes\n",
|
||||
"\n",
|
||||
"We extract out the set of nodes that will be stored in the VectorIndex. This includes both the nodes with the sentence window parser, as well as the \"base\" nodes extracted using the standard parser."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nodes = node_parser.get_nodes_from_documents(documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"base_nodes = text_splitter.get_nodes_from_documents(documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Build the Indexes\n",
|
||||
"\n",
|
||||
"We build both the sentence index, as well as the \"base\" index (with default chunk sizes)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"sentence_index = VectorStoreIndex(nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"base_index = VectorStoreIndex(base_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Querying\n",
|
||||
"\n",
|
||||
"### With MetadataReplacementPostProcessor\n",
|
||||
"\n",
|
||||
"Here, we now use the `MetadataReplacementPostProcessor` to replace the sentence in each node with it's surrounding context."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"There is low confidence in the quantification of Atlantic Meridional Overturning Circulation (AMOC) changes in the 20th century due to low agreement in quantitative reconstructed and simulated trends. Additionally, direct observational records since the mid-2000s remain too short to determine the relative contributions of internal variability, natural forcing, and anthropogenic forcing to AMOC change. However, it is very likely that AMOC will decline for all SSP scenarios over the 21st century, but it will not involve an abrupt collapse before 2100.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.postprocessor import MetadataReplacementPostProcessor\n",
|
||||
"\n",
|
||||
"query_engine = sentence_index.as_query_engine(\n",
|
||||
" similarity_top_k=2,\n",
|
||||
" # the target key defaults to `window` to match the node_parser's default\n",
|
||||
" node_postprocessors=[\n",
|
||||
" MetadataReplacementPostProcessor(target_metadata_key=\"window\")\n",
|
||||
" ],\n",
|
||||
")\n",
|
||||
"window_response = query_engine.query(\n",
|
||||
" \"What are the concerns surrounding the AMOC?\"\n",
|
||||
")\n",
|
||||
"print(window_response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can also check the original sentence that was retrieved for each node, as well as the actual window of sentences that was sent to the LLM."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Window: Nevertheless, projected future annual cumulative upwelling wind \n",
|
||||
"changes at most locations and seasons remain within ±10–20% of \n",
|
||||
"present-day values (medium confidence) (WGI AR6 Section 9.2.3.5; \n",
|
||||
"Fox-Kemper et al., 2021).\n",
|
||||
" Continuous observation of the Atlantic meridional overturning \n",
|
||||
"circulation (AMOC) has improved the understanding of its variability \n",
|
||||
"(Frajka-Williams et al., 2019), but there is low confidence in the \n",
|
||||
"quantification of AMOC changes in the 20th century because of low \n",
|
||||
"agreement in quantitative reconstructed and simulated trends (WGI \n",
|
||||
"AR6 Sections 2.3.3, 9.2.3.1; Fox-Kemper et al., 2021; Gulev et al., 2021). \n",
|
||||
" Direct observational records since the mid-2000s remain too short to \n",
|
||||
"determine the relative contributions of internal variability, natural \n",
|
||||
"forcing and anthropogenic forcing to AMOC change (high confidence) \n",
|
||||
"(WGI AR6 Sections 2.3.3, 9.2.3.1; Fox-Kemper et al., 2021; Gulev et al., \n",
|
||||
"2021). Over the 21st century, AMOC will very likely decline for all SSP \n",
|
||||
"scenarios but will not involve an abrupt collapse before 2100 (WGI \n",
|
||||
"AR6 Sections 4.3.2, 9.2.3.1; Fox-Kemper et al., 2021; Lee et al., 2021).\n",
|
||||
" 3.2.2.4 Sea Ice Changes\n",
|
||||
"Sea ice is a key driver of polar marine life, hosting unique ecosystems \n",
|
||||
"and affecting diverse marine organisms and food webs through its \n",
|
||||
"impact on light penetration and supplies of nutrients and organic \n",
|
||||
"matter (Arrigo, 2014). Since the late 1970s, Arctic sea ice area has \n",
|
||||
"decreased for all months, with an estimated decrease of 2 million km2 \n",
|
||||
"(or 25%) for summer sea ice (averaged for August, September and \n",
|
||||
"October) in 2010–2019 as compared with 1979–1988 (WGI AR6 \n",
|
||||
"Section 9.3.1.1; Fox-Kemper et al., 2021). \n",
|
||||
"------------------\n",
|
||||
"Original Sentence: Over the 21st century, AMOC will very likely decline for all SSP \n",
|
||||
"scenarios but will not involve an abrupt collapse before 2100 (WGI \n",
|
||||
"AR6 Sections 4.3.2, 9.2.3.1; Fox-Kemper et al., 2021; Lee et al., 2021).\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"window = window_response.source_nodes[0].node.metadata[\"window\"]\n",
|
||||
"sentence = window_response.source_nodes[0].node.metadata[\"original_text\"]\n",
|
||||
"\n",
|
||||
"print(f\"Window: {window}\")\n",
|
||||
"print(\"------------------\")\n",
|
||||
"print(f\"Original Sentence: {sentence}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Contrast with normal VectorStoreIndex"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The concerns surrounding the AMOC are not provided in the given context information.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = base_index.as_query_engine(similarity_top_k=2)\n",
|
||||
"vector_response = query_engine.query(\n",
|
||||
" \"What are the concerns surrounding the AMOC?\"\n",
|
||||
")\n",
|
||||
"print(vector_response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Well, that didn't work. Let's bump up the top k! This will be slower and use more tokens compared to the sentence window index."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"There are concerns surrounding the AMOC (Atlantic Meridional Overturning Circulation). The context information mentions that the AMOC will decline over the 21st century, with high confidence but low confidence for quantitative projections.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = base_index.as_query_engine(similarity_top_k=5)\n",
|
||||
"vector_response = query_engine.query(\n",
|
||||
" \"What are the concerns surrounding the AMOC?\"\n",
|
||||
")\n",
|
||||
"print(vector_response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Analysis\n",
|
||||
"\n",
|
||||
"So the `SentenceWindowNodeParser` + `MetadataReplacementNodePostProcessor` combo is the clear winner here. But why?\n",
|
||||
"\n",
|
||||
"Embeddings at a sentence level seem to capture more fine-grained details, like the word `AMOC`.\n",
|
||||
"\n",
|
||||
"We can also compare the retrieved chunks for each index!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Over the 21st century, AMOC will very likely decline for all SSP \n",
|
||||
"scenarios but will not involve an abrupt collapse before 2100 (WGI \n",
|
||||
"AR6 Sections 4.3.2, 9.2.3.1; Fox-Kemper et al., 2021; Lee et al., 2021).\n",
|
||||
"\n",
|
||||
"--------\n",
|
||||
"Direct observational records since the mid-2000s remain too short to \n",
|
||||
"determine the relative contributions of internal variability, natural \n",
|
||||
"forcing and anthropogenic forcing to AMOC change (high confidence) \n",
|
||||
"(WGI AR6 Sections 2.3.3, 9.2.3.1; Fox-Kemper et al., 2021; Gulev et al., \n",
|
||||
"2021). \n",
|
||||
"--------\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for source_node in window_response.source_nodes:\n",
|
||||
" print(source_node.node.metadata[\"original_text\"])\n",
|
||||
" print(\"--------\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here, we can see that the sentence window index easily retrieved two nodes that talk about AMOC. Remember, the embeddings are based purely on the original sentence here, but the LLM actually ends up reading the surrounding context as well!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now, let's try and disect why the naive vector index failed."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"AMOC mentioned? False\n",
|
||||
"--------\n",
|
||||
"AMOC mentioned? False\n",
|
||||
"--------\n",
|
||||
"AMOC mentioned? True\n",
|
||||
"--------\n",
|
||||
"AMOC mentioned? False\n",
|
||||
"--------\n",
|
||||
"AMOC mentioned? False\n",
|
||||
"--------\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for node in vector_response.source_nodes:\n",
|
||||
" print(\"AMOC mentioned?\", \"AMOC\" in node.node.text)\n",
|
||||
" print(\"--------\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So source node at index [2] mentions AMOC, but what did this text actually look like?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2021; Gulev et al. \n",
|
||||
"2021)The AMOC will decline over the 21st century \n",
|
||||
"(high confidence, but low confidence for \n",
|
||||
"quantitative projections).4.3.2.3, 9.2.3 (Fox-Kemper \n",
|
||||
"et al. 2021; Lee et al. \n",
|
||||
"2021)\n",
|
||||
"Sea ice\n",
|
||||
"Arctic sea ice \n",
|
||||
"changes‘Current Arctic sea ice coverage levels are the \n",
|
||||
"lowest since at least 1850 for both annual mean \n",
|
||||
"and late-summer values (high confidence).’2.3.2.1, 9.3.1 (Fox-Kemper \n",
|
||||
"et al. 2021; Gulev et al. \n",
|
||||
"2021)‘The Arctic will become practically ice-free in \n",
|
||||
"September by the end of the 21st century under \n",
|
||||
"SSP2-4.5, SSP3-7.0 and SSP5-8.5[…](high \n",
|
||||
"confidence).’4.3.2.1, 9.3.1 (Fox-Kemper \n",
|
||||
"et al. 2021; Lee et al. \n",
|
||||
"2021)\n",
|
||||
"Antarctic sea ice \n",
|
||||
"changesThere is no global significant trend in \n",
|
||||
"Antarctic sea ice area from 1979 to 2020 (high \n",
|
||||
"confidence).2.3.2.1, 9.3.2 (Fox-Kemper \n",
|
||||
"et al. 2021; Gulev et al. \n",
|
||||
"2021)There is low confidence in model simulations of \n",
|
||||
"future Antarctic sea ice.9.3.2 (Fox-Kemper et al. \n",
|
||||
"2021)\n",
|
||||
"Ocean chemistry\n",
|
||||
"Changes in salinityThe ‘large-scale, near-surface salinity contrasts \n",
|
||||
"have intensified since at least 1950 […] \n",
|
||||
"(virtually certain).’2.3.3.2, 9.2.2.2 \n",
|
||||
"(Fox-Kemper et al. 2021; \n",
|
||||
"Gulev et al. 2021)‘Fresh ocean regions will continue to get fresher \n",
|
||||
"and salty ocean regions will continue to get \n",
|
||||
"saltier in the 21st century (medium confidence).’9.2.2.2 (Fox-Kemper et al. \n",
|
||||
"2021)\n",
|
||||
"Ocean acidificationOcean surface pH has declined globally over the \n",
|
||||
"past four decades (virtually certain).2.3.3.5, 5.3.2.2 (Canadell \n",
|
||||
"et al. 2021; Gulev et al. \n",
|
||||
"2021)Ocean surface pH will continue to decrease \n",
|
||||
"‘through the 21st century, except for the \n",
|
||||
"lower-emission scenarios SSP1-1.9 and SSP1-2.6 \n",
|
||||
"[…] (high confidence).’4.3.2.5, 4.5.2.2, 5.3.4.1 \n",
|
||||
"(Lee et al. 2021; Canadell \n",
|
||||
"et al. 2021)\n",
|
||||
"Ocean \n",
|
||||
"deoxygenationDeoxygenation has occurred in most open \n",
|
||||
"ocean regions since the mid-20th century (high \n",
|
||||
"confidence).2.3.3.6, 5.3.3.2 (Canadell \n",
|
||||
"et al. 2021; Gulev et al. \n",
|
||||
"2021)Subsurface oxygen content ‘is projected to \n",
|
||||
"transition to historically unprecedented condition \n",
|
||||
"with decline over the 21st century (medium \n",
|
||||
"confidence).’5.3.3.2 (Canadell et al. \n",
|
||||
"2021)\n",
|
||||
"Changes in nutrient \n",
|
||||
"concentrationsNot assessed in WGI Not assessed in WGI\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(vector_response.source_nodes[2].node.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So AMOC is disuccsed, but sadly it is in the middle chunk. With LLMs, it is often observed that text in the middle of retrieved context is often ignored or less useful. A recent paper [\"Lost in the Middle\" discusses this here](https://arxiv.org/abs/2307.03172)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## [Optional] Evaluation\n",
|
||||
"\n",
|
||||
"We more rigorously evaluate how well the sentence window retriever works compared to the base retriever.\n",
|
||||
"\n",
|
||||
"We define/load an eval benchmark dataset and then run different evaluations over it.\n",
|
||||
"\n",
|
||||
"**WARNING**: This can be *expensive*, especially with GPT-4. Use caution and tune the sample size to fit your budget."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.evaluation import DatasetGenerator, QueryResponseDataset\n",
|
||||
"\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"import nest_asyncio\n",
|
||||
"import random\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"428"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"len(base_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"num_nodes_eval = 30\n",
|
||||
"# there are 428 nodes total. Take the first 200 to generate questions (the back half of the doc is all references)\n",
|
||||
"sample_eval_nodes = random.sample(base_nodes[:200], num_nodes_eval)\n",
|
||||
"# NOTE: run this if the dataset isn't already saved\n",
|
||||
"# generate questions from the largest chunks (1024)\n",
|
||||
"dataset_generator = DatasetGenerator(\n",
|
||||
" sample_eval_nodes,\n",
|
||||
" llm=OpenAI(model=\"gpt-4\"),\n",
|
||||
" show_progress=True,\n",
|
||||
" num_questions_per_chunk=2,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"eval_dataset = await dataset_generator.agenerate_dataset_from_nodes()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"eval_dataset.save_json(\"data/ipcc_eval_qr_dataset.json\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# optional\n",
|
||||
"eval_dataset = QueryResponseDataset.from_json(\"data/ipcc_eval_qr_dataset.json\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Compare Results"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import asyncio\n",
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.evaluation import (\n",
|
||||
" CorrectnessEvaluator,\n",
|
||||
" SemanticSimilarityEvaluator,\n",
|
||||
" RelevancyEvaluator,\n",
|
||||
" FaithfulnessEvaluator,\n",
|
||||
" PairwiseComparisonEvaluator,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"from collections import defaultdict\n",
|
||||
"import pandas as pd\n",
|
||||
"\n",
|
||||
"# NOTE: can uncomment other evaluators\n",
|
||||
"evaluator_c = CorrectnessEvaluator(llm=OpenAI(model=\"gpt-4\"))\n",
|
||||
"evaluator_s = SemanticSimilarityEvaluator()\n",
|
||||
"evaluator_r = RelevancyEvaluator(llm=OpenAI(model=\"gpt-4\"))\n",
|
||||
"evaluator_f = FaithfulnessEvaluator(llm=OpenAI(model=\"gpt-4\"))\n",
|
||||
"# pairwise_evaluator = PairwiseComparisonEvaluator(llm=OpenAI(model=\"gpt-4\"))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.evaluation.eval_utils import (\n",
|
||||
" get_responses,\n",
|
||||
" get_results_df,\n",
|
||||
")\n",
|
||||
"from llama_index.core.evaluation import BatchEvalRunner\n",
|
||||
"\n",
|
||||
"max_samples = 30\n",
|
||||
"\n",
|
||||
"eval_qs = eval_dataset.questions\n",
|
||||
"ref_response_strs = [r for (_, r) in eval_dataset.qr_pairs]\n",
|
||||
"\n",
|
||||
"# resetup base query engine and sentence window query engine\n",
|
||||
"# base query engine\n",
|
||||
"base_query_engine = base_index.as_query_engine(similarity_top_k=2)\n",
|
||||
"# sentence window query engine\n",
|
||||
"query_engine = sentence_index.as_query_engine(\n",
|
||||
" similarity_top_k=2,\n",
|
||||
" # the target key defaults to `window` to match the node_parser's default\n",
|
||||
" node_postprocessors=[\n",
|
||||
" MetadataReplacementPostProcessor(target_metadata_key=\"window\")\n",
|
||||
" ],\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"base_pred_responses = get_responses(\n",
|
||||
" eval_qs[:max_samples], base_query_engine, show_progress=True\n",
|
||||
")\n",
|
||||
"pred_responses = get_responses(\n",
|
||||
" eval_qs[:max_samples], query_engine, show_progress=True\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"pred_response_strs = [str(p) for p in pred_responses]\n",
|
||||
"base_pred_response_strs = [str(p) for p in base_pred_responses]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"evaluator_dict = {\n",
|
||||
" \"correctness\": evaluator_c,\n",
|
||||
" \"faithfulness\": evaluator_f,\n",
|
||||
" \"relevancy\": evaluator_r,\n",
|
||||
" \"semantic_similarity\": evaluator_s,\n",
|
||||
"}\n",
|
||||
"batch_runner = BatchEvalRunner(evaluator_dict, workers=2, show_progress=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Run evaluations over faithfulness/semantic similarity."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"eval_results = await batch_runner.aevaluate_responses(\n",
|
||||
" queries=eval_qs[:max_samples],\n",
|
||||
" responses=pred_responses[:max_samples],\n",
|
||||
" reference=ref_response_strs[:max_samples],\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"base_eval_results = await batch_runner.aevaluate_responses(\n",
|
||||
" queries=eval_qs[:max_samples],\n",
|
||||
" responses=base_pred_responses[:max_samples],\n",
|
||||
" reference=ref_response_strs[:max_samples],\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>names</th>\n",
|
||||
" <th>correctness</th>\n",
|
||||
" <th>relevancy</th>\n",
|
||||
" <th>faithfulness</th>\n",
|
||||
" <th>semantic_similarity</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>Sentence Window Retriever</td>\n",
|
||||
" <td>4.366667</td>\n",
|
||||
" <td>0.933333</td>\n",
|
||||
" <td>0.933333</td>\n",
|
||||
" <td>0.959583</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>Base Retriever</td>\n",
|
||||
" <td>4.216667</td>\n",
|
||||
" <td>0.900000</td>\n",
|
||||
" <td>0.933333</td>\n",
|
||||
" <td>0.958664</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" names correctness relevancy faithfulness \\\n",
|
||||
"0 Sentence Window Retriever 4.366667 0.933333 0.933333 \n",
|
||||
"1 Base Retriever 4.216667 0.900000 0.933333 \n",
|
||||
"\n",
|
||||
" semantic_similarity \n",
|
||||
"0 0.959583 \n",
|
||||
"1 0.958664 "
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"results_df = get_results_df(\n",
|
||||
" [eval_results, base_eval_results],\n",
|
||||
" [\"Sentence Window Retriever\", \"Base Retriever\"],\n",
|
||||
" [\"correctness\", \"relevancy\", \"faithfulness\", \"semantic_similarity\"],\n",
|
||||
")\n",
|
||||
"display(results_df)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4b5daafbac08a79e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/MixedbreadAIRerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "29555001ef61b56f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Mixedbread AI Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "84e7cd944c6dd365",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "84a638b7ae22e597",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index > /dev/null\n",
|
||||
"%pip install llama-index-postprocessor-mixedbreadai-rerank > /dev/null\n",
|
||||
"%pip install llama-index-llms-openai > /dev/null"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c570bf054bffa9e8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.response.pprint_utils import pprint_response"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "30de4fe08c5f0f72",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8260dc57d8861d01",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2025-07-24 19:14:25-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt\n",
|
||||
"Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 2606:50c0:8000::154, 2606:50c0:8001::154, 2606:50c0:8002::154, ...\n",
|
||||
"Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|2606:50c0:8000::154|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 75042 (73K) [text/plain]\n",
|
||||
"Saving to: ‘data/paul_graham/paul_graham_essay.txt’\n",
|
||||
"\n",
|
||||
"data/paul_graham/pa 100%[===================>] 73.28K --.-KB/s in 0.03s \n",
|
||||
"\n",
|
||||
"2025-07-24 19:14:25 (2.35 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "87822dcbf61b0068",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from llama_index.embeddings.mixedbreadai import MixedbreadAIEmbedding\n",
|
||||
"\n",
|
||||
"# You can visit https://www.mixedbread.ai/api-reference#quick-start-guide\n",
|
||||
"# to get an api key\n",
|
||||
"mixedbread_api_key = os.environ.get(\"MXBAI_API_KEY\", \"your-api-key\")\n",
|
||||
"model_name = \"mixedbread-ai/mxbai-embed-large-v1\"\n",
|
||||
"\n",
|
||||
"mixbreadai_embeddings = MixedbreadAIEmbedding(\n",
|
||||
" api_key=mixedbread_api_key, model_name=model_name\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()\n",
|
||||
"\n",
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents=documents, embed_model=mixbreadai_embeddings\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dabb021ef1c0b8cb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Retrieve top 10 most relevant nodes, then filter with MixedbreadAI Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "47844a96d5208b1c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.mixedbreadai_rerank import MixedbreadAIRerank\n",
|
||||
"\n",
|
||||
"mixedbreadai_rerank = MixedbreadAIRerank(\n",
|
||||
" api_key=mixedbread_api_key,\n",
|
||||
" top_n=2,\n",
|
||||
" model=\"mixedbread-ai/mxbai-rerank-large-v1\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d3ce8019715b2525",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10,\n",
|
||||
" node_postprocessors=[mixedbreadai_rerank],\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "66a3b098e2612db",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: Sam Altman was asked to become the president of Y\n",
|
||||
"Combinator (YC) after the original founders decided to step back and\n",
|
||||
"reorganize the company to ensure its longevity. Initially hesitant due\n",
|
||||
"to his interest in starting a nuclear reactor startup, Sam eventually\n",
|
||||
"agreed to take over as president starting with the winter 2014 batch.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: 9bef8795-4532-44eb-a590-45abf15b11e5\n",
|
||||
"Similarity: 0.109680176\n",
|
||||
"Text: This seemed strange advice, because YC was doing great. But if\n",
|
||||
"there was one thing rarer than Rtm offering advice, it was Rtm being\n",
|
||||
"wrong. So this set me thinking. It was true that on my current\n",
|
||||
"trajectory, YC would be the last thing I did, because it was only\n",
|
||||
"taking up more of my attention. It had already eaten Arc, and was in\n",
|
||||
"the process of ea...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: 3060722a-0e57-492e-9071-2148e5eec2be\n",
|
||||
"Similarity: 0.041625977\n",
|
||||
"Text: But after Heroku got bought we had enough money to go back to\n",
|
||||
"being self-funded. [15] I've never liked the term \"deal flow,\"\n",
|
||||
"because it implies that the number of new startups at any given time\n",
|
||||
"is fixed. This is not only false, but it's the purpose of YC to\n",
|
||||
"falsify it, by causing startups to be founded that would not otherwise\n",
|
||||
"have existed. [1...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2fd6d2dbfa36548e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Directly retrieve top 2 most similar nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5477bfa95604d475",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=2,\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "532fcad0c87faa22",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Retrieved context is irrelevant and response is hallucinated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5354dc02c93d83d1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: Sam Altman worked on the application builder, while\n",
|
||||
"Dan worked on network infrastructure, and two undergrads worked on the\n",
|
||||
"first two services (images and phone calls). Later on, Sam realized he\n",
|
||||
"didn't want to run a company and decided to build a subset of the\n",
|
||||
"project as an open source project.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: a42ab697-0bd1-40fc-8e23-64148e62fe6d\n",
|
||||
"Similarity: 0.557881093860686\n",
|
||||
"Text: I started working on the application builder, Dan worked on\n",
|
||||
"network infrastructure, and the two undergrads worked on the first two\n",
|
||||
"services (images and phone calls). But about halfway through the\n",
|
||||
"summer I realized I really didn't want to run a company — especially\n",
|
||||
"not a big one, which it was looking like this would have to be. I'd\n",
|
||||
"only started V...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: a398b429-fad6-4284-a201-835e5c1fec3c\n",
|
||||
"Similarity: 0.49815489887733433\n",
|
||||
"Text: But alas it was more like the Accademia than not. Better\n",
|
||||
"organized, certainly, and a lot more expensive, but it was now\n",
|
||||
"becoming clear that art school did not bear the same relationship to\n",
|
||||
"art that medical school bore to medicine. At least not the painting\n",
|
||||
"department. The textile department, which my next door neighbor\n",
|
||||
"belonged to, seemed to be ...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# NVIDIA NIMs\n",
|
||||
"\n",
|
||||
"The `llama-index-postprocessor-nvidia-rerank` package contains LlamaIndex integrations for building applications with models on NVIDIA NIM inference microservices. NIM supports models across domains like chat, embedding, and re-ranking models \n",
|
||||
"from the community as well as NVIDIA. These models are optimized by NVIDIA to deliver the best performance on NVIDIA \n",
|
||||
"accelerated infrastructure and deployed as a NIM, an easy-to-use, prebuilt containers that deploy anywhere using a single \n",
|
||||
"command on NVIDIA accelerated infrastructure.\n",
|
||||
"\n",
|
||||
"NVIDIA hosted deployments of NIMs are available to test on the [NVIDIA API catalog](https://build.nvidia.com/). After testing, \n",
|
||||
"NIMs can be exported from NVIDIA’s API catalog using the NVIDIA AI Enterprise license and run on-premises or in the cloud, \n",
|
||||
"giving enterprises ownership and full control of their IP and AI application.\n",
|
||||
"\n",
|
||||
"NIMs are packaged as container images on a per model basis and are distributed as NGC container images through the NVIDIA NGC Catalog. \n",
|
||||
"At their core, NIMs provide easy, consistent, and familiar APIs for running inference on an AI model.\n",
|
||||
"\n",
|
||||
"# NVIDIA Rerank connector\n",
|
||||
"\n",
|
||||
"This example demonstrates how to use LlamaIndex to interact with the supported [NVIDIA Retrieval QA Ranking Model](https://build.nvidia.com/explore/retrieval) for [retrieval-augmented generation](https://developer.nvidia.com/blog/build-enterprise-retrieval-augmented-generation-apps-with-nvidia-retrieval-qa-embedding-model/) via the `NVIDIARerank` class."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Reranking\n",
|
||||
"\n",
|
||||
"Reranking is a critical piece of high accuracy, efficient retrieval pipelines.\n",
|
||||
"\n",
|
||||
"Two important use cases:\n",
|
||||
"- Combining results from multiple data sources\n",
|
||||
"- Enhancing accuracy for single data sources"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Combining results from multiple sources\n",
|
||||
"\n",
|
||||
"Consider a pipeline with data from a semantic store, such as VectorStoreIndex, as well as a BM25 store.\n",
|
||||
"\n",
|
||||
"Each store is queried independently and returns results that the individual store considers to be highly relevant. Figuring out the overall relevance of the results is where reranking comes into play.\n",
|
||||
"\n",
|
||||
"Follow along with the [Advanced - Hybrid Retriever + Re-Ranking](https://docs.llamaindex.ai/en/stable/examples/retrievers/bm25_retriever/#advanced-hybrid-retriever-re-ranking) use case, substitute [the reranker](https://docs.llamaindex.ai/en/stable/examples/retrievers/bm25_retriever/#re-ranker-setup) with -"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Installation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install --upgrade --quiet llama-index-postprocessor-nvidia-rerank llama-index-llms-nvidia llama-index-readers-file"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"**To get started:**\n",
|
||||
"\n",
|
||||
"1. Create a free account with [NVIDIA](https://build.nvidia.com/), which hosts NVIDIA AI Foundation models.\n",
|
||||
"\n",
|
||||
"2. Click on your model of choice.\n",
|
||||
"\n",
|
||||
"3. Under Input select the Python tab, and click `Get API Key`. Then click `Generate Key`.\n",
|
||||
"\n",
|
||||
"4. Copy and save the generated key as NVIDIA_API_KEY. From there, you should have access to the endpoints."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# del os.environ['NVIDIA_API_KEY'] ## delete key and reset\n",
|
||||
"if os.environ.get(\"NVIDIA_API_KEY\", \"\").startswith(\"nvapi-\"):\n",
|
||||
" print(\"Valid NVIDIA_API_KEY already in environment. Delete to reset\")\n",
|
||||
"else:\n",
|
||||
" nvapi_key = getpass.getpass(\"NVAPI Key (starts with nvapi-): \")\n",
|
||||
" assert nvapi_key.startswith(\n",
|
||||
" \"nvapi-\"\n",
|
||||
" ), f\"{nvapi_key[:5]}... is not a valid key\"\n",
|
||||
" os.environ[\"NVIDIA_API_KEY\"] = nvapi_key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Working with the NVIDIA API Catalog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.nvidia_rerank import NVIDIARerank\n",
|
||||
"from llama_index.core import SimpleDirectoryReader, Settings, VectorStoreIndex\n",
|
||||
"from llama_index.embeddings.nvidia import NVIDIAEmbedding\n",
|
||||
"from llama_index.llms.nvidia import NVIDIA\n",
|
||||
"from llama_index.core.node_parser import SentenceSplitter\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"reranker = NVIDIARerank(top_n=4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"mkdir: cannot create directory ‘data’: File exists\n",
|
||||
"--2024-07-03 10:33:17-- https://www.dropbox.com/scl/fi/p33j9112y0ysgwg77fdjz/2021_Housing_Inventory.pdf?rlkey=yyok6bb18s5o31snjd2dxkxz3&dl=0\n",
|
||||
"Resolving www.dropbox.com (www.dropbox.com)... 162.125.81.18, 2620:100:6031:18::a27d:5112\n",
|
||||
"Connecting to www.dropbox.com (www.dropbox.com)|162.125.81.18|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 302 Found\n",
|
||||
"Location: https://uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com/cd/0/inline/CV9Hy3nIrjnOf-Fqsgd-YhHcMaj0AHvOQaE1b4sdiKnOBqZL_u9ml6dAGctGxr5I79yD_kI8BNwDtFl_ll_sdfdt0iXcIYosfxaPr2NdbkRAMR6vg9UXuCU8kNEFi0D3Grs/file# [following]\n",
|
||||
"--2024-07-03 10:33:18-- https://uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com/cd/0/inline/CV9Hy3nIrjnOf-Fqsgd-YhHcMaj0AHvOQaE1b4sdiKnOBqZL_u9ml6dAGctGxr5I79yD_kI8BNwDtFl_ll_sdfdt0iXcIYosfxaPr2NdbkRAMR6vg9UXuCU8kNEFi0D3Grs/file\n",
|
||||
"Resolving uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com (uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com)... 162.125.81.15, 2620:100:6031:15::a27d:510f\n",
|
||||
"Connecting to uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com (uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com)|162.125.81.15|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 302 Found\n",
|
||||
"Location: /cd/0/inline2/CV9Ugj_mK7TSMb3sw_BdQFrj2rzx-SI2cfGU7-VF4bcW3PdhxO4qw--AXQKUidWtDL_54rViwvbaBGHMvtMEAK_lCIwXXj5XwkKpJKTmP0mDrz8eU2qu0FGyi4uOGfO7TeNLFMFY_bBGUMHMatvKJVPF59Ps94-8LC40ba-Cgv2YKZtcU-UjFpLh-Fnf6emkG-c8eUWB2uKPX_Lx0E4hCENQEPOGOfMhDHU0DC8k6khZiilmLtjXsDJ0H4y3efQ-Fz-VsWCC2FcoGpDcxXGu1Ysp5-mP2eHpH3qOx20d2IrndwN4RGLAqzR6cfsOHPMvoYPyLjOW1322t1O46mXqcjv94OPEEIIHI-2K8xL4pBjLUQ/file [following]\n",
|
||||
"--2024-07-03 10:33:18-- https://uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com/cd/0/inline2/CV9Ugj_mK7TSMb3sw_BdQFrj2rzx-SI2cfGU7-VF4bcW3PdhxO4qw--AXQKUidWtDL_54rViwvbaBGHMvtMEAK_lCIwXXj5XwkKpJKTmP0mDrz8eU2qu0FGyi4uOGfO7TeNLFMFY_bBGUMHMatvKJVPF59Ps94-8LC40ba-Cgv2YKZtcU-UjFpLh-Fnf6emkG-c8eUWB2uKPX_Lx0E4hCENQEPOGOfMhDHU0DC8k6khZiilmLtjXsDJ0H4y3efQ-Fz-VsWCC2FcoGpDcxXGu1Ysp5-mP2eHpH3qOx20d2IrndwN4RGLAqzR6cfsOHPMvoYPyLjOW1322t1O46mXqcjv94OPEEIIHI-2K8xL4pBjLUQ/file\n",
|
||||
"Reusing existing connection to uc471d2c8af935aa4ab2f86937a6.dl.dropboxusercontent.com:443.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 4808625 (4.6M) [application/pdf]\n",
|
||||
"Saving to: ‘data/housing_data.pdf’\n",
|
||||
"\n",
|
||||
"data/housing_data.p 100%[===================>] 4.58M 2.68MB/s in 1.7s \n",
|
||||
"\n",
|
||||
"2024-07-03 10:33:21 (2.68 MB/s) - ‘data/housing_data.pdf’ saved [4808625/4808625]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir data\n",
|
||||
"!wget \"https://www.dropbox.com/scl/fi/p33j9112y0ysgwg77fdjz/2021_Housing_Inventory.pdf?rlkey=yyok6bb18s5o31snjd2dxkxz3&dl=0\" -O \"data/housing_data.pdf\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"Settings.text_splitter = SentenceSplitter(chunk_size=500)\n",
|
||||
"\n",
|
||||
"documents = SimpleDirectoryReader(\"./data\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"Settings.embed_model = NVIDIAEmbedding(model=\"NV-Embed-QA\", truncate=\"END\")\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex.from_documents(documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"Settings.llm = NVIDIA()\n",
|
||||
"\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=20, node_postprocessors=[reranker]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The net gain in housing units in the Mission in 2021 was not specified in the provided context information.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"What was the net gain in housing units in the Mission in 2021?\"\n",
|
||||
")\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Working with NVIDIA NIMs\n",
|
||||
"\n",
|
||||
"In addition to connecting to hosted [NVIDIA NIMs](https://ai.nvidia.com), this connector can be used to connect to local NIM instances. This helps you take your applications local when necessary.\n",
|
||||
"\n",
|
||||
"For instructions on how to set up local NIM instances, refer to [NVIDIA NIM](https://developer.nvidia.com/nim)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.nvidia_rerank import NVIDIARerank\n",
|
||||
"\n",
|
||||
"# Connect to a rerank NIM running at localhost:1976\n",
|
||||
"reranker = NVIDIARerank(base_url=\"http://localhost:1976/v1\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "35984f41",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/OptimizerDemo.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "7ff2c269",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Sentence Embedding Optimizer\n",
|
||||
"\n",
|
||||
"This postprocessor optimizes token usage by removing sentences that are not relevant to the query (this is done using embeddings).The percentile cutoff is a measure for using the top percentage of relevant sentences. The threshold cutoff can be specified instead, which uses a raw similarity cutoff for picking which sentences to keep."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5d8d212e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-readers-wikipedia"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "839c4a87",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# My OpenAI Key\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"INSERT OPENAI KEY\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "40cf0773",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "1429a4c9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "01f3b5d1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fa34cd83",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import download_loader\n",
|
||||
"\n",
|
||||
"from llama_index.readers.wikipedia import WikipediaReader\n",
|
||||
"\n",
|
||||
"loader = WikipediaReader()\n",
|
||||
"documents = loader.load_data(pages=[\"Berlin\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f59e6c18",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"<class 'llama_index.readers.schema.base.Document'>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:root:> [build_index_from_documents] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:root:> [build_index_from_documents] Total embedding token usage: 18390 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex.from_documents(documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "827ada33",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Compare query with and without optimization for LLM token usage, Embedding Model usage on query, Embedding model usage for optimizer, and total time."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a04e4535",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Without optimization\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:root:> [query] Total LLM token usage: 3545 tokens\n",
|
||||
"INFO:root:> [query] Total embedding token usage: 7 tokens\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total time elapsed: 2.8928110599517822\n",
|
||||
"Answer: \n",
|
||||
"The population of Berlin in 1949 was approximately 2.2 million inhabitants. After the fall of the Berlin Wall in 1989, the population of Berlin increased to approximately 3.7 million inhabitants.\n",
|
||||
"\n",
|
||||
"With optimization\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:root:> [optimize] Total embedding token usage: 7 tokens\n",
|
||||
"INFO:root:> [query] Total LLM token usage: 1779 tokens\n",
|
||||
"INFO:root:> [query] Total embedding token usage: 7 tokens\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total time elapsed: 2.346346139907837\n",
|
||||
"Answer: \n",
|
||||
"The population of Berlin is around 4.5 million.\n",
|
||||
"Alternate optimization cutoff\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:root:> [optimize] Total embedding token usage: 7 tokens\n",
|
||||
"INFO:root:> [query] Total LLM token usage: 3215 tokens\n",
|
||||
"INFO:root:> [query] Total embedding token usage: 7 tokens\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total time elapsed: 2.101111888885498\n",
|
||||
"Answer: \n",
|
||||
"The population of Berlin is around 4.5 million.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import time\n",
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"from llama_index.core.postprocessor import SentenceEmbeddingOptimizer\n",
|
||||
"\n",
|
||||
"print(\"Without optimization\")\n",
|
||||
"start_time = time.time()\n",
|
||||
"query_engine = index.as_query_engine()\n",
|
||||
"res = query_engine.query(\"What is the population of Berlin?\")\n",
|
||||
"end_time = time.time()\n",
|
||||
"print(\"Total time elapsed: {}\".format(end_time - start_time))\n",
|
||||
"print(\"Answer: {}\".format(res))\n",
|
||||
"\n",
|
||||
"print(\"With optimization\")\n",
|
||||
"start_time = time.time()\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" node_postprocessors=[SentenceEmbeddingOptimizer(percentile_cutoff=0.5)]\n",
|
||||
")\n",
|
||||
"res = query_engine.query(\"What is the population of Berlin?\")\n",
|
||||
"end_time = time.time()\n",
|
||||
"print(\"Total time elapsed: {}\".format(end_time - start_time))\n",
|
||||
"print(\"Answer: {}\".format(res))\n",
|
||||
"\n",
|
||||
"print(\"Alternate optimization cutoff\")\n",
|
||||
"start_time = time.time()\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" node_postprocessors=[SentenceEmbeddingOptimizer(threshold_cutoff=0.7)]\n",
|
||||
")\n",
|
||||
"res = query_engine.query(\"What is the population of Berlin?\")\n",
|
||||
"end_time = time.time()\n",
|
||||
"print(\"Total time elapsed: {}\".format(end_time - start_time))\n",
|
||||
"print(\"Answer: {}\".format(res))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "8f74e1c4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/PII.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "c04ffe8e-6573-470f-aef5-348522a0de15",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# PII Masking"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "94cf2040",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "83660e9a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-llms-openai\n",
|
||||
"%pip install llama-index-llms-huggingface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "254fff73",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "efa2a242-27bc-478f-8939-18a7f8153d4f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:numexpr.utils:Note: NumExpr detected 16 cores but \"NUMEXPR_MAX_THREADS\" not set, so enforcing safe limit of 8.\n",
|
||||
"Note: NumExpr detected 16 cores but \"NUMEXPR_MAX_THREADS\" not set, so enforcing safe limit of 8.\n",
|
||||
"INFO:numexpr.utils:NumExpr defaulting to 8 threads.\n",
|
||||
"NumExpr defaulting to 8 threads.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/loganm/miniconda3/envs/llama-index/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
||||
" from .autonotebook import tqdm as notebook_tqdm\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import logging\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
|
||||
"logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))\n",
|
||||
"\n",
|
||||
"from llama_index.core.postprocessor import (\n",
|
||||
" PIINodePostprocessor,\n",
|
||||
" NERPIINodePostprocessor,\n",
|
||||
")\n",
|
||||
"from llama_index.llms.huggingface import HuggingFaceLLM\n",
|
||||
"from llama_index.core import Document, VectorStoreIndex\n",
|
||||
"from llama_index.core.schema import TextNode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "216e951a-42c4-4e6b-b16d-6a6064829ebf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"text = \"\"\"\n",
|
||||
"Hello Paulo Santos. The latest statement for your credit card account \\\n",
|
||||
"1111-0000-1111-0000 was mailed to 123 Any Street, Seattle, WA 98109.\n",
|
||||
"\"\"\"\n",
|
||||
"node = TextNode(text=text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "24495d69-d568-4cc7-9445-87692bf77863",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Option 1: Use NER Model for PII Masking\n",
|
||||
"\n",
|
||||
"Use a Hugging Face NER model for PII Masking"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "003f66f0-f67f-47f2-88eb-b2bbb6d33791",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"processor = NERPIINodePostprocessor()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e76c995c-57ee-4d1b-a771-6626ef93e8cd",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"No model was supplied, defaulted to dbmdz/bert-large-cased-finetuned-conll03-english and revision f2482bf (https://huggingface.co/dbmdz/bert-large-cased-finetuned-conll03-english).\n",
|
||||
"Using a pipeline without specifying a model name and revision in production is not recommended.\n",
|
||||
"/home/loganm/miniconda3/envs/llama-index/lib/python3.11/site-packages/transformers/pipelines/token_classification.py:169: UserWarning: `grouped_entities` is deprecated and will be removed in version v5.0.0, defaulted to `aggregation_strategy=\"AggregationStrategy.SIMPLE\"` instead.\n",
|
||||
" warnings.warn(\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.schema import NodeWithScore\n",
|
||||
"\n",
|
||||
"new_nodes = processor.postprocess_nodes([NodeWithScore(node=node)])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d4783c27-9a55-44f1-be9e-a4fe1fc1e0fa",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'Hello [ORG_6]. The latest statement for your credit card account 1111-0000-1111-0000 was mailed to 123 [ORG_108] [LOC_112], [LOC_120], [LOC_129] 98109.'"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# view redacted text\n",
|
||||
"new_nodes[0].node.get_text()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "075d45dc-a226-4ba7-8c8a-d9dd536f8560",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'[ORG_6]': 'Paulo Santos',\n",
|
||||
" '[ORG_108]': 'Any',\n",
|
||||
" '[LOC_112]': 'Street',\n",
|
||||
" '[LOC_120]': 'Seattle',\n",
|
||||
" '[LOC_129]': 'WA'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# get mapping in metadata\n",
|
||||
"# NOTE: this is not sent to the LLM!\n",
|
||||
"new_nodes[0].node.metadata[\"__pii_node_info__\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "06ca1e50-eeee-4079-bec6-3621cb760f98",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Option 2: Use LLM for PII Masking\n",
|
||||
"\n",
|
||||
"NOTE: You should be using a *local* LLM model for PII masking. The example shown is using OpenAI, but normally you'd use an LLM running locally, possibly from huggingface. Examples for local LLMs are [here](https://gpt-index.readthedocs.io/en/latest/how_to/customization/custom_llms.html#example-using-a-huggingface-llm)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5a2db8d3-6bb7-4855-852e-a4941abb03bf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"\n",
|
||||
"processor = PIINodePostprocessor(llm=OpenAI())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b834e7a3-8f90-45eb-841a-335b0d33dcab",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.schema import NodeWithScore\n",
|
||||
"\n",
|
||||
"new_nodes = processor.postprocess_nodes([NodeWithScore(node=node)])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ca1498f3-34a1-4001-90f9-03feb5532d7d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'Hello [NAME]. The latest statement for your credit card account [CREDIT_CARD_NUMBER] was mailed to [ADDRESS].'"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# view redacted text\n",
|
||||
"new_nodes[0].node.get_text()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d574d591-c1db-498b-ba32-9ed4190c6b4c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'NAME': 'Paulo Santos',\n",
|
||||
" 'CREDIT_CARD_NUMBER': '1111-0000-1111-0000',\n",
|
||||
" 'ADDRESS': '123 Any Street, Seattle, WA 98109'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# get mapping in metadata\n",
|
||||
"# NOTE: this is not sent to the LLM!\n",
|
||||
"new_nodes[0].node.metadata[\"__pii_node_info__\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6cc87ed4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Option 3: Use Presidio for PII Masking\n",
|
||||
"\n",
|
||||
"Use presidio to identify and anonymize PII"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ac215117",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"text = \"\"\"\n",
|
||||
"Hello Paulo Santos. The latest statement for your credit card account \\\n",
|
||||
"4095-2609-9393-4932 was mailed to Seattle, WA 98109. \\\n",
|
||||
"IBAN GB90YNTU67299444055881 and social security number is 474-49-7577 were verified on the system. \\\n",
|
||||
"Further communications will be sent to paulo@presidio.site \n",
|
||||
"\"\"\"\n",
|
||||
"presidio_node = TextNode(text=text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8a745520",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.presidio import PresidioPIINodePostprocessor\n",
|
||||
"\n",
|
||||
"processor = PresidioPIINodePostprocessor()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "89cb17ed",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.schema import NodeWithScore\n",
|
||||
"\n",
|
||||
"presidio_new_nodes = processor.postprocess_nodes(\n",
|
||||
" [NodeWithScore(node=presidio_node)]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b8fe9cef",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'\\nHello <PERSON_1>. The latest statement for your credit card account <CREDIT_CARD_1> was mailed to <LOCATION_2>, <LOCATION_1>. IBAN <IBAN_CODE_1> and social security number is <US_SSN_1> were verified on the system. Further communications will be sent to <EMAIL_ADDRESS_1> \\n'"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# view redacted text\n",
|
||||
"presidio_new_nodes[0].node.get_text()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "80203af0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'<EMAIL_ADDRESS_1>': 'paulo@presidio.site',\n",
|
||||
" '<US_SSN_1>': '474-49-7577',\n",
|
||||
" '<IBAN_CODE_1>': 'GB90YNTU67299444055881',\n",
|
||||
" '<LOCATION_1>': 'WA 98109',\n",
|
||||
" '<LOCATION_2>': 'Seattle',\n",
|
||||
" '<CREDIT_CARD_1>': '4095-2609-9393-4932',\n",
|
||||
" '<PERSON_1>': 'Paulo Santos'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# get mapping in metadata\n",
|
||||
"# NOTE: this is not sent to the LLM!\n",
|
||||
"presidio_new_nodes[0].node.metadata[\"__pii_node_info__\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "3444d895-e2fd-4af9-834a-64acf49f74f8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Feed Nodes to Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9d33a9c0-efcd-4e79-b1f5-05aca9fc109f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total embedding token usage: 30 tokens\n",
|
||||
"> [build_index_from_nodes] Total embedding token usage: 30 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# feed into index\n",
|
||||
"index = VectorStoreIndex([n.node for n in new_nodes])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dc8b1993-d23b-4db1-8bb9-4f882bded66c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"> [retrieve] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [retrieve] Total embedding token usage: 8 tokens\n",
|
||||
"> [retrieve] Total embedding token usage: 8 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [get_response] Total LLM token usage: 71 tokens\n",
|
||||
"> [get_response] Total LLM token usage: 71 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [get_response] Total embedding token usage: 0 tokens\n",
|
||||
"> [get_response] Total embedding token usage: 0 tokens\n",
|
||||
"\n",
|
||||
"[ADDRESS]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = index.as_query_engine().query(\n",
|
||||
" \"What address was the statement mailed to?\"\n",
|
||||
")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-index",
|
||||
"language": "python",
|
||||
"name": "llama-index"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "01958126",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/PrevNextPostprocessorDemo.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b1c1ebaa-50de-4851-a720-acbb977551ea",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Forward/Backward Augmentation\n",
|
||||
"\n",
|
||||
"Showcase capabilities of leveraging Node relationships on top of PG's essay"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "af13dadb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4c9fd41c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "92d06b38-2103-4a40-93c3-60e0708a1124",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import (\n",
|
||||
" PrevNextNodePostprocessor,\n",
|
||||
" AutoPrevNextNodePostprocessor,\n",
|
||||
")\n",
|
||||
"from llama_index.core.node_parser import SentenceSplitter\n",
|
||||
"from llama_index.core.storage.docstore import SimpleDocumentStore"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "f5b971dd",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f7c432bb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "67020156-2975-4bbb-8e98-afc55abb3d72",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Parse Documents into Nodes, add to Docstore"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "caddd84e-9827-40a4-9520-dba6405fd1fd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"from llama_index.core import StorageContext\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham\").load_data()\n",
|
||||
"\n",
|
||||
"# define settings\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.chunk_size = 512\n",
|
||||
"\n",
|
||||
"# use node parser in settings to parse into nodes\n",
|
||||
"nodes = Settings.node_parser.get_nodes_from_documents(documents)\n",
|
||||
"\n",
|
||||
"# add to docstore\n",
|
||||
"docstore = SimpleDocumentStore()\n",
|
||||
"docstore.add_documents(nodes)\n",
|
||||
"\n",
|
||||
"storage_context = StorageContext.from_defaults(docstore=docstore)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e5a25b95-de5e-4e56-a846-51e9c6eba181",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5f7f68d6-2389-4f6c-bc4e-8612a1a53fb8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex(nodes, storage_context=storage_context)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e493666e-ca76-47c0-bb9a-aa70c9eee3df",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Add PrevNext Node Postprocessor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a1d34f87-2997-452a-bad4-65380775e534",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"node_postprocessor = PrevNextNodePostprocessor(docstore=docstore, num_nodes=4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7675437d-d7be-436b-898c-dac0df5990b9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=1,\n",
|
||||
" node_postprocessors=[node_postprocessor],\n",
|
||||
" response_mode=\"tree_summarize\",\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do after handing off Y Combinator to Sam Altman?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3d2391ea-2bac-4ceb-bedb-57ba0c9cabca",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"After handing off Y Combinator to Sam Altman, the author decided to take up painting. He spent most of the rest of 2014 painting and eventually ran out of steam in November. He then started writing essays again and wrote a few that weren't about startups. In March 2015, he started working on Lisp again and wrote a new Lisp, called Bel, in itself in Arc. He banned himself from writing essays during most of this time and worked on Bel intensively. In the summer of 2016, he and his family moved to England and he continued working on Bel there. In the fall of 2019, Bel was finally finished and he wrote a bunch of essays about topics he had stacked up. He then started to think about other things he could work on and wrote an essay for himself to answer that question.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0cafc75d-fd83-43ff-948b-b171da75c647",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Try querying index without node postprocessor\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=1, response_mode=\"tree_summarize\"\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do after handing off Y Combinator to Sam Altman?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f2aa1763-5557-4ad8-ac43-74d2661a0966",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"The author decided to take up painting and spent the rest of 2014 painting. He wanted to see how good he could get if he really focused on it.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a1c3e599-5376-4706-9a83-d3a769df6e46",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Try querying index without node postprocessor and higher top-k\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3, response_mode=\"tree_summarize\"\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do after handing off Y Combinator to Sam Altman?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7cfda042-c88b-4ce1-a61d-65baafff4d1c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"After handing off Y Combinator to Sam Altman, the author decided to take a break and focus on painting. He also gave a talk to the Harvard Computer Society about how to start a startup, and decided to start angel investing. He also schemed with Robert and Trevor about projects they could work on together. Finally, he and Jessica decided to start their own investment firm, which eventually became Y Combinator.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e6917ff5-be24-4b76-837a-ea5de7f492cb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Add Auto Prev/Next Node Postprocessor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "82d510b0-5a90-45bb-ace1-de764bc7a068",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"node_postprocessor = AutoPrevNextNodePostprocessor(\n",
|
||||
" docstore=docstore,\n",
|
||||
" num_nodes=3,\n",
|
||||
" verbose=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c6a8094f-c757-4dae-b81a-248d65166443",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Postprocessor Predicted mode: next\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Infer that we need to search nodes after current one\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=1,\n",
|
||||
" node_postprocessors=[node_postprocessor],\n",
|
||||
" response_mode=\"tree_summarize\",\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do after handing off Y Combinator to Sam Altman?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "055f5663-b1f8-4f11-bfbf-b04bcf6ee53c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"After handing off Y Combinator to Sam Altman, the author decided to take a break and focus on painting. He spent most of 2014 painting and was able to work more uninterruptedly than he had before. He also wrote a few essays that weren't about startups. In March 2015, he started working on Lisp again and wrote a new Lisp, called Bel, in itself in Arc. He had to ban himself from writing essays during most of this time in order to finish the project. In the summer of 2016, he and his family moved to England and he wrote most of Bel there. In the fall of 2019, Bel was finally finished. He then wrote a bunch of essays about topics he had stacked up and started to think about other things he could work on.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1fd4392f-8e71-4a07-b123-5af23d33744a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Postprocessor Predicted mode: none\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Infer that we don't need to search previous or next\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do during his time at Y Combinator?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dfa87d01-5349-452d-af5a-58c474e89d7a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"The author did a variety of things during his time at Y Combinator, including hacking, writing essays, and working on YC. He also worked on a new version of Arc and wrote Hacker News in it. Additionally, he noticed the advantages of scaling startup funding and the tight community of alumni dedicated to helping one another.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "33b92118-50fb-4b19-85a6-a94a11950fb6",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Postprocessor Predicted mode: previous\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Infer that we need to search nodes before current one\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do before handing off Y Combinator to Sam Altman?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6de2caac-95cc-4d98-9c3d-d16916aaab11",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"Before handing off Y Combinator to Sam Altman, the author worked on writing essays, working on Y Combinator, writing all of Y Combinator's internal software in Arc, and fighting with people who maltreated the startups. He also spent time visiting his mother, who had a stroke and was in a nursing home, and thinking about what to do next.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "14822e9b-fe96-44e9-a7fd-a441f6fe2ae4",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Postprocessor Predicted mode: previous\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did the author do before handing off Y Combinator to Sam Altman?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7dbdeafc-1829-4110-a6ca-ca81eac6e0c9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"Before handing off Y Combinator to Sam Altman, the author worked on YC, wrote essays, and wrote all of YC's internal software in Arc. He also worked on a new version of Arc with Robert Morris, which he tested by writing Hacker News in it.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-index",
|
||||
"language": "python",
|
||||
"name": "llama-index"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "b1c1ebaa-50de-4851-a720-acbb977551ea",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Recency Filtering\n",
|
||||
"\n",
|
||||
"Showcase capabilities of recency-weighted node postprocessor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "89a402a6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "92d06b38-2103-4a40-93c3-60e0708a1124",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import (\n",
|
||||
" FixedRecencyPostprocessor,\n",
|
||||
" EmbeddingRecencyPostprocessor,\n",
|
||||
")\n",
|
||||
"from llama_index.core.node_parser import SentenceSplitter\n",
|
||||
"from llama_index.core.storage.docstore import SimpleDocumentStore\n",
|
||||
"from llama_index.core.response.notebook_utils import display_response"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "67020156-2975-4bbb-8e98-afc55abb3d72",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Parse Documents into Nodes, add to Docstore\n",
|
||||
"\n",
|
||||
"In this example, there are 3 different versions of PG's essay. They are largely identical **except** \n",
|
||||
"for one specific section, which details the amount of funding they raised for Viaweb. \n",
|
||||
"\n",
|
||||
"V1: 50k, V2: 30k, V3: 10K\n",
|
||||
"\n",
|
||||
"V1: 2020-01-01, V2: 2020-02-03, V3: 2022-04-12\n",
|
||||
"\n",
|
||||
"The idea is to encourage index to fetch the most recent info (which is V3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "caddd84e-9827-40a4-9520-dba6405fd1fd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"from llama_index.core import StorageContext\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_file_metadata(file_name: str):\n",
|
||||
" \"\"\"Get file metadata.\"\"\"\n",
|
||||
" if \"v1\" in file_name:\n",
|
||||
" return {\"date\": \"2020-01-01\"}\n",
|
||||
" elif \"v2\" in file_name:\n",
|
||||
" return {\"date\": \"2020-02-03\"}\n",
|
||||
" elif \"v3\" in file_name:\n",
|
||||
" return {\"date\": \"2022-04-12\"}\n",
|
||||
" else:\n",
|
||||
" raise ValueError(\"invalid file\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"documents = SimpleDirectoryReader(\n",
|
||||
" input_files=[\n",
|
||||
" \"test_versioned_data/paul_graham_essay_v1.txt\",\n",
|
||||
" \"test_versioned_data/paul_graham_essay_v2.txt\",\n",
|
||||
" \"test_versioned_data/paul_graham_essay_v3.txt\",\n",
|
||||
" ],\n",
|
||||
" file_metadata=get_file_metadata,\n",
|
||||
").load_data()\n",
|
||||
"\n",
|
||||
"# define settings\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.text_splitter = SentenceSplitter(chunk_size=512)\n",
|
||||
"\n",
|
||||
"# use node parser to parse into nodes\n",
|
||||
"nodes = Settings.text_splitter.get_nodes_from_documents(documents)\n",
|
||||
"\n",
|
||||
"# add to docstore\n",
|
||||
"docstore = SimpleDocumentStore()\n",
|
||||
"docstore.add_documents(nodes)\n",
|
||||
"\n",
|
||||
"storage_context = StorageContext.from_defaults(docstore=docstore)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "191ced40-80f4-40e7-bf31-0c9a5a664cf2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(documents[2].get_text())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e5a25b95-de5e-4e56-a846-51e9c6eba181",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5f7f68d6-2389-4f6c-bc4e-8612a1a53fb8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total embedding token usage: 84471 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex(nodes, storage_context=storage_context)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "86c5e8aa-18d8-4229-b7b2-a1c97c11a09a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Define Recency Postprocessors"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ba5e10c9-5a7e-4ea8-a74d-0e0f74b5cd1b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"node_postprocessor = FixedRecencyPostprocessor()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "94f44f2b-d816-43a0-87dc-ea8eefc7d534",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"node_postprocessor_emb = EmbeddingRecencyPostprocessor()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "efcfffe4-a8aa-486d-b46d-f73f985dffca",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Query Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "78d6c3db-61e6-4d9a-a84d-d7be846b4112",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 1813 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 22 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# naive query\n",
|
||||
"\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3,\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"How much did the author raise in seed funding from Idelle's husband\"\n",
|
||||
" \" (Julian) for Viaweb?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1d672c52-c0ac-4e5f-9175-855e66eb97ba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# query using fixed recency node postprocessor\n",
|
||||
"\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3, node_postprocessors=[node_postprocessor]\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"How much did the author raise in seed funding from Idelle's husband\"\n",
|
||||
" \" (Julian) for Viaweb?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bc1328c1-23b2-406c-b80b-6d97bffc33ae",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 541 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 22 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# query using embedding-based node postprocessor\n",
|
||||
"\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3, node_postprocessors=[node_postprocessor_emb]\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"How much did the author raise in seed funding from Idelle's husband\"\n",
|
||||
" \" (Julian) for Viaweb?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dd00cc97-4de7-4c61-9c0c-3f9ee3598528",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Query Index (Lower-Level Usage)\n",
|
||||
"\n",
|
||||
"In this example we first get the full set of nodes from a query call, and then send to node postprocessor, and then\n",
|
||||
"finally synthesize response through a summary index."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "350b039e-d45d-4b6b-957a-4b14d8816cbd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SummaryIndex"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "234f909f-6faa-43e6-96f8-0966699c9552",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_str = (\n",
|
||||
" \"How much did the author raise in seed funding from Idelle's husband\"\n",
|
||||
" \" (Julian) for Viaweb?\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "20afbf6b-9473-446e-b522-b90fef2e3bf0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 22 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3, response_mode=\"no_text\"\n",
|
||||
")\n",
|
||||
"init_response = query_engine.query(\n",
|
||||
" query_str,\n",
|
||||
")\n",
|
||||
"resp_nodes = [n.node for n in init_response.source_nodes]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cdc03574-a806-4255-953c-6f82fc3f202f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total LLM token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total embedding token usage: 0 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 541 tokens\n",
|
||||
"INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 0 tokens\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"summary_index = SummaryIndex(resp_nodes)\n",
|
||||
"query_engine = summary_index.as_query_engine(\n",
|
||||
" node_postprocessors=[node_postprocessor]\n",
|
||||
")\n",
|
||||
"response = query_engine.query(query_str)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "c9c30403",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/SentenceTransformerRerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cd1f531c-303c-4d19-9a6a-1259def23c07",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Rerank can speed up an LLM query without sacrificing accuracy (and in fact, probably improving it). It does so by pruning away irrelevant nodes from the context."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "2d21a258",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5ef31b9e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-embeddings-huggingface\n",
|
||||
"%pip install llama-index-llms-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c65114dc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ae5c7d2f-ad2f-4d42-8d05-7441f7d344d9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "caee0963",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2479d058",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2fcb92e6-f1e2-4ba5-9ccb-d69a2c959197",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4fbd38ae-0821-465d-b422-80fd9901213b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/jonch/.local/lib/python3.10/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
||||
" from .autonotebook import tqdm as notebook_tqdm\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"\n",
|
||||
"Settings.llm = OpenAI(model=\"gpt-3.5-turbo\")\n",
|
||||
"Settings.embed_model = HuggingFaceEmbedding(\n",
|
||||
" model_name=\"BAAI/bge-small-en-v1.5\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "06f4a1c6-7320-4252-89ff-81e15a8eadae",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(documents=documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "85f21b3c-43c6-4fde-b60f-e464ee3e435f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.postprocessor import SentenceTransformerRerank\n",
|
||||
"\n",
|
||||
"rerank = SentenceTransformerRerank(\n",
|
||||
" model=\"cross-encoder/ms-marco-MiniLM-L2-v2\", top_n=3\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4027f9c4-044e-48f5-8231-820e91fab20d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"First, we try with reranking. We time the query to see how long it takes to process the output from the retrieved context."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "51abb86b-43c3-49ad-b262-311b8159fe4e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from time import time"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "740d20ab-cd91-4bc4-ba64-170f23fdadfc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Elapsed: 4.03s\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10, node_postprocessors=[rerank]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"now = time()\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"Which grad schools did the author apply for and why?\",\n",
|
||||
")\n",
|
||||
"print(f\"Elapsed: {round(time() - now, 2)}s\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e07f98ac-df41-445f-a050-66d4a193a603",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"The author applied to three grad schools: MIT and Yale, which were renowned for AI at the time, and Harvard, which the author had visited because a friend went there and it was also home to Bill Woods, who had invented the type of parser the author used in his SHRDLU clone. The author chose these schools because he wanted to learn about AI and Lisp, and these schools were known for their expertise in these areas.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cb808169-b7bb-4ed7-9bf0-c3091afbaf0b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: 08074ca9-1806-4e49-84de-102a97f1f220): been explored. But all I wanted was to get out of grad school, and my rapidly written dissertation sufficed, just barely.\n",
|
||||
"\n",
|
||||
"Meanwhile I was applying to art schools. I applied to two: RISD in the US,...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 737f4526-2752-45e8-a59a-e1e4528cc025): about money, because I could sense that Interleaf was on the way down. Freelance Lisp hacking work was very rare, and I didn't want to have to program in another language, which in those days would...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: b8883569-44f9-454c-9f62-15e926d04b98): showed Terry Winograd using SHRDLU. I haven't tried rereading The Moon is a Harsh Mistress, so I don't know how well it has aged, but when I read it I was drawn entirely into its world. It seemed o...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.get_formatted_sources(length=200))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8de93bda-09f1-44cf-87ee-0b249758a28d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next, we try without rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "655f975d-69db-470c-9388-5736b1ca6d0f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Elapsed: 28.13s\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(similarity_top_k=10)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"now = time()\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"Which grad schools did the author apply for and why?\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(f\"Elapsed: {round(time() - now, 2)}s\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b4a57135-9944-4154-a100-22c80cc94a87",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"The author applied to three grad schools: MIT and Yale, which were renowned for AI at the time, and Harvard, which the author had visited because a friend went there and was also home to Bill Woods, who had invented the type of parser the author used in his SHRDLU clone. The author chose these schools because he was interested in Artificial Intelligence and wanted to pursue it further, and they were the most renowned for it at the time. He was also inspired by a novel by Heinlein called The Moon is a Harsh Mistress, which featured an intelligent computer called Mike, and a PBS documentary that showed Terry Winograd using SHRDLU. Additionally, the author had dropped out of RISD, where he had been learning to paint, and was looking for a new challenge. He was drawn to the idea of pursuing AI, as it was a field that was rapidly growing and he wanted to be part of the cutting edge of technology. He was also inspired by the idea of creating something unique and innovative, as he had done with his SHRDLU clone, and wanted to continue to explore the possibilities of AI.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "30d2da74-ec2b-4f8f-90fb-9b0685ded447",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: 08074ca9-1806-4e49-84de-102a97f1f220): been explored. But all I wanted was to get out of grad school, and my rapidly written dissertation sufficed, just barely.\n",
|
||||
"\n",
|
||||
"Meanwhile I was applying to art schools. I applied to two: RISD in the US,...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 737f4526-2752-45e8-a59a-e1e4528cc025): about money, because I could sense that Interleaf was on the way down. Freelance Lisp hacking work was very rare, and I didn't want to have to program in another language, which in those days would...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: b8883569-44f9-454c-9f62-15e926d04b98): showed Terry Winograd using SHRDLU. I haven't tried rereading The Moon is a Harsh Mistress, so I don't know how well it has aged, but when I read it I was drawn entirely into its world. It seemed o...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 599f469b-9a92-4952-8753-a063c31a953b): I didn't know but would turn out to like a lot: a woman called Jessica Livingston. A couple days later I asked her out.\n",
|
||||
"\n",
|
||||
"Jessica was in charge of marketing at a Boston investment bank. This bank th...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: c865f333-b731-4a8b-a99f-eec54eaa1e6b): Like McCarthy's original Lisp, it's a spec rather than an implementation, although like McCarthy's Lisp it's a spec expressed as code.\n",
|
||||
"\n",
|
||||
"Now that I could write essays again, I wrote a bunch about to...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 69c6b190-2d4e-4128-b9c4-4fd31af2df65): 1960 paper.\n",
|
||||
"\n",
|
||||
"But if so there's no reason to suppose that this is the limit of the language that might be known to them. Presumably aliens need numbers and errors and I/O too. So it seems likely the...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: c9c95028-a49e-440e-a953-7aabe6b9996d): What I Worked On\n",
|
||||
"\n",
|
||||
"February 2021\n",
|
||||
"\n",
|
||||
"Before college the two main things I worked on, outside of school, were writing and programming. I didn't write essays. I wrote what beginning writers were supposed...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 7f0c11db-d6f0-41f9-95bc-1feab914f58f): that big, bureaucratic customers are a dangerous source of money, and that there's not much overlap between conventional office hours and the optimal time for hacking, or conventional offices and t...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: c143a6c2-5f5d-49c5-bc1e-b9caa0ce4931): must tell readers things they don't already know, and some people dislike being told such things.\n",
|
||||
"\n",
|
||||
"[11] People put plenty of stuff on the internet in the 90s of course, but putting something online...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 6e281eec-6964-414b-be61-bcc509d95903): which I'd created years before using Viaweb but had never used for anything. In one day it got 30,000 page views. What on earth had happened? The referring urls showed that someone had posted it on...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.get_formatted_sources(length=200))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "858826fa-d9a9-45b6-be57-3ec7f25704ce",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"As we can see, the query engine with reranking produced a much more concise output in much lower time (4s v.s. 28s). While both responses were essentially correct, the query engine without reranking included a lot of irrelevant information - a phenomenon we could attribute to \"pollution of the context window\"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "93e3f84f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/Structured-LLMReranker-Lyft-10k.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "11b52622-f38a-4b3a-a916-c73619babb48",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Structured LLM Reranker Demonstration (2021 Lyft 10-k)\n",
|
||||
"\n",
|
||||
"This tutorial showcases how to do a two-stage pass for retrieval. Use embedding-based retrieval with a high top-k value\n",
|
||||
"in order to maximize recall and get a large set of candidate items. Then, use LLM-based retrieval\n",
|
||||
"to dynamically select the nodes that are actually relevant to the query using structured output.\n",
|
||||
"\n",
|
||||
"Usage of `StructuredLLMReranker` is preferred over `LLMReranker` when you are using a model that supports function calling.\n",
|
||||
"This class will make use of the structured output capability of the model instead of relying on prompting the model to rank the nodes in a desired format."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e66e4c0c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-llms-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "91b61e96-864c-4ed2-80d6-0ebfdbb57d5c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f630346f-fedd-40f2-8fb3-e052e219a873",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import StructuredLLMRerank\n",
|
||||
"\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from IPython.display import Markdown, display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "231c4418",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "36f2294f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2025-03-20 15:13:23-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/lyft_2021.pdf\n",
|
||||
"Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.110.133, ...\n",
|
||||
"Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 1440303 (1.4M) [application/octet-stream]\n",
|
||||
"Saving to: ‘data/10k/lyft_2021.pdf’\n",
|
||||
"\n",
|
||||
"data/10k/lyft_2021. 100%[===================>] 1.37M --.-KB/s in 0.06s \n",
|
||||
"\n",
|
||||
"2025-03-20 15:13:24 (23.9 MB/s) - ‘data/10k/lyft_2021.pdf’ saved [1440303/1440303]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir -p 'data/10k/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/lyft_2021.pdf' -O 'data/10k/lyft_2021.pdf'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "8a8fdeb2-939c-49dd-b8e6-0139d53a4fb6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data, Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ee132733-b525-4aaf-81db-7eed19ded815",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"# LLM (gpt-4o-mini)\n",
|
||||
"Settings.llm = OpenAI(temperature=0, model=\"gpt-4o-mini\")\n",
|
||||
"\n",
|
||||
"Settings.chunk_overlap = 0\n",
|
||||
"Settings.chunk_size = 128"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "88344ea2-540c-4b46-8a66-ed78870cb80a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\n",
|
||||
" input_files=[\"./data/10k/lyft_2021.pdf\"]\n",
|
||||
").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d478f416-8e85-49ae-9817-e4d78122a120",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "7e3d5f23-dfcd-458d-a9d3-dd66de0ab054",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Retrieval Comparisons"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "47480c6d-8914-4562-a789-fd53a99a7afb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.retrievers import VectorIndexRetriever\n",
|
||||
"from llama_index.core import QueryBundle\n",
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"from copy import deepcopy\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_retrieved_nodes(\n",
|
||||
" query_str, vector_top_k=10, reranker_top_n=3, with_reranker=False\n",
|
||||
"):\n",
|
||||
" query_bundle = QueryBundle(query_str)\n",
|
||||
" # configure retriever\n",
|
||||
" retriever = VectorIndexRetriever(\n",
|
||||
" index=index,\n",
|
||||
" similarity_top_k=vector_top_k,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = retriever.retrieve(query_bundle)\n",
|
||||
"\n",
|
||||
" if with_reranker:\n",
|
||||
" # configure reranker\n",
|
||||
" reranker = StructuredLLMRerank(\n",
|
||||
" choice_batch_size=5,\n",
|
||||
" top_n=reranker_top_n,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = reranker.postprocess_nodes(\n",
|
||||
" retrieved_nodes, query_bundle\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return retrieved_nodes\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def pretty_print(df):\n",
|
||||
" return display(HTML(df.to_html().replace(\"\\\\n\", \"<br>\")))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def visualize_retrieved_nodes(nodes) -> None:\n",
|
||||
" result_dicts = []\n",
|
||||
" for node in nodes:\n",
|
||||
" node = deepcopy(node)\n",
|
||||
" node.node.metadata = {}\n",
|
||||
" node_text = node.node.get_text()\n",
|
||||
" node_text = node_text.replace(\"\\n\", \" \")\n",
|
||||
"\n",
|
||||
" result_dict = {\"Score\": node.score, \"Text\": node_text}\n",
|
||||
" result_dicts.append(result_dict)\n",
|
||||
"\n",
|
||||
" pretty_print(pd.DataFrame(result_dicts))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b8bedc4f-444b-4233-9b72-728e3cfbe056",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What is Lyft's response to COVID-19?\", vector_top_k=5, with_reranker=False\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e85e656b-9377-4640-a10d-a6655afd82bd",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.870327</td>\n",
|
||||
" <td>Further, COVID-19 has and may continue to negatively impact Lyft’s ability to conduct rental operationsthrough the Express Drive program and Lyft Rentals as a result of restrictions on travel, mandated closures, limited staffing availability, and other factors relatedto COVID-19. For example, in 2020, Lyft Rentals temporarily ceased operations, closing its rental locations, as a result of COVID-19.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.858815</td>\n",
|
||||
" <td>The Company has adopted a number of measures in response to the COVID-19 pandemic including, but not limited to, establishing new health and safetyrequirements for ridesharing and updating workplace policies. The Company also made adjustments to its expenses and cash flow to correlate with declines in revenuesincluding headcount reductions in 2020. Refer to Note 17 “Restructuring” to the consolidated financial statements for information regarding the 2020 restructuring events.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.857701</td>\n",
|
||||
" <td>•The responsive measures to the COVID-19 pandemic have caused us to modify our business practices by permitting corporate employees in nearly all of ourlocations to work remotely, limiting employee travel, and canceling, postponing or holding virtual events and meetings.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>0.855108</td>\n",
|
||||
" <td>The strength and duration ofthese challenges cannot be presently estimated.In response to the COVID-19 pandemic, we have adopted multiple measures, including, but not limited, to establishing new health and safety requirements forridesharing and updating workplace policies. We also made adjustments to our expenses and cash flow to correlate with declines in revenues including headcountreductions in 2020.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>0.854779</td>\n",
|
||||
" <td>In 2020, Flexdrive also began to waive rental fees for drivers who are confirmed to have testedpositive for COVID-19 or requested to quarantine by a medical professional, which it continues to do at this time. Further, Lyft Rentals and Flexdrive have facedsignificantly higher costs in transporting, repossessing, cleaning, and17</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8ba150e2-c4e7-4404-b8e1-1603c2b346d3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What is Lyft's response to COVID-19?\",\n",
|
||||
" vector_top_k=20,\n",
|
||||
" reranker_top_n=5,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7541606f-6424-470b-987c-a986ac0a7cf8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>The Company has adopted a number of measures in response to the COVID-19 pandemic including, but not limited to, establishing new health and safetyrequirements for ridesharing and updating workplace policies. The Company also made adjustments to its expenses and cash flow to correlate with declines in revenuesincluding headcount reductions in 2020. Refer to Note 17 “Restructuring” to the consolidated financial statements for information regarding the 2020 restructuring events.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>We have adopted several measures in response to the COVID-19 pandemic including, but not limited to, establishing new health and safety requirements forridesharing, and updating workplace policies. We also made adjustments to our expenses and cash flow to correlate with declines in revenues including the transaction withWoven Planet completed on July 13, 2021 and headcount reductions in 2020.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>10.0</td>\n",
|
||||
" <td>•manage our platform and our business assets and expenses in light of the COVID-19 pandemic and related public health measures issued by various jurisdictions,including travel bans, travel restrictions and shelter-in-place orders, as well as maintain demand for and confidence in the safety of our platform during andfollowing the COVID-19 pandemic;•plan for and manage capital expenditures for our current and future offerings,</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>9.0</td>\n",
|
||||
" <td>The strength and duration ofthese challenges cannot be presently estimated.In response to the COVID-19 pandemic, we have adopted multiple measures, including, but not limited, to establishing new health and safety requirements forridesharing and updating workplace policies. We also made adjustments to our expenses and cash flow to correlate with declines in revenues including headcountreductions in 2020.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>9.0</td>\n",
|
||||
" <td>The strength and duration ofthese challenges cannot be presently estimated.In response to the COVID-19 pandemic, we have adopted multiple measures, including, but not limited, to establishing new health and safety requirements forridesharing and updating workplace policies. We also made adjustments to our expenses and cash flow to correlate with declines in revenues including headcountreductions in 2020.56</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "eb88c0bb-4d3f-4426-b2be-66b0d5635abb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What initiatives are the company focusing on independently of COVID-19?\",\n",
|
||||
" vector_top_k=5,\n",
|
||||
" with_reranker=False,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3c4b3962-2873-40b3-9f50-58cf7685454a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.813871</td>\n",
|
||||
" <td>•The responsive measures to the COVID-19 pandemic have caused us to modify our business practices by permitting corporate employees in nearly all of ourlocations to work remotely, limiting employee travel, and canceling, postponing or holding virtual events and meetings.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.810687</td>\n",
|
||||
" <td>•manage our platform and our business assets and expenses in light of the COVID-19 pandemic and related public health measures issued by various jurisdictions,including travel bans, travel restrictions and shelter-in-place orders, as well as maintain demand for and confidence in the safety of our platform during andfollowing the COVID-19 pandemic;•plan for and manage capital expenditures for our current and future offerings,</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.809540</td>\n",
|
||||
" <td>The strength and duration ofthese challenges cannot be presently estimated.In response to the COVID-19 pandemic, we have adopted multiple measures, including, but not limited, to establishing new health and safety requirements forridesharing and updating workplace policies. We also made adjustments to our expenses and cash flow to correlate with declines in revenues including headcountreductions in 2020.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>0.806794</td>\n",
|
||||
" <td>the timing and extent of spending to support ourefforts to develop our platform, actual insurance payments for which we have made reserves, measures we take in response to the COVID-19 pandemic, our ability tomaintain demand for and confidence in the safety of our platform during and following the COVID-19 pandemic, and the expansion of sales and marketing activities.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>0.805533</td>\n",
|
||||
" <td>•anticipate and respond to macroeconomic changes and changes in the markets in which we operate;•maintain and enhance the value of our reputation and brand;•effectively manage our growth and business operations, including the impacts of the COVID-19 pandemic on our business;•successfully expand our geographic reach;•hire, integrate and retain talented people at all levels of our organization;•successfully develop new platform features, offerings and services to enhance the experience of users; and•right-size our real estate portfolio.</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1dcc798a-3940-4426-8110-d9a3f7dc5a68",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"What initiatives are the company focusing on independently of COVID-19?\",\n",
|
||||
" vector_top_k=40,\n",
|
||||
" reranker_top_n=5,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "38bae391-7dca-4f8d-a90e-ada1beddcd2e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>9.0</td>\n",
|
||||
" <td>Even as we invest in the business, we also remain focused on finding ways to operate more efficiently.To advance our mission, we aim to build the defining brand of our generation and to advocate through our commitment to social and environmental responsibility.We believe that our brand represents freedom at your fingertips: freedom from the stresses of car ownership and freedom to do and see more.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>8.0</td>\n",
|
||||
" <td>We have also invested in sales and marketing to grow our community,cultivate a differentiated brand that resonates with drivers and riders and promote further brand awareness. Together, these investments have enabled us to create a powerfulmultimodal platform and scaled user network.Notwithstanding the impact of COVID-19, we are continuing to invest in the future, both organically and through acquisitions of complementary businesses.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>8.0</td>\n",
|
||||
" <td>As a result, we may introduce significantchanges to our existing offerings or develop and introduce new and unproven offerings. For example, in April 2020, we began piloting a delivery service platform inresponse to the COVID-19 pandemic.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>6.0</td>\n",
|
||||
" <td>•anticipate and respond to macroeconomic changes and changes in the markets in which we operate;•maintain and enhance the value of our reputation and brand;•effectively manage our growth and business operations, including the impacts of the COVID-19 pandemic on our business;•successfully expand our geographic reach;•hire, integrate and retain talented people at all levels of our organization;•successfully develop new platform features, offerings and services to enhance the experience of users; and•right-size our real estate portfolio.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>6.0</td>\n",
|
||||
" <td>has been critical to our success. We face a number ofchallenges that may affect our ability to sustain our corporate culture, including:•failure to identify, attract, reward and retain people in leadership positions in our organization who share and further our culture, values and mission;•the increasing size and geographic diversity of our workforce;•shelter-in-place orders in certain jurisdictions where we operate that have required many of our employees to work remotely,</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-index-cXQhuK8v-py3.11",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b1c1ebaa-50de-4851-a720-acbb977551ea",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Time-Weighted Rerank\n",
|
||||
"\n",
|
||||
"Showcase capabilities of time-weighted node postprocessor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "92d06b38-2103-4a40-93c3-60e0708a1124",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/home/loganm/miniconda3/envs/llama-index/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
||||
" from .autonotebook import tqdm as notebook_tqdm\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import TimeWeightedPostprocessor\n",
|
||||
"from llama_index.core.node_parser import SentenceSplitter\n",
|
||||
"from llama_index.core.storage.docstore import SimpleDocumentStore\n",
|
||||
"from llama_index.core.response.notebook_utils import display_response\n",
|
||||
"from datetime import datetime, timedelta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "67020156-2975-4bbb-8e98-afc55abb3d72",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Parse Documents into Nodes, add to Docstore\n",
|
||||
"\n",
|
||||
"In this example, there are 3 different versions of PG's essay. They are largely identical **except** \n",
|
||||
"for one specific section, which details the amount of funding they raised for Viaweb. \n",
|
||||
"\n",
|
||||
"V1: 50k, V2: 30k, V3: 10K\n",
|
||||
"\n",
|
||||
"V1: -1 day, V2: -2 days, V3: -3 days\n",
|
||||
"\n",
|
||||
"The idea is to encourage index to fetch the most recent info (which is V3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "caddd84e-9827-40a4-9520-dba6405fd1fd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"from llama_index.core import StorageContext\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"now = datetime.now()\n",
|
||||
"key = \"__last_accessed__\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"doc1 = SimpleDirectoryReader(\n",
|
||||
" input_files=[\"./test_versioned_data/paul_graham_essay_v1.txt\"]\n",
|
||||
").load_data()[0]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"doc2 = SimpleDirectoryReader(\n",
|
||||
" input_files=[\"./test_versioned_data/paul_graham_essay_v2.txt\"]\n",
|
||||
").load_data()[0]\n",
|
||||
"\n",
|
||||
"doc3 = SimpleDirectoryReader(\n",
|
||||
" input_files=[\"./test_versioned_data/paul_graham_essay_v3.txt\"]\n",
|
||||
").load_data()[0]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# define settings\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.text_splitter = SentenceSplitter(chunk_size=512)\n",
|
||||
"\n",
|
||||
"# use node parser from settings to parse docs into nodes\n",
|
||||
"nodes1 = Settings.text_splitter.get_nodes_from_documents([doc1])\n",
|
||||
"nodes2 = Settings.text_splitter.get_nodes_from_documents([doc2])\n",
|
||||
"nodes3 = Settings.text_splitter.get_nodes_from_documents([doc3])\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# fetch the modified chunk from each document, set metadata\n",
|
||||
"# also exclude the date from being read by the LLM\n",
|
||||
"nodes1[14].metadata[key] = (now - timedelta(hours=3)).timestamp()\n",
|
||||
"nodes1[14].excluded_llm_metadata_keys = [key]\n",
|
||||
"\n",
|
||||
"nodes2[14].metadata[key] = (now - timedelta(hours=2)).timestamp()\n",
|
||||
"nodes2[14].excluded_llm_metadata_keys = [key]\n",
|
||||
"\n",
|
||||
"nodes3[14].metadata[key] = (now - timedelta(hours=1)).timestamp()\n",
|
||||
"nodes2[14].excluded_llm_metadata_keys = [key]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# add to docstore\n",
|
||||
"docstore = SimpleDocumentStore()\n",
|
||||
"nodes = [nodes1[14], nodes2[14], nodes3[14]]\n",
|
||||
"docstore.add_documents(nodes)\n",
|
||||
"\n",
|
||||
"storage_context = StorageContext.from_defaults(docstore=docstore)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e5a25b95-de5e-4e56-a846-51e9c6eba181",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5f7f68d6-2389-4f6c-bc4e-8612a1a53fb8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex(nodes, storage_context=storage_context)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "86c5e8aa-18d8-4229-b7b2-a1c97c11a09a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Define Recency Postprocessors"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ba5e10c9-5a7e-4ea8-a74d-0e0f74b5cd1b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"node_postprocessor = TimeWeightedPostprocessor(\n",
|
||||
" time_decay=0.5, time_access_refresh=False, top_k=1\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "efcfffe4-a8aa-486d-b46d-f73f985dffca",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Query Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "78d6c3db-61e6-4d9a-a84d-d7be846b4112",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# naive query\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3,\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"How much did the author raise in seed funding from Idelle's husband\"\n",
|
||||
" \" (Julian) for Viaweb?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "84a608cd-fd70-40ba-a2f5-1414148db7de",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"**`Final Response:`** $50,000"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"display_response(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1d672c52-c0ac-4e5f-9175-855e66eb97ba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# query using time weighted node postprocessor\n",
|
||||
"\n",
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3, node_postprocessors=[node_postprocessor]\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"How much did the author raise in seed funding from Idelle's husband\"\n",
|
||||
" \" (Julian) for Viaweb?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cd4b971e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"**`Final Response:`** The author raised $10,000 in seed funding from Idelle's husband (Julian) for Viaweb."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"display_response(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dd00cc97-4de7-4c61-9c0c-3f9ee3598528",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Query Index (Lower-Level Usage)\n",
|
||||
"\n",
|
||||
"In this example we first get the full set of nodes from a query call, and then send to node postprocessor, and then\n",
|
||||
"finally synthesize response through a summary index."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "350b039e-d45d-4b6b-957a-4b14d8816cbd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SummaryIndex"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "234f909f-6faa-43e6-96f8-0966699c9552",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_str = (\n",
|
||||
" \"How much did the author raise in seed funding from Idelle's husband\"\n",
|
||||
" \" (Julian) for Viaweb?\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "20afbf6b-9473-446e-b522-b90fef2e3bf0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=3, response_mode=\"no_text\"\n",
|
||||
")\n",
|
||||
"init_response = query_engine.query(\n",
|
||||
" query_str,\n",
|
||||
")\n",
|
||||
"resp_nodes = [n for n in init_response.source_nodes]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cdc03574-a806-4255-953c-6f82fc3f202f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# get the post-processed nodes -- which should be the top-1 sorted by date\n",
|
||||
"new_resp_nodes = node_postprocessor.postprocess_nodes(resp_nodes)\n",
|
||||
"\n",
|
||||
"summary_index = SummaryIndex([n.node for n in new_resp_nodes])\n",
|
||||
"query_engine = summary_index.as_query_engine()\n",
|
||||
"response = query_engine.query(query_str)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9d4de372-653f-4d57-9e0f-17a90f39b874",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"**`Final Response:`** The author raised $10,000 in seed funding from Idelle's husband (Julian) for Viaweb."
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"display_response(response)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-index",
|
||||
"language": "python",
|
||||
"name": "llama-index"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/VoyageAIRerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# VoyageAI Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.3.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install llama-index > /dev/null\n",
|
||||
"%pip install llama-index-postprocessor-voyageai-rerank > /dev/null\n",
|
||||
"%pip install llama-index-embeddings-voyageai > /dev/null"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.response.pprint_utils import pprint_response"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2024-05-09 17:56:26-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt\n",
|
||||
"Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 2606:50c0:8003::154, 2606:50c0:8000::154, 2606:50c0:8002::154, ...\n",
|
||||
"Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|2606:50c0:8003::154|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 75042 (73K) [text/plain]\n",
|
||||
"Saving to: ‘data/paul_graham/paul_graham_essay.txt’\n",
|
||||
"\n",
|
||||
"data/paul_graham/pa 100%[===================>] 73.28K --.-KB/s in 0.009s \n",
|
||||
"\n",
|
||||
"2024-05-09 17:56:26 (7.81 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from llama_index.embeddings.voyageai import VoyageEmbedding\n",
|
||||
"\n",
|
||||
"api_key = os.environ[\"VOYAGE_API_KEY\"]\n",
|
||||
"voyageai_embeddings = VoyageEmbedding(\n",
|
||||
" voyage_api_key=api_key, model_name=\"voyage-3\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()\n",
|
||||
"\n",
|
||||
"# build index\n",
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents=documents, embed_model=voyageai_embeddings\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieve top 10 most relevant nodes, then filter with VoyageAI Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.voyageai_rerank import VoyageAIRerank\n",
|
||||
"\n",
|
||||
"voyageai_rerank = VoyageAIRerank(\n",
|
||||
" api_key=api_key, top_k=2, model=\"rerank-2\", truncation=True\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10,\n",
|
||||
" node_postprocessors=[voyageai_rerank],\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Directly retrieve top 2 most similar nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=2,\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Retrieved context is irrelevant and response is hallucinated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,603 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c9d89b5c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/ibm_watsonx.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "70996d8a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# IBM watsonx.ai\n",
|
||||
"\n",
|
||||
">WatsonxRerank is a wrapper for IBM [watsonx.ai](https://www.ibm.com/products/watsonx-ai) Rerank.\n",
|
||||
"\n",
|
||||
"The aim of these examples is to show how to take advantage of `watsonx.ai` Rerank, Embeddings and LLMs using the `LlamaIndex` postprocessor API."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ea35b2b7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setting up\n",
|
||||
"\n",
|
||||
"Install required packages:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2f1fff4e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install -qU llama-index\n",
|
||||
"%pip install -qU llama-index-llms-ibm\n",
|
||||
"%pip install -qU llama-index-postprocessor-ibm\n",
|
||||
"%pip install -qU llama-index-embeddings-ibm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f406e092",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The cell below defines the credentials required to work with watsonx Foundation Models, Embeddings and Rerank.\n",
|
||||
"\n",
|
||||
"**Action:** Provide the IBM Cloud user API key. For details, see\n",
|
||||
"[Managing user API keys](https://cloud.ibm.com/docs/account?topic=account-userapikey&interface=ui)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "11d572a1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from getpass import getpass\n",
|
||||
"\n",
|
||||
"watsonx_api_key = getpass()\n",
|
||||
"os.environ[\"WATSONX_APIKEY\"] = watsonx_api_key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c59782a7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Additionally, you can pass additional secrets as an environment variable:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f98c573c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"WATSONX_URL\"] = \"your service instance url\"\n",
|
||||
"os.environ[\"WATSONX_TOKEN\"] = \"your token for accessing the CPD cluster\"\n",
|
||||
"os.environ[\"WATSONX_PASSWORD\"] = \"your password for accessing the CPD cluster\"\n",
|
||||
"os.environ[\"WATSONX_USERNAME\"] = \"your username for accessing the CPD cluster\"\n",
|
||||
"os.environ[\n",
|
||||
" \"WATSONX_INSTANCE_ID\"\n",
|
||||
"] = \"your instance_id for accessing the CPD cluster\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b0de9336",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Note**: \n",
|
||||
"\n",
|
||||
"- To provide context for the API call, you must pass the `project_id` or `space_id`. To get your project or space ID, open your project or space, go to the **Manage** tab, and click **General**. For more information see: [Project documentation](https://www.ibm.com/docs/en/watsonx-as-a-service?topic=projects) or [Deployment space documentation](https://www.ibm.com/docs/en/watsonx/saas?topic=spaces-creating-deployment).\n",
|
||||
"- Depending on the region of your provisioned service instance, use one of the urls listed in [watsonx.ai API Authentication](https://ibm.github.io/watsonx-ai-python-sdk/setup_cloud.html#authentication).\n",
|
||||
"\n",
|
||||
"In this example, we’ll use the `project_id` and Dallas URL."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a3ef7659",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Provide `PROJECT_ID` that will be used for initialize each watsonx integration instance."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b933bb7f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"PROJECT_ID = \"PASTE YOUR PROJECT_ID HERE\"\n",
|
||||
"URL = \"https://us-south.ml.cloud.ibm.com\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f0308874",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download data and load documents\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3d67b5f7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2025-02-24 10:46:16-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt\n",
|
||||
"Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 2606:50c0:8000::154, 2606:50c0:8001::154, 2606:50c0:8002::154, ...\n",
|
||||
"Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|2606:50c0:8000::154|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 75042 (73K) [text/plain]\n",
|
||||
"Saving to: ‘data/paul_graham/paul_graham_essay.txt’\n",
|
||||
"\n",
|
||||
"data/paul_graham/pa 100%[===================>] 73,28K --.-KB/s in 0,06s \n",
|
||||
"\n",
|
||||
"2025-02-24 10:46:17 (1,30 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a65dc946",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cd7ac083",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load the Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "166b40ca",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You might need to adjust rerank parameters for different tasks:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15647312",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"truncate_input_tokens = 512"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a03571f0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Initialize `WatsonxRerank` instance."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "79dcb01b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You need to specify the `model_id` that will be used for rerank. You can find the list of all the available models in [Supported reranker models](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models-embed.html?context=wx#rerank)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "33efcbc5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.ibm import WatsonxRerank\n",
|
||||
"\n",
|
||||
"watsonx_rerank = WatsonxRerank(\n",
|
||||
" model_id=\"cross-encoder/ms-marco-minilm-l12-v2\",\n",
|
||||
" top_n=2,\n",
|
||||
" url=URL,\n",
|
||||
" project_id=PROJECT_ID,\n",
|
||||
" truncate_input_tokens=truncate_input_tokens,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7e79e20d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Alternatively, you can use Cloud Pak for Data credentials. For details, see [watsonx.ai software setup](https://ibm.github.io/watsonx-ai-python-sdk/setup_cpd.html). "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c08ee5a1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.ibm import WatsonxRerank\n",
|
||||
"\n",
|
||||
"watsonx_rerank = WatsonxRerank(\n",
|
||||
" model_id=\"cross-encoder/ms-marco-minilm-l12-v2\",\n",
|
||||
" url=URL,\n",
|
||||
" username=\"PASTE YOUR USERNAME HERE\",\n",
|
||||
" password=\"PASTE YOUR PASSWORD HERE\",\n",
|
||||
" instance_id=\"openshift\",\n",
|
||||
" version=\"5.1\",\n",
|
||||
" project_id=PROJECT_ID,\n",
|
||||
" truncate_input_tokens=truncate_input_tokens,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "106479c9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load the embedding model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "10b86b6b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Initialize the `WatsonxEmbeddings` instance.\n",
|
||||
"\n",
|
||||
">For more information about `WatsonxEmbeddings` please refer to the sample notebook: <a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/embeddings/ibm_watsonx.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e5bf6aaf",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You might need to adjust embedding parameters for different tasks:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "66c3226c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"truncate_input_tokens = 512"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cf2a9d4f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You need to specify the `model_id` that will be used for embedding. You can find the list of all the available models in [Supported embedding models](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models-embed.html?context=wx#embed)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c81d51e1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.embeddings.ibm import WatsonxEmbeddings\n",
|
||||
"\n",
|
||||
"watsonx_embedding = WatsonxEmbeddings(\n",
|
||||
" model_id=\"ibm/slate-30m-english-rtrvr\",\n",
|
||||
" url=URL,\n",
|
||||
" project_id=PROJECT_ID,\n",
|
||||
" truncate_input_tokens=truncate_input_tokens,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8647a00c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Change default settings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "12645356",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.chunk_size = 512"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b1a5570f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Build index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "eb518f53",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents=documents, embed_model=watsonx_embedding\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e36acbef",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load the LLM"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e2924c37",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Initialize the `WatsonxLLM` instance.\n",
|
||||
"\n",
|
||||
">For more information about `WatsonxLLM` please refer to the sample notebook: <a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/llm/ibm_watsonx.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ae227410",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You need to specify the `model_id` that will be used for inferencing. You can find the list of all the available models in [Supported foundation models](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models.html?context=wx)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ba54c1de",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You might need to adjust model `parameters` for different models or tasks. For details, refer to [Available MetaNames](https://ibm.github.io/watsonx-ai-python-sdk/fm_model.html#metanames.GenTextParamsMetaNames)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "54e38eb1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"max_new_tokens = 128"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "359898de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.ibm import WatsonxLLM\n",
|
||||
"\n",
|
||||
"watsonx_llm = WatsonxLLM(\n",
|
||||
" model_id=\"meta-llama/llama-3-3-70b-instruct\",\n",
|
||||
" url=URL,\n",
|
||||
" project_id=PROJECT_ID,\n",
|
||||
" max_new_tokens=max_new_tokens,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "55aa40af",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Send a query"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9be7fc6c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieve top 10 most relevant nodes, then filter with `WatsonxRerank`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b84f0158",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" llm=watsonx_llm,\n",
|
||||
" similarity_top_k=10,\n",
|
||||
" node_postprocessors=[watsonx_rerank],\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3fdc1eb4",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: In this essay, Sam Altman was recruited to be the\n",
|
||||
"president of Y Combinator (YC), and he agreed to take over the role\n",
|
||||
"starting with the winter 2014 batch. He initially declined the offer,\n",
|
||||
"wanting to start a startup to make nuclear reactors, but eventually\n",
|
||||
"agreed after being persuaded. He began learning the job and taking\n",
|
||||
"over responsibilities from the author in the latter part of 2013, and\n",
|
||||
"officially took over as president in 2014.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: 2ed5d8e7-2681-49b0-a112-ea35cc9a8b9e\n",
|
||||
"Similarity: 3.2075154781341553\n",
|
||||
"Text: \"You know,\" he said, \"you should make sure Y Combinator isn't\n",
|
||||
"the last cool thing you do.\" At the time I didn't understand what he\n",
|
||||
"meant, but gradually it dawned on me that he was saying I should quit.\n",
|
||||
"This seemed strange advice, because YC was doing great. But if there\n",
|
||||
"was one thing rarer than Rtm offering advice, it was Rtm being wrong.\n",
|
||||
"So th...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: 6ae17865-aaa7-46a5-bc49-f38abf4a825e\n",
|
||||
"Similarity: -1.3127477169036865\n",
|
||||
"Text: I asked Jessica if she wanted to be president, but she didn't,\n",
|
||||
"so we decided we'd try to recruit Sam Altman. We talked to Robert and\n",
|
||||
"Trevor and we agreed to make it a complete changing of the guard. Up\n",
|
||||
"till that point YC had been controlled by the original LLC we four had\n",
|
||||
"started. But we wanted YC to last for a long time, and to do that it\n",
|
||||
"could...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.response.pprint_utils import pprint_response\n",
|
||||
"\n",
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "baf5df0b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Directly retrieve top 2 most similar nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1f784254",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" llm=watsonx_llm,\n",
|
||||
" similarity_top_k=2,\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8465e7a9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Retrieved context is irrelevant and response is hallucinated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4dd6af0d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Final Response: Sam Altman was one of the founders of the first batch\n",
|
||||
"of startups funded by the Summer Founders Program, and he later became\n",
|
||||
"the second president of YC.\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 1/2\n",
|
||||
"Node ID: ba52769a-7342-4e6c-af02-4159216a79a8\n",
|
||||
"Similarity: 0.6396056863136902\n",
|
||||
"Text: We knew undergrads were deciding then about summer jobs, so in a\n",
|
||||
"matter of days we cooked up something we called the Summer Founders\n",
|
||||
"Program, and I posted an announcement on my site, inviting undergrads\n",
|
||||
"to apply. I had never imagined that writing essays would be a way to\n",
|
||||
"get \"deal flow,\" as investors call it, but it turned out to be the\n",
|
||||
"perfect ...\n",
|
||||
"______________________________________________________________________\n",
|
||||
"Source Node 2/2\n",
|
||||
"Node ID: 43a6cf9f-8284-45db-bbbd-44109fcb9373\n",
|
||||
"Similarity: 0.6334836031239921\n",
|
||||
"Text: I wrote this new Lisp, called Bel, in itself in Arc. That may\n",
|
||||
"sound like a contradiction, but it's an indication of the sort of\n",
|
||||
"trickery I had to engage in to make this work. By means of an\n",
|
||||
"egregious collection of hacks I managed to make something close enough\n",
|
||||
"to an interpreter written in itself that could actually run. Not fast,\n",
|
||||
"but fast enough...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pprint_response(response, show_source=True)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,359 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/openvino_rerank.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# OpenVINO Rerank\n",
|
||||
"\n",
|
||||
"[OpenVINO™](https://github.com/openvinotoolkit/openvino) is an open-source toolkit for optimizing and deploying AI inference. The OpenVINO™ Runtime supports various hardware [devices](https://github.com/openvinotoolkit/openvino?tab=readme-ov-file#supported-hardware-matrix) including x86 and ARM CPUs, and Intel GPUs. It can help to boost deep learning performance in Computer Vision, Automatic Speech Recognition, Natural Language Processing and other common tasks.\n",
|
||||
"\n",
|
||||
"Hugging Face rerank model can be supported by OpenVINO through ``OpenVINORerank`` class."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-postprocessor-openvino-rerank\n",
|
||||
"%pip install llama-index-embeddings-openvino"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2024-08-01 00:38:50-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt\n",
|
||||
"Resolving proxy-dmz.intel.com (proxy-dmz.intel.com)... 10.1.192.48\n",
|
||||
"Connecting to proxy-dmz.intel.com (proxy-dmz.intel.com)|10.1.192.48|:912... connected.\n",
|
||||
"Proxy request sent, awaiting response... 200 OK\n",
|
||||
"Length: 75042 (73K) [text/plain]\n",
|
||||
"Saving to: ‘data/paul_graham/paul_graham_essay.txt’\n",
|
||||
"\n",
|
||||
"data/paul_graham/pa 100%[===================>] 73.28K --.-KB/s in 0.009s \n",
|
||||
"\n",
|
||||
"2024-08-01 00:38:50 (7.64 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!mkdir -p 'data/paul_graham/'\n",
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Embedding, Rerank models and LLM"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.embeddings.huggingface_openvino import OpenVINOEmbedding\n",
|
||||
"\n",
|
||||
"OpenVINOEmbedding.create_and_save_openvino_model(\n",
|
||||
" \"BAAI/bge-small-en-v1.5\", \"./embedding_ov\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.openvino_rerank import OpenVINORerank\n",
|
||||
"\n",
|
||||
"OpenVINORerank.create_and_save_openvino_model(\n",
|
||||
" \"BAAI/bge-reranker-large\", \"./rerank_ov\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!optimum-cli export openvino --model HuggingFaceH4/zephyr-7b-beta --weight-format int4 llm_ov"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Retrieve top 10 most relevant nodes, then filter with OpenVINO Rerank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Compiling the model to AUTO ...\n",
|
||||
"Compiling the model to AUTO ...\n",
|
||||
"Compiling the model to CPU ...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.postprocessor.openvino_rerank import OpenVINORerank\n",
|
||||
"from llama_index.llms.openvino import OpenVINOLLM\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Settings.embed_model = OpenVINOEmbedding(model_id_or_path=\"./embedding_ov\")\n",
|
||||
"Settings.llm = OpenVINOLLM(model_id_or_path=\"./llm_ov\")\n",
|
||||
"\n",
|
||||
"ov_rerank = OpenVINORerank(\n",
|
||||
" model_id_or_path=\"./rerank_ov\", device=\"cpu\", top_n=2\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(documents=documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=10,\n",
|
||||
" node_postprocessors=[ov_rerank],\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"Sam Altman was asked to become the president of Y Combinator, and he initially declined as he wanted to start a startup to make nuclear reactors. However, the author kept persuading him, and in October 2013, Sam agreed to take over as the president of Y Combinator starting from the winter 2014 batch. The author then stepped back from running Y Combinator and focused on other activities, including painting and writing essays.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: 0bd0a382-d974-4939-aed6-2ac0e49e0802): Why not organize a summer program where they'd start startups instead? We wouldn't feel guilty for being in a sense fake investors, because they would in a similar sense be fake founders. So while ...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 523617f4-08c7-415c-a3c0-b60595e4bca8): This seemed strange advice, because YC was doing great. But if there was one thing rarer than Rtm offering advice, it was Rtm being wrong. So this set me thinking. It was true that on my current tr...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.get_formatted_sources(length=200))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Directly retrieve top 2 most similar nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Setting `pad_token_id` to `eos_token_id`:2 for open-end generation.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(\n",
|
||||
" similarity_top_k=2,\n",
|
||||
")\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What did Sam Altman do in this essay?\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Retrieved context is irrelevant and response is hallucinated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"Sam Altman was asked by Jessica and Robert to become the president of Y Combinator, which he initially declined as he wanted to start a startup to make nuclear reactors. However, the author kept persuading him, and in October 2013, he finally agreed to take over as the president of Y Combinator starting with the winter 2014 batch. The author then left running Y Combinator more and more to Sam, partly to help him learn the job, and partly because the author was focused on his mother, whose cancer had returned. The author kept working on Y Combinator till March, to help get that batch of startups through Demo Day, and then he checked out completely.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Based on the text material above, generate the response to the following quesion or instruction: Can you summarize the author's career path and the projects he worked on after selling his startup to Yahoo?\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"> Source (Doc id: 523617f4-08c7-415c-a3c0-b60595e4bca8): This seemed strange advice, because YC was doing great. But if there was one thing rarer than Rtm offering advice, it was Rtm being wrong. So this set me thinking. It was true that on my current tr...\n",
|
||||
"\n",
|
||||
"> Source (Doc id: 276c693d-9164-4890-9272-ad60c23015c8): I knew that online essays would be a marginal medium at first. Socially they'd seem more like rants posted by nutjobs on their GeoCities sites than the genteel and beautifully typeset compositions ...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(response.get_formatted_sources(length=200))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"For more information refer to:\n",
|
||||
"\n",
|
||||
"* [OpenVINO LLM guide](https://docs.openvino.ai/2024/learn-openvino/llm_inference_guide.html).\n",
|
||||
"\n",
|
||||
"* [OpenVINO Documentation](https://docs.openvino.ai/2024/home.html).\n",
|
||||
"\n",
|
||||
"* [OpenVINO Get Started Guide](https://www.intel.com/content/www/us/en/content-details/819067/openvino-get-started-guide.html).\n",
|
||||
"\n",
|
||||
"* [RAG example with LlamaIndex](https://github.com/openvinotoolkit/openvino_notebooks/tree/latest/notebooks/llm-rag-llamaindex)."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,620 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "f1b23ffc-22d8-4414-b2e4-66d45a03523d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/node_postprocessor/rankGPT.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"# RankGPT Reranker Demonstration (Van Gogh Wiki)\n",
|
||||
"\n",
|
||||
"This demo integrates [RankGPT](https://github.com/sunnweiwei/RankGPT) into LlamaIndex as a reranker.\n",
|
||||
"\n",
|
||||
"Paper: [Is ChatGPT Good at Search? Investigating Large Language Models as Re-Ranking Agents](https://arxiv.org/abs/2304.09542)\n",
|
||||
"\n",
|
||||
"the idea of `RankGPT`:\n",
|
||||
"* it is a zero-shot listwise passage reranking using LLM (ChatGPT or GPT-4 or other LLMs)\n",
|
||||
"* it applies permutation generation approach and sliding window strategy to rerank passages efficiently. \n",
|
||||
"\n",
|
||||
"In this example, we use Van Gogh's wikipedia as an example to compare the Retrieval results with/without RankGPT reranking.\n",
|
||||
"we showcase two models for RankGPT:\n",
|
||||
"* OpenAI `GPT3.5`\n",
|
||||
"* `Mistral` model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "93aa4a94",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-postprocessor-rankgpt-rerank\n",
|
||||
"%pip install llama-index-llms-huggingface\n",
|
||||
"%pip install llama-index-llms-huggingface-api\n",
|
||||
"%pip install llama-index-llms-openai\n",
|
||||
"%pip install llama-index-llms-ollama"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ab68a3ee-f4c1-4830-856a-9c37f7a42364",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8c16404b-db81-4ee6-9c0f-cc4cdf3cb147",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import logging\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
|
||||
"logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))\n",
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import LLMRerank\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from IPython.display import Markdown, display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "159f915d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"OPENAI_API_KEY = \"sk-\"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "8a5b0ac6-ec9c-40e1-9120-d20e33c37f80",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data, Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b785b75a-cf4d-4799-8fd2-970e5c39727c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.llm = OpenAI(temperature=0, model=\"gpt-3.5-turbo\")\n",
|
||||
"Settings.chunk_size = 512"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7ac13a92",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Download Van Gogh wiki from Wikipedia"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e5a86c2c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pathlib import Path\n",
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"wiki_titles = [\n",
|
||||
" \"Vincent van Gogh\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"data_path = Path(\"data_wiki\")\n",
|
||||
"\n",
|
||||
"for title in wiki_titles:\n",
|
||||
" response = requests.get(\n",
|
||||
" \"https://en.wikipedia.org/w/api.php\",\n",
|
||||
" params={\n",
|
||||
" \"action\": \"query\",\n",
|
||||
" \"format\": \"json\",\n",
|
||||
" \"titles\": title,\n",
|
||||
" \"prop\": \"extracts\",\n",
|
||||
" \"explaintext\": True,\n",
|
||||
" },\n",
|
||||
" ).json()\n",
|
||||
" page = next(iter(response[\"query\"][\"pages\"].values()))\n",
|
||||
" wiki_text = page[\"extract\"]\n",
|
||||
"\n",
|
||||
" if not data_path.exists():\n",
|
||||
" Path.mkdir(data_path)\n",
|
||||
"\n",
|
||||
" with open(data_path / f\"{title}.txt\", \"w\") as fp:\n",
|
||||
" fp.write(wiki_text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9b689e92-fc55-48b5-859f-2a2c1394c872",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data_wiki/\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7a886b11",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Build vector store index for this Wikipedia page"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d8555b6d-5289-4803-bced-6b2f85dea3da",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"id": "805847d9-a2c1-4930-98a9-98126e730000",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Retrieval + RankGPT reranking\n",
|
||||
"Steps:\n",
|
||||
"1. Setting up retriever and reranker (as an option) \n",
|
||||
"2. Retrieve results given a search query without reranking\n",
|
||||
"3. Retrieve results given a search query with RankGPT reranking enabled\n",
|
||||
"4. Comparing the results with and without reranking"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ace86835-832e-4964-a025-428891aa2c8b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.retrievers import VectorIndexRetriever\n",
|
||||
"from llama_index.core import QueryBundle\n",
|
||||
"from llama_index.postprocessor.rankgpt_rerank import RankGPTRerank\n",
|
||||
"\n",
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_retrieved_nodes(\n",
|
||||
" query_str, vector_top_k=10, reranker_top_n=3, with_reranker=False\n",
|
||||
"):\n",
|
||||
" query_bundle = QueryBundle(query_str)\n",
|
||||
" # configure retriever\n",
|
||||
" retriever = VectorIndexRetriever(\n",
|
||||
" index=index,\n",
|
||||
" similarity_top_k=vector_top_k,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = retriever.retrieve(query_bundle)\n",
|
||||
"\n",
|
||||
" if with_reranker:\n",
|
||||
" # configure reranker\n",
|
||||
" reranker = RankGPTRerank(\n",
|
||||
" llm=OpenAI(\n",
|
||||
" model=\"gpt-3.5-turbo-16k\",\n",
|
||||
" temperature=0.0,\n",
|
||||
" api_key=OPENAI_API_KEY,\n",
|
||||
" ),\n",
|
||||
" top_n=reranker_top_n,\n",
|
||||
" verbose=True,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = reranker.postprocess_nodes(\n",
|
||||
" retrieved_nodes, query_bundle\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return retrieved_nodes\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def pretty_print(df):\n",
|
||||
" return display(HTML(df.to_html().replace(\"\\\\n\", \"<br>\")))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def visualize_retrieved_nodes(nodes) -> None:\n",
|
||||
" result_dicts = []\n",
|
||||
" for node in nodes:\n",
|
||||
" result_dict = {\"Score\": node.score, \"Text\": node.node.get_text()}\n",
|
||||
" result_dicts.append(result_dict)\n",
|
||||
"\n",
|
||||
" pretty_print(pd.DataFrame(result_dicts))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c6a13f13",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Retrieval top 3 results without Reranking"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "20993200-b725-403e-8a79-e2571dab2ebc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Which date did Paul Gauguin arrive in Arles?\",\n",
|
||||
" vector_top_k=3,\n",
|
||||
" with_reranker=False,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bdc83fbc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Expected result is:\n",
|
||||
"```After much pleading from Van Gogh, Gauguin arrived in Arles on 23 October and, in November, the two painted together. Gauguin depicted Van Gogh in his The Painter of Sunflowers;```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9dd3bc25-6ef1-46b7-869e-247c83af9d4d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.857523</td>\n",
|
||||
" <td>Gauguin fled Arles, never to see Van Gogh again. They continued to correspond, and in 1890, Gauguin proposed they form a studio in Antwerp. Meanwhile, other visitors to the hospital included Marie Ginoux and Roulin.Despite a pessimistic diagnosis, Van Gogh recovered and returned to the Yellow House on 7 January 1889. He spent the following month between hospital and home, suffering from hallucinations and delusions of poisoning. In March, the police closed his house after a petition by 30 townspeople (including the Ginoux family) who described him as le fou roux \"the redheaded madman\"; Van Gogh returned to hospital. Paul Signac visited him twice in March; in April, Van Gogh moved into rooms owned by Dr Rey after floods damaged paintings in his own home. Two months later, he left Arles and voluntarily entered an asylum in Saint-Rémy-de-Provence. Around this time, he wrote, \"Sometimes moods of indescribable anguish, sometimes moments when the veil of time and fatality of circumstances seemed to be torn apart for an instant.\"Van Gogh gave his 1889 Portrait of Doctor Félix Rey to Dr Rey. The physician was not fond of the painting and used it to repair a chicken coop, then gave it away. In 2016, the portrait was housed at the Pushkin Museum of Fine Arts and estimated to be worth over $50 million.<br><br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br><br><br>==== Saint-Rémy (May 1889 – May 1890) ====<br><br>Van Gogh entered the Saint-Paul-de-Mausole asylum on 8 May 1889, accompanied by his caregiver, Frédéric Salles, a Protestant clergyman. Saint-Paul was a former monastery in Saint-Rémy, located less than 30 kilometres (19 mi) from Arles, and it was run by a former naval doctor, Théophile Peyron. Van Gogh had two cells with barred windows, one of which he used as a studio. The clinic and its garden became the main subjects of his paintings.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.853599</td>\n",
|
||||
" <td>When he visited Saintes-Maries-de-la-Mer in June, he gave lessons to a Zouave second lieutenant – Paul-Eugène Milliet – and painted boats on the sea and the village. MacKnight introduced Van Gogh to Eugène Boch, a Belgian painter who sometimes stayed in Fontvieille, and the two exchanged visits in July.<br><br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br><br><br>==== Gauguin's visit (1888) ====<br> <br>When Gauguin agreed to visit Arles in 1888, Van Gogh hoped for friendship and to realize his idea of an artists' collective. Van Gogh prepared for Gauguin's arrival by painting four versions of Sunflowers in one week. \"In the hope of living in a studio of our own with Gauguin,\" he wrote in a letter to Theo, \"I'd like to do a decoration for the studio. Nothing but large Sunflowers.\"When Boch visited again, Van Gogh painted a portrait of him, as well as the study The Poet Against a Starry Sky.In preparation for Gauguin's visit, Van Gogh bought two beds on advice from the station's postal supervisor Joseph Roulin, whose portrait he painted. On 17 September, he spent his first night in the still sparsely furnished Yellow House. When Gauguin consented to work and live in Arles with him, Van Gogh started to work on the Décoration for the Yellow House, probably the most ambitious effort he ever undertook. He completed two chair paintings: Van Gogh's Chair and Gauguin's Chair.After much pleading from Van Gogh, Gauguin arrived in Arles on 23 October and, in November, the two painted together. Gauguin depicted Van Gogh in his The Painter of Sunflowers; Van Gogh painted pictures from memory, following Gauguin's suggestion. Among these \"imaginative\" paintings is Memory of the Garden at Etten. Their first joint outdoor venture was at the Alyscamps, when they produced the pendants Les Alyscamps. The single painting Gauguin completed during his visit was his portrait of Van Gogh.Van Gogh and Gauguin visited Montpellier in December 1888, where they saw works by Courbet and Delacroix in the Musée Fabre. Their relationship began to deteriorate; Van Gogh admired Gauguin and wanted to be treated as his equal, but Gauguin was arrogant and domineering, which frustrated Van Gogh. They often quarrelled; Van Gogh increasingly feared that Gauguin was going to desert him, and the situation, which Van Gogh described as one of \"excessive tension\", rapidly headed towards crisis point.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.842413</td>\n",
|
||||
" <td>=== Artistic breakthrough ===<br><br><br>==== Arles (1888–89) ====<br><br>Ill from drink and suffering from smoker's cough, in February 1888 Van Gogh sought refuge in Arles. He seems to have moved with thoughts of founding an art colony. The Danish artist Christian Mourier-Petersen became his companion for two months, and, at first, Arles appeared exotic. In a letter, he described it as a foreign country: \"The Zouaves, the brothels, the adorable little Arlésienne going to her First Communion, the priest in his surplice, who looks like a dangerous rhinoceros, the people drinking absinthe, all seem to me creatures from another world.\"The time in Arles became one of Van Gogh's more prolific periods: he completed 200 paintings and more than 100 drawings and watercolours. He was enchanted by the local countryside and light; his works from this period are rich in yellow, ultramarine and mauve. They include harvests, wheat fields and general rural landmarks from the area, including The Old Mill (1888), one of seven canvases sent to Pont-Aven on 4 October 1888 in an exchange of works with Paul Gauguin, Émile Bernard, Charles Laval and others. <br>The portrayals of Arles are informed by his Dutch upbringing; the patchworks of fields and avenues are flat and lacking perspective, but excel in their use of colour.In March 1888, he painted landscapes using a gridded \"perspective frame\"; three of the works were shown at the annual exhibition of the Société des Artistes Indépendants. In April, he was visited by the American artist Dodge MacKnight, who was living nearby at Fontvieille. On 1 May 1888, for 15 francs per month, he signed a lease for the eastern wing of the Yellow House at 2 place Lamartine. The rooms were unfurnished and had been uninhabited for months.On 7 May, Van Gogh moved from the Hôtel Carrel to the Café de la Gare, having befriended the proprietors, Joseph and Marie Ginoux. The Yellow House had to be furnished before he could fully move in, but he was able to use it as a studio.</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8800f71e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Finding: the right result is ranked at 2nd without reranking"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "203cbef7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Retrieve and Reranking top 10 results using RankGPT and return top 3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0ad7d62b-dba9-45d5-896f-4baa9a40edba",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
|
||||
"After Reranking, new rank list for nodes: [1, 6, 0, 2, 7, 9, 4, 5, 3, 8]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Which date did Paul Gauguin arrive in Arles ?\",\n",
|
||||
" vector_top_k=10,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ae22d297-dd3b-4a71-a890-faceafab4e1a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.852371</td>\n",
|
||||
" <td>When he visited Saintes-Maries-de-la-Mer in June, he gave lessons to a Zouave second lieutenant – Paul-Eugène Milliet – and painted boats on the sea and the village. MacKnight introduced Van Gogh to Eugène Boch, a Belgian painter who sometimes stayed in Fontvieille, and the two exchanged visits in July.<br><br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br><br><br>==== Gauguin's visit (1888) ====<br> <br>When Gauguin agreed to visit Arles in 1888, Van Gogh hoped for friendship and to realize his idea of an artists' collective. Van Gogh prepared for Gauguin's arrival by painting four versions of Sunflowers in one week. \"In the hope of living in a studio of our own with Gauguin,\" he wrote in a letter to Theo, \"I'd like to do a decoration for the studio. Nothing but large Sunflowers.\"When Boch visited again, Van Gogh painted a portrait of him, as well as the study The Poet Against a Starry Sky.In preparation for Gauguin's visit, Van Gogh bought two beds on advice from the station's postal supervisor Joseph Roulin, whose portrait he painted. On 17 September, he spent his first night in the still sparsely furnished Yellow House. When Gauguin consented to work and live in Arles with him, Van Gogh started to work on the Décoration for the Yellow House, probably the most ambitious effort he ever undertook. He completed two chair paintings: Van Gogh's Chair and Gauguin's Chair.After much pleading from Van Gogh, Gauguin arrived in Arles on 23 October and, in November, the two painted together. Gauguin depicted Van Gogh in his The Painter of Sunflowers; Van Gogh painted pictures from memory, following Gauguin's suggestion. Among these \"imaginative\" paintings is Memory of the Garden at Etten. Their first joint outdoor venture was at the Alyscamps, when they produced the pendants Les Alyscamps. The single painting Gauguin completed during his visit was his portrait of Van Gogh.Van Gogh and Gauguin visited Montpellier in December 1888, where they saw works by Courbet and Delacroix in the Musée Fabre. Their relationship began to deteriorate; Van Gogh admired Gauguin and wanted to be treated as his equal, but Gauguin was arrogant and domineering, which frustrated Van Gogh. They often quarrelled; Van Gogh increasingly feared that Gauguin was going to desert him, and the situation, which Van Gogh described as one of \"excessive tension\", rapidly headed towards crisis point.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.819758</td>\n",
|
||||
" <td>==== Hospital in Arles (December 1888) ====<br><br>The exact sequence that led to the mutilation of van Gogh's ear is not known. Gauguin said, fifteen years later, that the night followed several instances of physically threatening behaviour. Their relationship was complex and Theo may have owed money to Gauguin, who suspected the brothers were exploiting him financially. It seems likely that Vincent realised that Gauguin was planning to leave. The following days saw heavy rain, leading to the two men being shut in the Yellow House. Gauguin recalled that Van Gogh followed him after he left for a walk and \"rushed towards me, an open razor in his hand.\" This account is uncorroborated; Gauguin was almost certainly absent from the Yellow House that night, most likely staying in a hotel.After an altercation on the evening of 23 December 1888, Van Gogh returned to his room where he seemingly heard voices and either wholly or in part severed his left ear with a razor causing severe bleeding. He bandaged the wound, wrapped the ear in paper and delivered the package to a woman at a brothel Van Gogh and Gauguin both frequented. Van Gogh was found unconscious the next morning by a policeman and taken to hospital, where he was treated by Félix Rey, a young doctor still in training. The ear was brought to the hospital, but Rey did not attempt to reattach it as too much time had passed. Van Gogh researcher and art historian Bernadette Murphy discovered the true identity of the woman named Gabrielle, who died in Arles at the age of 80 in 1952, and whose descendants still lived (as of 2020) just outside Arles. Gabrielle, known in her youth as \"Gaby,\" was a 17-year-old cleaning girl at the brothel and other local establishments at the time Van Gogh presented her with his ear.Van Gogh had no recollection of the event, suggesting that he may have suffered an acute mental breakdown. The hospital diagnosis was \"acute mania with generalised delirium\", and within a few days, the local police ordered that he be placed in hospital care. Gauguin immediately notified Theo, who, on 24 December, had proposed marriage to his old friend Andries Bonger's sister Johanna.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.855685</td>\n",
|
||||
" <td>Gauguin fled Arles, never to see Van Gogh again. They continued to correspond, and in 1890, Gauguin proposed they form a studio in Antwerp. Meanwhile, other visitors to the hospital included Marie Ginoux and Roulin.Despite a pessimistic diagnosis, Van Gogh recovered and returned to the Yellow House on 7 January 1889. He spent the following month between hospital and home, suffering from hallucinations and delusions of poisoning. In March, the police closed his house after a petition by 30 townspeople (including the Ginoux family) who described him as le fou roux \"the redheaded madman\"; Van Gogh returned to hospital. Paul Signac visited him twice in March; in April, Van Gogh moved into rooms owned by Dr Rey after floods damaged paintings in his own home. Two months later, he left Arles and voluntarily entered an asylum in Saint-Rémy-de-Provence. Around this time, he wrote, \"Sometimes moods of indescribable anguish, sometimes moments when the veil of time and fatality of circumstances seemed to be torn apart for an instant.\"Van Gogh gave his 1889 Portrait of Doctor Félix Rey to Dr Rey. The physician was not fond of the painting and used it to repair a chicken coop, then gave it away. In 2016, the portrait was housed at the Pushkin Museum of Fine Arts and estimated to be worth over $50 million.<br><br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br><br><br>==== Saint-Rémy (May 1889 – May 1890) ====<br><br>Van Gogh entered the Saint-Paul-de-Mausole asylum on 8 May 1889, accompanied by his caregiver, Frédéric Salles, a Protestant clergyman. Saint-Paul was a former monastery in Saint-Rémy, located less than 30 kilometres (19 mi) from Arles, and it was run by a former naval doctor, Théophile Peyron. Van Gogh had two cells with barred windows, one of which he used as a studio. The clinic and its garden became the main subjects of his paintings.</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5850a6af",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Finding: After RankGPT reranking, the top 1st result is the right text containing the answer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "67d6631a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using other LLM for RankGPT reranking"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "36945a55",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Using `Ollama` for serving local `Mistral` models"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "eecd3244",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.ollama import Ollama\n",
|
||||
"\n",
|
||||
"llm = Ollama(\n",
|
||||
" model=\"mistral\",\n",
|
||||
" request_timeout=30.0,\n",
|
||||
" # Manually set the context window to limit memory usage\n",
|
||||
" context_window=8000,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "da5a8c60",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.retrievers import VectorIndexRetriever\n",
|
||||
"from llama_index.core import QueryBundle\n",
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI\n",
|
||||
"from llama_index.llms.huggingface import HuggingFaceLLM\n",
|
||||
"\n",
|
||||
"from llama_index.postprocessor.rankgpt_rerank import RankGPTRerank\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_retrieved_nodes(\n",
|
||||
" query_str, vector_top_k=5, reranker_top_n=3, with_reranker=False\n",
|
||||
"):\n",
|
||||
" query_bundle = QueryBundle(query_str)\n",
|
||||
" # configure retriever\n",
|
||||
" retriever = VectorIndexRetriever(\n",
|
||||
" index=index,\n",
|
||||
" similarity_top_k=vector_top_k,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = retriever.retrieve(query_bundle)\n",
|
||||
"\n",
|
||||
" if with_reranker:\n",
|
||||
" # configure reranker\n",
|
||||
" reranker = RankGPTRerank(\n",
|
||||
" llm=llm,\n",
|
||||
" top_n=reranker_top_n,\n",
|
||||
" verbose=True,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = reranker.postprocess_nodes(\n",
|
||||
" retrieved_nodes, query_bundle\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return retrieved_nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4d13f013",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"INFO:httpx:HTTP Request: POST http://localhost:11434/api/chat \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST http://localhost:11434/api/chat \"HTTP/1.1 200 OK\"\n",
|
||||
"After Reranking, new rank list for nodes: [4, 5, 0, 1, 2, 3, 6, 7, 8, 9]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Which date did Paul Gauguin arrive in Arles ?\",\n",
|
||||
" vector_top_k=10,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c32fbafb",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.824605</td>\n",
|
||||
" <td>He adopted elements of Pointillism, a technique in which a multitude of small coloured dots are applied to the canvas so that when seen from a distance they create an optical blend of hues. The style stresses the ability of complementary colours – including blue and orange – to form vibrant contrasts.<br><br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>While in Asnières Van Gogh painted parks, restaurants and the Seine, including Bridges across the Seine at Asnières. In November 1887, Theo and Vincent befriended Paul Gauguin who had just arrived in Paris. Towards the end of the year, Vincent arranged an exhibition alongside Bernard, Anquetin, and probably Toulouse-Lautrec, at the Grand-Bouillon Restaurant du Chalet, 43 avenue de Clichy, Montmartre. In a contemporary account, Bernard wrote that the exhibition was ahead of anything else in Paris. There, Bernard and Anquetin sold their first paintings, and Van Gogh exchanged work with Gauguin. Discussions on art, artists, and their social situations started during this exhibition, continued and expanded to include visitors to the show, like Camille Pissarro and his son Lucien, Signac and Seurat. In February 1888, feeling worn out from life in Paris, Van Gogh left, having painted more than 200 paintings during his two years there. Hours before his departure, accompanied by Theo, he paid his first and only visit to Seurat in his studio.<br><br><br>=== Artistic breakthrough ===<br><br><br>==== Arles (1888–89) ====<br><br>Ill from drink and suffering from smoker's cough, in February 1888 Van Gogh sought refuge in Arles. He seems to have moved with thoughts of founding an art colony. The Danish artist Christian Mourier-Petersen became his companion for two months, and, at first, Arles appeared exotic. In a letter, he described it as a foreign country: \"The Zouaves, the brothels, the adorable little Arlésienne going to her First Communion, the priest in his surplice, who looks like a dangerous rhinoceros, the people drinking absinthe, all seem to me creatures from another world.\"The time in Arles became one of Van Gogh's more prolific periods: he completed 200 paintings and more than 100 drawings and watercolours.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.822903</td>\n",
|
||||
" <td>Two years later, Vincent and Theo paid for the publication of a book on Monticelli paintings, and Vincent bought some of Monticelli's works to add to his collection.Van Gogh learned about Fernand Cormon's atelier from Theo. He worked at the studio in April and May 1886, where he frequented the circle of the Australian artist John Russell, who painted his portrait in 1886. Van Gogh also met fellow students Émile Bernard, Louis Anquetin and Henri de Toulouse-Lautrec – who painted a portrait of him in pastel. They met at Julien \"Père\" Tanguy's paint shop, (which was, at that time, the only place where Paul Cézanne's paintings were displayed). In 1886, two large exhibitions were staged there, showing Pointillism and Neo-impressionism for the first time and bringing attention to Georges Seurat and Paul Signac. Theo kept a stock of Impressionist paintings in his gallery on boulevard Montmartre, but Van Gogh was slow to acknowledge the new developments in art.Conflicts arose between the brothers. At the end of 1886 Theo found living with Vincent to be \"almost unbearable\". By early 1887, they were again at peace, and Vincent had moved to Asnières, a northwestern suburb of Paris, where he got to know Signac. He adopted elements of Pointillism, a technique in which a multitude of small coloured dots are applied to the canvas so that when seen from a distance they create an optical blend of hues. The style stresses the ability of complementary colours – including blue and orange – to form vibrant contrasts.<br><br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>While in Asnières Van Gogh painted parks, restaurants and the Seine, including Bridges across the Seine at Asnières. In November 1887, Theo and Vincent befriended Paul Gauguin who had just arrived in Paris. Towards the end of the year, Vincent arranged an exhibition alongside Bernard, Anquetin, and probably Toulouse-Lautrec, at the Grand-Bouillon Restaurant du Chalet, 43 avenue de Clichy, Montmartre. In a contemporary account, Bernard wrote that the exhibition was ahead of anything else in Paris.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.855685</td>\n",
|
||||
" <td>Gauguin fled Arles, never to see Van Gogh again. They continued to correspond, and in 1890, Gauguin proposed they form a studio in Antwerp. Meanwhile, other visitors to the hospital included Marie Ginoux and Roulin.Despite a pessimistic diagnosis, Van Gogh recovered and returned to the Yellow House on 7 January 1889. He spent the following month between hospital and home, suffering from hallucinations and delusions of poisoning. In March, the police closed his house after a petition by 30 townspeople (including the Ginoux family) who described him as le fou roux \"the redheaded madman\"; Van Gogh returned to hospital. Paul Signac visited him twice in March; in April, Van Gogh moved into rooms owned by Dr Rey after floods damaged paintings in his own home. Two months later, he left Arles and voluntarily entered an asylum in Saint-Rémy-de-Provence. Around this time, he wrote, \"Sometimes moods of indescribable anguish, sometimes moments when the veil of time and fatality of circumstances seemed to be torn apart for an instant.\"Van Gogh gave his 1889 Portrait of Doctor Félix Rey to Dr Rey. The physician was not fond of the painting and used it to repair a chicken coop, then gave it away. In 2016, the portrait was housed at the Pushkin Museum of Fine Arts and estimated to be worth over $50 million.<br><br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br><br><br>==== Saint-Rémy (May 1889 – May 1890) ====<br><br>Van Gogh entered the Saint-Paul-de-Mausole asylum on 8 May 1889, accompanied by his caregiver, Frédéric Salles, a Protestant clergyman. Saint-Paul was a former monastery in Saint-Rémy, located less than 30 kilometres (19 mi) from Arles, and it was run by a former naval doctor, Théophile Peyron. Van Gogh had two cells with barred windows, one of which he used as a studio. The clinic and its garden became the main subjects of his paintings.</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "venv",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RankLLM Reranker Demonstration (Van Gogh Wiki)\n",
|
||||
"\n",
|
||||
"This demo showcases how to use [RankLLM](https://github.com/castorini/rank_llm) to rerank passages. \n",
|
||||
"\n",
|
||||
"RankLLM offers a suite of listwise, pairwise, and pointwise rerankers, albeit with focus on open source LLMs finetuned for the task - RankVicuna and RankZephyr being two of them. It also features ranking with OpenAI and GenAI.\n",
|
||||
"\n",
|
||||
"It compares query search results from Van Gogh’s wikipedia with just retrieval (using VectorIndexRetriever from llama-index) and retrieval+reranking with RankLLM. We show an example of reranking 50 candidates using the RankZephyr reranker, which uses a listwise sliding window algorithm.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"_______________________________\n",
|
||||
"Dependencies:\n",
|
||||
"\n",
|
||||
"- RankLLM's [dependencies](https://github.com/castorini/rank_llm?tab=readme-ov-file#-installation)\n",
|
||||
"- The built-in retriever, which uses [Pyserini](https://github.com/castorini/pyserini), requires `JDK11`, `PyTorch`, and `Faiss`\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"### castorini/rank_llm\n",
|
||||
"RankLLM is a Python toolkit for reproducible information retrieval research using rerankers, with a focus on listwise reranking.\\\n",
|
||||
"Website: [http://rankllm.ai](http://rankllm.ai)\\"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index-core\n",
|
||||
"%pip install llama-index-llms-openai\n",
|
||||
"%pip install llama-index-postprocessor-rankllm-rerank\n",
|
||||
"%pip install rank-llm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import logging\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
|
||||
"logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))\n",
|
||||
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader\n",
|
||||
"from llama_index.core.postprocessor import LLMRerank\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from IPython.display import Markdown, display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"OPENAI_API_KEY = \"sk-\"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.llm = OpenAI(temperature=0, model=\"gpt-3.5-turbo\")\n",
|
||||
"Settings.chunk_size = 512"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data, Build Index"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pathlib import Path\n",
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"wiki_titles = [\n",
|
||||
" \"Vincent van Gogh\",\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"data_path = Path(\"data_wiki\")\n",
|
||||
"for title in wiki_titles:\n",
|
||||
" response = requests.get(\n",
|
||||
" \"https://en.wikipedia.org/w/api.php\",\n",
|
||||
" params={\n",
|
||||
" \"action\": \"query\",\n",
|
||||
" \"format\": \"json\",\n",
|
||||
" \"titles\": title,\n",
|
||||
" \"prop\": \"extracts\",\n",
|
||||
" \"explaintext\": True,\n",
|
||||
" },\n",
|
||||
" ).json()\n",
|
||||
" page = next(iter(response[\"query\"][\"pages\"].values()))\n",
|
||||
" wiki_text = page[\"extract\"]\n",
|
||||
"\n",
|
||||
" if not data_path.exists():\n",
|
||||
" Path.mkdir(data_path)\n",
|
||||
"\n",
|
||||
" with open(data_path / f\"{title}.txt\", \"w\") as fp:\n",
|
||||
" fp.write(wiki_text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# load documents\n",
|
||||
"documents = SimpleDirectoryReader(\"./data_wiki/\").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(\n",
|
||||
" documents,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Retrieval + RankLLM Reranking (sliding window)\n",
|
||||
"\n",
|
||||
"1. Set up retriever and reranker\n",
|
||||
"2. Retrieve results given search query without reranking\n",
|
||||
"3. Retrieve results given search query with RankZephyr reranking\n",
|
||||
"\n",
|
||||
"**All the field arguments and defaults for RankLLMRerank:**\n",
|
||||
"```python\n",
|
||||
"model: str = Field(\n",
|
||||
" description=\"Model name.\",\n",
|
||||
" default=\"rank_zephyr\"\n",
|
||||
")\n",
|
||||
"top_n: Optional[int] = Field(\n",
|
||||
" description=\"Number of nodes to return sorted by reranking score.\"\n",
|
||||
")\n",
|
||||
"window_size: int = Field(\n",
|
||||
" description=\"Reranking window size. Applicable only for listwise and pairwise models.\",\n",
|
||||
" default=20\n",
|
||||
")\n",
|
||||
"batch_size: Optional[int] = Field(\n",
|
||||
" description=\"Reranking batch size. Applicable only for pointwise models.\"\n",
|
||||
")\n",
|
||||
"context_size: int = Field(\n",
|
||||
" description=\"Maximum number of tokens for the context window.\",\n",
|
||||
" default=4096\n",
|
||||
")\n",
|
||||
"prompt_mode: PromptMode = Field(\n",
|
||||
" description=\"Prompt format and strategy used when invoking the reranking model.\",\n",
|
||||
" default=PromptMode.RANK_GPT\n",
|
||||
")\n",
|
||||
"num_gpus: int = Field(\n",
|
||||
" description=\"Number of GPUs to use for inference if applicable.\",\n",
|
||||
" default=1\n",
|
||||
")\n",
|
||||
"num_few_shot_examples: int = Field(\n",
|
||||
" description=\"Number of few-shot examples to include in the prompt.\",\n",
|
||||
" default=0\n",
|
||||
")\n",
|
||||
"few_shot_file: Optional[str] = Field(\n",
|
||||
" description=\"Path to a file containing few-shot examples, used if few-shot prompting is enabled.\",\n",
|
||||
" default=None\n",
|
||||
")\n",
|
||||
"use_logits: bool = Field(\n",
|
||||
" description=\"Whether to use raw logits for reranking scores instead of probabilities.\",\n",
|
||||
" default=False\n",
|
||||
")\n",
|
||||
"use_alpha: bool = Field(\n",
|
||||
" description=\"Whether to apply an alpha scaling factor in the reranking score calculation.\",\n",
|
||||
" default=False\n",
|
||||
")\n",
|
||||
"variable_passages: bool = Field(\n",
|
||||
" description=\"Whether to allow passages of variable lengths instead of fixed-size chunks.\",\n",
|
||||
" default=False\n",
|
||||
")\n",
|
||||
"stride: int = Field(\n",
|
||||
" description=\"Stride to use when sliding over long documents for reranking.\",\n",
|
||||
" default=10\n",
|
||||
")\n",
|
||||
"use_azure_openai: bool = Field(\n",
|
||||
" description=\"Whether to use Azure OpenAI instead of the standard OpenAI API.\",\n",
|
||||
" default=False\n",
|
||||
")\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.retrievers import VectorIndexRetriever\n",
|
||||
"from llama_index.core import QueryBundle\n",
|
||||
"from llama_index.postprocessor.rankllm_rerank import RankLLMRerank\n",
|
||||
"\n",
|
||||
"import pandas as pd\n",
|
||||
"import torch\n",
|
||||
"from IPython.display import display, HTML\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_retrieved_nodes(\n",
|
||||
" query_str,\n",
|
||||
" vector_top_k=10,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=False,\n",
|
||||
" model=\"rank_zephyr\",\n",
|
||||
" window_size=None,\n",
|
||||
"):\n",
|
||||
" query_bundle = QueryBundle(query_str)\n",
|
||||
" # configure retriever\n",
|
||||
" retriever = VectorIndexRetriever(\n",
|
||||
" index=index,\n",
|
||||
" similarity_top_k=vector_top_k,\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = retriever.retrieve(query_bundle)\n",
|
||||
" retrieved_nodes.reverse()\n",
|
||||
"\n",
|
||||
" if with_reranker:\n",
|
||||
" # configure reranker\n",
|
||||
" reranker = RankLLMRerank(\n",
|
||||
" model=model, top_n=reranker_top_n, window_size=window_size\n",
|
||||
" )\n",
|
||||
" retrieved_nodes = reranker.postprocess_nodes(\n",
|
||||
" retrieved_nodes, query_bundle\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # clear cache, rank_zephyr uses 16GB of GPU VRAM\n",
|
||||
" del reranker\n",
|
||||
" torch.cuda.empty_cache()\n",
|
||||
"\n",
|
||||
" return retrieved_nodes\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def pretty_print(df):\n",
|
||||
" return display(HTML(df.to_html().replace(\"\\\\n\", \"<br>\")))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def visualize_retrieved_nodes(nodes) -> None:\n",
|
||||
" result_dicts = []\n",
|
||||
" for node in nodes:\n",
|
||||
" result_dict = {\"Score\": node.score, \"Text\": node.node.get_text()}\n",
|
||||
" result_dicts.append(result_dict)\n",
|
||||
"\n",
|
||||
" pretty_print(pd.DataFrame(result_dicts))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Without `RankZephyr` reranking, the correct result is ranked `47`th/50.\n",
|
||||
"\n",
|
||||
"#### Expected result:\n",
|
||||
"```After much pleading from Van Gogh, Gauguin arrived in Arles on 23 October and, in November, the two painted together. Gauguin depicted Van Gogh in his The Painter of Sunflowers;```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.766322</td>\n",
|
||||
" <td>Yellow meant the most to him, because it symbolised emotional truth. He used yellow as a symbol for sunlight, life, and God.<br>Van Gogh strove to be a painter of rural life and nature; during his first summer in Arles he used his new palette to paint landscapes and traditional rural life. His belief that a power existed behind the natural led him to try to capture a sense of that power, or the essence of nature in his art, sometimes through the use of symbols. His renditions of the sower, at first copied from Jean-François Millet, reflect the influence of Thomas Carlyle and Friedrich Nietzsche's thoughts on the heroism of physical labour, as well as van Gogh's religious beliefs: the sower as Christ sowing life beneath the hot sun. These were themes and motifs he returned to often to rework and develop. His paintings of flowers are filled with symbolism, but rather than use traditional Christian iconography he made up his own, where life is lived under the sun and work is an allegory of life. In Arles, having gained confidence after painting spring blossoms and learning to capture bright sunlight, he was ready to paint The Sower.<br><br>Van Gogh stayed within what he called the \"guise of reality\" and was critical of overly stylised works. He wrote afterwards that the abstraction of Starry Night had gone too far and that reality had \"receded too far in the background\". Hughes describes it as a moment of extreme visionary ecstasy: the stars are in a great whirl, reminiscent of Hokusai's Great Wave, the movement in the heaven above is reflected by the movement of the cypress on the earth below, and the painter's vision is \"translated into a thick, emphatic plasma of paint\".<br>Between 1885 and his death in 1890, van Gogh appears to have been building an oeuvre, a collection that reflected his personal vision and could be commercially successful. He was influenced by Blanc's definition of style, that a true painting required optimal use of colour, perspective and brushstrokes. Van Gogh applied the word \"purposeful\" to paintings he thought he had mastered, as opposed to those he thought of as studies.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.768032</td>\n",
|
||||
" <td>==== Self-portraits ====<br><br>Van Gogh created more than 43 self-portraits between 1885 and 1889. They were usually completed in series, such as those painted in Paris in mid-1887, and continued until shortly before his death. Generally the portraits were studies, created during periods when he was reluctant to mix with others or when he lacked models and painted himself.<br>Van Gogh's self-portraits reflect a high degree of self-scrutiny. Often they were intended to mark important periods in his life; for example, the mid-1887 Paris series were painted at the point where he became aware of Claude Monet, Paul Cézanne and Signac. In Self-Portrait with Grey Felt Hat, heavy strains of paint spread outwards across the canvas. It is one of his most renowned self-portraits of that period, \"with its highly organized rhythmic brushstrokes, and the novel halo derived from the Neo-impressionist repertoire was what van Gogh himself called a 'purposeful' canvas\".<br>They contain a wide array of physiognomical representations. Van Gogh's mental and physical condition is usually apparent; he may appear unkempt, unshaven or with a neglected beard, with deeply sunken eyes, a weak jaw, or having lost teeth. Some show him with full lips, a long face or prominent skull, or sharpened, alert features. His hair is sometimes depicted in a vibrant reddish hue and at other times ash colored.<br>Van Gogh's self-portraits vary stylistically. In those painted after December 1888, the strong contrast of vivid colors highlight the haggard pallor of his skin. Some depict the artist with a beard, others without. He can be seen with bandages in portraits executed just after he mutilated his ear. In only a few does he depict himself as a painter. Those painted in Saint-Rémy show the head from the right, the side opposite his damaged ear, as he painted himself reflected in his mirror.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.769051</td>\n",
|
||||
" <td>With their broad brushstrokes, inventive perspectives, colours, contours and designs, these paintings represent the style he sought.<br><br><br>=== Major series ===<br><br>Van Gogh's stylistic developments are usually linked to the periods he spent living in different places across Europe. He was inclined to immerse himself in local cultures and lighting conditions, although he maintained a highly individual visual outlook throughout. His evolution as an artist was slow and he was aware of his painterly limitations. Van Gogh moved home often, perhaps to expose himself to new visual stimuli, and through exposure develop his technical skill. Art historian Melissa McQuillan believes the moves also reflect later stylistic changes and that van Gogh used the moves to avoid conflict, and as a coping mechanism for when the idealistic artist was faced with the realities of his then current situation.<br><br><br>==== Portraits ====<br><br>Van Gogh said portraiture was his greatest interest. \"What I'm most passionate about, much much more than all the rest in my profession\", he wrote in 1890, \"is the portrait, the modern portrait.\" It is \"the only thing in painting that moves me deeply and that gives me a sense of the infinite.\" He wrote to his sister that he wished to paint portraits that would endure, and that he would use colour to capture their emotions and character rather than aiming for photographic realism. Those closest to van Gogh are mostly absent from his portraits; he rarely painted Theo, van Rappard or Bernard. The portraits of his mother were from photographs.<br>Van Gogh painted Arles' postmaster Joseph Roulin and his family repeatedly. In five versions of La Berceuse (The Lullaby), van Gogh painted Augustine Roulin quietly holding a rope that rocks the unseen cradle of her infant daughter. Van Gogh had planned for it to be the central image of a triptych, flanked by paintings of sunflowers.</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Which date did Paul Gauguin arrive in Arles?\",\n",
|
||||
" vector_top_k=50,\n",
|
||||
" with_reranker=False,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"visualize_retrieved_nodes(new_nodes[:3])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With `RankZephyr` reranking, the correct result is ranked `1`st/50"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"Loading rank_zephyr ...\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Loading checkpoint shards: 100%|██████████| 3/3 [00:02<00:00, 1.11it/s]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Completed loading rank_zephyr\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"100%|██████████| 1/1 [00:11<00:00, 11.38s/it]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Score</th>\n",
|
||||
" <th>Text</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.857234</td>\n",
|
||||
" <td>After much pleading from van Gogh, Gauguin arrived in Arles on 23 October and, in November, the two painted together. Gauguin depicted van Gogh in his The Painter of Sunflowers; van Gogh painted pictures from memory, following Gauguin's suggestion. Among these \"imaginative\" paintings is Memory of the Garden at Etten. Their first joint outdoor venture was at the Alyscamps, when they produced the pendants Les Alyscamps. The single painting Gauguin completed during his visit was his portrait of van Gogh.<br>Van Gogh and Gauguin visited Montpellier in December 1888, where they saw works by Courbet and Delacroix in the Musée Fabre. Their relationship began to deteriorate; van Gogh admired Gauguin and wanted to be treated as his equal, but Gauguin was arrogant and domineering, which frustrated van Gogh. They often quarreled; van Gogh increasingly feared that Gauguin was going to desert him, and the situation, which van Gogh described as one of \"excessive tension\", rapidly headed towards crisis point.<br><br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br><br><br>==== Hospital in Arles (December 1888) ====<br><br>The exact sequence that led to the mutilation of van Gogh's ear is not known. Gauguin said, fifteen years later, that the night followed several instances of physically threatening behaviour. Their relationship was complex and Theo may have owed money to Gauguin, who suspected the brothers were exploiting him financially. It seems likely that Vincent realised that Gauguin was planning to leave. The following days saw heavy rain, leading to the two men being shut in the Yellow House. Gauguin recalled that van Gogh followed him after he left for a walk and \"rushed towards me, an open razor in his hand.\" This account is uncorroborated; Gauguin was almost certainly absent from the Yellow House that night, most likely staying in a hotel.<br>After an altercation on the evening of 23 December 1888, van Gogh returned to his room where he seemingly heard voices and either wholly or in part severed his left ear with a razor causing severe bleeding.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.861649</td>\n",
|
||||
" <td>==== Gauguin's visit (1888) ====<br> <br><br>When Gauguin agreed to visit Arles in 1888, van Gogh hoped for friendship and to realize his idea of an artists' collective. Van Gogh prepared for Gauguin's arrival by painting four versions of Sunflowers in one week. \"In the hope of living in a studio of our own with Gauguin,\" he wrote in a letter to Theo, \"I'd like to do a decoration for the studio. Nothing but large Sunflowers.\" <br>When Boch visited again, van Gogh painted a portrait of him, as well as the study The Poet Against a Starry Sky.<br>In preparation for Gauguin's visit, van Gogh bought two beds on advice from the station's postal supervisor Joseph Roulin, whose portrait he painted. On 17 September, he spent his first night in the still sparsely furnished Yellow House. When Gauguin consented to work and live in Arles with him, van Gogh started to work on the Décoration for the Yellow House, probably the most ambitious effort he ever undertook. He completed two chair paintings: Van Gogh's Chair and Gauguin's Chair.<br>After much pleading from van Gogh, Gauguin arrived in Arles on 23 October and, in November, the two painted together. Gauguin depicted van Gogh in his The Painter of Sunflowers; van Gogh painted pictures from memory, following Gauguin's suggestion. Among these \"imaginative\" paintings is Memory of the Garden at Etten. Their first joint outdoor venture was at the Alyscamps, when they produced the pendants Les Alyscamps. The single painting Gauguin completed during his visit was his portrait of van Gogh.<br>Van Gogh and Gauguin visited Montpellier in December 1888, where they saw works by Courbet and Delacroix in the Musée Fabre. Their relationship began to deteriorate; van Gogh admired Gauguin and wanted to be treated as his equal, but Gauguin was arrogant and domineering, which frustrated van Gogh.</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.852035</td>\n",
|
||||
" <td>Gauguin fled Arles, never to see van Gogh again. They continued to correspond, and in 1890, Gauguin proposed they form a studio in Antwerp. Meanwhile, other visitors to the hospital included Marie Ginoux and Roulin.<br>Despite a pessimistic diagnosis, van Gogh recovered and returned to the Yellow House on 7 January 1889. He spent the following month between hospital and home, suffering from hallucinations and delusions of poisoning. In March, the police closed his house after a petition by 30 townspeople (including the Ginoux family) who described him as le fou roux \"the redheaded madman\"; Van Gogh returned to hospital. Paul Signac visited him twice in March; in April, van Gogh moved into rooms owned by Dr Rey after floods damaged paintings in his own home. Two months later, he left Arles and voluntarily entered an asylum in Saint-Rémy-de-Provence. Around this time, he wrote, \"Sometimes moods of indescribable anguish, sometimes moments when the veil of time and fatality of circumstances seemed to be torn apart for an instant.\"<br>Van Gogh gave his 1889 Portrait of Doctor Félix Rey to Dr Rey. The physician was not fond of the painting and used it to repair a chicken coop, then gave it away. In 2016, the portrait was housed at the Pushkin Museum of Fine Arts and estimated to be worth over $50 million.<br><br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br>\\t\\t<br>\\t\\t\\t<br>\\t\\t\\t<br>\\t\\t<br><br><br>==== Saint-Rémy (May 1889 – May 1890) ====<br><br>Van Gogh entered the Saint-Paul-de-Mausole asylum on 8 May 1889, accompanied by his caregiver, Frédéric Salles, a Protestant clergyman. Saint-Paul was a former monastery in Saint-Rémy, located less than 30 kilometres (19 mi) from Arles, and it was run by a former naval doctor, Théophile Peyron. Van Gogh had two cells with barred windows, one of which he used as a studio. The clinic and its garden became the main subjects of his paintings.</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.HTML object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Which date did Paul Gauguin arrive in Arles?\",\n",
|
||||
" vector_top_k=50,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=True,\n",
|
||||
" model=\"rank_zephyr\",\n",
|
||||
" window_size=15,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Retrieve and Rerank top 10 results using RankVicuna, RankGPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# RankVicuna\n",
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Which date did Paul Gauguin arrive in Arles?\",\n",
|
||||
" vector_top_k=10,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=True,\n",
|
||||
" model=\"rank_vicuna\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Using RankGPT\n",
|
||||
"new_nodes = get_retrieved_nodes(\n",
|
||||
" \"Which date did Paul Gauguin arrive in Arles?\",\n",
|
||||
" vector_top_k=10,\n",
|
||||
" reranker_top_n=3,\n",
|
||||
" with_reranker=True,\n",
|
||||
" model=\"gpt-3.5-turbo\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"visualize_retrieved_nodes(new_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### For other models, use `model=`\n",
|
||||
"- `monot5` for MonoT5 pointwise reranker\n",
|
||||
"- `castorini/LiT5-Distill-base` for LiT5 distill reranker\n",
|
||||
"- `castorini/LiT5-Score-base` for LiT5 score reranker\n",
|
||||
"- or any hugging face model path"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "main",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
Reference in New Issue
Block a user