面向NL2BI的大模型微调最佳实践

本文以Qwen系列大模型为例,介绍如何在人工智能平台PAI上构建从训练数据生成、模型微调训练到服务部署和调用的NL2BI全链路解决方案。

背景信息

NL2SQL(自然语言生成SQL)技术旨在将自然语言转换为数据库查询语句,使得即使不熟悉SQL的用户也能轻松地从数据库中提取数据进行分析,从而提高决策效率并深入挖掘数据背后的商业洞察(NL2BI)。

通过将NL2SQL与当前先进的大型语言模型相结合,可以显著增强语义理解能力,并支持更复杂的SQL语法生成,实现更精准的SQL查询和更流畅的数据提取分析体验。

尽管如此,NL2BI的应用场景仍面临诸多挑战,例如LLM推理服务的高成本和对业务语义理解能力的不足。为了解决这些问题,通常需要在您自己的业务场景下,对LLMNL2BI能力进行微调训练。本方案的数据生产过程采用Qwen2-72B-Instruct大语言模型,模型微调采用CodeQwen1.5-7B-Chat模型。

使用流程

基于LLMNL2BI全链路解决方案的使用流程如下:

image
  1. 准备数据集

    您可以参照数据格式要求和数据准备策略,并针对特定的业务场景准备相应的训练数据集。由于NL2SQL人工标注需要较大的工作量,您可以使用PAI-DLCQwen2-72B大模型进行批量数据生成,用于后续的模型训练。

  2. 训练模型

    在快速开始中,基于CodeQwen1.5-7B-Chat模型进行训练。

  3. 部署及调用模型服务

    通过快速开始将训练好的模型部署为EAS在线服务。

前提条件

在开始执行操作前,请确认您已完成以下准备工作:

  • 已开通PAI(DLC、EAS)后付费,并创建默认工作空间,详情请参见开通PAI并创建默认工作空间

  • 已创建OSS存储空间(Bucket),用于存储训练数据和训练获得的模型文件。关于如何创建存储空间,详情请参见控制台创建存储空间

  • 如果您使用RDS数据库,则需要配置包含公网访问的专有网络,进行数据库连接用于生成SQL可执行性的验证。如何创建专有网络,请参见创建和管理专有网络。如何配置公网访问,请参见NAT网关

使用限制

仅支持在华北6(乌兰察布)地域,使用以下灵骏智算资源,基于PAI-DLCQwen2-72B大模型进行批量数据生成:

  • ml.gu7xf.8xlarge-gu108

  • ml.gu8xf.8xlarge-gu108

准备数据集

支持使用以下两种方式准备训练数据,本方案以方式二为例,为您介绍如何准备训练数据:

数据准备策略

为了提升训练的有效性和稳定性,您可以参考以下策略准备相关数据:

  • 数据库DDL优化

    • 尽量减少表中存在歧义的字段,并对所有字段添加详细的文本说明。

    • 测试模型在处理最多3个表格、包含20列左右的场景时,准确率较优。

    示例数据如下:

    正确示例

    CREATE TABLE `orders` (
      `Row ID` int(11) DEFAULT NULL COMMENT '行的唯一标识符',
      `Order ID` varchar(14) DEFAULT NULL COMMENT '订单的唯一标识符',
      `Order Date` date DEFAULT NULL COMMENT '下单日期',
      `Ship Date` date DEFAULT NULL COMMENT '发货日期',
      `Ship Mode` varchar(15) DEFAULT NULL COMMENT '发货方式',
      `Customer ID` varchar(8) DEFAULT NULL COMMENT '客户的唯一标识符',
      `Customer Name` varchar(25) DEFAULT NULL COMMENT '客户的名字',
      `Segment` varchar(15) DEFAULT NULL COMMENT '客户所属的市场细分',
      `Country` varchar(15) DEFAULT NULL COMMENT '订单发货国家的名称',
      `City` varchar(17) DEFAULT NULL COMMENT '订单发货城市的名称',
      `State` varchar(20) DEFAULT NULL COMMENT '订单发货州的名称',
      `Postal Code` int(11) DEFAULT NULL COMMENT '发货地址的邮政编码',
      `Region` varchar(10) DEFAULT NULL COMMENT '订单发货的地区',
      `Product ID` varchar(15) DEFAULT NULL COMMENT '产品的唯一标识符',
      `Category` varchar(15) DEFAULT NULL COMMENT '产品的高级别类别',
      `Sub-Category` varchar(11) DEFAULT NULL COMMENT '产品的子类别',
      `Product Name` varchar(128) DEFAULT NULL COMMENT '产品的名称',
      `Sales` double DEFAULT NULL COMMENT '订单折扣后的总销售额',
      `Quantity` int(11) DEFAULT NULL COMMENT '订购的商品数量',
      `Discount` double DEFAULT NULL COMMENT '订单的折扣',
      `Profit` double DEFAULT NULL COMMENT '订单产生的利润'
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

    错误示例

    CREATE TABLE `orders` (
      `Row ID` int(11) DEFAULT NULL,
      `Order ID` varchar(14) DEFAULT NULL,
      `Order Date` date DEFAULT NULL,
      `Ship Date` date DEFAULT NULL,
      `Ship Mode` varchar(15) DEFAULT NULL,
      `Customer ID` varchar(8) DEFAULT NULL,
      `Customer Name` varchar(25) DEFAULT NULL,
      `Segment` varchar(15) DEFAULT NULL,
      `Country` varchar(15) DEFAULT NULL,
      `City` varchar(17) DEFAULT NULL,
      `State` varchar(20) DEFAULT NULL,
      `Postal Code` int(11) DEFAULT NULL,
      `Region` varchar(10) DEFAULT NULL,
      `Product ID` varchar(15) DEFAULT NULL,
      `Category` varchar(15) DEFAULT NULL,
      `Sub-Category` varchar(11) DEFAULT NULL,
      `Product Name` varchar(128) DEFAULT NULL,
      `Sales` double DEFAULT NULL,
      `Quantity` int(11) DEFAULT NULL,
      `Discount` double DEFAULT NULL,
      `Profit` double DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  • 训练数据集问题尽量涵盖所有实际使用字段,推荐数据集至少包含2000条数据,当模型微调效果不佳时,您可以考虑增加标注数据量。

  • 问题描述需要尽可能丰富问法和场景。

数据格式要求

训练数据接受JSON格式输入,每条数据包括如下字段:

  • "id":序号。

  • "conversations":对话内容。包括"human"和"gpt"字段,分别表示用户的问题和模型输出。

  • "system":工具列表。包含该数据库场景的DDL。

具体示例如下所示:

[
  {
    "id": 0,
    "conversations": [
      {
        "from": "human",
        "value": "返回“PVLDB”的主页。\n"
      },
      {
        "from": "gpt",
        "value": "```sql\nSELECT homepage FROM journal WHERE name  =  \"PVLDB\"\n```\n"
      }
    ],
    "system": "你是一个sql助手,根据用户的问题生成sql。给定以下数据库信息:\n```sql\nCREATE TABLE IF NOT EXISTS author(\naid BIGINT COMMENT '作者ID',\nhomepage STRING COMMENT '作者主页',\nname STRING COMMENT '作者名字',\noid BIGINT COMMENT '组织ID'\n);\nCREATE TABLE IF NOT EXISTS conference(\ncid BIGINT COMMENT '会议ID',\nhomepage STRING COMMENT '会议主页',\nname STRING COMMENT '会议名称'\n);\nCREATE TABLE IF NOT EXISTS domain(\ndid BIGINT COMMENT '领域ID',\nname STRING COMMENT '领域名称'\n);\nCREATE TABLE IF NOT EXISTS domain_author(\naid BIGINT COMMENT '作者ID',\ndid BIGINT COMMENT '领域ID'\n);\nCREATE TABLE IF NOT EXISTS domain_conference(\ncid BIGINT COMMENT '会议ID',\ndid BIGINT COMMENT '领域ID'\n);\nCREATE TABLE IF NOT EXISTS journal(\nhomepage STRING COMMENT '期刊主页',\njid BIGINT COMMENT '期刊ID',\nname STRING COMMENT '期刊名称'\n);\nCREATE TABLE IF NOT EXISTS domain_journal(\ndid BIGINT COMMENT '领域ID',\njid BIGINT COMMENT '期刊ID'\n);\nCREATE TABLE IF NOT EXISTS keyword(\nkeyword STRING COMMENT '关键词',\nkid BIGINT COMMENT '关键词ID'\n);\nCREATE TABLE IF NOT EXISTS domain_keyword(\ndid BIGINT COMMENT '领域ID',\nkid BIGINT COMMENT '关键词ID'\n);\nCREATE TABLE IF NOT EXISTS publication(\nabstract STRING COMMENT '摘要',\ncitation_num BIGINT COMMENT '引用数',\njid BIGINT COMMENT '期刊ID',\npid BIGINT COMMENT '论文ID',\nreference_num BIGINT COMMENT '参考论文数',\ntitle STRING COMMENT '论文标题',\nyear BIGINT COMMENT '年份'\n);\nCREATE TABLE IF NOT EXISTS domain_publication(\ndid BIGINT COMMENT '领域ID',\npid BIGINT COMMENT '论文ID'\n);\nCREATE TABLE IF NOT EXISTS organization(\ncontinent STRING COMMENT '作者所在大陆',\nhomepage STRING COMMENT '组织主页',\noid BIGINT COMMENT '组织ID'\n);\nCREATE TABLE IF NOT EXISTS publication_keyword(\npid BIGINT COMMENT '论文ID',\nkid BIGINT COMMENT '关键词ID'\n);\nCREATE TABLE IF NOT EXISTS writes(\naid BIGINT COMMENT '作者ID',\npid BIGINT COMMENT '论文ID'\n);\nCREATE TABLE IF NOT EXISTS cite(\ncited BIGINT COMMENT '被引用论文ID',\nciting BIGINT COMMENT '引用论文ID'\n);\n```\n"
  }
]

批量训练数据生成

具体操作步骤如下:

  1. 创建云数据库RDS实例和数据库(本方案以RDS MySQL为例,您也可以使用自己的数据库产品),用于生产SQL的可执行性验证。具体操作,请参见RDS-MySQL使用流程

  2. 配置MySQL数据库,您需要尽量完善当前场景中的表字段说明。您可以在MySQL命令行中,执行如下命令快速导入数据库文件(example_superstore.sql)。如何连接MySQL数据库,请参见通过命令行、客户端连接RDS MySQL实例

    create database superstore;
    use superstore;
    source example_superstore.sql;
  3. 准备示例问题文件和证据文件。

    • 示例问题文件(few_shot_example.json):包含querycolumns两个字段。其中:

      • query:代表与当前数据库相关的示例问题。

      • columns:代表与该问题相关的列名。

      准备3-5个示例问题,列名个数从易到难在1-3个之间,示例问题文件示例内容如下所示:

      [
          {
              "query": "总销售额是多少",
              "columns": [
                  "Sales"
              ]
          },
          {
              "query": "不同城市的销售额是多少",
              "columns": [
                  "City",
                  "Sales"
              ]
          },
          {
              "query": "2016年每个月总销售额是多少",
              "columns": [
                  "Order Date",
                  "Sales"
              ]
          },
          {
              "query": "2016年每个月总销售额是多少,按发货时间算, 并按地区统计",
              "columns": [
                  "Profit",
                  "Ship Date",
                  "Region"
              ]
          }
      ]
    • 证据文件(evidence_example.json):包含需要在生成数据prompt中进行描述的列名,其中包含如下三个字段:

      • table:列名所在的表名。

      • column:代表列名。

      • type:代表列名的类型。对于不同的type类型,在数据增广prompt中会产生额外描述。type类型如下表所示:

        type

        说明

        data_column

        代表时间类型,指定后会产生该示例描述:这一列代表日期,日期的范围是XXXXXX。

        enum_column

        代表需要进行枚举的类型,指定后会产生该示例描述:这一列的值是枚举值,可以使用的枚举值为[XXX, XXX, XXX]。

        skip_column

        表示与业务无关的列名,指定后不会生成与该列相关的问题。

      证据文件示例内容如下所示:

      [
          {
              "table": "orders",
              "type": "date_column",
              "column": "Order Date"
          },
          {
              "table": "orders",
              "type": "date_column",
              "column": "Ship Date"
          },
          {
              "table": "orders",
              "type": "enum_column",
              "column": "Ship Mode"
          },
          {
              "table": "orders",
              "type": "enum_column",
              "column": "Segment"
          },
          {
              "table": "orders",
              "type": "enum_column",
              "column": "Region"
          },
          {
              "table": "orders",
              "type": "enum_column",
              "column": "Country"
          },
          {
              "table": "orders",
              "type": "enum_column",
              "column": "Sub-Category"
          },
          {
              "table": "orders",
              "type": "enum_column",
              "column": "Category"
          },
          {
              "table": "orders",
              "type": "skip_column",
              "column": "Row ID"
          }
      ]
  4. 将示例问题文件和证据文件上传到已创建的OSS Bucket存储空间,详情请参见步骤三:上传文件。文件上传的示例路径如下:

    • 示例问题文件:oss://example-bucket/simplebi/few_shot_example.json

    • 证据文件:oss://example-bucket/simplebi/evidence_example.json

  5. 使用PAI-DLC批量生产数据。

    创建分布式训练(DLC)任务,并配置以下关键参数,其他参数配置说明,请参见创建训练任务

    参数

    描述

    基本信息

    任务名称

    自定义配置任务名称。

    环境信息

    节点镜像

    单击镜像地址,并在文本框中输入镜像dsw-registry-vpc.<region>.cr.aliyuncs.com/pai-training-algorithm/llm_deepspeed_llamafactory:v0.0.3。其中<region>需要根据实际地域进行调整,例如华北6(乌兰察布)配置为cn-wulanchabu。

    挂载配置

    单击添加,将示例问题文件和证据文件所在目录挂载到训练容器中。挂载类型选择对象存储(OSS),并配置以下参数:

    • OSS:选择示例问题文件和证据文件所在的OSS路径。例如oss://example-bucket/。

    • 挂载路径:配置为/mnt/data。

    启动命令

    在代码编辑框中配置如下启动命令:

    python -m simplebi.data_augmentation.data_generate \
    --generate_number 10000 \
    --processes_number 40 \
    --fewshot_query_filepath /mnt/data/simplebi/few_shot_example.json \
    --evidence_filepath /mnt/data/simplebi/evidence_example.json \
    --output_filepath /mnt/data/simplebi/qwen2_72b_1000.json \
    --host rm-******o.mysql.rds.aliyuncs.com \
    --port 3306 \
    --user Simple**** \
    --database supers**** \
    --passwd SimpleB**** \
    --dtype bfloat16 \
    --max_model_len 8192 \
    --tensor_parallel_size 8 \
    --query_temperature 0.8 \
    --sql_temperature 0.2 \
    --max_tokens 1024

    参数配置说明,请参见启动参数说明

    资源信息

    资源类型

    选择灵骏智算

    资源来源

    选择竞价资源

    任务资源

    单击image选择资源规格:ml.gu7xf.8xlarge-gu108ml.gu8xf.8xlarge-gu108,并配置最高出价。

    专有网络配置

    专有网络配置(ID)

    选择已配置公网访问的VPC网络。如何配置公网访问,请参见NAT网关

    交换机

    安全组

    选择安全组。

    启动参数说明

    参数

    描述

    generate_number

    生成的问题和SQL对条数。

    processes_number

    同时进行数据生成进程数。

    fewshot_query_filepath

    示例问题文件挂载到容器中的路径。例如:/mnt/data/simplebi/few_shot_example.json。

    evidence_filepath

    证据文件挂载到容器中的路径。例如:/mnt/data/simplebi/evidence_example.json

    output_filepath

    生成数据文件路径,同时会生成_llamafactory后缀的JSON文件,该文件可直接用于后续训练。

    host

    RDS数据库的公网地址。如何获取,请参见通过客户端、命令行连接RDS MySQL实例

    port

    RDS数据库的连接端口。如何获取,请参见通过客户端、命令行连接RDS MySQL实例

    user

    RDS数据库的连接用户名。如何获取,请参见通过客户端、命令行连接RDS MySQL实例

    database

    RDS数据库的连接数据库名称。

    passwd

    RDS数据库的连接密码。如何获取,请参见通过客户端、命令行连接RDS MySQL实例

    tensor_parallel_size

    模型张量并行大小。

    query_temperature

    生成问题时使用的采样温度。

    sql_temperature

    生成SQL时使用的采样温度。

    max_tokens

    最大生成长度。

训练模型

快速开始汇集了优秀的国内外AI开源社区预训练模型。您可以在快速开始>Model Gallery中,实现从训练到部署再至推理的完整流程,无需编写代码,极大简化了模型的开发过程。

本方案以CodeQwen1.5-7b-NL2SQL模型为例,为您介绍如何使用已准备好的训练数据,在快速开始中进行模型训练。具体操作步骤如下:

  1. 进入Model Gallery页面。

    1. 登录PAI控制台

    2. 在顶部左上角根据实际情况选择地域。

    3. 在左侧导航栏选择工作空间列表,单击指定工作空间名称,进入对应工作空间内。

    4. 在左侧导航栏选择快速开始 > Model Gallery

  2. Model Gallery页面右侧的模型列表中,搜索并单击CodeQwen1.5-7b-NL2SQL模型卡片,进入模型详情页面。

  3. 在模型详情页面,单击右上角的微调训练,并在微调训练配置面板中,配置以下关键参数。

    参数

    描述

    训练方式

    支持以下两种训练方式,具体说明如下:

    • QLoRA:QLoRA训练属于高效训练的一种,会在固定并量化模型本身参数的基础上,仅对自注意力权重矩阵进行低秩分解,并更新低秩矩阵参数。该训练方法训练时间短,但效果可能会略差于LoRA。

    • LoRA:LoRA训练属于高效训练的一种,会在固定模型本身参数的基础上,仅对自注意力权重矩阵进行低秩分解,并更新低秩矩阵参数。

    数据集配置

    训练数据集

    参照以下操作步骤,选择已准备好的训练数据集。

    1. 在下拉列表中选择OSS文件或目录

    2. 单击image按钮,选择已创建的OSS目录。

    3. 选择OSS文件对话框中,单击上传文件,拖拽上传已准备好的训练数据集文件(示例文件:qwen2_72b_10000_llamafactory.json),并单击确定

      说明

      如果出现“数据解析失败,请检查文件内容格式”字样,请忽略,不影响您执行后续操作。

    训练输出配置

    模型名称

    注册到AI资产管理>模型中的模型名称。按照控制台界面提示自定义配置。

    模型输出路径

    选择OSS目录,用来存放训练输出的配置文件。

    计算资源配置

    资源组类型

    选择公共资源组(按量付费)

    任务资源

    系统已默认配置了资源规格,您也可以根据需要进行修改:

    • 当训练方式选择QLoRA时:最低使用V100/P100/T4(16 GB显存)及以上卡型。

    • 当训练方式选择LoRA时:最低使用V100(32 GB显存)/A10及以上卡型。

    超参数配置

    训练算法支持的超参信息,请参见1.全量超参数说明。针对不同的训练方式,关键超参数推荐配置,请参见2.超参数推荐配置

    1.全量超参数说明

    超参数

    类型

    是否必选

    含义

    默认值

    learning_rate

    FLOAT

    学习率,用于控制模型权重调整幅度。

    3e-4

    num_train_epochs

    INT

    训练数据集被重复使用的次数。

    1

    per_device_train_batch_size

    INT

    每个GPU在一次训练迭代中处理的样本数量。较大的批次大小可以提高效率,也会增加显存的需求。

    1

    seq_length

    INT

    序列长度,指模型在一次训练中处理的输入数据的长度。

    1024

    lora_dim

    INT

    LoRA维度,当lora_dim>0时,使用LoRAQLoRA轻量化训练。

    64

    lora_alpha

    INT

    LoRA权重,当lora_dim>0时,使用LoRAQLoRA轻量化训练,该参数生效。

    32

    load_in_4bit

    BOOL

    模型是否以4 bit加载。

    lora_dim>0、load_in_4bittrueload_in_8bitfalse时,使用4 bit QLoRA轻量化训练。

    true

    load_in_8bit

    BOOL

    模型是否以8比特加载。

    lora_dim>0、load_in_4bitfalseload_in_8bittrue时,使用8 bit QLoRA轻量化训练。

    false

    gradient_accumulation_steps

    INT

    梯度累积步骤数。

    8

    template

    STRING

    模型使用的prompt拼接模板,该示例使用qwen模板。

    qwen

    2.超参数推荐配置

    参数

    全参数微调

    LoRA/QLoRA

    learning_rate

    5e-6、5e-5

    3e-4

    全局批次大小

    128

    128

    seq_length

    1024

    1024

    num_train_epochs

    2、3

    2、3

    lora_dim

    0

    32、64

    lora_alpha

    0

    32

    load_in_4bit

    False

    True/False

    load_in_8bit

    False

    True/False

  4. 参数配置完成后,单击训练,然后在计费提醒对话框中,单击确定

    系统自动跳转到训练任务详情页面,训练任务启动成功,您可以在该页面查看训练任务状态和任务日志。

部署及调用模型服务

部署模型服务

模型训练成功后,即可部署模型服务。PAI预置了模型的部署配置信息,您仅需提供推理服务的名称以及部署配置使用的资源信息,即可将训练获得的模型部署到模型在线服务(EAS)平台。具体操作步骤如下:

  1. 任务详情页面,单击右上角的部署

  2. 部署配置面板中,系统已默认配置了模型服务信息和资源部署信息,您也可以根据需要进行修改,参数配置完成后,单击部署

  3. 计费提醒对话框中,单击确定

    系统将自动跳转到部署任务页面,当状态运行中时,表示服务部署成功。

调用模型服务

当模型服务部署成功后,您可以按照以下操作步骤调用模型服务:

  1. 查询服务访问地址和Token。

    1. 部署任务页面,单击服务名称,进入服务详情页面。

    2. 基本信息区域,单击查看调用信息

    3. 调用信息对话框的公网地址调用页签,查看访问地址Tokenimage

  2. 本方案是API方式的模型服务部署,您可以在终端中执行如下Python代码,使用OpenAPISDK调用模型服务。

    from openai import OpenAI
    
    client = OpenAI(
        base_url="<eas_service_path>/v1",
        api_key="<eas_service_token>",
    )
    
    chat_completion = client.chat.completions.create(
        model="/model_dir",
        messages=[
            {"role": "system", "content": "你是一个sql助手,根据用户的问题生成sql,参考如下ddl:\nCREATE TABLE `orders` (\n  `Row ID` int DEFAULT NULL COMMENT '行的唯一标识符',\n  `Order ID` varchar(14) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '订单的唯一标识符',\n  `Order Date` date DEFAULT NULL COMMENT '下单日期',\n  `Ship Date` date DEFAULT NULL COMMENT '发货日期',\n  `Ship Mode` varchar(15) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '发货方式',\n  `Customer ID` varchar(8) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '客户的唯一标识符',\n  `Customer Name` varchar(25) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '客户的名字',\n  `Segment` varchar(15) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '客户所属的市场细分',\n  `Country` varchar(15) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '客户所在国家的名称',\n  `City` varchar(17) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '客户所在城市的名称',\n  `State` varchar(20) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '客户所在州的名称',\n  `Postal Code` int DEFAULT NULL COMMENT '客户地址的邮政编码',\n  `Region` varchar(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '客户所在的地区',\n  `Product ID` varchar(15) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '产品的唯一标识符',\n  `Category` varchar(15) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '产品的高级别类别',\n  `Sub-Category` varchar(11) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '产品的子类别',\n  `Product Name` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '产品的名称',\n  `Sales` double DEFAULT NULL COMMENT '订单折扣后的总销售额',\n  `Quantity` int DEFAULT NULL COMMENT '订购的商品数量',\n  `Discount` double DEFAULT NULL COMMENT '订单的折扣',\n  `Profit` double DEFAULT NULL COMMENT '订单产生的利润'\n) ENGINE=InnoDB DEFAULT CHARSET=latin1\nCREATE TABLE `people` (\n  `Person` varchar(20) DEFAULT NULL,\n  `Region` varchar(10) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=latin1\nCREATE TABLE `returns` (\n  `Returned` varchar(3) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '订单是否被退单',\n  `Order ID` varchar(15) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '订单的唯一标识符'\n) ENGINE=InnoDB DEFAULT CHARSET=latin1,回答sql查询问题"},
            {"role": "user", "content": "在2016年,每个月各类产品的订单数量是多少?"}
            ],
    )
    
    print(chat_completion.choices)

    其中:

    • <eas_service_path>:替换为上述步骤已查询的服务访问地址。

    • <eas_service_token>:替换为上述步骤已查询的服务Token。

    调用成功后,返回结果示例如下,您的结果以实际为准:

    [Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content="在2016年,我们可以通过以下SQL查询获取每个月各类产品的订单数量:\n\n```sql\nSELECT \n    DATE_FORMAT(`Order Date`, '%Y-%m') AS YearMonth,\n    `Category`,\n    COUNT(*) AS OrderCount\nFROM \n    orders\nWHERE \n    YEAR(`Order Date`) = 2016\nGROUP BY \n    YearMonth,\n    `Category`;\n```\n\n这个查询首先通过DATE_FORMAT函数将订单日期格式化为年月(YYYY-MM),然后按照年月和类别进行分组,最后计算每个月各类产品的订单数量。", role='assistant', function_call=None, tool_calls=None), stop_reason=None)]
  3. 服务调用成功后,您可在终端中执行如下Python代码,基于RDS-MySQL验证模型生成SQL。

    import re
    import pymysql
    
    
    def parse(text):
        pattern = r"```sql\n(.*?)\n```"
        matches = re.findall(pattern, text, re.DOTALL)
        if matches:
            sql_content = matches[0].strip()
            if not sql_content.endswith(";"):
                sql_content += ";"
            return sql_content
        else:
            if not text.endswith(";"):
                text += ";"
            return text
    
    
    def excute_sql(input_text: str) -> tuple:
        sql = parse(input_text)
        cursor = db.cursor()
        try:
            cursor.execute(sql)
            col = cursor.description
            sql_data = cursor.fetchall()
            return sql_data
        except Exception as e:
            return "error"
    
    
    db = pymysql.connect(
        host="数据库连接",
        user="数据库用户名",
        passwd="数据库密码",
        port=3306,
        db="数据库名称",
    )
    
    print(
        excute_sql(
            "填写模型输出文本"
        )
    )
    

    其中关键配置说明如下:

    关键配置

    描述

    host

    配置为RDS数据库的公网地址。

    user

    配置为RDS数据库的连接用户名。

    passwd

    配置为RDS数据库的连接密码。

    port

    配置为RDS数据库的连接端口。

    db

    配置为RDS数据库的连接数据库名称。

    excute_sql

    将文本内容配置为步骤2调用服务返回结果中的content字段内容。