NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧

NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧

NL2SQL基础系列(1):业界顶尖排行榜、权威测评数据集及LLM大模型(Spider vs BIRD)全面对比优劣分析[Text2SQL、Text2DSL]

NL2SQL基础系列(2):主流大模型与微调方法精选集,Text2SQL经典算法技术回顾七年发展脉络梳理

NL2SQL进阶系列(1):DB-GPT-Hub、SQLcoder、Text2SQL开源应用实践详解

NL2SQL进阶系列(2):DAIL-SQL、DB-GPT开源应用实践详解[Text2SQL]

NL2SQL进阶系列(3):Data-Copilot、Chat2DB、Vanna Text2SQL优化框架开源应用实践详解[Text2SQL]

☆☆NL2SQL进阶系列(4):ConvAI、DIN-SQL、C3-浙大、DAIL-SQL-阿里等16个业界开源应用实践详解[Text2SQL]

☆☆NL2SQL进阶系列(5):论文解读业界前沿方案(DIN-SQL、C3-SQL、DAIL-SQL、SQL-PaLM)、新一代数据集BIRD-SQL解读

NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧

NL2SQL实践系列(2):2024最新模型实战效果(Chat2DB-GLM、书生·浦语2、InternLM2-SQL等)以及工业级案例教学

NL2SQL任务的目标是将用户对某个数据库的自然语言问题转化为相应的SQL查询。随着LLM的发展,使用LLM进行NL2SQL已成为一种新的范式。在这一过程中,如何利用提示工程来发掘LLM的NL2SQL能力显得尤为重要。

prompt的组成包四个元素:

  • Instruction(指令,必须)
  • Context(上下文信息,可选)
  • Input Data(需要处理的数据,可选)
  • Output Indicator(要输出的类型或格式,可选)

一个面向复杂任务的prompt的一般都包含Instruction,Context,Input Data,Output Indicator。
所以面向大语言模型的开发应用过程就是如下公式:
LMM(Instruction + Context + Input Data + Output Indicator) = Output
prompt engineering 就是写好这四块东西Instruction,Context,Input Data,Output Indicator,让模型的输出Output越准越好

1.text2sql prompt

> prompt = """
>         现在你是一个数据分析师,SQL大神,请根据用户提供的表的信息,以及用户的需求,写出效率最高的SQL,
>         表信息如下:
>             表名:students;
>             字段:id,name,age,location
>         用户需求:统计一下姓名年龄大于23,姓名包含andy且在beijing,的的学生个数。
>         并且要求输出的SQL以#开头,以#结尾,样例如下:
>                 #SELECT * FROM table#
>                 #SELECT COUNT(*) FROM table#
>         注意不需要分析过程,直接给出SQL语句
>        """
> inputttext ="""<human>:
>      {}
> <aibot>:
> """.format(prompt)

输出结果: #SELECT COUNT(*) FROM students WHERE age > 23 AND name LIKE '%andy%' AND location = 'beijing'#

2.大模型text2sql 微调教程

LLM大模型:https://huggingface.co/baichuan-inc/Baichuan-13B-Chat

训练数据:https://huggingface.co/datasets/Clinton/Text-to-sql-v1

Baichuan-13B 是由百川智能继 Baichuan-7B 之后开发的包含 130 亿参数的开源可商用的大规模语言模型,在权威的中文和英文 benchmark 上均取得同尺寸最好的效果。本次发布包含有预训练 (Baichuan-13B-Base) 和对齐 (Baichuan-13B-Chat) 两个版本。Baichuan-13B 有如下几个特点:

  • 更大尺寸、更多数据:Baichuan-13B 在 Baichuan-7B 的基础上进一步扩大参数量到 130 亿,并且在高质量的语料上训练了 1.4 万亿 tokens,超过 LLaMA-13B 40%,是当前开源 13B 尺寸下训练数据量最多的模型。支持中英双语,使用 ALiBi 位置编码,上下文窗口长度为 4096。
  • 同时开源预训练和对齐模型:预训练模型是适用开发者的“基座”,而广大普通用户对有对话功能的对齐模型具有更强的需求。因此本次开源同时发布了对齐模型(Baichuan-13B-Chat),具有很强的对话能力,开箱即用,几行代码即可简单的部署。
  • 更高效的推理:为了支持更广大用户的使用,本次同时开源了 int8 和 int4 的量化版本,相对非量化版本在几乎没有效果损失的情况下大大降低了部署的机器资源门槛,可以部署在如 Nvidia 3090 这样的消费级显卡上。
  • 开源免费可商用:Baichuan-13B 不仅对学术研究完全开放,开发者也仅需邮件申请并获得官方商用许可后,即可以免费商用。
数据格式如下:
"""Below are sql tables schemas paired with instruction that describes a task. Using valid SQLite, write a response that appropriately completes the request for the provided tables. ### Instruction: provide the number of patients whose diagnoses icd9 code is 60000? ### Input: CREATE TABLE procedures (\n    subject_id text,\n    hadm_id text,\n    icd9_code text,\n    short_title text,\n    long_title text\n)\n\nCREATE TABLE prescriptions (\n    subject_id text,\n    hadm_id text,\n    icustay_id text,\n    drug_type text,\n    drug text,\n    formulary_drug_cd text,\n    route text,\n    drug_dose text\n)\n\nCREATE TABLE demographic (\n    subject_id text,\n    hadm_id text,\n    name text,\n    marital_status text,\n    age text,\n    dob text,\n    gender text,\n    language text,\n    religion text,\n    admission_type text,\n    days_stay text,\n    insurance text,\n    ethnicity text,\n    expire_flag text,\n    admission_location text,\n    discharge_location text,\n    diagnosis text,\n    dod text,\n    dob_year text,\n    dod_year text,\n    admittime text,\n    dischtime text,\n    admityear text\n)\n\nCREATE TABLE lab (\n    subject_id text,\n    hadm_id text,\n    itemid text,\n    charttime text,\n    flag text,\n    value_unit text,\n    label text,\n    fluid text\n)\n\nCREATE TABLE diagnoses (\n    subject_id text,\n    hadm_id text,\n    icd9_code text,\n    short_title text,\n    long_title text\n) ### Response:SELECT COUNT(DISTINCT demographic.subject_id) FROM demographic INNER JOIN diagnoses ON demographic.hadm_id = diagnoses.hadm_id WHERE diagnoses.icd9_code = "60000" """

训练代码:text2sqlBaichuan13B.py

2.1 姜子牙系列模型

姜子牙通用大模型V1是基于LLaMa的130亿参数的大规模预训练模型,具备翻译,编程,文本分类,信息抽取,摘要,文案生成,常识问答和数学计算等能力。目前姜子牙通用大模型已完成大规模预训练、多任务有监督微调和人类反馈学习三阶段的训练过程。

https://huggingface.co/IDEA-CCNL/Ziya-LLaMA-13B-v1

https://github.com/IDEA-CCNL/Ziya-Coding

https://www.modelscope.cn/models/Fengshenbang/Ziya-LLaMA-13B-v1/summary

继续预训练 Continual pretraining
原始数据包含英文和中文,其中英文数据来自openwebtext、Books、Wikipedia和Code,中文数据来自清洗后的悟道数据集、自建的中文数据集。在对原始数据进行去重、模型打分、数据分桶、规则过滤、敏感主题过滤和数据评估后,最终得到125B tokens的有效数据。
为了解决LLaMA原生分词对中文编解码效率低下的问题,在LLaMA词表的基础上增加了7k+个常见中文字,通过和LLaMA原生的词表去重,最终得到一个39410大小的词表,并通过复用Transformers里LlamaTokenizer来实现了这一效果。
在增量训练过程中,使用了160张40GB的A100,采用2.6M tokens的训练集样本数量和FP 16的混合精度,吞吐量达到118 TFLOP per GPU per second。因此能够在8天的时间里在原生的LLaMA-13B模型基础上,增量训练110B tokens的数据。

  • 多任务有监督微调 Supervised finetuning
    在多任务有监督微调阶段,采用了课程学习(curiculum learning)和增量训练(continual learning)的策略,用大模型辅助划分已有的数据难度,然后通过“Easy To Hard”的方式,分多个阶段进行SFT训练。SFT训练数据包含多个高质量的数据集,均经过人工筛选和校验:
  1. Self-Instruct构造的数据(约2M):BELLE、Alpaca、Alpaca-GPT4等多个数据集
  2. 内部收集Code数据(300K):包含leetcode、多种Code任务形式
  3. 内部收集推理/逻辑相关数据(500K):推理、申论、数学应用题、数值计算等
  4. 中英平行语料(2M):中英互译语料、COT类型翻译语料、古文翻译语料等
  5. 多轮对话语料(500K):Self-Instruct生成、任务型多轮对话、Role-Playing型多轮对话等

Ziya2-13B-Chat采用"<human>:"和"<bot>:"作为用户和模型的角色识别Prompt,使用"\n"分隔不同角色对话内容。 在推理时,需要将"<human>:"和"<bot>:"作为前缀分别拼接至用户问题和模型回复的前面,并使用"\n"串连各对话内容。

Ziya2-13B-Chat adopts "<human>:" and "<bot>:" as the role recognition prompts for users and models, and uses "\n" to separate the contents of different roles. When doing inference, "<human>:" and "<bot>:" need to be concatenated as prefixes in front of the user's question and the model's reply respectively, and "\n" is used to join the contents of each role.

以下为具体使用方法:

Following are the details of how to use it:

from modelscope import AutoTokenizer, AutoModelForCausalLM, snapshot_download
import torch

device = torch.device("cuda")

messages = [{"role": "user", "content": "手机如果贴膜贴了一张防指纹的钢化膜,那屏幕指纹解锁还有效吗?"}]
user_prefix = "<human>:"
assistant_prefix = "<bot>:"
separator = "\n"

prompt = []
for item in messages:
    prefix = user_prefix if item["role"] == "user" else assistant_prefix
    prompt.append(f"{prefix}{item['content']}")
prompt.append(assistant_prefix)
prompt = separator.join(prompt)

model_dir = snapshot_download('Fengshenbang/Ziya2-13B-Chat', revision='master')
model = AutoModelForCausalLM.from_pretrained(model_dir,torch_dtype=torch.bfloat16).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_dir, use_fast=False)
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(device)
generate_ids = model.generate(
            input_ids,
            max_new_tokens=512, 
            do_sample = True, 
            top_p = 0.9, 
            temperature = 0.85, 
            repetition_penalty=1.05, 
            eos_token_id=tokenizer.encode("</s>"), 
            )
output = tokenizer.batch_decode(generate_ids)[0]
print(output)

模型部署

import gradio as gr
import os
import gc
import torch


from transformers import AutoTokenizer
#指定环境的GPU,我的环境是2张A100(40GB)显卡,于是我设置了两张卡,也可以一张80GB的A100
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1"
#这个utils文件直接下载官方给的文件即可
from utils import SteamGenerationMixin


class MindBot(object):
    def __init__(self):
        #这个model_path为你本地的模型路径
        model_path = './ziya_v1.1'
        self.model = SteamGenerationMixin.from_pretrained(model_path, device_map='auto').half()
        self.model.eval()

        self.tokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=False)

    def build_prompt(self, instruction, history, human='<human>', bot='<bot>'):
        pmt = ''
        if len(history) > 0:
            for line in history:
                pmt += f'{human}: {line[0].strip()}\n{bot}: {line[1]}\n'
        pmt += f'{human}: {instruction.strip()}\n{bot}: \n'
        return pmt

    def interaction(
        self,
        instruction,
        history,
        max_new_tokens,
        temperature,
        top_p,
        max_memory=1024
    ):

        prompt = self.build_prompt(instruction, history)
        input_ids = self.tokenizer(prompt, return_tensors="pt").input_ids
        if input_ids.shape[1] > max_memory:
            input_ids = input_ids[:, -max_memory:]

        prompt_len = input_ids.shape[1]
        # stream generation method
        try:
            tmp = history.copy()
            output = ''
            with torch.no_grad():
                for generation_output in self.model.stream_generate(
                    input_ids.cuda(),
                    max_new_tokens=max_new_tokens, 
                    do_sample=True,
                    top_p=top_p, 
                    temperature=temperature, 
                    repetition_penalty=1., 
                    eos_token_id=2, 
                    bos_token_id=1, 
                    pad_token_id=0
                ):
                    s = generation_output[0][prompt_len:]
                    output = self.tokenizer.decode(s, skip_special_tokens=True)
                    # output = output.replace('\n', '<br>')
                    output = output.replace('\n', '\n\n')
                    tmp.append((instruction, output))
                    yield  '', tmp
                    tmp.pop()
                    # gc.collect()
                    # torch.cuda.empty_cache()
                history.append((instruction, output))
                print('input -----> \n', prompt)
                print('output -------> \n', output)
                print('history: ======> \n', history)
        except torch.cuda.OutOfMemoryError:
            gc.collect()
            torch.cuda.empty_cache()
            self.model.empty_cache()
            history.append((instruction, "【显存不足,请清理历史信息后再重试】"))
        return "", history

    def chat(self):

        with gr.Blocks(title='IDEA MindBot', css=".bgcolor {color: white !important; background: #FFA500 !important;}") as demo:
            with gr.Row():
                gr.Column(scale=0.25)
                with gr.Column(scale=0.5):
                    gr.Markdown("<center><h1>IDEA Ziya</h1></center>")
                    gr.Markdown("<center>姜子牙通用大模型V1.1是基于LLaMa的130亿参数的大规模预训练模型,具备翻译,编程,文本分类,信息抽取,摘要,文案生成,常识问答和数学计算等能力。目前姜子牙通用大模型已完成大规模预训练、多任务有监督微调和人类反馈学习三阶段的训练过程。</center>")
                gr.Column(scale=0.25)
            with gr.Row():
                gr.Column(scale=0.25)
                with gr.Column(scale=0.5):
                    chatbot = gr.Chatbot(label='Ziya').style(height=500)
                    msg = gr.Textbox(label="Input")
                # gr.Column(scale=0.25)
                with gr.Column(scale=0.25):
                    max_new_tokens = gr.Slider(0, 2048, value=1024, step=1.0, label="Max_new_tokens", interactive=True)
                    top_p = gr.Slider(0, 1, value=0.85, step=0.01, label="Top P", interactive=True)
                    temperature = gr.Slider(0, 1, value=0.8, step=0.01, label="Temperature", interactive=True)
            with gr.Row():
                gr.Column(scale=0.25)
                with gr.Column(scale=0.25):
                    clear = gr.Button("Clear")
                with gr.Column(scale=0.25):
                    submit = gr.Button("Submit")
                gr.Column(scale=0.25)

            msg.submit(self.interaction, [msg, chatbot,max_new_tokens,top_p,temperature], [msg, chatbot])
            clear.click(lambda: None, None, chatbot, queue=False)
            submit.click(self.interaction, [msg, chatbot,max_new_tokens,top_p,temperature], [msg, chatbot])
        return demo.queue(concurrency_count=10).launch(share=False,server_name="127.0.0.1", server_port=7886)


if __name__ == '__main__':
    mind_bot = MindBot()
    mind_bot.chat()
  • 人类反馈学习 Reinforcement learning from Human Feedback

基于SFT阶段的模型,Ziya2-13B-Chat针对多种问答、写作以及模型安全性的任务上进行了人类偏好的对齐。自行采集了数万条高质量人类偏好数据,使用Ziya2-13B-Base训练了人类偏好反馈模型,在各任务的偏好数据上达到了72%以上的准确率。

  • 效果评估 Performance
    Ziya2-13B-Base在Llama2-13B的基础上进行了约650B自建高质量中英文数据集的继续训练,在中文、英文、数学、代码等下游理解任务上相对于Llama2-13B取得了明显的提升,相对Ziya-LLaMA-13B也有明显的提升。

3.Prompt升级

参考文章:https://zhuanlan.zhihu.com/p/635799364?utm_id=0

  • 第一版

尽管模型的输出SQL语句本身都是正确的,却存在着一个明显的问题:它会产生多余的输出。具体来说,模型似乎过度地“幻想”了SQL查询的结果,将一些并不属于实际查询结果的数据也一并输出,这导致了信息冗余和不必要的复杂性。

  • 第二版

经过版本升级后,引入了角色扮演的功能,告知模型它现在是一名数据分析师,且精通SQL。然而,尽管模型的输出SQL语句本身是正确的,但结果呈现的方式却不够结构化,这导致它并不适合后续的操作和分析。期望模型仅输出一段单独的、结构清晰的SQL语句,而不是包含多余或复杂化的输出。作为数据分析师,更注重结果的准确性和实用性,因此希望模型能够在这方面进行改进。

  • 第三版

经过进一步的版本升级,增强了模型的输出引导功能,希望它输出的SQL语句能够以“#”开头,并以“#”结尾。然而,发现尽管模型的SQL语句本身是正确的,但其输出结果却存在错误:结尾部分缺少了一个“#”。这导致了输出格式的不一致和潜在的识别问题。期待模型在输出SQL时能够严格遵守规定的格式,确保每个SQL语句都以“#”完整包围,以满足后续处理和分析的需求。

  • 最终版

经过又一次的版本升级,不仅在输出引导方面进行了增强,还提供了具体的示例,以帮助模型更好地理解的期望。这次,欣喜地发现,模型的输出SQL语句完全符合的需求。通过明确的输出引导和示例,模型能够准确地生成结构清晰、格式规范的SQL语句,为后续的数据处理和分析提供了极大的便利。这一改进不仅提升了模型的性能,也进一步提高了的工作效率和准确性。

至此,已深入掌握面向大模型开发的核心技术,学会如何有效利用大模型的强大能力,以应对各类复杂任务。整个过程可细化为以下关键步骤:

  • 首先,需精心构建高质量的prompt。其中,指令(Instruction)的设定至关重要,需精确、明确地传达的任务需求;上下文信息(Context)作为可选内容,有助于模型更全面地理解问题背景;输入数据(Input Data)是模型处理的具体对象,应根据任务特点灵活选择;输出指引(Output Indicator)则用于规定输出结果的类型、格式及精度,确保模型输出符合专业标准。

  • 随后,需要不断迭代与优化prompt。这是一个精细的调试过程,通过对比分析模型的实际输出与预期结果,可以发现prompt中的不足之处,进而针对性地调整其表述和细节。通过多次迭代,可以逐步完善prompt,使模型输出更加精确、全面。

  • 最后,验证prompt的稳定性和准确性是不可或缺的环节。通过大量的测试与验证,可以评估模型在不同情境下的表现,确保其输出的稳定性和可靠性。此外,还需要关注模型的泛化能力,确保其能够应对各种未知或复杂情况。

更多优质内容请关注公号:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。

相关文章
|
4天前
|
机器学习/深度学习 人工智能 自然语言处理
思通数科AI平台在尽职调查中的技术解析与应用
思通数科AI多模态能力平台结合OCR、NLP和深度学习技术,为IPO尽职调查、融资等重要交易环节提供智能化解决方案。平台自动识别、提取并分类海量文档,实现高效数据核验与合规性检查,显著提升审查速度和精准度,同时保障敏感信息管理和数据安全。
37 11
|
1天前
|
编解码 前端开发 UED
探索无界:前端开发中的响应式设计深度解析与实践####
【10月更文挑战第29天】 本文深入探讨了响应式设计的核心理念,即通过灵活的布局、媒体查询及弹性图片等技术手段,使网站能够在不同设备上提供一致且优质的用户体验。不同于传统摘要概述,本文将以一次具体项目实践为引,逐步剖析响应式设计的关键技术点,分享实战经验与避坑指南,旨在为前端开发者提供一套实用的响应式设计方法论。 ####
20 4
|
2天前
|
安全 编译器 PHP
PHP 8新特性解析与实践应用####
————探索PHP 8的创新功能及其在现代Web开发中的实际应用
|
4天前
|
机器学习/深度学习 人工智能 自然语言处理
医疗行业的语音识别技术解析:AI多模态能力平台的应用与架构
AI多模态能力平台通过语音识别技术,实现实时转录医患对话,自动生成结构化数据,提高医疗效率。平台具备强大的环境降噪、语音分离及自然语言处理能力,支持与医院系统无缝集成,广泛应用于门诊记录、多学科会诊和急诊场景,显著提升工作效率和数据准确性。
|
11天前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
40 10
|
5天前
|
机器学习/深度学习 人工智能 安全
TPAMI:安全强化学习方法、理论与应用综述,慕工大、同济、伯克利等深度解析
【10月更文挑战第27天】强化学习(RL)在实际应用中展现出巨大潜力,但其安全性问题日益凸显。为此,安全强化学习(SRL)应运而生。近日,来自慕尼黑工业大学、同济大学和加州大学伯克利分校的研究人员在《IEEE模式分析与机器智能汇刊》上发表了一篇综述论文,系统介绍了SRL的方法、理论和应用。SRL主要面临安全性定义模糊、探索与利用平衡以及鲁棒性与可靠性等挑战。研究人员提出了基于约束、基于风险和基于监督学习等多种方法来应对这些挑战。
15 2
|
10天前
|
存储 弹性计算 NoSQL
"从入门到实践,全方位解析云服务器ECS的秘密——手把手教你轻松驾驭阿里云的强大计算力!"
【10月更文挑战第23天】云服务器ECS(Elastic Compute Service)是阿里云提供的基础云计算服务,允许用户在云端租用和管理虚拟服务器。ECS具有弹性伸缩、按需付费、简单易用等特点,适用于网站托管、数据库部署、大数据分析等多种场景。本文介绍ECS的基本概念、使用场景及快速上手指南。
40 3
|
9天前
|
测试技术 开发者 Python
深入浅出:Python中的装饰器解析与应用###
【10月更文挑战第22天】 本文将带你走进Python装饰器的世界,揭示其背后的魔法。我们将一起探索装饰器的定义、工作原理、常见用法以及如何自定义装饰器,让你的代码更加简洁高效。无论你是Python新手还是有一定经验的开发者,相信这篇文章都能为你带来新的启发和收获。 ###
9 1
|
13天前
|
PHP 数据安全/隐私保护 开发者
PHP 7新特性解析与实践
【10月更文挑战第20天】本文将深入浅出地介绍PHP 7的新特性,包括性能提升、语法改进等方面。我们将通过实际代码示例,展示如何利用这些新特性优化现有项目,提高开发效率。无论你是PHP新手还是资深开发者,都能从中获得启发和帮助。
|
13天前
|
传感器 监控 安全

推荐镜像

更多