LLM'ы в преобразовании запроса на естественном языке в SQL (text2sql)
Изображение создано с помощью Kandinsky 2.2.
Привет, Хабр! На связи участница профессионального сообщества NTA Марина Коробова.
Данные занимают центральное место в информационном обществе. Именно информация является основой для принятия решений, развития бизнеса и научных исследований. Многие организации инвестируют огромные средства в системы, способные хранить, обрабатывать и анализировать данные.
Одной из главных проблем, с которыми сталкиваются компании, это непосредственная работа с базами данных с помощью языка SQL (Structured Query Language). Не все знают этот язык, и не у всех есть время изучать его. Поэтому на рынке появляются инструменты, позволяющие писать запрос на естественном языке и получать ответ на языке запросов.
В посте познакомлю вас с двумя AI-инструментами для генерации SQL-запросов: SQLCoder Defog и SQLthroughAI.
Введение
Проблема преобразования запросов на естественном языке в SQL-запросы является одной из ключевых задач в области обработки естественного языка (Natural Language Processing, NLP). Одним из наиболее эффективных подходов к решению задачи text2sql является использование больших языковых моделей (Large Language Models, LLM). В научных публикациях используются различные наименования этой задачи: NL2SQL, seq2sql, NLQ-SQL, NLQ2Query, natural language to SQL и прочее. В данном посте все эти термины являются синонимами.
Модели типа LLM for SQL-queries обучаются и тестируются на больших наборах пар запросов на естественном языке (natural language querying, NLQ) и языке SQL, которые способны извлекать информацию из одной или нескольких баз данных. Часто используются такие наборы данных, как Spider, WikiSQL, SParC и другие.
Запрос text-to-SQL обычно состоит минимум из двух компонентов: вопроса на естественном языке и описания (схемы) базы данных. Необязательными элементами являются демонстрационный пример и инструкции по выполнению задачи.
Основными проблемами применения LLM for SQL-queries являются генерирование ошибочных ответов (галлюцинации модели) и риск похищения пользовательских данных. Пользователи должны самостоятельно проверять выдаваемый моделью SQL-запрос, поскольку нет никаких гарантий, что скрипт будет рабочий. Вторая же проблема решается созданием собственной LLM или размещением автономной (self-hosted) модели на собственном сервере.
Сейчас на рынке доступно множество решений так или иначе связанных с генерацией SQL-запросов: Dataherald, DB-GBT, NL2SQL и другие.
В продолжение предыдущего поста я сосредоточилась на модели SQLCoder Defog, а для сравнения с ней выбрала SQLthroughAI, использующую технологии от Open AI.
Немного о моделях
SQLCoder — это большая языковая модель с 15 миллиардами параметров, дообученная на модели StarCoder компанией Defog. Модель прошла обучение на 10 537 вопросах, заданных людьми на основе 10 различных схем баз данных. Обучение проходило в два этапа в зависимости от уровня сложности вопросов:
первый этап: «легкие» и «средние» вопросы (easy+medium);
второй этап: «сложные» и «сверхсложные» вопросы (hard+extra-hard).
Эта классификация была выполнена путем адаптации рубрикации, используемой набором данных Spider. Результаты обучения на данных, взятых с первого этапа, были сохранены в модели под названием defog-easy. Для оценивания корректности предлагаемых запросов компания разработала свой собственный фреймворк — sql-eval.
SQLCoder превосходит gpt-3.5-turbo и text-davinci-003, которые являются моделями, более чем в 10 раз превышающими его размер, а при тонкой настройке для отдельных схем баз данных SQLCoder будет обладать такой же или лучшей производительностью, чем GPT-4 OpenAI, с меньшей задержкой (на A100 GPU).
Способы использования SQLCoder:
непосредственно скачать из Hugging Face;
воспользоваться демо-версией через веб-сайт;
запустить блокнот в Colab.
SQLthroughAI — это инструмент искусственного интеллекта, созданный на базе технологий от Open AI. На сайте представлено крайне мало информации, поэтому неизвестно, как именно была доработана модель, но за этой информацией можно обратиться к разработчикам: SQLtroughAI@gmail.com.
Почему я выбрала этот AI-помощник? Он бесплатный, не требует API key и имеет веб-интерфейс.
Практическая часть
Поскольку я хотела, чтобы любой пользователь смог самостоятельно поэкспериментировать с запросами, то реализую все практические примеры на сайтах моделей.
Я буду писать запросы на русском языке, заставляя модель подстраиваться под запросы рядового пользователя. Поэтому, как вы понимаете, качество представленных результатов будет ниже ожидаемого. В случае, если модель допустит ошибку, попробую помочь ей, добавив немного контекста.
Хочу отметить, что несмотря на информацию, представленную на сайте о том, что в настоящее время SQLthroughAI поддерживает только английский язык, AI-помощник принимал запросы на русском языке и выдавал корректные SQL-ответы.
Все задания взяты c сайта sql-academy. Выберу базу данных «Авиаперелеты» и продемонстрирую работу большой языковой модели.
Схема базы данных во всех запросах одинаковая. Создам её с помощью DDL (языка описания данных). Также перед промтом для модели SQLCoder буду писать MySQL, поскольку сайт sql-academy принимает ответы только на этом диалекте.
Для SQLthroughAI создам схему базы данных вручную и настрою связи с помощью веб-интерфейса. При отправке промта необходимо выбирать все таблицы из базы данных, и отмечать необходимый диалект, в моём случае — MySQL.
Сразу отмечу, что на сайте был представлен единственный сложный запрос для данной таблицы. Поэтому я попросила AI-инструменты сгенерировать сложные запросы и для другой базы данных Airbnb.
Авиаперелеты
SQLCoder
CREATE TABLE trip(
id INT PRIMARY KEY,
company INT, -- идентификатор компании-перевозчика
plane VARCHAR, -- модель самолета
town_from VARCHAR, -- город вылета
town_to VARCHAR, -- город прилёта
time_out DATETIME, -- время вылета
time_in DATETIME -- время прилёта
);
CREATE TABLE company(
id INT PRIMARY KEY,
name VARCHAR -- название компании-перевозчика
);
CREATE TABLE pass_in_trip(
id INT PRIMARY KEY,
trip INT, -- идентификатор билета
passenger INT, -- идентификатор пассажира
place VARCHAR -- место пассажира в самолёте
);
CREATE TABLE passenger(
id INT PRIMARY KEY,
name VARCHAR -- имя и фамилия пассажира
);
SQLthroughAI
Интерфейс для создания полей в таблице. Предлагается всего 4 типа поля (string, date, number, id).
Airbnb
SQLCoder
-- отзывы на арендуемое жилье
CREATE TABLE Reviews(
id INT PRIMARY KEY,
reservation_id INT, -- идентификатор брони
rating INT, -- рейтинг от 1 до 5
);
-- пользователи сервиса бронирования
CREATE TABLE users(
id INT PRIMARY KEY,
name VARCHAR, -- имя и фамилия пользователя
email VARCHAR, -- электронная почта пользователя
email_verified_at DATETIME, -- дата подтверждения почты
password VARCHAR, -- пароль от аккаунта
phone_number VARCHAR -- номер телефона пользователя
);
-- история бронирования жилья
CREATE TABLE Reservations(
id INT PRIMARY KEY,
user_id INT, -- идентификатор пользователя
room_id INT, -- идентификатор жилья
start_date DATETIME, -- дата начала бронирования
end_date DATETIME, -- дата окончания бронирования
price INT, -- цена за сутки
total INT -- общая стоимость бронирования
);
-- доступные вариант жилья
CREATE TABLE Rooms(
id INT PRIMARY KEY,
home_type VARCHAR, -- тип жилья
address VARCHAR, -- адрес жилья
has_tv BOOLEAN, -- наличие телевизора
has_internet BOOLEAN, -- наличие интернета
has_kitchen BOOLEAN, -- наличие кухни
has_air_con BOOLEAN, -- наличие кондиционера
price INT, -- цена за сутки
owner_id INT, -- идентификатор владельца
latitude FLOAT, -- географическая широта
longitude FLOAT -- географическая долгота
);
SQLthroughAI
Выбираю все таблицы из базы данных для формирования запроса.
Примеры запросов
№ 55:
NL-query (запрос на естественном языке) | |
Удалить компании, совершившие наименьшее количество рейсов. | |
SQL query (полученный SQL-запрос) | |
SQLCoder (неверно) | SQLthroughAI (верно) |
|
|
Комментарий
В чём же проблема решения от SQLCoder? Модель считает, что только одна компания совершает наименьшее количество рейсов. К сожалению, даже корректировка запроса не помогла решить данную задачу.
№ 58:
NL-query | |
Добавить отзыв с рейтингом 5 на жилье, находящиеся по адресу »11218, Friel Place, New York», от имени «George Clooney». В качестве первичного ключа (id) укажите количество записей в таблице + 1. Резервация комнаты, на которую вам нужно оставить отзыв, уже была сделана, нужно лишь её найти. | |
SQL query | |
SQLCoder (верно) | SQLthroughAI (неверно) |
|
|
Комментарий
SQLthroughAI не учитывает условие, связанное с пользователем (name = 'George Clooney'
), и поэтому даже не связывает необходимые таблицы.
№ 68:
NL-query | |
Для каждой комнаты, которую снимали как минимум 1 раз, найдите имя человека, снимавшего ее последний раз, и дату, когда он выехал. Поля в результирующей таблице:
Используйте конструкцию » | |
SQL query | |
SQLCoder (верно) | SQLthroughAI (верно) |
|
|
Комментарий
Как можно увидеть, подход моделей к решению отличается, но это не влияет на успешность выполнения задания.
№ 69:
Мне кажется, что данное задание составлено некорректно. В итоговом решении требуется замена NULL на нулевые значения, поэтому было принято решение скорректировать запрос на естественном языке.
Модели плохо справлялась с данным заданием, поэтому явно указала необходимую конструкцию.
NL-query | |
Вывести идентификаторы всех владельцев комнат и сумму, которую они заработали. Суммирование происходит по полю total. Замени все NULL в поле суммы на ноль с помощью COALESCE. Используйте конструкцию » | |
SQL query | |
SQLCoder (верно) | SQLthroughAI (верно) |
|
|
Комментарий
Обе модели успешно справились с заданием.
№ 71:
NL-query | |
Найдите какой процент пользователей, зарегистрированных на сервисе бронирования, хоть раз арендовали или сдавали в аренду жилье. Результат округлите до сотых. Поля в результирующей таблице:
Используйте конструкцию » | |
SQL query | |
SQLCoder (неверно) | SQLthroughAI (неверно) |
|
|
Комментарий
Как видно, обе модели не учитывают владельцев жилья, также SQLthroughAI не использует команду округления.
Оценка моделей
Модель | База данных | Уровень сложности | Верно (номера заданий) | Неверно (номера заданий) | Процент верных |
---|---|---|---|---|---|
SQLCoder | Перелёты | Лёгкие | 2, 3, 4, 5, 6, 7, 9, 28, 56 | 1, 12, 14, 15 | 17/26≈65% |
Средние | 8, 13, 16, 29, 30 | 10, 11, 67 | |||
Сложные | 55 | ||||
Airbnb | Сложные | 58, 68, 69 | 71 | ||
SQLthroughAI | Перелёты | Лёгкие | 2, 3, 4, 5, 7, 9, 14, 15, 28, 56 | 1, 6, 12 | 18/26≈69% |
Средние | 10, 11, 16, 29, 30 | 8, 13, 67 | |||
Сложные | 55 | ||||
Airbnb | Сложные | 68, 69 | 58, 71 |
Как видно, каждая из моделей выполнила примерно две трети запросов успешно.
SQLCoder | SQLthroughAI | |
---|---|---|
Лёгкие | ≈ 69,2% | ≈ 76,9% |
Средние | ≈ 62,5% | ≈ 62,5% |
Тяжелые | ≈ 60% | ≈ 60% |
Сравнение моделей
В таблице я сравнила модели и результаты их работы:
SQLCoder | SQLthroughAI | |
---|---|---|
Способы использования | Hugging Face; Colab; веб-сайт. | Веб-сайт. |
Возможность доработки модели | Да | Нет |
Поддерживаемые базы данных | MySQL, PostgreSQL, Amazon Redshift, Showflake, BigQuery, Azure SQL | MySQL, PostgreSQL, MS SQL, Mongo DB, Oracle PL/SQL, BigQuery, MariaDB |
Способы создания базы данных | DDL | CSV/Excel; DDL; вручную на сайте |
Настройка типов данных | Все известные типы | String, Date, Number, ID |
Регистрация | Нет | Да |
Процент полученных верных ответов | 65% | 69% |
Вывод
SQLCoder и SQLthroughAI частично справились с задачей преобразования запроса на естественном языке в запрос на языке SQL. Не рекомендую пользователям без опыта в данной области применять эти AI-помощники, поскольку почти в трети случаев всё ещё совершаются ошибки, и это может быть критично для ваших данных. Тем не менее, как помощник или генератор идей эти инструменты могут быть полезными: инструменты могут предложить пользователю различные варианты запросов и помочь синтаксически правильно составить их.