Skip to content

Instantly share code, notes, and snippets.

@Daethyra
Last active October 5, 2023 19:43
Show Gist options
  • Save Daethyra/e8a213a44f47df2f9b0a770d840df7ca to your computer and use it in GitHub Desktop.
Save Daethyra/e8a213a44f47df2f9b0a770d840df7ca to your computer and use it in GitHub Desktop.
Generative: Question/Answering w/ OpenAI
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/Daethyra/e8a213a44f47df2f9b0a770d840df7ca/copy-of-gen-qa-openai.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SMFUgtvbFeLQ"
},
"source": [
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/docs/gen-qa-openai.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/docs/gen-qa-openai.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "v0to-QXCQjsm"
},
"source": [
"# Retrieval Enhanced Generative Question Answering with OpenAI\n",
"\n",
"#### Fixing LLMs that Hallucinate\n",
"\n",
"In this notebook we will learn how to query relevant contexts to our queries from Pinecone, and pass these to a generative OpenAI model to generate an answer backed by real data sources. Required installs for this notebook are:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "VpMvHAYRQf9N",
"outputId": "29c0552f-22e2-4fe4-93e4-de9e34bbf96a"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m72.0/72.0 kB\u001b[0m \u001b[31m1.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m177.2/177.2 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m62.5/62.5 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m300.4/300.4 kB\u001b[0m \u001b[31m6.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.3/1.3 MB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.1/1.1 MB\u001b[0m \u001b[31m12.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m12.3/12.3 MB\u001b[0m \u001b[31m30.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m16.4/16.4 MB\u001b[0m \u001b[31m53.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m34.9/34.9 MB\u001b[0m \u001b[31m14.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m224.5/224.5 kB\u001b[0m \u001b[31m17.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m223.6/223.6 kB\u001b[0m \u001b[31m14.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m223.0/223.0 kB\u001b[0m \u001b[31m17.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m218.0/218.0 kB\u001b[0m \u001b[31m17.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m218.0/218.0 kB\u001b[0m \u001b[31m18.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m211.7/211.7 kB\u001b[0m \u001b[31m18.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m341.8/341.8 kB\u001b[0m \u001b[31m23.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.4/73.4 kB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m11.1/11.1 MB\u001b[0m \u001b[31m81.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m143.4/143.4 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m121.4/121.4 kB\u001b[0m \u001b[31m11.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m120.3/120.3 kB\u001b[0m \u001b[31m11.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m115.6/115.6 kB\u001b[0m \u001b[31m10.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m115.5/115.5 kB\u001b[0m \u001b[31m11.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m115.3/115.3 kB\u001b[0m \u001b[31m10.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m115.1/115.1 kB\u001b[0m \u001b[31m11.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.6/114.6 kB\u001b[0m \u001b[31m11.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
"google-cloud-bigquery 3.10.0 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-cloud-bigquery-connection 1.12.1 requires google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0, but you have google-api-core 2.8.2 which is incompatible.\n",
"google-cloud-bigquery-connection 1.12.1 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-cloud-bigquery-storage 2.22.0 requires google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0, but you have google-api-core 2.8.2 which is incompatible.\n",
"google-cloud-bigquery-storage 2.22.0 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-cloud-datastore 2.15.2 requires google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0, but you have google-api-core 2.8.2 which is incompatible.\n",
"google-cloud-datastore 2.15.2 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-cloud-firestore 2.11.1 requires google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0, but you have google-api-core 2.8.2 which is incompatible.\n",
"google-cloud-firestore 2.11.1 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-cloud-functions 1.13.3 requires google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0, but you have google-api-core 2.8.2 which is incompatible.\n",
"google-cloud-functions 1.13.3 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-cloud-language 2.9.1 requires google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0, but you have google-api-core 2.8.2 which is incompatible.\n",
"google-cloud-language 2.9.1 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-cloud-translate 3.11.3 requires google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0, but you have google-api-core 2.8.2 which is incompatible.\n",
"google-cloud-translate 3.11.3 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"google-colab 1.0.0 requires pandas==1.5.3, but you have pandas 2.1.1 which is incompatible.\n",
"grpc-google-iam-v1 0.12.6 requires protobuf!=3.20.0,!=3.20.1,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you have protobuf 3.19.3 which is incompatible.\n",
"pandas-gbq 0.17.9 requires pyarrow<10.0dev,>=3.0.0, but you have pyarrow 11.0.0 which is incompatible.\n",
"tensorboard 2.13.0 requires protobuf>=3.19.6, but you have protobuf 3.19.3 which is incompatible.\n",
"tensorflow 2.13.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.20.3, but you have protobuf 3.19.3 which is incompatible.\n",
"tensorflow-datasets 4.9.3 requires protobuf>=3.20, but you have protobuf 3.19.3 which is incompatible.\n",
"tensorflow-hub 0.14.0 requires protobuf>=3.19.6, but you have protobuf 3.19.3 which is incompatible.\n",
"tensorflow-metadata 1.14.0 requires protobuf<4.21,>=3.20.3, but you have protobuf 3.19.3 which is incompatible.\u001b[0m\u001b[31m\n",
"\u001b[0m"
]
}
],
"source": [
"!pip install -qU \\\n",
" openai==0.27.7 \\\n",
" \"pinecone-client[grpc]\"==2.2.1 \\\n",
" pinecone-datasets=='0.5.0rc11' \\\n",
" tqdm"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NhWnLkHqmeWI"
},
"source": [
"---\n",
"\n",
"## Building a Knowledge Base\n",
"\n",
"Building more reliable LLMs tools requires an external _\"Knowledge Base\"_, a place where we can store and use to efficiently retrieve information. We can think of this as the external _long-term memory_ of our LLM.\n",
"\n",
"We will need to retrieve information that is semantically related to our queries, to do this we need to use _\"dense vector embeddings\"_. These can be thought of as numerical representations of the *meaning* behind our sentences.\n",
"\n",
"There are many options for creating these dense vectors, like open source [sentence transformers](https://pinecone.io/learn/nlp/) or OpenAI's [ada-002 model](https://youtu.be/ocxq84ocYi0). We will use OpenAI's offering in this example.\n",
"\n",
"We have already precomputed the embeddings here to speed things up. If you'd like to work through the full process however, check out [this notebook](https://colab.research.google.com/github/pinecone-io/examples/blob/master/docs/gen-qa-openai.ipynb).\n",
"\n",
"To download our precomputed embeddings we use Pinecone datasets:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 206
},
"id": "EI2iYxq16or9",
"outputId": "99d415cf-5c3d-4718-cbee-7983e320eb86"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" id \\\n",
"0 35Pdoyi6ZoQ-t0.0 \n",
"1 35Pdoyi6ZoQ-t18.48 \n",
"2 35Pdoyi6ZoQ-t32.36 \n",
"3 35Pdoyi6ZoQ-t51.519999999999996 \n",
"4 35Pdoyi6ZoQ-t67.28 \n",
"\n",
" values sparse_values \\\n",
"0 [-0.010402066633105278, -0.018359748646616936,... None \n",
"1 [-0.011849376372992992, 0.0007984379190020263,... None \n",
"2 [-0.014534404501318932, -0.0003158661129418760... None \n",
"3 [-0.011597747914493084, -0.007550035137683153,... None \n",
"4 [-0.015879768878221512, 0.0030445053707808256,... None \n",
"\n",
" metadata \n",
"0 {'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en... \n",
"1 {'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en... \n",
"2 {'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en... \n",
"3 {'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en... \n",
"4 {'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en... "
],
"text/html": [
"\n",
" <div id=\"df-1f6bcb73-f60c-414e-ad74-787d6b3055df\" class=\"colab-df-container\">\n",
" <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>id</th>\n",
" <th>values</th>\n",
" <th>sparse_values</th>\n",
" <th>metadata</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>35Pdoyi6ZoQ-t0.0</td>\n",
" <td>[-0.010402066633105278, -0.018359748646616936,...</td>\n",
" <td>None</td>\n",
" <td>{'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>35Pdoyi6ZoQ-t18.48</td>\n",
" <td>[-0.011849376372992992, 0.0007984379190020263,...</td>\n",
" <td>None</td>\n",
" <td>{'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>35Pdoyi6ZoQ-t32.36</td>\n",
" <td>[-0.014534404501318932, -0.0003158661129418760...</td>\n",
" <td>None</td>\n",
" <td>{'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>35Pdoyi6ZoQ-t51.519999999999996</td>\n",
" <td>[-0.011597747914493084, -0.007550035137683153,...</td>\n",
" <td>None</td>\n",
" <td>{'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>35Pdoyi6ZoQ-t67.28</td>\n",
" <td>[-0.015879768878221512, 0.0030445053707808256,...</td>\n",
" <td>None</td>\n",
" <td>{'channel_id': 'UCv83tO5cePwHMt1952IVVHw', 'en...</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
" <div class=\"colab-df-buttons\">\n",
"\n",
" <div class=\"colab-df-container\">\n",
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-1f6bcb73-f60c-414e-ad74-787d6b3055df')\"\n",
" title=\"Convert this dataframe to an interactive table.\"\n",
" style=\"display:none;\">\n",
"\n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
" </svg>\n",
" </button>\n",
"\n",
" <style>\n",
" .colab-df-container {\n",
" display:flex;\n",
" gap: 12px;\n",
" }\n",
"\n",
" .colab-df-convert {\n",
" background-color: #E8F0FE;\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: #1967D2;\n",
" height: 32px;\n",
" padding: 0 0 0 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-convert:hover {\n",
" background-color: #E2EBFA;\n",
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: #174EA6;\n",
" }\n",
"\n",
" .colab-df-buttons div {\n",
" margin-bottom: 4px;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert {\n",
" background-color: #3B4455;\n",
" fill: #D2E3FC;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert:hover {\n",
" background-color: #434B5C;\n",
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
" fill: #FFFFFF;\n",
" }\n",
" </style>\n",
"\n",
" <script>\n",
" const buttonEl =\n",
" document.querySelector('#df-1f6bcb73-f60c-414e-ad74-787d6b3055df button.colab-df-convert');\n",
" buttonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
"\n",
" async function convertToInteractive(key) {\n",
" const element = document.querySelector('#df-1f6bcb73-f60c-414e-ad74-787d6b3055df');\n",
" const dataTable =\n",
" await google.colab.kernel.invokeFunction('convertToInteractive',\n",
" [key], {});\n",
" if (!dataTable) return;\n",
"\n",
" const docLinkHtml = 'Like what you see? Visit the ' +\n",
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
" + ' to learn more about interactive tables.';\n",
" element.innerHTML = '';\n",
" dataTable['output_type'] = 'display_data';\n",
" await google.colab.output.renderOutput(dataTable, element);\n",
" const docLink = document.createElement('div');\n",
" docLink.innerHTML = docLinkHtml;\n",
" element.appendChild(docLink);\n",
" }\n",
" </script>\n",
" </div>\n",
"\n",
"\n",
"<div id=\"df-f9c333da-3de8-421d-9a04-ed68947e4fd2\">\n",
" <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-f9c333da-3de8-421d-9a04-ed68947e4fd2')\"\n",
" title=\"Suggest charts.\"\n",
" style=\"display:none;\">\n",
"\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
" width=\"24px\">\n",
" <g>\n",
" <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
" </g>\n",
"</svg>\n",
" </button>\n",
"\n",
"<style>\n",
" .colab-df-quickchart {\n",
" --bg-color: #E8F0FE;\n",
" --fill-color: #1967D2;\n",
" --hover-bg-color: #E2EBFA;\n",
" --hover-fill-color: #174EA6;\n",
" --disabled-fill-color: #AAA;\n",
" --disabled-bg-color: #DDD;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-quickchart {\n",
" --bg-color: #3B4455;\n",
" --fill-color: #D2E3FC;\n",
" --hover-bg-color: #434B5C;\n",
" --hover-fill-color: #FFFFFF;\n",
" --disabled-bg-color: #3B4455;\n",
" --disabled-fill-color: #666;\n",
" }\n",
"\n",
" .colab-df-quickchart {\n",
" background-color: var(--bg-color);\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: var(--fill-color);\n",
" height: 32px;\n",
" padding: 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-quickchart:hover {\n",
" background-color: var(--hover-bg-color);\n",
" box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: var(--button-hover-fill-color);\n",
" }\n",
"\n",
" .colab-df-quickchart-complete:disabled,\n",
" .colab-df-quickchart-complete:disabled:hover {\n",
" background-color: var(--disabled-bg-color);\n",
" fill: var(--disabled-fill-color);\n",
" box-shadow: none;\n",
" }\n",
"\n",
" .colab-df-spinner {\n",
" border: 2px solid var(--fill-color);\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" animation:\n",
" spin 1s steps(1) infinite;\n",
" }\n",
"\n",
" @keyframes spin {\n",
" 0% {\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" border-left-color: var(--fill-color);\n",
" }\n",
" 20% {\n",
" border-color: transparent;\n",
" border-left-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" }\n",
" 30% {\n",
" border-color: transparent;\n",
" border-left-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" border-right-color: var(--fill-color);\n",
" }\n",
" 40% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" border-top-color: var(--fill-color);\n",
" }\n",
" 60% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" }\n",
" 80% {\n",
" border-color: transparent;\n",
" border-right-color: var(--fill-color);\n",
" border-bottom-color: var(--fill-color);\n",
" }\n",
" 90% {\n",
" border-color: transparent;\n",
" border-bottom-color: var(--fill-color);\n",
" }\n",
" }\n",
"</style>\n",
"\n",
" <script>\n",
" async function quickchart(key) {\n",
" const quickchartButtonEl =\n",
" document.querySelector('#' + key + ' button');\n",
" quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n",
" quickchartButtonEl.classList.add('colab-df-spinner');\n",
" try {\n",
" const charts = await google.colab.kernel.invokeFunction(\n",
" 'suggestCharts', [key], {});\n",
" } catch (error) {\n",
" console.error('Error during call to suggestCharts:', error);\n",
" }\n",
" quickchartButtonEl.classList.remove('colab-df-spinner');\n",
" quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
" }\n",
" (() => {\n",
" let quickchartButtonEl =\n",
" document.querySelector('#df-f9c333da-3de8-421d-9a04-ed68947e4fd2 button');\n",
" quickchartButtonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
" })();\n",
" </script>\n",
"</div>\n",
" </div>\n",
" </div>\n"
]
},
"metadata": {},
"execution_count": 2
}
],
"source": [
"from pinecone_datasets import load_dataset\n",
"\n",
"dataset = load_dataset('youtube-transcripts-text-embedding-ada-002')\n",
"# we drop sparse_values as they are not needed for this example\n",
"dataset.documents.drop(['metadata'], axis=1, inplace=True)\n",
"dataset.documents.rename(columns={'blob': 'metadata'}, inplace=True)\n",
"dataset.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VMyJjt1cnwcH"
},
"source": [
"Now we need a place to store these embeddings and enable a efficient _vector search_ through them all. To do that we use Pinecone, we can get a [free API key](https://app.pinecone.io) and enter it below where we will initialize our connection to Pinecone and create a new index."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "qbJrLMWZFeLY",
"outputId": "d52cfe13-6a5c-40b7-8bc6-756e8a831802"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"WhoAmIResponse(username='dddd16c', user_label='default', projectname='88af56d')"
]
},
"metadata": {},
"execution_count": 3
}
],
"source": [
"import os\n",
"import pinecone\n",
"\n",
"# initialize connection to pinecone (get API key at app.pinecone.io)\n",
"api_key = os.getenv(\"PINECONE_API_KEY\") or \"api_key\"\n",
"# find your environment next to the api key in pinecone console\n",
"env = os.getenv(\"PINECONE_ENVIRONMENT\") or \"us-central1-gcp\"\n",
"\n",
"pinecone.init(api_key=api_key, environment=env)\n",
"pinecone.whoami()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "L4C_TQWcFeLY",
"tags": [
"parameters"
]
},
"outputs": [],
"source": [
"index_name = 'gen-qa-openai-fast'"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "UPNwQTH0RNcl"
},
"outputs": [],
"source": [
"# check if index already exists (it shouldn't if this is first time)\n",
"if index_name not in pinecone.list_indexes():\n",
" # if does not exist, create index\n",
" pinecone.create_index(\n",
" index_name,\n",
" dimension=1536, # dimensionality of text-embedding-ada-002\n",
" metric='cosine',\n",
" )\n",
"# connect to index\n",
"index = pinecone.GRPCIndex(index_name)\n",
"# view index stats\n",
"#index.describe_index_stats() # Could not run successfully -- Commented out this line."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nELBmqxxzeqL"
},
"source": [
"We can see the index is currently empty with a `total_vector_count` of `0`. We can begin populating it with OpenAI `text-embedding-ada-002` built embeddings like so:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"id": "vPb9liovzrc8"
},
"outputs": [],
"source": [
"for batch in dataset.iter_documents(batch_size=64):\n",
" index.upsert(batch)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2yiF91IbyGYo"
},
"source": [
"Now we've added all of our langchain docs to the index. With that we can move on to retrieval and then answer generation."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VfP0TQVeG1hO"
},
"source": [
"## Retrieval"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kXXYoANbG13a"
},
"source": [
"To search through our documents we first need to create a query vector `xq`. Using `xq` we will retrieve the most relevant chunks from the LangChain docs. To create that query vector we must initialize a `text-embedding-ada-002` embedding model with OpenAI. For this, you need an [OpenAI API key](https://platform.openai.com/)."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "2O0kRYO8G7Qi"
},
"outputs": [],
"source": [
"import openai\n",
"\n",
"# get api key from platform.openai.com\n",
"openai.api_key = os.getenv('OPENAI_API_KEY') or 'sk-'\n",
"\n",
"embed_model = \"text-embedding-ada-002\""
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "LF1U_yZGojRJ"
},
"outputs": [],
"source": [
"query = (\n",
" \"Which training method should I use for sentence transformers when \" +\n",
" \"I only have pairs of related sentences?\"\n",
")\n",
"\n",
"res = openai.Embedding.create(\n",
" input=[query],\n",
" engine=embed_model\n",
")\n",
"\n",
"# retrieve from Pinecone\n",
"xq = res['data'][0]['embedding']\n",
"\n",
"# get relevant contexts (including the questions)\n",
"res = index.query(xq, top_k=2, include_metadata=True)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "GH_DkmsNomww",
"outputId": "5cfba1bd-3c2b-4438-eae2-a74795046f3d"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"{'matches': [{'id': 'pNvujJ1XyeQ-t418.88',\n",
" 'metadata': {'channel_id': 'UCv83tO5cePwHMt1952IVVHw',\n",
" 'end': 568.0,\n",
" 'published': '2021-11-24 16:24:24 UTC',\n",
" 'start': 418.0,\n",
" 'text': 'pairs of related sentences you can go '\n",
" 'ahead and actually try training or '\n",
" 'fine-tuning using NLI with multiple '\n",
" \"negative ranking loss. If you don't have \"\n",
" 'that fine. Another option is that you have '\n",
" 'a semantic textual similarity data set or '\n",
" 'STS and what this is is you have so you '\n",
" 'have sentence A here, sentence B here and '\n",
" 'then you have a score from from 0 to 1 '\n",
" 'that tells you the similarity between '\n",
" 'those two scores and you would train this '\n",
" 'using something like cosine similarity '\n",
" \"loss. Now if that's not an option and your \"\n",
" 'focus or use case is on building a '\n",
" 'sentence transformer for another language '\n",
" 'where there is no current sentence '\n",
" 'transformer you can use multilingual '\n",
" 'parallel data. So what I mean by that is '\n",
" 'so parallel data just means translation '\n",
" 'pairs so if you have for example a English '\n",
" 'sentence and then you have another '\n",
" 'language here so it can it can be anything '\n",
" \"I'm just going to put XX and that XX is \"\n",
" 'your target language you can fine-tune a '\n",
" 'model using something called multilingual '\n",
" 'knowledge distillation and what that does '\n",
" 'is takes a monolingual model for example '\n",
" 'in English and using those translation '\n",
" 'pairs it distills the knowledge the '\n",
" 'semantic similarity knowledge from that '\n",
" 'monolingual English model into a '\n",
" 'multilingual model which can handle both '\n",
" 'English and your target language. So '\n",
" \"they're three options quite popular very \"\n",
" 'common that you can go for and as a '\n",
" 'supervised methods the chances are that '\n",
" 'probably going to outperform anything you '\n",
" 'do with unsupervised training at least for '\n",
" 'now. So if none of those sound like '\n",
" 'something',\n",
" 'title': 'Today Unsupervised Sentence Transformers, '\n",
" 'Tomorrow Skynet (how TSDAE works)',\n",
" 'url': 'https://youtu.be/pNvujJ1XyeQ'},\n",
" 'score': 0.8653147,\n",
" 'sparse_values': {'indices': [], 'values': []},\n",
" 'values': []},\n",
" {'id': 'WS1uVMGhlWQ-t747.92',\n",
" 'metadata': {'channel_id': 'UCv83tO5cePwHMt1952IVVHw',\n",
" 'end': 906.0,\n",
" 'published': '2021-10-20 17:06:20 UTC',\n",
" 'start': 747.0,\n",
" 'text': \"pooling approach. Or we can't use it in \"\n",
" 'its current form. Now the solution to this '\n",
" 'problem was introduced by two people in '\n",
" '2019 Nils Reimers and Irenia Gurevich. '\n",
" 'They introduced what is the first sentence '\n",
" 'transformer or sentence BERT. And it was '\n",
" 'found that sentence BERT or S BERT '\n",
" 'outformed all of the previous Save the Art '\n",
" 'models on pretty much all benchmarks. Not '\n",
" 'all of them but most of them. And it did '\n",
" 'it in a very quick time. So if we compare '\n",
" 'it to BERT, if we wanted to find the most '\n",
" 'similar sentence pair from 10,000 '\n",
" 'sentences in that 2019 paper they found '\n",
" 'that with BERT that took 65 hours. With S '\n",
" 'BERT embeddings they could create all the '\n",
" 'embeddings in just around five seconds. '\n",
" 'And then they could compare all those with '\n",
" \"cosine similarity in 0.01 seconds. So it's \"\n",
" 'a lot faster. We go from 65 hours to just '\n",
" 'over five seconds which is I think pretty '\n",
" \"incredible. Now I think that's pretty much \"\n",
" 'all the context we need behind sentence '\n",
" 'transformers. And what we do now is dive '\n",
" 'into a little bit of how they actually '\n",
" 'work. Now we said before we have the core '\n",
" 'transform models and what S BERT does is '\n",
" 'fine tunes on sentence pairs using what is '\n",
" 'called a Siamese architecture or Siamese '\n",
" 'network. What we mean by a Siamese network '\n",
" 'is that we have what we can see, what can '\n",
" 'view as two BERT models that are identical '\n",
" 'and the weights between those two models '\n",
" 'are tied. Now in reality when implementing '\n",
" 'this we just use a single BERT model. And '\n",
" 'what we do is we process one sentence, a '\n",
" 'sentence A through the model and then we '\n",
" 'process another sentence, sentence B '\n",
" \"through the model. And that's the sentence \"\n",
" 'pair. So with our cross-linked we were '\n",
" 'processing the sentence pair together. We '\n",
" 'were putting them both together, '\n",
" 'processing them all at once. This time we '\n",
" 'process them separately. And during '\n",
" 'training what happens is the weights '\n",
" 'within BERT are optimized to reduce the '\n",
" 'difference between two vector embeddings '\n",
" 'or two sentence',\n",
" 'title': 'Intro to Sentence Embeddings with '\n",
" 'Transformers',\n",
" 'url': 'https://youtu.be/WS1uVMGhlWQ'},\n",
" 'score': 0.8645074,\n",
" 'sparse_values': {'indices': [], 'values': []},\n",
" 'values': []}],\n",
" 'namespace': ''}"
]
},
"metadata": {},
"execution_count": 11
}
],
"source": [
"res"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "A5dDWPGoIrd9"
},
"source": [
"We write some functions to handle the retrieval and completion steps:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"id": "92NmGGJ1TKQp"
},
"outputs": [],
"source": [
"limit = 3750\n",
"\n",
"def retrieve(query):\n",
" res = openai.Embedding.create(\n",
" input=[query],\n",
" engine=embed_model\n",
" )\n",
"\n",
" # retrieve from Pinecone\n",
" xq = res['data'][0]['embedding']\n",
"\n",
" # get relevant contexts\n",
" res = index.query(xq, top_k=3, include_metadata=True)\n",
" contexts = [\n",
" x['metadata']['text'] for x in res['matches']\n",
" ]\n",
"\n",
" # build our prompt with the retrieved contexts included\n",
" prompt_start = (\n",
" \"Answer the question based on the context below.\\n\\n\"+\n",
" \"Context:\\n\"\n",
" )\n",
" prompt_end = (\n",
" f\"\\n\\nQuestion: {query}\\nAnswer:\"\n",
" )\n",
" # append contexts until hitting limit\n",
" for i in range(1, len(contexts)):\n",
" if len(\"\\n\\n---\\n\\n\".join(contexts[:i])) >= limit:\n",
" prompt = (\n",
" prompt_start +\n",
" \"\\n\\n---\\n\\n\".join(contexts[:i-1]) +\n",
" prompt_end\n",
" )\n",
" break\n",
" elif i == len(contexts)-1:\n",
" prompt = (\n",
" prompt_start +\n",
" \"\\n\\n---\\n\\n\".join(contexts) +\n",
" prompt_end\n",
" )\n",
" return prompt\n",
"\n",
"\n",
"def complete(prompt):\n",
" # query text-davinci-003\n",
" res = openai.Completion.create(\n",
" engine='text-davinci-003',\n",
" prompt=prompt,\n",
" temperature=0,\n",
" max_tokens=400,\n",
" top_p=1,\n",
" frequency_penalty=0,\n",
" presence_penalty=0,\n",
" stop=None\n",
" )\n",
" return res['choices'][0]['text'].strip()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 105
},
"id": "LwsZuxiTvU2d",
"outputId": "f4ec11fc-feff-4a75-82d6-d173e930a641"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"\"Answer the question based on the context below.\\n\\nContext:\\npairs of related sentences you can go ahead and actually try training or fine-tuning using NLI with multiple negative ranking loss. If you don't have that fine. Another option is that you have a semantic textual similarity data set or STS and what this is is you have so you have sentence A here, sentence B here and then you have a score from from 0 to 1 that tells you the similarity between those two scores and you would train this using something like cosine similarity loss. Now if that's not an option and your focus or use case is on building a sentence transformer for another language where there is no current sentence transformer you can use multilingual parallel data. So what I mean by that is so parallel data just means translation pairs so if you have for example a English sentence and then you have another language here so it can it can be anything I'm just going to put XX and that XX is your target language you can fine-tune a model using something called multilingual knowledge distillation and what that does is takes a monolingual model for example in English and using those translation pairs it distills the knowledge the semantic similarity knowledge from that monolingual English model into a multilingual model which can handle both English and your target language. So they're three options quite popular very common that you can go for and as a supervised methods the chances are that probably going to outperform anything you do with unsupervised training at least for now. So if none of those sound like something\\n\\n---\\n\\npooling approach. Or we can't use it in its current form. Now the solution to this problem was introduced by two people in 2019 Nils Reimers and Irenia Gurevich. They introduced what is the first sentence transformer or sentence BERT. And it was found that sentence BERT or S BERT outformed all of the previous Save the Art models on pretty much all benchmarks. Not all of them but most of them. And it did it in a very quick time. So if we compare it to BERT, if we wanted to find the most similar sentence pair from 10,000 sentences in that 2019 paper they found that with BERT that took 65 hours. With S BERT embeddings they could create all the embeddings in just around five seconds. And then they could compare all those with cosine similarity in 0.01 seconds. So it's a lot faster. We go from 65 hours to just over five seconds which is I think pretty incredible. Now I think that's pretty much all the context we need behind sentence transformers. And what we do now is dive into a little bit of how they actually work. Now we said before we have the core transform models and what S BERT does is fine tunes on sentence pairs using what is called a Siamese architecture or Siamese network. What we mean by a Siamese network is that we have what we can see, what can view as two BERT models that are identical and the weights between those two models are tied. Now in reality when implementing this we just use a single BERT model. And what we do is we process one sentence, a sentence A through the model and then we process another sentence, sentence B through the model. And that's the sentence pair. So with our cross-linked we were processing the sentence pair together. We were putting them both together, processing them all at once. This time we process them separately. And during training what happens is the weights within BERT are optimized to reduce the difference between two vector embeddings or two sentence\\n\\n---\\n\\nstraight into it and take a look at where we might want to use this training approach and and how we can actually implement it. So the first question we need to ask is do we really need to resort to unsupervised training? Now what we're going to do here is just have a look at a few of the most popular training approaches and what sort of data we need for that. So the first one we're looking at here is Natural Language Inference or NLI and NLI requires that we have pairs of sentences that are labeled as either contradictory, neutral which means they're not necessarily related or as entailing or as inferring each other. So you have pairs that entail each other so they are both very similar pairs that are neutral and also pairs that are contradictory. And this is the traditional NLI data. Now using another version of fine-tuning with NLI called a multiple negatives ranking loss you can get by with only entailment pairs so pairs that are related to each other or positive pairs and it can also use contradictory pairs to improve the performance of training as well but you don't need it. So if you have positive pairs of related sentences you can go ahead and actually try training or fine-tuning using NLI with multiple negative ranking loss. If you don't have that fine. Another option is that you have a semantic textual similarity data set or STS and what this is is you have so you have sentence A here, sentence B here and then you have a score from from 0 to 1 that tells you the similarity\\n\\nQuestion: Which training method should I use for sentence transformers when I only have pairs of related sentences?\\nAnswer:\""
],
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "string"
}
},
"metadata": {},
"execution_count": 13
}
],
"source": [
"# first we retrieve relevant items from Pinecone\n",
"query_with_contexts = retrieve(query)\n",
"query_with_contexts"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
},
"id": "ioDVGF7lkDQL",
"outputId": "d4ca7b3a-db37-40c7-fa42-32c45779ffb4"
},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"'NLI with multiple negative ranking loss.'"
],
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "string"
}
},
"metadata": {},
"execution_count": 14
}
],
"source": [
"# then we complete the context-infused query\n",
"complete(query_with_contexts)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "OPO36aN8QoPZ"
},
"source": [
"And we get a pretty great answer straight away, specifying to use _multiple-rankings loss_ (also called _multiple negatives ranking loss_)."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sjOBIQ5rFeLZ"
},
"source": [
"Once we're done with the index we delete it to save resources:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"id": "PpJp-xExFeLa"
},
"outputs": [],
"source": [
"pinecone.delete_index(index_name)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2kNh44bEFeLe"
},
"source": [
"---"
]
}
],
"metadata": {
"colab": {
"provenance": [],
"include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.6"
},
"vscode": {
"interpreter": {
"hash": "57376684f67c5d7b1589c855d7d0f1a1bdf8944ab1b903e711fdbf39434567bb"
}
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment