From a61f99d826b809b1d5b2f4401a27b181f52f3ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Fri, 5 Jan 2024 10:15:05 +0100 Subject: [PATCH 1/7] Adds openai inference service notebook. --- notebooks/search/07-inference.ipynb | 381 ++++++++++++++++++++++++++++ 1 file changed, 381 insertions(+) create mode 100644 notebooks/search/07-inference.ipynb diff --git a/notebooks/search/07-inference.ipynb b/notebooks/search/07-inference.ipynb new file mode 100644 index 00000000..c63415c2 --- /dev/null +++ b/notebooks/search/07-inference.ipynb @@ -0,0 +1,381 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7a765629", + "metadata": {}, + "source": [ + "# Semantic Search using the Inference API\n", + "\n", + "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/elastic/elasticsearch-labs/blob/main/notebooks/search/07-inference.ipynb)\n", + "\n", + "\n", + "Learn how to use the [Inference API](https://www.elastic.co/guide/en/elasticsearch/reference/current/inference-apis.html) for semantic search." + ] + }, + { + "cell_type": "markdown", + "id": "9c99b06d", + "metadata": {}, + "source": [ + "# 🧰 Requirements\n", + "\n", + "For this example, you will need:\n", + "\n", + "- An Elastic deployment with minimum **4GB machine learning node**\n", + " - We'll be using [Elastic Cloud](https://www.elastic.co/guide/en/cloud/current/ec-getting-started.html) for this example (available with a [free trial](https://cloud.elastic.co/registration?utm_source=github&utm_content=elasticsearch-labs-notebook))\n", + " \n", + "- An [OpenAI account](https://openai.com/) is required to use the Inference API with \n", + "the OpenAI service. " + ] + }, + { + "cell_type": "markdown", + "id": "15193c10", + "metadata": {}, + "source": [ + "# Create Elastic Cloud deployment\n", + "\n", + "If you don't have an Elastic Cloud deployment, sign up [here](https://cloud.elastic.co/registration?utm_source=github&utm_content=elasticsearch-labs-notebook) for a free trial.\n", + "\n", + "- Go to the [Create deployment](https://cloud.elastic.co/deployments/create) page\n", + " - Under **Advanced settings**, go to **Machine Learning instances**\n", + " - You'll need at least **4GB** RAM per zone for this tutorial\n", + " - Select **Create deployment**" + ] + }, + { + "cell_type": "markdown", + "id": "f27dffbf", + "metadata": {}, + "source": [ + "# Install packages and connect with Elasticsearch Client\n", + "\n", + "To get started, we'll need to connect to our Elastic deployment using the Python client.\n", + "Because we're using an Elastic Cloud deployment, we'll use the **Cloud ID** to identify our deployment.\n", + "\n", + "First we need to `pip` install the following packages:\n", + "\n", + "- `elasticsearch`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c4b16bc", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install elasticsearch" + ] + }, + { + "cell_type": "markdown", + "id": "41ef96b3", + "metadata": {}, + "source": [ + "Next, we need to import the modules we need. 🔐 NOTE: getpass enables us to securely prompt the user for credentials without echoing them to the terminal, or storing it in memory." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "690ff9af", + "metadata": {}, + "outputs": [], + "source": [ + "from elasticsearch import Elasticsearch, helpers\n", + "from urllib.request import urlopen\n", + "import getpass\n", + "import json\n", + "import time" + ] + }, + { + "cell_type": "markdown", + "id": "23fa2b6c", + "metadata": {}, + "source": [ + "Now we can instantiate the Python Elasticsearch client.\n", + "\n", + "First we prompt the user for their password and Cloud ID.\n", + "Then we create a `client` object that instantiates an instance of the `Elasticsearch` class." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "195cc597", + "metadata": {}, + "outputs": [], + "source": [ + "# Found in the 'Manage Deployment' page\n", + "CLOUD_ID = getpass.getpass('Enter Elastic Cloud ID: ')\n", + "\n", + "# Password for the 'elastic' user generated by Elasticsearch\n", + "ELASTIC_PASSWORD = getpass.getpass('Enter Elastic password: ')\n", + "\n", + "# Create the client instance\n", + "client = Elasticsearch(\n", + " cloud_id=CLOUD_ID,\n", + " basic_auth=(\"elastic\", ELASTIC_PASSWORD)\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b1115ffb", + "metadata": {}, + "source": [ + "Confirm that the client has connected with this test:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc0de5ea", + "metadata": {}, + "outputs": [], + "source": [ + "print(client.info())" + ] + }, + { + "cell_type": "markdown", + "id": "4e9e7354", + "metadata": {}, + "source": [ + "Refer to [the documentation](https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#connect-self-managed-new) to learn how to connect to a self-managed deployment.\n", + "\n", + "Read [this page](https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#connect-self-managed-new) to learn how to connect using API keys.\n" + ] + }, + { + "cell_type": "markdown", + "id": "96788aa1", + "metadata": {}, + "source": [ + "## Create the inference task\n", + "\n", + "Let's create the inference task by using the [Create inference API](https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html).\n", + "\n", + "You'll need an OpenAI API key for this that you can find in your OpenAI account under the [API keys section](https://platform.openai.com/api-keys)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e6d98af", + "metadata": {}, + "outputs": [], + "source": [ + "API_KEY = getpass.getpass('Enter OpenAI API key: ')\n", + "\n", + "client.inference.put_model(\n", + " task_type=\"text_embedding\",\n", + " model_id=\"openai_embeddings\",\n", + " body={\n", + " \"service\": \"openai\",\n", + " \"service_settings\": {\n", + " \"api_key\": API_KEY\n", + " },\n", + " \"task_settings\": {\n", + " \"model\": \"text-embedding-ada-002\"\n", + " }\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "e5feaf12", + "metadata": {}, + "source": [ + "## Create an ingest pipeline with an inference processor\n", + "\n", + "Create an ingest pipeline with an inference processor by using the [`put_pipeline`](https://www.elastic.co/guide/en/elasticsearch/reference/master/put-pipeline-api.html) method. Reference the OpenAI model created above to infer against the data that is being ingested in the pipeline." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5897fe4", + "metadata": {}, + "outputs": [], + "source": [ + "client.ingest.put_pipeline(\n", + " id=\"openai_embeddings\", \n", + " description=\"Ingest pipeline for OpenAI inference.\",\n", + " processors=[\n", + " {\n", + " \"inference\": {\n", + " \"model_id\": \"openai_embeddings\",\n", + " \"input_output\": {\n", + " \"input_field\": \"plot\",\n", + " \"output_field\": \"plot_embedding\"\n", + " }\n", + " }\n", + " }\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "7b6dd89c", + "metadata": {}, + "source": [ + "Let's note a few important parameters from that API call:\n", + "\n", + "- `inference`: A processor that performs inference using a machine learning model.\n", + "- `model_id`: Specifies the ID of the machine learning model to be used. In this example, the model ID is set to `openai_embeddings`.\n", + "- `input_output`: Specifies input and output fields.\n", + "- `input_field`: Field name from which the `dense_vector` representation is created.\n", + "- `output_field`: Field name which contains inference results. " + ] + }, + { + "cell_type": "markdown", + "id": "f167c8cf", + "metadata": {}, + "source": [ + "## Create index\n", + "\n", + "The mapping of the destination index - the index that contains the embeddings that the model will create based on your input text - must be created. The destination index must have a field with the [dense_vector](https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html) field type to index the output of the OpenAI model.\n", + "\n", + "Let's create an index named `openai-movie-embeddings` with the mappings we need." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37558907", + "metadata": {}, + "outputs": [], + "source": [ + "client.indices.delete(index=\"openai-movie-embeddings\", ignore_unavailable=True)\n", + "client.indices.create(\n", + " index=\"openai-movie-embeddings\",\n", + " settings={\n", + " \"index\": {\n", + " \"default_pipeline\": \"openai_embeddings\"\n", + " }\n", + " },\n", + " mappings={\n", + " \"properties\": {\n", + " \"plot_embedding\": { \n", + " \"type\": \"dense_vector\", \n", + " \"dims\": 1536, \n", + " \"element_type\": \"byte\",\n", + " \"similarity\": \"dot_product\" \n", + " },\n", + " \"plot\": { \n", + " \"type\": \"text\" \n", + " }\n", + " }\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "e9d4bfd2", + "metadata": {}, + "source": [ + "## Insert Documents (option 1)\n", + "\n", + "Let's insert our example dataset of 12 movies." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfa8eda5", + "metadata": {}, + "outputs": [], + "source": [ + "url = \"https://raw.githubusercontent.com/elastic/elasticsearch-labs/main/notebooks/search/movies.json\"\n", + "response = urlopen(url)\n", + "\n", + "# Load the response data into a JSON object\n", + "data_json = json.loads(response.read())\n", + "\n", + "# Prepare the documents to be indexed\n", + "documents = []\n", + "for doc in data_json:\n", + " documents.append({\n", + " \"_index\": \"openai-movie-embeddings\",\n", + " \"_source\": doc,\n", + " })\n", + "\n", + "# Use helpers.bulk to index\n", + "helpers.bulk(client, documents)\n", + "\n", + "print(\"Done indexing documents into `openai-movie-embeddings` index!\")\n", + "time.sleep(3)" + ] + }, + { + "cell_type": "markdown", + "id": "a68e808e", + "metadata": {}, + "source": [ + "## Semantic search\n", + "\n", + "After the dataset has been enriched with the embeddings, you can query the data using [semantic search](https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html#knn-semantic-search). Pass a `query_vector_builder` to the k-nearest neighbor (kNN) vector search API, and provide the query text and the model you have used to create the embeddings." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a47cdc60", + "metadata": {}, + "outputs": [], + "source": [ + "response = client.search(\n", + " index='openai-movie-embeddings', \n", + " size=3,\n", + " knn={\n", + " \"field\": \"plot_embedding\",\n", + " \"query_vector_builder\": {\n", + " \"text_embedding\": {\n", + " \"model_id\": \"openai_embeddings\",\n", + " \"model_text\": \"Fighting movie\"\n", + " }\n", + " },\n", + " \"k\": 10,\n", + " \"num_candidates\": 100\n", + " }\n", + ")\n", + "\n", + "for hit in response['hits']['hits']:\n", + " doc_id = hit['_id']\n", + " score = hit['_score']\n", + " title = hit['_source']['title']\n", + " plot = hit['_source']['plot']\n", + " print(f\"Score: {score}\\nTitle: {title}\\nPlot: {plot}\\n\")" + ] + } + ], + "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", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 4c7ab0000f060bd2d8fe07838f6285fccd95e703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Fri, 5 Jan 2024 11:40:47 +0100 Subject: [PATCH 2/7] Apply suggestions from code review --- notebooks/search/07-inference.ipynb | 1 - 1 file changed, 1 deletion(-) diff --git a/notebooks/search/07-inference.ipynb b/notebooks/search/07-inference.ipynb index c63415c2..fa926ae2 100644 --- a/notebooks/search/07-inference.ipynb +++ b/notebooks/search/07-inference.ipynb @@ -266,7 +266,6 @@ " \"plot_embedding\": { \n", " \"type\": \"dense_vector\", \n", " \"dims\": 1536, \n", - " \"element_type\": \"byte\",\n", " \"similarity\": \"dot_product\" \n", " },\n", " \"plot\": { \n", From 130b25c0eb0e643b1cf3e09df786e6375ebcd623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Wed, 10 Jan 2024 11:59:19 +0100 Subject: [PATCH 3/7] [DOCS] Refines notebook. --- notebooks/search/07-inference.ipynb | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/notebooks/search/07-inference.ipynb b/notebooks/search/07-inference.ipynb index c63415c2..afc70054 100644 --- a/notebooks/search/07-inference.ipynb +++ b/notebooks/search/07-inference.ipynb @@ -25,8 +25,8 @@ "- An Elastic deployment with minimum **4GB machine learning node**\n", " - We'll be using [Elastic Cloud](https://www.elastic.co/guide/en/cloud/current/ec-getting-started.html) for this example (available with a [free trial](https://cloud.elastic.co/registration?utm_source=github&utm_content=elasticsearch-labs-notebook))\n", " \n", - "- An [OpenAI account](https://openai.com/) is required to use the Inference API with \n", - "the OpenAI service. " + "- A paid [OpenAI account](https://openai.com/) is required to use the Inference API with \n", + "the OpenAI service as the OpenAI free trial API usage is limited. " ] }, { @@ -109,16 +109,18 @@ "metadata": {}, "outputs": [], "source": [ - "# Found in the 'Manage Deployment' page\n", - "CLOUD_ID = getpass.getpass('Enter Elastic Cloud ID: ')\n", + "# https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud#finding-your-cloud-id\n", + "ELASTIC_CLOUD_ID = getpass(\"Elastic Cloud ID: \")\n", "\n", - "# Password for the 'elastic' user generated by Elasticsearch\n", - "ELASTIC_PASSWORD = getpass.getpass('Enter Elastic password: ')\n", + "# https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud#creating-an-api-key\n", + "ELASTIC_API_KEY = getpass(\"Elastic Api Key: \")\n", "\n", "# Create the client instance\n", "client = Elasticsearch(\n", - " cloud_id=CLOUD_ID,\n", - " basic_auth=(\"elastic\", ELASTIC_PASSWORD)\n", + " # For local development\n", + " # hosts=[\"http://localhost:9200\"] \n", + " cloud_id=ELASTIC_CLOUD_ID,\n", + " api_key=ELASTIC_API_KEY,\n", ")" ] }, @@ -159,7 +161,7 @@ "\n", "Let's create the inference task by using the [Create inference API](https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html).\n", "\n", - "You'll need an OpenAI API key for this that you can find in your OpenAI account under the [API keys section](https://platform.openai.com/api-keys)." + "You'll need an OpenAI API key for this that you can find in your OpenAI account under the [API keys section](https://platform.openai.com/api-keys). A paid membership is required to complete the steps in this notebook as the OpenAI free trial API usage is limited." ] }, { @@ -241,7 +243,7 @@ "source": [ "## Create index\n", "\n", - "The mapping of the destination index - the index that contains the embeddings that the model will create based on your input text - must be created. The destination index must have a field with the [dense_vector](https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html) field type to index the output of the OpenAI model.\n", + "The mapping of the destination index – the index that contains the embeddings that the model will create based on your input text – must be created. The destination index must have a field with the [dense_vector](https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html) field type to index the output of the OpenAI model.\n", "\n", "Let's create an index named `openai-movie-embeddings` with the mappings we need." ] @@ -265,8 +267,7 @@ " \"properties\": {\n", " \"plot_embedding\": { \n", " \"type\": \"dense_vector\", \n", - " \"dims\": 1536, \n", - " \"element_type\": \"byte\",\n", + " \"dims\": 1536,\n", " \"similarity\": \"dot_product\" \n", " },\n", " \"plot\": { \n", @@ -282,9 +283,9 @@ "id": "e9d4bfd2", "metadata": {}, "source": [ - "## Insert Documents (option 1)\n", + "## Insert Documents\n", "\n", - "Let's insert our example dataset of 12 movies." + "Let's insert our example dataset of 12 movies. You need a paid OpenAI account to complete this step, otherwise the documentation ingest will time out due to the API request rate limits." ] }, { From 26d77c61f6273bac63a2bb1f53573f16ee6e4995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Wed, 10 Jan 2024 12:02:23 +0100 Subject: [PATCH 4/7] [DOCS] Updates notebook. --- notebooks/search/07-inference.ipynb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/notebooks/search/07-inference.ipynb b/notebooks/search/07-inference.ipynb index 085dd831..afc70054 100644 --- a/notebooks/search/07-inference.ipynb +++ b/notebooks/search/07-inference.ipynb @@ -267,11 +267,7 @@ " \"properties\": {\n", " \"plot_embedding\": { \n", " \"type\": \"dense_vector\", \n", -<<<<<<< HEAD " \"dims\": 1536,\n", -======= - " \"dims\": 1536, \n", ->>>>>>> 4c7ab0000f060bd2d8fe07838f6285fccd95e703 " \"similarity\": \"dot_product\" \n", " },\n", " \"plot\": { \n", From e23a2a3cd249130e5619cb8640d17212e313cc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Wed, 10 Jan 2024 14:02:07 +0100 Subject: [PATCH 5/7] Adds output to search. --- notebooks/search/07-inference.ipynb | 104 +++++++++++++++++----------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/notebooks/search/07-inference.ipynb b/notebooks/search/07-inference.ipynb index afc70054..10d30726 100644 --- a/notebooks/search/07-inference.ipynb +++ b/notebooks/search/07-inference.ipynb @@ -15,14 +15,14 @@ }, { "cell_type": "markdown", - "id": "9c99b06d", + "id": "f9101eb9", "metadata": {}, "source": [ "# 🧰 Requirements\n", "\n", "For this example, you will need:\n", "\n", - "- An Elastic deployment with minimum **4GB machine learning node**\n", + "- An Elastic deployment:\n", " - We'll be using [Elastic Cloud](https://www.elastic.co/guide/en/cloud/current/ec-getting-started.html) for this example (available with a [free trial](https://cloud.elastic.co/registration?utm_source=github&utm_content=elasticsearch-labs-notebook))\n", " \n", "- A paid [OpenAI account](https://openai.com/) is required to use the Inference API with \n", @@ -31,17 +31,12 @@ }, { "cell_type": "markdown", - "id": "15193c10", + "id": "4cd69cc0", "metadata": {}, "source": [ "# Create Elastic Cloud deployment\n", "\n", - "If you don't have an Elastic Cloud deployment, sign up [here](https://cloud.elastic.co/registration?utm_source=github&utm_content=elasticsearch-labs-notebook) for a free trial.\n", - "\n", - "- Go to the [Create deployment](https://cloud.elastic.co/deployments/create) page\n", - " - Under **Advanced settings**, go to **Machine Learning instances**\n", - " - You'll need at least **4GB** RAM per zone for this tutorial\n", - " - Select **Create deployment**" + "If you don't have an Elastic Cloud deployment, sign up [here](https://cloud.elastic.co/registration?utm_source=github&utm_content=elasticsearch-labs-notebook) for a free trial." ] }, { @@ -79,12 +74,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "690ff9af", "metadata": {}, "outputs": [], "source": [ - "from elasticsearch import Elasticsearch, helpers\n", + "from elasticsearch import Elasticsearch, helpers, exceptions\n", "from urllib.request import urlopen\n", "import getpass\n", "import json\n", @@ -134,27 +129,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "cc0de5ea", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'name': 'instance-0000000000', 'cluster_name': '0a47378bc5e04c1995cd4c4c92131cd0', 'cluster_uuid': 'DgpshH2GTGefHGUStkD85w', 'version': {'number': '8.12.0', 'build_flavor': 'default', 'build_type': 'docker', 'build_hash': '5077850702d0aa4fc42d3eb53bd39b282ae8ad3a', 'build_date': '2023-12-28T10:04:50.840819947Z', 'build_snapshot': False, 'lucene_version': '9.9.1', 'minimum_wire_compatibility_version': '7.17.0', 'minimum_index_compatibility_version': '7.0.0'}, 'tagline': 'You Know, for Search'}\n" + ] + } + ], "source": [ "print(client.info())" ] }, { "cell_type": "markdown", - "id": "4e9e7354", + "id": "659c5890", "metadata": {}, "source": [ "Refer to [the documentation](https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#connect-self-managed-new) to learn how to connect to a self-managed deployment.\n", "\n", - "Read [this page](https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#connect-self-managed-new) to learn how to connect using API keys.\n" + "Read [this page](https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/connecting.html#connect-self-managed-new) to learn how to connect using API keys." ] }, { "cell_type": "markdown", - "id": "96788aa1", + "id": "840d92f0", "metadata": {}, "source": [ "## Create the inference task\n", @@ -167,15 +170,15 @@ { "cell_type": "code", "execution_count": null, - "id": "3e6d98af", + "id": "0d007737", "metadata": {}, "outputs": [], "source": [ - "API_KEY = getpass.getpass('Enter OpenAI API key: ')\n", + "API_KEY = getpass.getpass('OpenAI API key: ')\n", "\n", "client.inference.put_model(\n", " task_type=\"text_embedding\",\n", - " model_id=\"openai_embeddings\",\n", + " model_id=\"my_openai_embedding_model\",\n", " body={\n", " \"service\": \"openai\",\n", " \"service_settings\": {\n", @@ -190,7 +193,7 @@ }, { "cell_type": "markdown", - "id": "e5feaf12", + "id": "1024d070", "metadata": {}, "source": [ "## Create an ingest pipeline with an inference processor\n", @@ -201,21 +204,21 @@ { "cell_type": "code", "execution_count": null, - "id": "c5897fe4", + "id": "6ace9e2e", "metadata": {}, "outputs": [], "source": [ "client.ingest.put_pipeline(\n", - " id=\"openai_embeddings\", \n", + " id=\"openai_embeddings_pipeline\", \n", " description=\"Ingest pipeline for OpenAI inference.\",\n", " processors=[\n", " {\n", " \"inference\": {\n", - " \"model_id\": \"openai_embeddings\",\n", + " \"model_id\": \"my_openai_embedding_model\",\n", " \"input_output\": {\n", " \"input_field\": \"plot\",\n", " \"output_field\": \"plot_embedding\"\n", - " }\n", + " }\n", " }\n", " }\n", " ]\n", @@ -224,13 +227,13 @@ }, { "cell_type": "markdown", - "id": "7b6dd89c", + "id": "76d07567", "metadata": {}, "source": [ "Let's note a few important parameters from that API call:\n", "\n", "- `inference`: A processor that performs inference using a machine learning model.\n", - "- `model_id`: Specifies the ID of the machine learning model to be used. In this example, the model ID is set to `openai_embeddings`.\n", + "- `model_id`: Specifies the ID of the machine learning model to be used. In this example, the model ID is set to `my_openai_embedding_model`. Use the model ID you defined when created the inference task.\n", "- `input_output`: Specifies input and output fields.\n", "- `input_field`: Field name from which the `dense_vector` representation is created.\n", "- `output_field`: Field name which contains inference results. " @@ -238,12 +241,12 @@ }, { "cell_type": "markdown", - "id": "f167c8cf", + "id": "28e12d7a", "metadata": {}, "source": [ "## Create index\n", "\n", - "The mapping of the destination index – the index that contains the embeddings that the model will create based on your input text – must be created. The destination index must have a field with the [dense_vector](https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html) field type to index the output of the OpenAI model.\n", + "The mapping of the destination index - the index that contains the embeddings that the model will create based on your input text - must be created. The destination index must have a field with the [dense_vector](https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html) field type to index the output of the OpenAI model.\n", "\n", "Let's create an index named `openai-movie-embeddings` with the mappings we need." ] @@ -251,7 +254,7 @@ { "cell_type": "code", "execution_count": null, - "id": "37558907", + "id": "6ddcbca3", "metadata": {}, "outputs": [], "source": [ @@ -260,27 +263,27 @@ " index=\"openai-movie-embeddings\",\n", " settings={\n", " \"index\": {\n", - " \"default_pipeline\": \"openai_embeddings\"\n", + " \"default_pipeline\": \"openai_embeddings_pipeline\"\n", " }\n", " },\n", " mappings={\n", " \"properties\": {\n", " \"plot_embedding\": { \n", " \"type\": \"dense_vector\", \n", - " \"dims\": 1536,\n", + " \"dims\": 1536, \n", " \"similarity\": \"dot_product\" \n", " },\n", - " \"plot\": { \n", - " \"type\": \"text\" \n", + " \"plot\": {\n", + " \"type\": \"text\"\n", + " }\n", " }\n", " }\n", - " }\n", ")" ] }, { "cell_type": "markdown", - "id": "e9d4bfd2", + "id": "07c187a9", "metadata": {}, "source": [ "## Insert Documents\n", @@ -291,7 +294,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cfa8eda5", + "id": "d68737cb", "metadata": {}, "outputs": [], "source": [ @@ -318,7 +321,7 @@ }, { "cell_type": "markdown", - "id": "a68e808e", + "id": "cf0f6df7", "metadata": {}, "source": [ "## Semantic search\n", @@ -328,10 +331,29 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "a47cdc60", + "execution_count": 23, + "id": "d9b21b71", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Score: 0.91674197\n", + "Title: Fight Club\n", + "Plot: An insomniac office worker and a devil-may-care soapmaker form an underground fight club that evolves into something much, much more.\n", + "\n", + "Score: 0.9069592\n", + "Title: Pulp Fiction\n", + "Plot: The lives of two mob hitmen, a boxer, a gangster and his wife, and a pair of diner bandits intertwine in four tales of violence and redemption.\n", + "\n", + "Score: 0.8992071\n", + "Title: The Dark Knight\n", + "Plot: When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.\n", + "\n" + ] + } + ], "source": [ "response = client.search(\n", " index='openai-movie-embeddings', \n", @@ -340,7 +362,7 @@ " \"field\": \"plot_embedding\",\n", " \"query_vector_builder\": {\n", " \"text_embedding\": {\n", - " \"model_id\": \"openai_embeddings\",\n", + " \"model_id\": \"my_openai_embedding_model\",\n", " \"model_text\": \"Fighting movie\"\n", " }\n", " },\n", From 9c4cf2be858fbfc3cdb76b8728fa5cdc207c3737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Wed, 10 Jan 2024 14:03:37 +0100 Subject: [PATCH 6/7] Update notebooks/search/07-inference.ipynb --- notebooks/search/07-inference.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebooks/search/07-inference.ipynb b/notebooks/search/07-inference.ipynb index 10d30726..2a61412a 100644 --- a/notebooks/search/07-inference.ipynb +++ b/notebooks/search/07-inference.ipynb @@ -331,7 +331,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "id": "d9b21b71", "metadata": {}, "outputs": [ From 020a82b0d8dedaad1050672db8797efe0cda54be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Wed, 10 Jan 2024 14:08:58 +0100 Subject: [PATCH 7/7] Cleans up outputs. --- notebooks/search/07-inference.ipynb | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/notebooks/search/07-inference.ipynb b/notebooks/search/07-inference.ipynb index 2a61412a..182b19e8 100644 --- a/notebooks/search/07-inference.ipynb +++ b/notebooks/search/07-inference.ipynb @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "690ff9af", "metadata": {}, "outputs": [], @@ -129,18 +129,10 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "cc0de5ea", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'name': 'instance-0000000000', 'cluster_name': '0a47378bc5e04c1995cd4c4c92131cd0', 'cluster_uuid': 'DgpshH2GTGefHGUStkD85w', 'version': {'number': '8.12.0', 'build_flavor': 'default', 'build_type': 'docker', 'build_hash': '5077850702d0aa4fc42d3eb53bd39b282ae8ad3a', 'build_date': '2023-12-28T10:04:50.840819947Z', 'build_snapshot': False, 'lucene_version': '9.9.1', 'minimum_wire_compatibility_version': '7.17.0', 'minimum_index_compatibility_version': '7.0.0'}, 'tagline': 'You Know, for Search'}\n" - ] - } - ], + "outputs": [], "source": [ "print(client.info())" ]