Создание мощнейшего поиска данных на основе ИИ в Greenplum с помощью pgvector и OpenAI
Экспоненциальный прогресс моделей искусственного интеллекта за последний год, например ChatGPT, вдохновил многие организации на дальнейшее улучшение пользовательского опыта и раскрытие полного потенциала неструктурированных данных, от текстов до изображений и видео, путем использования генеративного искусственного интеллекта и больших языковых моделей (LLM).
В этой статье Вы узнаете о том, как использовать всю мощь поиска векторного сходства в расширении pgvector в хранилище данных Greenplum и объединить его с моделями OpenAI для извлечения ценной информации из текстовых данных в масштабе петабайта данных.
Введение
Компании начали искать технологии и способы расширения своих платформ данных для использования ИИ и больших языковых моделей для своих чат-ботов, систем рекомендаций или поисковых систем...
Одной из специфических проблем стало управление и развертывание этих моделей ИИ, а также хранение и запрос генерируемых ML эмбеддингов в масштабе.
Что такое эмбеддинги?
Эмбеддинги относятся к преобразованию данных или сложных объектов, таких как тексты, изображения или аудио, в список чисел в высокоразмерном пространстве.
Эта техника используется в абсолютно каждом алгоритме машинного обучения (ML) или глубокого обучения (DL), который позволяет улавливать/понимать смысл и контекст данных (семантические связи) и узнавать сложные взаимосвязи и закономерности внутри данных (синтаксические связи).
Полученные векторные представления можно использовать в самых различных приложениях, таких как информационный поиск, классификация изображений, обработка естественного языка и т.д.
Следующая диаграмма наглядно изображает то, как это выглядит для эмбеддингов слов в двумерном пространстве.
Вы можете заметить, что семантически схожие слова расположены близко друг к другу. Например: слово «яблоко» ближе к слову «апельсин», чем к слову «собака» или «кошка».
После генерации эмбеддингов компании могут выполнять поиск сходства в векторном пространстве и создавать приложения искусственного интеллекта, такие как системы рекомендаций товаров ...
Хранение эмбеддингов в Greenplum с помощью pgvector
Greenplum 7 хорошо оснащен и готов к хранению и запросам к векторным вкраплениям в больших масштабах благодаря расширению pgvector. Это привносит возможности векторных баз данных в хранилище данных Greenplum, что позволяет пользователям выполнять быстрый и эффективный поиск по сходству.
Используя pgvector в Greenplum, Вы можете настраивать, управлять и масштабировать базы данных для своих приложений с поддержкой ML.
Например, сервис потокового вещания может использовать pgvector для предоставления списка рекомендаций по фильмам, похожим на тот, который Вы только что посмотрели.
Почему именно Greenplum & pgvector?
Многие компании хотели бы хранить, запрашивать и выполнять векторный семантический поиск в своем КХЖ, не управляя другой базой данных.
К счастью, сочетание Greenplum и pgvector позволяет создавать быстрые и масштабируемые приложения с использованием эмбеддингов из моделей искусственного интеллекта и быстрее выходить на рынок.
Создание ИИ-ассистента для документации по продуктам в Greenplum с помощью pgvector и OpenAI
Контекст:
Все мы раньше пользовались такими чатботами, как ChatGPT, и не раз убеждались в том, что они отлично подходят для случайных ответов на вопросы общего назначения. Однако всем понятно, что ChatGPT не подходит для получения глубоких и специфических знаний. Кроме того, он придумывает ответы, чтобы заполнить свои пробелы в знаниях, и никогда не ссылается на свои источники.
Можем ли мы это улучшить? Как создать ChatGPT, который будет искать подходящие источники данных и точно отвечать на вопросы?
Ответ: сделать документацию по продукту доступной для поиска и снабдить OpenAI подсказками по конкретной задаче - это может привести к более надежным результатам. Другими словами, мы попросим pgvector искать подходящий набор данных в таблице Greenplum, когда пользователь задает тот или иной вопрос. Затем мы предоставим его OpenAI в качестве справочного документа для ответа на запросы пользователей.
Эмбеддинги на практике:
В этом разделе мы применим эмбеддинги на практике и научимся использовать расширение pgvector с открытым исходным кодом для Greenplum, которое облегчает хранение эмбеддингов и позволяет запрашивать ближайших соседей вектора.
Мы демонстрируем эту функциональность, создавая интеллектуального чатбота с помощью OpenAI и наделяя его функцией семантического поиска по тексту для получения более глубоких знаний о решениях VMware Data Solutions, способного отвечать на глубокие технические вопросы о Greenplum, RabbitMQ, Gemfire, VMware SQL и VMware Data Service Manager, как показано на следующем рисунке:
Основные шаги:
- Установка и запуск расширения pgvector
Сразу же после успешной установки Вы можете запустить хранение векторных эмбеддингов в Greenplum и выполнять семантический поиск, включив функцию pgvector:
CREATE EXTENSION vector;
- Создание таблицы «Документация по продукту» с типом данных VECTOR
Далее создадим таблицу для хранения документации по продуктам и их эмбеддингов:
CREATE TABLE tanzu_documents ( id bigserial primary key, content text, embedding vector(1536) ) DISTRIBUTED BY (id) ;
pgvector представляет собой совершенно новый тип данных, называемый вектором. В приведенном выше коде мы создаем столбец эмбеддинга с типом данных vector. Размер вектора определяет, сколько измерений он содержит. Модель OpenAI text-embedding-ada-002 выводит 1536 измерений, поэтому мы будем использовать именно этот размер.
Поскольку в этой статье мы используем API OpenAI, просим Вас установить пакет openai на каждый запущенный хост Greenplum:
gpssh -f gphostsfile -e 'pip3 install -y openai'
Мы также создадим текстовый столбец с именем content для хранения оригинального текста документации по продукту, в котором был создан этот эмбеддинг.
NB: В таблице , приведенной выше , данные распределены по столбцу «id» между сегментами Greenplum, расширение pgvectorпрекрасно сочетается со всеми функциями Greenplum. Таким образом, добавление pgvector в управление огромными массивами данных позволяет пользователям Greenplum создавать масштабируемые AI-приложения.
- Функция Greenplum PL/Python для получения эмбеддингов OpenAI
Теперь мы должны сгенерировать эмбеддинги для наших документов; здесь мы будем использовать API модели OpenAI text-embedding-ada-002 для генерации эмбеддингов из текста.
Лучший способ сделать это - создать функцию Python внутри базы данных Greenplum, используя процедурный язык PL/Python3u. Следующая функция Greenplum Python возвращает вектор эмбеддингов для каждого входного документа.
CREATE OR REPLACE FUNCTION get_embeddings(content text)
RETURNS VECTOR
AS
$$
import openai
import os
text = content
openai.api_key = os.getenv("OPENAI_API_KEY")
response = openai.Embedding.create(
model="text-embedding-ada-002",
input = text.replace("\n"," ")
)
embedding = response['data'][0]['embedding']
return embedding
$$ LANGUAGE PLPYTHON3U;
- Загрузка данных в таблицу Greenplum
Загрузите оригинальные тексты в таблицу tanzu_documents, в частности в столбец tocontent, а затем обновите столбец embedding и сгенерируйте эмбеддинги OpenAI для каждого содержимого полей с помощью ранее созданной Python-функции get_embeddings:
UPDATE tanzu_documents SET embedding = get_embeddings(content);
- Первый запрос на семантический поиск
Давайте построим наш первый запрос на семантический поиск, используя косинусное расстояние pgvector (с помощью оператора <=>), и найдем наиболее похожий на наш вопрос текст (т.е. текст с минимальным расстоянием): Как установить Greenplum?
WITH cte_question_embedding AS
(
SELECT get_embeddings('How to create an external table in Greenplum using PXF to read from an Oracle database ?')
AS question_embeddings
)
SELECT id, content, embedding <=> cte_question_embedding.question_embeddings AS distance
FROM tanzu_documents, cte_question_embedding
ORDER BY embedding <=> cte_question_embedding.question_embeddings
ASC LIMIT 1 ;
pgvector вводит три новых оператора, которые можно использовать для вычисления сходства: Евклидово расстояние (расстояние L2) <->, отрицательное внутреннее произведение<#> и косинусное расстояние <=>.
Оператор SELECT должен вернуть следующее:
id | 640 content | title: Accessing External Data with PXF --- Data managed by your organisation may already reside in external sources such as Hadoop, object stores, and other SQL databases. The Greenplum Platform Extension Framework \(PXF\) provides access to this external data via built-in connectors that map an external data source to a Greenplum Database table definition. PXF is installed with Hadoop and Object Storage connectors. These connectors enable you to read external data stored in text, Avro, JSON, RCFile, Parquet, SequenceFile, and ORC formats. You can use the JDBC connector to access an external SQL database. > **Note** In previous versions of the Greenplum Database, you may have used the `gphdfs` external table protocol to access data stored in Hadoop. Greenplum Database version 6.0.0 removes the `gphdfs` protocol. Use PXF and the `pxf` external table protocol to access Hadoop in Greenplum Database version 6.x. The Greenplum Platform Extension Framework includes a C-language extension and a Java service. After configuring and initialising PXF, you start a single PXF JVM process on each Greenplum Database segment host. This long-running process concurrently serves multiple query requests. For detailed information about the architecture of and using PXF, refer to the [Greenplum Platform Extension Framework \(PXF\)](https://docs.vmware.com/en/VMware-Greenplum-Platform-Extension-Framework/6.6/greenplum-platform-extension-framework/overview_pxf.html) documentation. **Parent topic:** [Working with External Data](../external/g-working-with-file-based-ext-tables.html) **Parent topic:** [Loading and Unloading Data](../load/topics/g-loading-and-unloading-data.html) distance | 0.12006528354516588
- SQL-функция поиска по сходству
Поскольку мы собираемся выполнить поиск по сходству по многим эмбеддингам, давайте создадим специальную SQL-функцию:
CREATE OR REPLACE FUNCTION match_documents (
query_embedding VECTOR(1536),
match_threshold FLOAT,
match_count INT
)
RETURNS TABLE (
id BIGINT,
content TEXT,
similarity FLOAT
)
AS $$
SELECT
documents.id,
documents.content,
1 - (documents.embedding <=> query_embedding) AS similarity
FROM tanzu_documents documents
WHERE 1 - (documents.embedding <=> query_embedding) > match_threshold
ORDER BY similarity DESC
LIMIT match_count;
$$ LANGUAGE SQL STABLE;
Мы будем использовать функцию match_documents и предоставим текст, наиболее похожий на модель OpenAI, в следующем виде:
SELECT t.id, t.content, t.similarity
FROM match_documents(
(select get_embeddings('How to create an external table in Greenplum using PXF to read from an Oracle database ?'))
, 0.8
, 1) t
;
id | 640
content | title: Accessing External Data with PXF --- Data managed by your organisation may already reside in external sources such as Hadoop, object stores, and other SQL databases. The Greenplum Platform Extension Framework \(PXF\) provides access to this external data via built-in connectors that map an external data source to a Greenplum Database table definition. PXF is installed with Hadoop and Object Storage connectors. These connectors enable you to read external data stored in text, Avro, JSON, RCFile, Parquet, SequenceFile, and ORC formats. You can use the JDBC connector to access an external SQL database. > **Note** In previous versions of the Greenplum Database, you may have used the `gphdfs` external table protocol to access data stored in Hadoop. Greenplum Database version 6.0.0 removes the `gphdfs` protocol. Use PXF and the `pxf` external table protocol to access Hadoop in Greenplum Database version 6.x. The Greenplum Platform Extension Framework includes a C-language extension and a Java service. After configuring and initialising PXF, you start a single PXF JVM process on each Greenplum Database segment host. This long-running process concurrently serves multiple query requests. For detailed information about the architecture of and using PXF, refer to the [Greenplum Platform Extension Framework \(PXF\)](https://docs.vmware.com/en/VMware-Greenplum-Platform-Extension-Framework/6.6/greenplum-platform-extension-framework/overview_pxf.html) documentation. **Parent topic:** [Working with External Data](../external/g-working-with-file-based-ext-tables.html) **Parent topic:** [Loading and Unloading Data](../load/topics/g-loading-and-unloading-data.html)
similarity | 0.8775289173395486
- Индексирование векторов
Наша таблица может со временем увеличиваться за счет эмбеддингов, и мы, скорее всего, захотим выполнить семантический поиск по миллиардам векторов.
Что замечательно в pgvector, так это его возможности индексирования для ускорения запросов и более быстрого поиска необходимых данных.
Векторные индексы выполняют точный поиск ближайших соседей (ANN/KNN); они важны для ускорения упорядочивания (ORDER BYclause), поскольку векторы не группируются по сходству, поэтому поиск ближайших вариантов путем последовательного сканирования - медленная операция.
Для каждого оператора расстояния требуется свой тип индекса. Подходящим начальным числом для списков является количество строк / 1000 для строк до 1M и sqrt (строк) для более 1M. Поскольку мы упорядочиваем по косинусному расстоянию, то будем использовать индекс vector_cosine_ops.
-- Create a Vector Index CREATE INDEX ON tanzu_documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 300); -- Analyze table ANALYZE tanzu_documents;
- Предоставление модели OpenAI нужного набора данных для получения релевантного ответа
Постройте PL/Python-функцию, которая принимает на вход сразу оба текста, пользовательский и наиболее похожий на него, а затем просит модель OpenAI дать нужный ответ:
CREATE FUNCTION ask_openai(user_input text, document text)
RETURNS TEXT
AS
$$
import openai
import os
openai.api_key = os.getenv("OPENAI_API_KEY")
search_string = user_input
docs_text = document
messages = [{"role": "system",
"content": "You concisely answer questions based on text provided to you."}]
prompt = """Answer the user's prompt or question:
{search_string}
by summarising the following text:
{docs_text}
Keep your answer direct and concise. Provide code snippets where applicable.
The question is about a Greenplum / PostgreSQL database. You can enrich the answer with other
Greenplum or PostgreSQL-relevant details if applicable.""".format(search_string=search_string, docs_text=docs_text)
messages.append({"role": "user", "content": prompt})
response = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=messages)
return response.choices[0]["message"]["content"]
$$ LANGUAGE PLPYTHON3U;
- Создание более оптимальной функнции поиска
Как мы уже говорили ранее, ChatGPT не просто возвращает существующие документы. Он также способен объединять различную информацию в единый, целостный ответ. Для этого нам нужно предоставить GPT некоторые релевантные документы и подсказку, которую он может использовать для формулирования ответа.
В качестве последнего шага мы должны объединить предыдущие функции в единый процесс, который будет служить нашему приложению «Интеллектуальный ИИ-ассистент».
Наши предыдущие функции и эмбеддинги могут помочь решить эту задачу, разделив подсказки на два этапа:
- Запросите нашу базу данных эмбеддингов для поиска наиболее релевантных документов, связанных с заданным вопросом.
- Вставьте эти документы в качестве контекста, на который модель OpenAI будет ссылаться в своем ответе.
CREATE OR REPLACE FUNCTION intelligent_ai_assistant(
user_input TEXT
)
RETURNS TABLE (
content TEXT
)
LANGUAGE SQL STABLE
AS $$
SELECT
ask_openai(user_input,
(SELECT t.content
FROM match_documents(
(SELECT get_embeddings(user_input)) ,
0.8,
1) t
)
);
$$;
Приведенная выше SQL-функция принимает пользовательский ввод, преобразует его в эмбеддинги, выполняет семантический поиск текста по таблице pgvectoron tanzu_documents для того, чтобы найти наиболее релевантную документацию, и, наконец, передает ее в качестве текста ссылки в вызов API OpenAI, который возвращает окончательный ответ.
- Создание собственного чатбота с возможностью семантического поиска по тексту с помощью OpenAI и Streamlit
Наконец, мы разработали чатбота Streamlit , который понимает наши документы и использует хранилище данных Greenplum с семантическим поиском по тексту pgvector.
Чатбот Streamlit доступен по ссылке: https://greenplum-pgvector-chatbot.streamlit.app/
Исходный код можно найти здесь: https://github.com/ahmedrachid/streamlit-chatbot-greenplum
Заключение
В заключение следует отметить то, что компании, желающие создать масштабируемые приложения ИИ, могут использовать производительность Greenplum и возможности массивно-параллельной обработки, объединить ее с процессом pgvectort и выполнять быстрый поиск по сходству и семантический поиск по огромным объемам векторных эмбеддингов и неструктурированных данных.













