Home Машинное обучение Создайте надежное решение для преобразования текста в SQL, генерирующее сложные запросы, самокорректирующиеся и осуществляющие запросы к различным источникам данных. | DeepTech

Создайте надежное решение для преобразования текста в SQL, генерирующее сложные запросы, самокорректирующиеся и осуществляющие запросы к различным источникам данных. | DeepTech

0
Создайте надежное решение для преобразования текста в SQL, генерирующее сложные запросы, самокорректирующиеся и осуществляющие запросы к различным источникам данных.
 | DeepTech

Язык структурированных запросов (SQL) — это сложный язык, требующий понимания баз данных и метаданных. Сегодня генеративный искусственный интеллект может помочь людям, не знающим SQL. Эта генеративная задача ИИ называется преобразованием текста в SQL, которая генерирует SQL-запросы на основе обработки естественного языка (NLP) и преобразует текст в семантически правильный SQL. Решение, представленное в этом посте, направлено на то, чтобы вывести операции корпоративной аналитики на новый уровень за счет сокращения пути к вашим данным с использованием естественного языка.

С появлением больших языковых моделей (LLM) генерация SQL на основе NLP претерпела значительную трансформацию. Демонстрируя исключительную производительность, LLM теперь способны генерировать точные SQL-запросы на основе описаний на естественном языке. Однако проблемы все еще остаются. Во-первых, человеческий язык по своей сути неоднозначен и зависит от контекста, тогда как SQL является точным, математическим и структурированным. Этот пробел может привести к неточному преобразованию потребностей пользователя в сгенерированный SQL. Во-вторых, вам может потребоваться создать функции преобразования текста в SQL для каждой базы данных, поскольку данные часто не хранятся в одном целевом объекте. Возможно, вам придется воссоздать возможности для каждой базы данных, чтобы предоставить пользователям возможность генерировать SQL на основе NLP. В-третьих, несмотря на более широкое внедрение решений централизованной аналитики, таких как озера данных и хранилища, сложность возрастает из-за разных имен таблиц и других метаданных, необходимых для создания SQL для нужных источников. Поэтому сбор всеобъемлющих и высококачественных метаданных также остается проблемой. Дополнительные сведения о передовых методах преобразования текста в SQL и шаблонах проектирования см. в разделе Создание ценности из корпоративных данных: лучшие практики для Text2SQL и генеративного искусственного интеллекта.

Наше решение направлено на решение этих проблем с помощью Amazon Bedrock и AWS Analytics Services. В качестве LLM мы используем Anthropic Claude v2.1 на Amazon Bedrock. Чтобы решить эти проблемы, наше решение сначала включает метаданные источников данных в каталог данных AWS Glue, чтобы повысить точность сгенерированного SQL-запроса. Рабочий процесс также включает цикл окончательной оценки и исправления на случай, если Amazon Athena выявит какие-либо проблемы с SQL, который используется в качестве механизма SQL. Athena также позволяет нам использовать множество поддерживаемых конечных точек и соединителей для покрытия большого набора источников данных.

После того, как мы пройдемся по шагам построения решения, мы представим результаты некоторых тестовых сценариев с различными уровнями сложности SQL. Наконец, мы обсудим, как легко включать различные источники данных в ваши запросы SQL.

Обзор решения

В нашей архитектуре есть три важнейших компонента: поисковая расширенная генерация (RAG) с метаданными базы данных, многоэтапный цикл самокоррекции и Athena в качестве нашего механизма SQL.

Мы используем метод RAG для получения описаний таблиц и схем (столбцов) из метахранилища AWS Glue, чтобы гарантировать, что запрос относится к правильной таблице и наборам данных. В нашем решении мы построили отдельные шаги для запуска платформы RAG с каталогом данных AWS Glue в демонстрационных целях. Однако вы также можете использовать базы знаний в Amazon Bedrock для быстрого создания решений RAG.

Многошаговый компонент позволяет LLM корректировать сгенерированный запрос SQL для обеспечения точности. Здесь сгенерированный SQL отправляется на наличие синтаксических ошибок. Мы используем сообщения об ошибках Athena, чтобы обогатить подсказку LLM для более точных и эффективных исправлений в сгенерированном SQL.

Сообщения об ошибках, время от времени поступающие от Athena, можно рассматривать как обратную связь. Стоимость этапа исправления ошибок пренебрежимо мала по сравнению с полученной ценностью. Вы даже можете включить эти корректирующие шаги в качестве примеров усиленного обучения под учителем для более точной настройки ваших LLM. Однако в целях простоты мы не рассматривали этот поток в нашей статье.

Обратите внимание, что всегда существует риск возникновения неточностей, который, естественно, связан с генеративными решениями ИИ. Даже если сообщения об ошибках Athena очень эффективны для снижения этого риска, вы можете добавить дополнительные элементы управления и представления, такие как отзывы пользователей или примеры запросов для тонкой настройки, чтобы еще больше минимизировать такие риски.

Athena не только позволяет нам исправлять SQL-запросы, но и упрощает для нас общую проблему, поскольку она служит концентратором, где лучами являются несколько источников данных. Управление доступом, синтаксис SQL и многое другое осуществляется через Athena.

На следующей диаграмме показана архитектура решения.

Показана архитектура решения и последовательность операций.

Рисунок 1. Архитектура решения и последовательность операций.

Технологическая схема включает в себя следующие этапы:

  1. Создайте каталог данных AWS Glue с помощью сканера AWS Glue (или другого метода).
  2. Используя модель Titan-Text-Embeddings в Amazon Bedrock, преобразуйте метаданные во встроенные элементы и сохраните их в бессерверном векторном хранилище Amazon OpenSearch, которое служит нашей базой знаний в нашей платформе RAG.

На этом этапе процесс готов принять запрос на естественном языке. Шаги 7–9 представляют собой цикл коррекции, если применимо.

  1. Пользователь вводит запрос на естественном языке. Вы можете использовать любое веб-приложение для предоставления пользовательского интерфейса чата. Поэтому мы не стали освещать детали пользовательского интерфейса в нашей статье.
  2. В решении применяется структура RAG посредством поиска по сходству, который добавляет дополнительный контекст из метаданных из базы данных векторов. Эта таблица используется для поиска правильной таблицы, базы данных и атрибутов.
  3. Запрос объединяется с контекстом и отправляется в Anthropic Claude v2.1 на Amazon Bedrock.
  4. Модель получает сгенерированный SQL-запрос и подключается к Athena для проверки синтаксиса.
  5. Если Athena выдает сообщение об ошибке, в котором упоминается неверный синтаксис, модель использует текст ошибки из ответа Athena.
  6. Новая подсказка добавляет ответ Афины.
  7. Модель создает исправленный SQL и продолжает процесс. Эту итерацию можно выполнять несколько раз.
  8. Наконец, мы запускаем SQL с помощью Athena и генерируем выходные данные. Здесь результат представляется пользователю. В целях архитектурной простоты мы не показали этот шаг.

Предварительные условия

Для этого поста вам необходимо выполнить следующие предварительные условия:

  1. Иметь учетную запись AWS.
  2. Установите интерфейс командной строки AWS (AWS CLI).
  3. Настройте SDK для Python (Boto3).
  4. Создайте каталог данных AWS Glue с помощью сканера AWS Glue (или другого метода).
  5. Используя модель Titan-Text-Embeddings на Amazon Bedrock, преобразуйте метаданные во встроенные элементы и сохраните их в бессерверном векторном хранилище OpenSearch.

Внедрить решение

Вы можете использовать следующее Блокнот Юпитер, который включает все фрагменты кода, представленные в этом разделе, для создания решения. Мы рекомендуем использовать Amazon SageMaker Studio, чтобы открыть этот блокнот с помощью экземпляра ml.t3.medium с ядром Python 3 (Data Science). Инструкции см. в разделе Обучение модели машинного обучения. Для настройки решения выполните следующие шаги:

  1. Создайте базу знаний в OpenSearch Service для платформы RAG:
    def add_documnets(self,index_name: str,file_name:str):
    
    documents = JSONLoader(file_path=file_name, jq_schema=".", text_content=False, json_lines=False).load()
    docs = OpenSearchVectorSearch.from_documents(embedding=self.embeddings, opensearch_url=self.opensearch_domain_endpoint, http_auth=self.http_auth, documents=documents, index_name=index_name, engine="faiss")
    index_exists = self.check_if_index_exists(index_name,aws_region,opensearch_domain_endpoint,http_auth)
    if not index_exists :
    logger.info(f'index :{index_name} is not existing ')
    sys.exit(-1)
    else:
    logger.info(f'index :{index_name} Got created')

  2. Создайте подсказку (final_question) путем объединения пользовательского ввода на естественном языке (user_query), соответствующие метаданные из векторного хранилища (vector_search_match) и наши инструкции (details):
    def userinput(user_query):
    logger.info(f'Searching metadata from vector store')
    
    # vector_search_match=rqst.getEmbeddding(user_query)
    vector_search_match = rqst.getOpenSearchEmbedding(index_name,user_query)
    
    # print(vector_search_match)
    details = "It is important that the SQL query complies with Athena syntax. \
    During join if column name are same please use alias ex llm.customer_id \
    in select statement. It is also important to respect the type of columns: \
    if a column is string, the value should be enclosed in quotes. \
    If you are writing CTEs then include all the required columns. \
    While concatenating a non string column, make sure cast the column to string. \
    For date columns comparing to string , please cast the string input."
    final_question = "\n\nHuman:"+details + vector_search_match + user_query+ "n\nAssistant:"
    answer = rqst.generate_sql(final_question)
    return answer

  3. Вызовите Amazon Bedrock для LLM (Claude v2) и предложите ему сгенерировать SQL-запрос. В следующем коде он предпринимает несколько попыток, чтобы проиллюстрировать этап самоисправления: x
    try:
    logger.info(f'we are in Try block to generate the sql and count is :{attempt + 1}')
    generated_sql = self.llm.predict(prompt)
    query_str = generated_sql.split("```")(1)
    query_str = " ".join(query_str.split("\n")).strip()
    sql_query = query_str(3:) if query_str.startswith("sql") else query_str
    
    # return sql_query
    syntaxcheckmsg=rqstath.syntax_checker(sql_query)
    if syntaxcheckmsg=='Passed':
    logger.info(f'syntax checked for query passed in attempt number :{attempt + 1}')
    return sql_query

  4. Если возникают какие-либо проблемы с сгенерированным SQL-запросом ({sqlgenerated}) из ответа Афины ({syntaxcheckmsg}), новое приглашение (prompt) генерируется на основе ответа, и модель снова пытается сгенерировать новый SQL:
    else:
    prompt = f"""{prompt} \
    This is syntax error: {syntaxcheckmsg}.
    To correct this, please generate an alternative SQL query which will correct the syntax error. The updated query should take care of all the syntax issues encountered. Follow the instructions mentioned above to remediate the error.
    Update the below SQL query to resolve the issue:
    {sqlgenerated}
    Make sure the updated SQL query aligns with the requirements provided in the initial question."""
    prompts.append(prompt)

  5. После генерации SQL вызывается клиент Athena для запуска и генерации выходных данных:
    query_execution = self.athena_client.start_query_execution(
    QueryString=query_string,
    ResultConfiguration=result_config,
    QueryExecutionContext=query_execution_context, )
    execution_id = query_execution("QueryExecutionId")

Проверьте решение

В этом разделе мы запускаем наше решение с различными примерами сценариев для тестирования SQL-запросов разных уровней сложности.

Чтобы протестировать преобразование текста в SQL, мы используем два наборы данных доступны на IMDB. Подмножества данных IMDb доступны для личного и некоммерческого использования. Вы можете загрузить наборы данных и сохранить их в Amazon Simple Storage Service (Amazon S3). Вы можете использовать следующий фрагмент Spark SQL для создания таблиц в AWS Glue. Для этого примера мы используем title_ratings и title:

source_title_ratings3_path="s3://llm-athena-output/input_data/title.ratings.tsv"
target_title_s3_path="s3://llm-athena-output/output_data/imdb_stg/title_ratings"
source_titleratingdf=spark.read.csv(source_title_ratings3_path,sep="\t",header=True)
source_titleratingdf.write.mode('overwrite').format('parquet').option('path', target_title_s3_path).saveAsTable('imdb_stg.title_ratings')

Храните данные в Amazon S3, а метаданные — в AWS Glue.

В этом сценарии наш набор данных хранится в корзине S3. Athena имеет разъем S3, который позволяет использовать Amazon S3 в качестве источника данных, к которому можно выполнять запросы.

Для нашего первого запроса мы предоставляем входные данные: «Я новичок в этом. Можете ли вы помочь мне увидеть все таблицы и столбцы в схеме imdb?»

Ниже приведен сгенерированный запрос:

WITH tables AS (
SELECT table_name
FROM information_schema.tables
WHERE table_schema="imdb_stg"),
columns AS (
SELECT
c.table_name,
c.column_name,
c.data_type,
c.is_nullable,
c.column_default,
c.ordinal_position
FROM information_schema.columns c
WHERE c.table_schema="imdb_stg")
SELECT
t.table_name,
c.column_name,
c.data_type,
c.is_nullable,
c.column_default,
c.ordinal_position
FROM tables t
INNER JOIN columns c
ON t.table_name = c.table_name
ORDER BY
t.table_name,
c.ordinal_position
LIMIT 10;

На следующем снимке экрана и в коде показан наш результат.

Таблица, показывающая атрибуты примера набора данных IMBD.

table_name column_name data_type
0 title titleid varchar
1 title ordering integer
2 title title varchar
3 title region varchar
4 title language varchar

Для нашего второго запроса мы просим: «Покажите мне все названия и детали в регионе США, рейтинг которого превышает 9,5».

Ниже приведен сгенерированный нами запрос:

WITH us_titles AS (
SELECT t.title, t.region, tr.averageRating, tr.numVotes
FROM imdb_stg.title t
INNER JOIN imdb_stg.title_ratings tr
ON t.titleId = tr.tconst
WHERE t.region = 'US' AND cast(tr.averageRating as varchar) > '9.5'
)
SELECT title, region, averageRating, numVotes
FROM us_titles
LIMIT 100;

Ответ следующий.

Таблица, показывающая результаты sql-запроса

title region averageRating numVotes
0 The Way You Saw Me US 9.7 8
1 The Brother Side of the Wake US 9.6 20
2 Ignis Fatuus US 9.6 11
3 Love and Hip Hop Atlanta US 9.9 11
4 ronny/lily US 9.7 14781

Для нашего третьего запроса мы вводим «Отличный ответ! А теперь покажите мне все оригинальные шрифтовые названия с рейтингом выше 7,5 и не из региона США».

Создается следующий запрос:

WITH titles AS (
SELECT t.titleId,
t.title,
t.types,
t.isOriginalTitle,
cast(tr.averageRating as decimal(3,1)) as averageRating,
tr.numVotes,
t.region
FROM imdb_stg.title t
INNER JOIN imdb_stg.title_ratings tr
ON t.titleId = tr.tconst
WHERE t.isOriginalTitle="1"
AND cast(tr.averageRating as decimal(3,1)) > 7.5
AND t.region != 'US')
SELECT *
FROM titles
LIMIT 100;

Мы получаем следующие результаты.

Одна строка, показывающая результат SQL-запроса.

titleId title types isOriginalTitle averageRating numVotes region
0 tt0986264 Taare Zameen Par original 1 8.3 203760 XWW

Генерация самокорректируемого SQL

Этот сценарий имитирует запрос SQL, имеющий проблемы с синтаксисом. Здесь сгенерированный SQL будет автоматически корректироваться на основе ответа от Athena. В следующем ответе Афина дала COLUMN_NOT_FOUND ошибка и упомянул, что table_description невозможно решить:

Status : {'State': 'FAILED', 'StateChangeReason': "COLUMN_NOT_FOUND: line 1:50: Column 'table_description' \
cannot be resolved or requester is not authorized to access requested resources",
'SubmissionDateTime': datetime.datetime(2024, 1, 14, 14, 38, 57, 501000, tzinfo=tzlocal()),
'CompletionDateTime': datetime.datetime(2024, 1, 14, 14, 38, 57, 778000, tzinfo=tzlocal()),
'AthenaError': {'ErrorCategory': 2, 'ErrorType': 1006, 'Retryable': False, 'ErrorMessage': "COLUMN_NOT_FOUND: \
line 1:50: Column 'table_description' cannot be resolved or requester is not authorized to \
access requested resources"}}
COLUMN_NOT_FOUND: line 1:50: Column 'table_description' cannot be resolved or requester is not authorized to access requested resources
Try Count: 2
2024-01-14 14:39:02,521,llm_execute,MainProcess,INFO,Try Count: 2
we are in Try block to generate the sql and count is :2
2024-01-14 14:39:02,521,llm_execute,MainProcess,INFO,we are in Try block to generate the sql and count is :2
Executing: Explain WITH tables AS ( SELECT table_name FROM information_schema.tables WHERE table_schema="imdb_stg" ), columns AS ( SELECT c.table_name, c.column_name, c.data_type, c.is_nullable, c.column_default, c.ordinal_position FROM information_schema.columns c WHERE c.table_schema="imdb_stg" ) SELECT t.table_name, c.column_name, c.data_type, c.is_nullable, c.column_default, c.ordinal_position FROM tables t INNER JOIN columns c ON t.table_name = c.table_name ORDER BY t.table_name, c.ordinal_position LIMIT 10;
I am checking the syntax here
execution_id: 904857c3-b7ac-47d0-8e7e-6b9d0456099b
Status : {'State': 'SUCCEEDED', 'SubmissionDateTime': datetime.datetime(2024, 1, 14, 14, 39, 29, 537000, tzinfo=tzlocal()), 'CompletionDateTime': datetime.datetime(2024, 1, 14, 14, 39, 30, 183000, tzinfo=tzlocal())}
syntax checked for query passed in tries number :2

Использование решения с другими источниками данных

Если вы хотите использовать решение с другими источниками данных, Athena выполнит эту работу за вас. Для этого Athena использует соединители источников данных, которые можно использовать с федеративными запросами. Соединитель можно рассматривать как расширение механизма запросов Athena. Существуют готовые коннекторы источников данных Athena для таких источников данных, как Amazon CloudWatch Logs, Amazon DynamoDB, Amazon DocumentDB (с совместимостью с MongoDB) и Amazon Relational Database Service (Amazon RDS), а также JDBC-совместимых реляционных источников данных, таких как MySQL и PostgreSQL, в разделе лицензия Apache 2.0. После настройки подключения к любому источнику данных вы можете использовать предыдущую базу кода для расширения решения. Дополнительную информацию см. в разделе Запрос к любому источнику данных с помощью нового интегрированного запроса Amazon Athena.

Очистить

Чтобы очистить ресурсы, вы можете начать с очистки корзины S3, в которой находятся данные. Если ваше приложение не использует Amazon Bedrock, оно не потребует никаких затрат. В целях использования передового опыта управления инфраструктурой мы рекомендуем удалить ресурсы, созданные в этой демонстрации.

Заключение

В этом посте мы представили решение, которое позволяет использовать NLP для генерации сложных SQL-запросов с использованием различных ресурсов, поддерживаемых Athena. Мы также повысили точность генерируемых SQL-запросов с помощью многоэтапного цикла оценки на основе сообщений об ошибках последующих процессов. Кроме того, мы использовали метаданные в каталоге данных AWS Glue, чтобы учитывать имена таблиц, запрашиваемые в запросе через платформу RAG. Затем мы протестировали решение в различных реалистичных сценариях с разными уровнями сложности запросов. Наконец, мы обсудили, как применить это решение к различным источникам данных, поддерживаемым Athena.

Amazon Bedrock находится в центре этого решения. Amazon Bedrock может помочь вам создать множество генеративных приложений искусственного интеллекта. Чтобы начать работу с Amazon Bedrock, мы рекомендуем выполнить быстрый старт, описанный ниже. Репозиторий GitHub и ознакомление с созданием генеративных приложений искусственного интеллекта. Вы также можете попробовать базы знаний в Amazon Bedrock, чтобы быстро создавать такие решения RAG.


Об авторах

Санджиб Панда — инженер данных и машинного обучения в Amazon. Имея опыт работы в области искусственного интеллекта и машинного обучения, науки о данных и больших данных, Санджиб проектирует и разрабатывает инновационные решения для обработки данных и машинного обучения, которые решают сложные технические задачи и достигают стратегических целей для глобальных 3P-продавцов, управляющих своим бизнесом на Amazon. Помимо работы инженером по обработке данных и машинному обучению в Amazon, Санджиб Панда является заядлым гурманом и любителем музыки.

Бурак Гозлуклу — главный специалист по архитектуре решений AI/ML в Бостоне, Массачусетс. Он помогает стратегическим клиентам внедрять технологии AWS и, в частности, решения генеративного искусственного интеллекта для достижения своих бизнес-целей. Бурак имеет докторскую степень в области аэрокосмической техники в METU, степень магистра в области системной инженерии и постдок по системной динамике в Массачусетском технологическом институте в Кембридже, штат Массачусетс. Бурак по-прежнему является научным сотрудником Массачусетского технологического института. Бурак увлечен йогой и медитацией.

LEAVE A REPLY

Please enter your comment!
Please enter your name here