"随着人工智能技术的迅猛发展,企业在数据处理和分析方面的需求也日益增长。为了更高效地从海量数据中提取有用信息,我们在数智助手中进行了Text2SQL微调实践。这不仅提高了数据查询的效率,还大幅提升了用户体验。"
问题分析
Text2SQL也称NL2SQL,指用自然语言向LLM提问,推理生成结构化SQL语句的过程。
随着大语言模型的迅猛演进,通过LLM将自然语言表达的用户需求转化为SQL查询指令,已确立为解决复杂数据检索问题的首选方案。我们利用海量数据对大模型进行微调,从而增强其在新场景下的适应性和准确性,最终形成:用户问题-SQL命令生成-SQL查询结果返回-查询结果总结输出的完整闭环,实现可靠、准确的问答流程。
在项目早期未引入Text2SQL时,针对用户套餐查询的需求,我们基于单纯RAG语义向量匹配和基座大模型能力,无法实现对用户问题的精准回答,例如:
当用户提问:“将流量套餐升档到20g,推荐什么”时,原有的回答仅简单提到了“畅想20GB流量套餐”,对于其他的选择并没有提及。此外,回答中还存在一些由大模型自行理解输出的信息,缺乏可靠性与真实性。
为了解决这一问题,我们在数智助手项目实践过程中,发现提升正确率的最大的难点是推理所用到的业务知识和场景(包括业务模型+业务规则)。单纯依赖于提示词的方案无法满足实际业务对回答准确率的要求。因此,如何将用户问题准确转换为SQL表可识别的查询语句,是我们需要重点解决的问题。
Text2SQL大模型现存问题
在实践过程中,我们发现目前的Text2SQL中存在的一些主要问题包括:
(1) 输出幻觉(Hallucination):LLM在生成SQL语句时会生成一些看似合理,但实际与输入文本无关或错误的查询,这可能是由于模型尚未充分学习到数据库的信息和SQL逻辑,导致在推理阶段产生误导性的输出。例如,当用户提问:“比语音翻倍包更经济的套餐有哪些?”,生成的SQL命令为:
SELECT * FROM database WHERE money < 50;
大模型直接认为”语音翻倍包“的价格为50元,并以此输出SQL语句,导致查询结果出错。
(2) 答案稳定性:模型生成答案不够稳定,偶尔需要多次提问才能找到最优答案。例如,用户多次提问”请问流量超过3000MB有几种套餐“,得到的回答会出现以下几种情况:
SELECT COUNT(*) FROM database WHERE en_names LIKE %'流量超过3000MB'%;
SELECT COUNT(*) FROM database WHERE en_broadband > 3;
SELECT COUNT(*) FROM database WHERE en_broadband > 3000;
在多次提问的过程中,出现了语义理解不清(将”流量超过3000MB“作为套餐名)、单位换算出错(MB转换成GB)的情况,暴露出大模型稳定性不强的问题。
优化方法
为了解决这些模型问题,我们考虑了Prompt Engineering(提示工程)、Fine-tuning(模型微调)等方式对模型进行优化。
(1) Prompt Engineering(提示工程) 能够通过设计特定的提示词或句子,引导模型生成更贴合用户意图的输出。在处理SQL查询时,向模型注入特定领域的知识,比如SQL规范、数据库架构以及注意单位转换等额外要求,能够显著提升模型对于SQL语句结构和逻辑的理解能力。
(2) Fine-tuning(模型微调) 是一种先进的机器学习技术,旨在针对预训练模型进行定制化调整,使其更加契合特定应用场景的需求。尤其在Text2SQL这类复杂任务中,我们可以通过利用富含SQL语句的专门数据集对模型进行微调,以此强化模型对SQL语言特性的理解和生成能力。
优化尝试
根据优化方案的调研结果,我们首先尝试通过提示工程对Text2SQL进行优化。Prompt示例如下:
你是一位优秀的文本转sql命令的AI专家,擅长的事情是分析用户提问的真实意图,将其转换成sql命令,sql命令切记不要生编乱造,且只返回sql,不返回其他分析内容。
sql表包含以下属性:***
示例:
用户输入:"用户打算将流量套餐升档到4GB,推荐什么",
返回sql:"SELECT * FROM database WHERE GB = 4000"。
我们对大模型输入提示词后,进行了性能测试,测试准确率为83%。例如,向其提问:“98太贵了,有没有便宜点的”,能够得到正确结果:
SELECT * FROM database WHERE en_money < 98 AND en_money != '';
而错误结果中,大部分错误数据与套餐名称有关。例如,用户提问:“教育全能会员计划里,哪些套餐包含至少2GB的数据?”,返回结果:
SELECT * FROM database WHERE AND en_GB >= 2000;
虽然正确筛选出了流量超过2GB的套餐,但无法定位到“教育全能会员计划”套餐,导致查询出大量的信息,为后续总结输出带来困难。
鉴于用户查询常涉及特定套餐名称,现有通用大模型可能缺乏这些细节信息。因此,我们计划让大模型对专业知识进行学习,从而进一步提升其语义理解能力。
目前模型微调主流的方法包括2021年微软提出的 LoRA (Low-Rank Adaptation)。LoRA微调通过将模型的部分权重矩阵分解为两个低秩矩阵,只更新这两个小矩阵的参数来实现微调,从而减少计算资源和内存占用。
微调训练数据准备
生成方法
(1) 提取关键属性信息:对业务知识提取关键属性及对应的信息。
套餐名称:{names}
套餐价格:{money}
套餐流量:{GB}
可通话时长:{duration}
套餐上线年份:{online_years}
套餐下线年份:{offline_years}
套餐宽带量:{broadband}
套餐地点:{locations}
(2) 构建常见的用户问题与sql命令语料对,通过抽象化用户可能提问的问题,并进行对应的同义词替换,生成大量训练样本
- 示例1:查询128元的套餐
SELECT * FROM {table_name} WHERE money = {money}; - 示例2:降档流量套餐到60G
SELECT * FROM {table_name} WHERE GB = {GB};
(3) 训练语料对保存为json格式
{
"user": "升级到41GB流量的套餐,有什么建议",
"assistant": "SELECT * FROM database WHERE GB = 41000;"
}
生成规模
共生成15w条语料对,包括正向语料和反向语料:
- 正向语料:
- 直接查询类:生成5w条样本。
- 数字比较类:生成5w条样本。
- 反向语料:生成5w条样本。
微调过程
- 所需资源:GPU:NVIDIA A100-SXM4-40GB x2;微调模型:QWen-7b-chat
- 训练时长:大约3.75小时
我们对微调后的模型进行测试,用户问题与SQL语句的转换正确率可达98.56%,达到了生产上线的标准。当我们将微调模型部署后,回答的套餐信息已明显扩充,并且从用户角度考虑了短期和长期两种情况,向用户提供了更全面、更可靠的答案。
未来展望
随着大模型技术的日新月异,Text2SQL技术也在以惊人的速度不断发展。目前所采用的优化手段,虽然在现阶段可能有效,但随着大模型能力的持续提升,这些手段很可能会逐渐显得过时,甚至被彻底淘汰。
一方面,我们不能神话大型语言模型(LLM)的能力,给予其过高的期望。另一方面,我们也不能因高估工程实现的难度而望而生畏。只有一步一个脚印,踏踏实实地解决工程实践中的每一个问题,才能最终将Text2SQL技术推向成熟的生产阶段。