论文精读:小白也会SQL:大模型改变交互方式(中)
来源:互联网
时间:2026-08-03 14:11:26

大模型技术论文层出不穷,每月新增上千篇。这个专栏精选的论文,始终围绕行业实践与工程量产。如果你在阅读中遇到知识盲区,可以回头翻翻
,或者翻翻
。想构建生成式AI架构,
里有些干货;技术宅们则不妨死磕
。今天要聊的这篇论文——《CodeS: Towards Building Open-source Language Models for Text-to-SQL》,恰恰是在尝试破解一个老难题:怎么把日常语言丝滑地转换成精准SQL查询,而且得用开放、高效、安全的方式,而不是依赖那些黑盒的、又贵又隐私敏感的大模型。本文承接上一篇,有兴趣的可以细品。
模块A:增强的预训练
想让模型从文本生成SQL,得先让模型具备两种本事:SQL生成能力和自然语言理解能力。为了强化这些能力,训练数据从三个方向收集了语料:SQL相关数据、自然语言相关数据、自然语言转代码数据。
,来自StarCoder预训练语料库中的SQL片段。
,从三个途径获得:
- 途径一:Alpaca-cleaned,斯坦福大学原始羊驼数据集的清理版。Alpaca包含52,000条指令和演示,由OpenAI的text-da vinci-003引擎生成,用于指令调优。
- 途径二:Unnatural-instructions,大规模指令遵循数据集,几乎不需要人工标注。用三个上下文演示作为种子,先让语言模型M生成指令、输入和约束,再用M生成输出,最后用于指令调优。这里M用的是GPT-3的text-da vinci-002。
- 途径三:UltraChat,多回合对话数据集,通过迭代调用两个GPT-3.5 API生成——一个扮演用户,一个生成响应,经过设计过的提示引导,最后再过滤提纯。
其中,途径一和二是单轮对话,途径三是多轮对话。
为了弥合自然语言提问与SQL查询之间的鸿沟,预训练语料从四个途径来凑:
- 途径一:CoNaLa和StaQC,从Stack Overflow自动衍生。CoNaLa经过爬取、自动筛选和人工整理,得到2,379个训练样本和500个测试样本;StaQC有约14.8万Python和12万SQL领域的问题-代码对,通过双向视图层次神经网络自动挖掘。
- 途径二:CodeAlpaca-20k,用Self-Instruct技术生成的20k条指令遵循数据集,用于CodeAlpaca模型微调。
- 途径三:Jupyter-structured-clean-dedup,StarCoder预训练语料的一部分,包含大量结构化Jupyter Notebook,附有自然语言说明。
- 途径四:NL-SQL-458K,论文作者自己造的。先用正则从The Pile、The Stack、GitHub Code5中提取所有“SELECT”查询,滤除语法错误,得到45.8万个SQL查询,再用GPT-3.5配合8个示范提示,为每个SQL生成自然语言提问。
CodeS训练小细节
语料备好之后,CodeS基于StarCoder构建。增量预训练时,在SQL相关数据上跑了
,在自然语言相关数据和自然语言转代码数据上各跑一个epoch。这种自然语言与代码混合训练的思路,给两个领域的任务都带来了好处。
训练采用
最大化序列概率,学习率设为
,配合权重衰减策略,调度器用余弦衰减,没有预热步骤。
,用梯度裁剪(阈值为1.0)保证稳定性。论文作者用了
框架加BF16混合精度计算来优化GPU内存,还集成了
,让CodeS能处理更长上下文。CodeS-(1B, 3B, 7B)最多能处理
个token,CodeS-15B能处理
个。
模块B:数据库提示词构建
先来看看Text转SQL查询模板长什么样——用户只需输入问题,后台会自动补上额外信息,让查询更精准高效。如果能在用户提问时,自动检索出相关的表、列、数据库数据以及各种元数据,那生成SQL的准确度就能大幅提升。为此,论文作者设计了两个核心组件:
和
。这两个策略需要事先整合数据库数据和元数据。具体流程如下图(左为流程图,右为伪代码),意思一样。
:考虑到模型处理上下文长度有限,作者参考了RESDSQL的方法——解耦schema link和skeleton parsing以降低难度。具体做法:先训练一个Schema分类器,用来预测用户提问与表和列之间的关联性分数(算法图中步骤1)。下图是Cross-encoder的输出,可以看到“airports”表相关度最高,里面的“city”列关联度也很高。然后保留排名top k1的表以及表中top k2的列(步骤2)。Schema分类器的结构如下。
下图来自RESDSQL论文。原始论文在得到相关表和列后,会进一步将问题+相关表列+额外外键输入新的骨架模型,输出类似“select...”的SQL语句。这本质上就是解耦数据库元信息和SQL生成。
:作者认为,如果模型在构造SQL时能拿到问题中提到的具体值,生成的查询会更精准。比如BIRD基准里的问题:“Jesenik分行开设账户的客户中有多少是女性?”需要跟数据库中数据对比。如果“district”表的“a2”列存着“Jesenik”,把“district.a2 = 'Jesenik'”塞进提示,能帮模型生成更准确的回答。
计算数据库值与问题之间匹配度的LCS(最长公共子串)算法很耗时。作者改用“从粗到精”的策略:先用粗粒度索引缩小范围,再用LCS精校。具体用Lucene为数据库所有值构建BM25索引,查询时快速找到可能相关的值(步骤3),再用LCS计算匹配度,找出最相关的值(步骤4)。
BM25是信息索引领域计算query与文档相似度得分的经典算法。它不同于TF-IDF,公式主要由三部分组成:query中每个单词t与文档d之间的相关性、单词t与query之间的相似性、每个单词的权重。BM25的一般公式:score(Q,d)=∑_{t in Q} IDF(t)·(f(t,d)·(k1+1))/(f(t,d)+k1·(1-b+b·|d|/a vgdl))。其中IDF(t)=log((N-df(t)+0.5)/(df(t)+0.5)),N是文档总数,df(t)是包含t的文档数。IDF越大说明t的区分度越高。
:提示模板中还融入了元数据信息,包括列的数据类型、注释(提高语义理解和模式关联正确性)、典型数据库值(如枚举值)和主外键关联关系(确保JOIN ON子句准确生成)。
模块C:双向语料自动生成与增强
实际应用中,每个领域都有自己的数据库,经常会缺带标签的训练数据。作者开发了双向数据增强组件,
旨在以最低的标注成本自动生成大量真实且通用的(提问,SQL)对。
先采集用户数据库常见的查询需求(提问)作为训练样本,研究人员手动标注这些提问对应的SQL语句——这只能得到
的(Q,SQL)对。为了获得更多,研究人员把刚才的查询需求输入给GPT-3.5,自动生成更多的Q新(新提问),再把(Q,SQL)对和Q新一起喂给GPT-3.5,让它生成新的SQL,这样就能得到更多的训练语料。如此以小博大,自动扩展语料(如图A)。为了保证新生成问题的多样性,还需要对用户查询需求问题进行洗牌,并为每次生成设置一个高温超参数,让概率分布更平坦。
2. SQL→Question(提问)的语料增强:
作者采用SyntaxSQLNet论文中从Spider衍生出的(Q, SQL)模板。研究人员通过填充
里的占位符,生成新的模板(Q, SQL)对。为了让这些(Q, SQL)对更生动,研究人员还为这些
的样本新增字段QRefine(从模板化提问出发,结合实际业务场景提炼出人性化的提问),从而得到
:[模板化提问_i]、[模板化SQL_i]和
。
Spider是一个广受认可的文本到SQL评估基准,涵盖75个常见SQL模板。例如,模板化问题:“返回{TABLE}中最低的{COLUMN}”,对应模板化SQL:“SELECT {COLUMN} FROM {TABLE} GROUP BY {COLUMN} ORDER BY COUNT(*) ASC LIMIT 1”。
为了继续增加(QRefine, SQL)对的数量,研究人员将三元组带上剩下的模板提问一并交给GPT-3.5,自动生成对应的QRefine,从而生成更多的(QRefine, SQL)对。
论文链接:https://arxiv.org/pdf/2402.16347.pdf