江苏移动数智助手Text2SQL大模型微调实践

Posted by Zhang Jian on August 3, 2024

“随着人工智能技术的迅猛发展,企业在数据处理和分析方面的需求也日益增长。为了更高效地从海量数据中提取有用信息,我们在数智助手中进行了Text2SQL微调实践。这不仅提高了数据查询的效率,还大幅提升了用户体验。”

问题分析

Text2SQL也称NL2SQL,指用自然语言向LLM提问,推理生成结构化SQL语句的过程。

随着大语言模型的迅猛演进,通过LLM将自然语言表达的用户需求转化为SQL查询指令,已确立为解决复杂数据检索问题的首选方案。我们利用海量数据对大模型进行微调,从而增强其在新场景下的适应性和准确性,最终形成:用户问题-SQL命令生成-SQL查询结果返回-查询结果总结输出的完整闭环,实现可靠、准确的问答流程。

在项目早期未引入Text2SQL时,针对用户套餐查询的需求,我们基于单纯RAG语义向量匹配和基座大模型能力,无法实现对用户问题的精准回答,例如:

当用户提问:“将流量套餐升档到20g,推荐什么”时,原有的回答仅简单提到了“畅想20GB流量套餐”,对于其他的选择并没有提及。此外,回答中还存在一些由大模型自行理解输出的信息,缺乏可靠性与真实性。

为了解决这一问题,我同慧舟在数智助手项目实践过程中,发现提升正确率的最大的难点是推理所用到的业务知识和场景(包括业务模型+业务规则)。单纯依赖于提示词的方案无法满足实际业务对回答准确率的要求。因此,如何将用户问题准确转换为SQL表可识别的查询语句,是我们需要重点解决的问题。

Text2SQL大模型现存问题

在实践过程中,我们发现目前的Text2SQL中存在的一些主要问题包括:

(1) 输出幻觉(Hallucination):LLM在生成SQL语句时会生成一些看似合理,但实际与输入文本无关或错误的查询,这可能是由于模型尚未充分学习到数据库的信息和SQL逻辑,导致在推理阶段产生误导性的输出。例如,当用户提问:“比语音翻倍包更经济的套餐有哪些?”,生成的SQL命令为:

1
"SELECT * FROM database WHERE money < 50;"

大模型直接认为”语音翻倍包“的价格为50元,并以此输出SQL语句,导致查询结果出错。

(2) 答案稳定性:模型生成答案不够稳定,偶尔需要多次提问才能找到最优答案。例如,用户多次提问”请问流量超过3000MB有几种套餐“,得到的回答会出现以下几种情况:

1
2
3
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语言特性的理解和生成能力。这一过程不仅保留了大模型的语言理解广度,同时提升了处理SQL转换的精确性和效率,有效避免生成SQL查询时的常见错误,显著提高了整体的执行效果。

优化尝试

根据优化方案的调研结果,我们首先尝试通过提示工程对Text2SQL进行优化。Prompt示例如下:

1
2
3
4
5
你是一位优秀的文本转sql命令的AI专家,擅长的事情是分析用户提问的真实意图,将其转换成sql命令,sql命令切记不要生编乱造,且只返回sql,不返回其他分析内容。
sql表包含以下属性:***
示例:
用户输入:"用户打算将流量套餐升档到4GB,推荐什么",
返回sql:"SELECT * FROM database WHERE GB = 4000"。

我们对大模型输入提示词后,进行了性能测试,测试准确率为83%。例如,向其提问:“98太贵了,有没有便宜点的”,能够得到正确结果:

1
SELECT * FROM database WHERE en_money < 98 AND en_money != '';

而错误结果中,大部分错误数据与套餐名称有关。例如,用户提问:“教育全能会员计划里,哪些套餐包含至少2GB的数据?”,返回结果:

1
SELECT * FROM database WHERE AND en_GB >= 2000;

虽然正确筛选出了流量超过2GB的套餐,但无法定位到“教育全能会员计划”套餐,导致查询出大量的信息,为后续总结输出带来困难。

鉴于用户查询常涉及特定套餐名称,现有通用大模型可能缺乏这些细节信息。因此,我们计划让大模型对专业知识进行学习,从而进一步提升其语义理解能力。下一步优化即可考虑在保留提示词的基础上,对模型进行微调。

目前模型微调主流的方法包括2019年 Houlsby N 等人提出的 Adapter Tuning,2021年微软提出的 LoRA,斯坦福提出的 Prefix-Tuning,谷歌提出的 Prompt Tuning,2022年清华提出的 P-tuning v2。其中,LoRA微调通过将模型的部分权重矩阵分解为两个低秩矩阵,只更新这两个小矩阵的参数来实现微调,从而减少计算资源和内存占用。LoRA微调最大优势在于预训练权重能够在下游任务之间共享,同时省去了预训练权重的梯度和相关的optimizer states,大大增加了训练效率并降低了硬件要求。

在我们的Text2SQL任务中,尝试使用LoRA方法进行模型微调。我们首先对业务知识库中的数据进行信息提取,抽取套餐名称、价格、流量等信息构建数据集,然后对模型进行重新训练和参数调整,使模型能够深度理解江苏移动套餐的查询场景及专业知识,同时能够对SQL常用命令进行学习和理解。

接下来,就让我们从训练数据开始,一步步分享下我们在Text2SQL中模型微调的一些经验。

微调训练数据准备

生成方法

(1) 提取关键属性信息 对业务知识提取关键属性及对应的信息,例如在套餐类问题中,用户关心的问题与价格、能使用多少流量、了解最新的套餐等为主。因此,可抽取的关键属性为:

1
2
3
4
5
6
7
8
套餐名称:{names}
套餐价格:{money}
套餐流量:{GB}
可通话时长:{duration}
套餐上线年份:{online_years}
套餐下线年份:{offline_years}
套餐宽带量:{broadband}
套餐地点:{locations}

(2) 构建常见的用户问题与sql命令语料对,通过抽象化用户可能提问的问题,并进行对应的同义词替换,生成大量训练样本

示例1:查询128元的套餐 用户提问: {Q_ask}{en_money}的套餐 对应sql命令:

1
SELECT * FROM {table_name} WHERE money = {money};

示例2:降档流量套餐到60G 用户提问: {Q_downgrade}{Q_normal}到{en_GB} 对应sql命令:

1
SELECT * FROM {table_name} WHERE GB = {GB};

(3) 训练语料对保存为json格式

1
2
3
4
{
  "user": {"升级到41GB流量的套餐,有什么建议"}, 
  "assistant": {"SELECT * FROM database WHERE GB = 41000;"}
}

(4) 根据用户实际提问继续补充完善语料

生成规模

共生成15w条语料对,包括正向语料和反向语料:

(1) 正向语料(用户输入能够生成sql命令): ➢ 直接查询类:用户直接询问明确的套餐名称、价格 生成5w条样本数字比较类:用户希望找到更优惠、更多流量的套餐 生成5w条样本

(2) 反向语料(用户输入无法生成sql命令): 生成5w条样本

生成样例

问题种类 用户问话 SQL命令
直接查询 随心享随心学随心阅会员的价钱有多少 sql SELECT * FROM database WHERE en_names LIKE '%随心享随心学随心阅会员%';
直接查询 套餐积分商城兑换出行类礼品去哪儿火车票代金券的流量有什么样的啊。 sql SELECT * FROM database WHERE en_names LIKE '%积分商城兑换出行类礼品去哪儿火车票代金券%';
直接查询 积分商城兑换数字类礼品小米影视会员怎么选套餐 sql SELECT * FROM database WHERE en_names LIKE '%积分商城兑换数字类礼品小米影视会员%';
数字比较 返回资费少于等于59的套餐 sql SELECT * FROM database WHERE (en_money <= '59' AND en_money != '');
数字比较 价格不超过481块的手机套餐 sql SELECT * FROM database WHERE (en_money <= '481' AND en_money != '');
我希望提升到高于等于590GB,有什么推荐? sql SELECT * FROM database WHERE en_GB >= '590000.0';  
反向语料 有啥样的手机套餐 NONE
反向语料 能不能给我搜寻流量套餐 NONE
反向语料 有啥嘛建议呀? NONE

微调过程

  1. 所需资源:GPU:NVIDIA A100-SXM4-40GB x2微调模型:QWen-7b-chat

  2. 微调过程

    (1) 训练时长:大约3.75小时

    (2) 训练过程示例

    (3) 训练损失效果图如下

我们对微调后的模型进行测试,用户问题与SQL语句的转换正确率可达98.56%,达到了生产上线的标准。当我们将微调模型部署后,再次提问:“将流量套餐升档到20g,推荐什么”时,回答的套餐信息已明显扩充,并且从用户角度考虑了短期和长期两种情况,向用户提供了更全面、更可靠的答案。

未来展望

随着大模型技术的日新月异,Text2SQL技术也在以惊人的速度不断发展。目前所采用的优化手段,虽然在现阶段可能有效,但随着大模型能力的持续提升,这些手段很可能会逐渐显得过时,甚至被彻底淘汰。

一方面,我们不能神话大型语言模型(LLM)的能力,给予其过高的期望。尽管LLM在诸多任务中展现出了令人瞩目的性能,但它们并非万能,仍然存在诸多局限性和挑战。过于依赖LLM可能会导致我们忽视其他重要的技术手段和工程实践,从而影响整体系统的稳定性和可扩展性。

另一方面,我们也不能因高估工程实现的难度而望而生畏。技术的进步往往伴随着各种挑战,但这些挑战并非不可克服。面对复杂的工程问题,我们需要保持冷静和理性,逐步分析问题,寻找解决方案。通过团队协作和持续创新,我们可以逐步克服这些困难。

只有一步一个脚印,踏踏实实地解决工程实践中的每一个问题,才能最终将Text2SQL技术推向成熟的生产阶段。这不仅需要我们在技术上不断创新,还需要在工程管理、团队协作和项目实施等方面进行全面的提升。通过不断积累经验和优化流程,我们可以逐步将Text2SQL技术应用到更多实际场景中,真正实现其商业价值和社会效益。