【Text2SQL 论文】DIN-SQL:分解任务 + 自我纠正 + in-context 让 LLM 完成 Text2SQL

论文:DIN-SQL: Decomposed In-Context Learning of Text-to-SQL with Self-Correction

⭐⭐⭐⭐

NeurIPS 2023, arXiv:2304.11015

Code: Few-shot-NL2SQL-with-prompting | GitHub

文章目录

    • 一、论文速读
      • [1.1 Schema Linking Module](#1.1 Schema Linking Module)
      • [1.2 Classification & Decomposition Module](#1.2 Classification & Decomposition Module)
      • [1.3 SQL Generation Module](#1.3 SQL Generation Module)
        • [1.3.1 EASY 类型](#1.3.1 EASY 类型)
        • [1.3.2 NON-NESTED 类型](#1.3.2 NON-NESTED 类型)
        • [1.3.3 NESTED 类型](#1.3.3 NESTED 类型)
      • [1.4 Self-correction Module](#1.4 Self-correction Module)
    • [二、Error cases 分析](#二、Error cases 分析)
    • 三、总结

一、论文速读

这篇论文通过对 LLM 做 prompt 来实现 Text2SQL,过程中通过 prompt 让 LLM 分解任务来降低难度,每个子任务通过 in-context learning 让 LLM 来完成,并在完成 SQL 生成后,通过 self-correction 来检查和纠正可能有错误的 SQL。最终,在执行精确度指标上超越了现有的 SOTA 模型。

生成 SQL 被分成四个阶段:

  1. Schema Linking:输入 NL query 和 DB schema,找出与 query 相关的 tables、columns 以及不同表之间的外键关系
  2. Classification & Decomposition:将 query 分成了三种不同的难度:EASY、NON-NESTED、NESTED
  3. SQL Generation:根据不同类型的 query,按照不同的策略来生成对应的 SQL
  4. Self-correction:通过 prompt 来让 LLM 检查和纠正可能错误的 SQL

1.1 Schema Linking Module

这个 module 输入 NL query 和 DB 的 schema 信息,输出的是将 query 链接到 DB 中的一些信息,具体来说输出就是:

  1. table 和 columns 的名称:找到 query 中涉及到的 DB 的 table 和 columns 的名称
  2. 条件值:从查询中提取出用于条件过滤的值,比如在查询"Find the departments with a budget greater than 500"中,需要提取出条件值"500"。
  3. 外键关系的确定:如果查询涉及到多个表,需要确定它们之间的关系,如通过外键连接。

下面是使用 in-context learning + CoT 来让 LLM 做 schema-linking 的示例:

demostration 的一个示例如下:

plain 复制代码
Table advisor, columns = [*,s_ID,i_ID]
Table classroom, columns = [*,building,room_number,capacity]
Table course, columns = [*,course_id,title,dept_name,credits]
Table department, columns = [*,dept_name,building,budget]
Table instructor, columns = [*,ID,name,dept_name,salary]
Table prereq, columns = [*,course_id,prereq_id]
Table section, columns = [*,course_id,sec_id,semester,year,building,room_number,time_slot_id]
Table student, columns = [*,ID,name,dept_name,tot_cred]
Table takes, columns = [*,ID,course_id,sec_id,semester,year,grade]
Table teaches, columns = [*,ID,course_id,sec_id,semester,year]
Table time_slot, columns = [*,time_slot_id,day,start_hr,start_min,end_hr,end_min]
Foreign_keys = [course.dept_name = department.dept_name,instructor.dept_name = department.dept_name,section.building = classroom.building,section.room_number = classroom.room_number,section.course_id = course.course_id,teaches.ID = instructor.ID,teaches.course_id = section.course_id,teaches.sec_id = section.sec_id,teaches.semester = section.semester,teaches.year = section.year,student.dept_name = department.dept_name,takes.ID = student.ID,takes.course_id = section.course_id,takes.sec_id = section.sec_id,takes.semester = section.semester,takes.year = section.year,advisor.s_ID = student.ID,advisor.i_ID = instructor.ID,prereq.prereq_id = course.course_id,prereq.course_id = course.course_id]
Q: "Find the buildings which have rooms with capacity more than 50."
A: Let's think step by step. In the question "Find the buildings which have rooms with capacity more than 50.", we are asked:
"the buildings which have rooms" so we need column = [classroom.capacity]
"rooms with capacity" so we need column = [classroom.building]
Based on the columns and tables, we need these Foreign_keys = [].
Based on the tables, columns, and Foreign_keys, The set of possible cell values are = [50]. So the Schema_links are:
Schema_links: [classroom.building,classroom.capacity,50]

如下面代码所示,schema linking 的结果就是从 GPT 的响应中解析出 Schema_links: 这个字符串后面的内容:

1.2 Classification & Decomposition Module

这一步将 query 分成三种不同的复杂度的类:

  • EASY:没有 JOIN 和 NESTING 的单表查询
  • NON-NESTED:需要 JOIN 但不需要子查询的查询
  • NESTED:可以包含 JOIN、sub-query 和 set opr

下面是一个该 module 的示例:

这部分代码如下:

1.3 SQL Generation Module

这一个 module 根据 query 的复杂度类型,使用不同的策略来生成 SQL。

1.3.1 EASY 类型

对于 EASY 类型的 question,不需要中间步骤,只需要少量提示就足够了,下面是一个 exemplar:

plain 复制代码
Q: "Find the buildings which have rooms with capacity more than 50."
Schema_links: [classroom.building,classroom.capacity,50]
SQL: SELECT DISTINCT building FROM classroom WHERE capacity  >  50

即要求 LLM 根据 question 和 schema links 输出 SQL。

1.3.2 NON-NESTED 类型

对于 NON-NESTED 类型的 question,启发 LLM 去思考从而生成 SQL,下面是一个 exemplar:

plain 复制代码
Q: "Find the total budgets of the Marketing or Finance department."
Schema_links: [department.budget,department.dept_name,Marketing,Finance]
A: Let's think step by step. For creating the SQL for the given question, we need to join these tables = []. First, create an intermediate representation, then use it to construct the SQL query.
Intermediate_representation: select sum(department.budget) from department  where  department.dept_name = \"Marketing\"  or  department.dept_name = \"Finance\"
SQL: SELECT sum(budget) FROM department WHERE dept_name  =  'Marketing' OR dept_name  =  'Finance'

也就是输入 question 和 schema links,然后加一句 Let's think step by step 启发 LLM 思考,从而得到 SQL。

1.3.3 NESTED 类型

在 "Classification & Decomposition Module" 模块中,除了为其复杂度分类,还会为 NESTED 类型的 user question 生成 sub-question,如下图:

然后,这里的 sub-questions 会被传入 SQL Generation Module 的 prompt 中用于解决 NESTED 类型的 SQL 生成。下面是一个 exemplar:

plain 复制代码
Q: "Find the title of courses that have two prerequisites?"
Schema_links: [course.title,course.course_id = prereq.course_id]
A: Let's think step by step. "Find the title of courses that have two prerequisites?" can be solved by knowing the answer to the following sub-question "What are the titles for courses with two prerequisites?".
The SQL query for the sub-question "What are the titles for courses with two prerequisites?" is SELECT T1.title FROM course AS T1 JOIN prereq AS T2 ON T1.course_id  =  T2.course_id GROUP BY T2.course_id HAVING count(*)  =  2
So, the answer to the question "Find the title of courses that have two prerequisites?" is =
Intermediate_representation: select course.title from course  where  count ( prereq.* )  = 2  group by prereq.course_id
SQL: SELECT T1.title FROM course AS T1 JOIN prereq AS T2 ON T1.course_id  =  T2.course_id GROUP BY T2.course_id HAVING count(*)  =  2

exemplar 的 prompt 的组成如下:

可以看到,这就是输入 question、sub-questions、schema links 来生成 SQL。

1.4 Self-correction Module

这一模块的目的是通过 prompt 让 LLM 来检查和纠正生成的 SQL 中可能的错误。这里的 prompt 如下:

这里的 prompt 让 LLM 多关注自己在生成 SQL 时容易犯的错。

二、Error cases 分析

论文对 error cases 做了分析,总结了如下 LLM 容易出的错:

  • Schema linking:这类是犯错最多的情况,指的是 model 错误地识别出 question 中提到的 column names、table names 或者 entities。
  • JOIN:第二大类情况,指的是 model 不能识别出所有需要的 tables 以及正确地将这些 tables 连接起来的外键。
  • GROUP BY:在生成 GROUP BY 子句时,可能会遗漏或者选错列
  • Queries with nesting and set operations:模型不能识别出 nested structure 或者不能检测出正确的 nesting 或 set 操作
  • Invalid SQL:一部分 SQL 有语法错误且不能执行
  • Miscellaneous:还有其他乱七八糟的原因,比如缺少 predicate、缺少或冗余 DISTINCT、DESC 等关键字

这些容易犯的错,都会在 self-correction module 被多关注来检查和纠正。

三、总结

本论文设计的 prompt 以及思路让 LLM 在解决 Text2SQL 任务上有了不错的表现,产生了与最先进的微调方法相当甚至更优的结果。

但是,本文的思路需要多轮与 LLM 交互,从而产生了巨大的花费和延迟,论文给出,在使用 GPT4 响应 Spider 数据集中 question 时表现出大约 60s 的延迟。

相关推荐
FIT2CLOUD飞致云10 分钟前
学习笔记丨MaxKB Office Word AI翻译加载项的实现
人工智能·ai·开源·智能体·maxkb
机器视觉的发动机18 分钟前
从实验室到工业现场:机器人视觉感知系统的边缘AI架构实战, 深度解析硬件选型、TensorRT量化加速与多传感器融合的极致优化方案
人工智能·机器人·视觉检测·人机交互·机器视觉
雾削木25 分钟前
AI文献提示词prompts
人工智能
~kiss~31 分钟前
大模型中激活函数、前馈神经网络 (FFN) 的本质
人工智能·深度学习·神经网络
老兵发新帖44 分钟前
推理平台ONNX性能对比PyTorch原生格式
人工智能
犀思云1 小时前
企业端到端NaaS连接的优势与应用
网络·人工智能·机器人·智能仓储·专线
Keep_Trying_Go1 小时前
基于GAN的文生图算法详解ControlGAN(Controllable Text-to-Image Generation)
人工智能·python·深度学习·神经网络·机器学习·生成对抗网络·文生图
Spey_Events1 小时前
星箭聚力启盛会,2026第二届商业航天产业发展大会暨商业航天展即将开幕!
大数据·人工智能
JoySSLLian1 小时前
IP SSL证书:一键解锁IP通信安全,高效抵御网络威胁!
网络·人工智能·网络协议·tcp/ip·ssl
AC赳赳老秦1 小时前
专利附图说明:DeepSeek生成的专业技术描述与权利要求书细化
大数据·人工智能·kafka·区块链·数据库开发·数据库架构·deepseek