diff --git a/examples/vector_databases/hologres/Getting_started_with_Hologres_and_OpenAI.ipynb b/examples/vector_databases/hologres/Getting_started_with_Hologres_and_OpenAI.ipynb new file mode 100644 index 0000000..3f6d5a6 --- /dev/null +++ b/examples/vector_databases/hologres/Getting_started_with_Hologres_and_OpenAI.ipynb @@ -0,0 +1,866 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Using Hologres as a vector database for OpenAI embeddings\n", + "\n", + "This notebook guides you step by step on using Hologres as a vector database for OpenAI embeddings.\n", + "\n", + "This notebook presents an end-to-end process of:\n", + "1. Using precomputed embeddings created by OpenAI API.\n", + "2. Storing the embeddings in a cloud instance of Hologres.\n", + "3. Converting raw text query to an embedding with OpenAI API.\n", + "4. Using Hologres to perform the nearest neighbour search in the created collection.\n", + "5. Provide large language models with the search results as context in prompt engineering\n", + "\n", + "### What is Hologres\n", + "\n", + "[Hologres](https://www.alibabacloud.com/help/en/hologres/latest/what-is-hologres) is a unified real-time data warehousing service developed by Alibaba Cloud. You can use Hologres to write, update, process, and analyze large amounts of data in real time. Hologres supports standard SQL syntax, is compatible with PostgreSQL, and supports most PostgreSQL functions. Hologres supports online analytical processing (OLAP) and ad hoc analysis for up to petabytes of data, and provides high-concurrency and low-latency online data services. Hologres supports fine-grained isolation of multiple workloads and enterprise-level security capabilities. Hologres is deeply integrated with MaxCompute, Realtime Compute for Apache Flink, and DataWorks, and provides full-stack online and offline data warehousing solutions for enterprises.\n", + "\n", + "Hologres provides vector database functionality by adopting [Proxima](https://www.alibabacloud.com/help/en/hologres/latest/vector-processing).\n", + "\n", + "Proxima is a high-performance software library developed by Alibaba DAMO Academy. It allows you to search for the nearest neighbors of vectors. Proxima provides higher stability and performance than similar open source software such as Facebook AI Similarity Search (Faiss). Proxima provides basic modules that have leading performance and effects in the industry and allows you to search for similar images, videos, or human faces. Hologres is deeply integrated with Proxima to provide a high-performance vector search service.\n", + "\n", + "### Deployment options\n", + "\n", + "- [Click here](https://www.alibabacloud.com/product/hologres) to fast deploy [Hologres data warehouse](https://www.alibabacloud.com/help/en/hologres/latest/getting-started).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prerequisites\n", + "\n", + "For the purposes of this exercise we need to prepare a couple of things:\n", + "\n", + "1. Hologres cloud server instance.\n", + "2. The 'psycopg2-binary' library to interact with the vector database. Any other postgresql client library is ok.\n", + "3. An [OpenAI API key](https://beta.openai.com/account/api-keys).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We might validate if the server was launched successfully by running a simple curl command:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Install requirements\n", + "\n", + "This notebook obviously requires the `openai` and `psycopg2-binary` packages, but there are also some other additional libraries we will use. The following command installs them all:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2023-02-16T12:05:05.718972Z", + "start_time": "2023-02-16T12:04:30.434820Z" + }, + "pycharm": { + "is_executing": true + } + }, + "outputs": [], + "source": [ + "! pip install openai psycopg2-binary pandas wget" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Prepare your OpenAI API key\n", + "\n", + "The OpenAI API key is used for vectorization of the documents and queries.\n", + "\n", + "If you don't have an OpenAI API key, you can get one from [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys).\n", + "\n", + "Once you get your key, please add it to your environment variables as `OPENAI_API_KEY`." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2023-02-16T12:05:05.730338Z", + "start_time": "2023-02-16T12:05:05.723351Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "OPENAI_API_KEY is ready\n" + ] + } + ], + "source": [ + "# Test that your OpenAI API key is correctly set as an environment variable\n", + "# Note. if you run this notebook locally, you will need to reload your terminal and the notebook for the env variables to be live.\n", + "import os\n", + "\n", + "# Note. alternatively you can set a temporary env variable like this:\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n", + "\n", + "if os.getenv(\"OPENAI_API_KEY\") is not None:\n", + " print(\"OPENAI_API_KEY is ready\")\n", + "else:\n", + " print(\"OPENAI_API_KEY environment variable not found\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Connect to Hologres\n", + "First add it to your environment variables. or you can just change the \"psycopg2.connect\" parameters below\n", + "\n", + "Connecting to a running instance of Hologres server is easy with the official Python library:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2023-02-16T12:05:06.827143Z", + "start_time": "2023-02-16T12:05:05.733771Z" + } + }, + "outputs": [], + "source": [ + "import os\n", + "import psycopg2\n", + "\n", + "# Note. alternatively you can set a temporary env variable like this:\n", + "# os.environ[\"PGHOST\"] = \"your_host\"\n", + "# os.environ[\"PGPORT\"] \"5432\"),\n", + "# os.environ[\"PGDATABASE\"] \"postgres\"),\n", + "# os.environ[\"PGUSER\"] \"user\"),\n", + "# os.environ[\"PGPASSWORD\"] \"password\"),\n", + "\n", + "connection = psycopg2.connect(\n", + " host=os.environ.get(\"PGHOST\", \"localhost\"),\n", + " port=os.environ.get(\"PGPORT\", \"5432\"),\n", + " database=os.environ.get(\"PGDATABASE\", \"postgres\"),\n", + " user=os.environ.get(\"PGUSER\", \"user\"),\n", + " password=os.environ.get(\"PGPASSWORD\", \"password\")\n", + ")\n", + "connection.set_session(autocommit=True)\n", + "\n", + "# Create a new cursor object\n", + "cursor = connection.cursor()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can test the connection by running any available method:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2023-02-16T12:05:06.848488Z", + "start_time": "2023-02-16T12:05:06.832612Z" + }, + "pycharm": { + "is_executing": true + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connection successful!\n" + ] + } + ], + "source": [ + "\n", + "# Execute a simple query to test the connection\n", + "cursor.execute(\"SELECT 1;\")\n", + "result = cursor.fetchone()\n", + "\n", + "# Check the query result\n", + "if result == (1,):\n", + " print(\"Connection successful!\")\n", + "else:\n", + " print(\"Connection failed.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2023-02-16T12:05:37.371951Z", + "start_time": "2023-02-16T12:05:06.851634Z" + }, + "pycharm": { + "is_executing": true + } + }, + "outputs": [], + "source": [ + "import wget\n", + "\n", + "embeddings_url = \"https://cdn.openai.com/API/examples/data/vector_database_wikipedia_articles_embedded.zip\"\n", + "\n", + "# The file is ~700 MB so this will take some time\n", + "wget.download(embeddings_url)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The downloaded file has to be then extracted:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2023-02-16T12:06:01.538851Z", + "start_time": "2023-02-16T12:05:37.376042Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The file vector_database_wikipedia_articles_embedded.csv exists in the data directory.\n" + ] + } + ], + "source": [ + "import zipfile\n", + "import os\n", + "import re\n", + "import tempfile\n", + "\n", + "current_directory = os.getcwd()\n", + "zip_file_path = os.path.join(current_directory, \"vector_database_wikipedia_articles_embedded.zip\")\n", + "output_directory = os.path.join(current_directory, \"../../data\")\n", + "\n", + "with zipfile.ZipFile(zip_file_path, \"r\") as zip_ref:\n", + " zip_ref.extractall(output_directory)\n", + "\n", + "\n", + "# check the csv file exist\n", + "file_name = \"vector_database_wikipedia_articles_embedded.csv\"\n", + "data_directory = os.path.join(current_directory, \"../../data\")\n", + "file_path = os.path.join(data_directory, file_name)\n", + "\n", + "\n", + "if os.path.exists(file_path):\n", + " print(f\"The file {file_name} exists in the data directory.\")\n", + "else:\n", + " print(f\"The file {file_name} does not exist in the data directory.\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load data\n", + "\n", + "In this section we are going to load the data prepared previous to this session, so you don't have to recompute the embeddings of Wikipedia articles with your own credits." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Archive: vector_database_wikipedia_articles_embedded.zip\n", + "-rw-r--r--@ 1 geng staff 1.7G Jan 31 01:19 vector_database_wikipedia_articles_embedded.csv\n" + ] + } + ], + "source": [ + "!unzip -n vector_database_wikipedia_articles_embedded.zip\n", + "!ls -lh vector_database_wikipedia_articles_embedded.csv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Take a look at the data." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + " | id | \n", + "url | \n", + "title | \n", + "text | \n", + "title_vector | \n", + "content_vector | \n", + "vector_id | \n", + "
---|---|---|---|---|---|---|---|
0 | \n", + "1 | \n", + "https://simple.wikipedia.org/wiki/April | \n", + "April | \n", + "April is the fourth month of the year in the J... | \n", + "[0.001009464613161981, -0.020700545981526375, ... | \n", + "[-0.011253940872848034, -0.013491976074874401,... | \n", + "0 | \n", + "
1 | \n", + "2 | \n", + "https://simple.wikipedia.org/wiki/August | \n", + "August | \n", + "August (Aug.) is the eighth month of the year ... | \n", + "[0.0009286514250561595, 0.000820168002974242, ... | \n", + "[0.0003609954728744924, 0.007262262050062418, ... | \n", + "1 | \n", + "
2 | \n", + "6 | \n", + "https://simple.wikipedia.org/wiki/Art | \n", + "Art | \n", + "Art is a creative activity that expresses imag... | \n", + "[0.003393713850528002, 0.0061537534929811954, ... | \n", + "[-0.004959689453244209, 0.015772193670272827, ... | \n", + "2 | \n", + "
3 | \n", + "8 | \n", + "https://simple.wikipedia.org/wiki/A | \n", + "A | \n", + "A or a is the first letter of the English alph... | \n", + "[0.0153952119871974, -0.013759135268628597, 0.... | \n", + "[0.024894846603274345, -0.022186409682035446, ... | \n", + "3 | \n", + "
4 | \n", + "9 | \n", + "https://simple.wikipedia.org/wiki/Air | \n", + "Air | \n", + "Air refers to the Earth's atmosphere. Air is a... | \n", + "[0.02224554680287838, -0.02044147066771984, -0... | \n", + "[0.021524671465158463, 0.018522677943110466, -... | \n", + "4 | \n", + "
... | \n", + "... | \n", + "... | \n", + "... | \n", + "... | \n", + "... | \n", + "... | \n", + "... | \n", + "
24995 | \n", + "98295 | \n", + "https://simple.wikipedia.org/wiki/Geneva | \n", + "Geneva | \n", + "Geneva (, , , , ) is the second biggest cit... | \n", + "[-0.015773078426718712, 0.01737344264984131, 0... | \n", + "[0.008000412955880165, 0.02008531428873539, 0.... | \n", + "24995 | \n", + "
24996 | \n", + "98316 | \n", + "https://simple.wikipedia.org/wiki/Concubinage | \n", + "Concubinage | \n", + "Concubinage is the state of a woman in a relat... | \n", + "[-0.00519518880173564, 0.005898841191083193, 0... | \n", + "[-0.01736736111342907, -0.002740012714639306, ... | \n", + "24996 | \n", + "
24997 | \n", + "98318 | \n", + "https://simple.wikipedia.org/wiki/Mistress%20%... | \n", + "Mistress (lover) | \n", + "A mistress is a man's long term female sexual ... | \n", + "[-0.023164259269833565, -0.02052430994808674, ... | \n", + "[-0.017878392711281776, -0.0004517830966506153... | \n", + "24997 | \n", + "
24998 | \n", + "98326 | \n", + "https://simple.wikipedia.org/wiki/Eastern%20Front | \n", + "Eastern Front | \n", + "Eastern Front can be one of the following:\\n\\n... | \n", + "[-0.00681863259524107, 0.002171179046854377, 8... | \n", + "[-0.0019235472427681088, -0.004023272544145584... | \n", + "24998 | \n", + "
24999 | \n", + "98327 | \n", + "https://simple.wikipedia.org/wiki/Italian%20Ca... | \n", + "Italian Campaign | \n", + "Italian Campaign can mean the following:\\n\\nTh... | \n", + "[-0.014151256531476974, -0.008553029969334602,... | \n", + "[-0.011758845299482346, -0.01346028596162796, ... | \n", + "24999 | \n", + "
25000 rows × 7 columns
\n", + "