大语言模型应用Text2SQL本地部署实践初探
自从两年前OpenAI公司发布ChatGPT后,大模型(Large Language Model,简称LLM)相关技术在国内外可谓百家争鸣,遍地开花,在传统数据挖掘、机器学习和深度学习的基础上,正式宣告进入快速发展的人工智能(Artificial Intelligence,简称AI)2.0时代。
人工智能的本质上是基于海量数据(包括结构化数据,文本数据,图片数据,音频数据,视频数据等)不断学习和推理,去模仿人类思考、认知、决策和行动。
我在项目实施工作中,跟数据打交道很多,主要是传统的数据建模和分析,基本都是基于商业产品,比如SAP,Qlik,帆软,永洪等;或者是基于公司的自研产品,大体功能类似但二次开发比较容易。由于这种壁垒,对机器学习和大模型了解甚少,基本停留在了解一些基本概念和关注一些技术新闻方面。最近几年的项目上重复遇到过一些困扰我好久的问题,项目范围内的数据模型搭完后,对数据比较依赖的部门比如财务,审计等会不断涌现出新的数据需求,如何让业务部门的用户快速获取和分析数据为日常工作提供决策支持是一个痛点,以往的大宽表模型和自助式BI分析解决方案不太理想,而学习数据建模由于太过技术性往往让用户望而却步。
最近通过在B站学习了一些优秀up主的大模型讲解视频,以及阅读了一些技术大拿的博文,受益匪浅。通过了解Text2SQL,帮我开拓了思路,似乎让我找到了解决以上痛点问题的契机。
Text2SQL也叫NL2SQL(Natural Language To SQL),是一种自然语言生成技术(文字->代码->结果),通过将人类用自然语言提出的数据问题(Text),转化为结构化查询语言(Structured Query Language,简称SQL)代码,然后自动执行生成的代码实现人类和数据的直接对话,持续提升数据分析效率。
Text2SQL实现的技术路线有很多,本篇主要讲述了基于阿里巴巴开源大模型Qwen,开源框架Vanna,以及Ollama,Mysql,Python3等技术栈的组合来部署实践。由于考虑到企业级数据的安全性,所有组件都是本地化部署,内网可以直接使用。虽然还没延伸考虑数据权限、SQL准确性、复杂场景实现等面临的挑战,但先迈出第一步等于成功了一半,不断学习不断进步,像LLM一样:)
以下是部署实践的步骤:
1. 准备一个linux虚拟机作为服务器。
我电脑是win11+vmware+centos7.6+Xshell,这里的安装略过,可自行网上搜索教程,安装后的效果:
如果装完的OS是图形化启动,可以通过如下命令设置为命令行启动,节省硬件资源:
systemctl set-default multi-user.target
再通过ifconfig查看ip:
获取到ip后就可以通过Xshell远程连系统了:
2. 安装Python3.11环境。
开源框架Vanna是基于Python的,我们通过Miniconda来安装Python3.11。
下载conda安装脚本:
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
安装:bash Miniconda3-latest-Linux-x86_64.sh
这里输入yes:
使环境变量生效后查看conda版本验证是否安装OK:
source ~/.bashrc
conda --version
安装python3.11
conda create -n py311 python=3.11
激活Python3环境,并查看版本:
conda activate py311
python -V
3. 安装Ollama。
Ollama是开源大模型的管理运行工具,支持很多国内外开源的大模型,包括我们这次要用的qwen2.5.
安装命令:
curl -fsSL https://ollama.com/install.sh | sh
4. 安装大模型。
安装好后通过ollama -v看下版本,考虑到笔记本性能,选择本地安装qwen2.5:3b版本的开源大模型,3b表示3billon也即30亿个模型参数。
qwen2.5:3b
ollama run qwen2.5:3b
安装完后,就可以直接run模型,和模型对话:
5. 安装mysql并模拟准备企业数据。
Mysql的安装此处略过,可以网上搜索教程。我安装的是mysql8.0+客户端工具Dbeaver:
创建一个vanna的数据库并准备三张表:
DDL和写数脚本如下:
CREATE DATABASE `vanna` /*!40100 DEFAULT CHARACTER SET utf16 */ /*!80016 DEFAULT ENCRYPTION='N' */;
-- vanna.DEPT definition
CREATE TABLE `DEPT` (
`DEPTNO` int NOT NULL COMMENT '部门编号',
`DNAME` varchar(14) DEFAULT NULL COMMENT '部门名称',
`LOC` varchar(13) DEFAULT NULL COMMENT '部门地址',
PRIMARY KEY (`DEPTNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf16 COMMENT='部门';
-- vanna.SALGRADE definition
CREATE TABLE `SALGRADE` (
`GRADE` int DEFAULT NULL COMMENT '工资等级',
`LOSAL` double DEFAULT NULL COMMENT '最低工资',
`HISAL` double DEFAULT NULL COMMENT '最高工资'
) ENGINE=InnoDB DEFAULT CHARSET=utf16 COMMENT='工资等级';
-- vanna.EMP definition
CREATE TABLE `EMP` (
`EMPNO` int NOT NULL COMMENT '员工编号',
`ENAME` varchar(10) DEFAULT NULL COMMENT '员工名称',
`JOB` varchar(9) DEFAULT NULL COMMENT '工作',
`MGR` double DEFAULT NULL COMMENT '直属领导编号',
`HIREDATE` date DEFAULT NULL COMMENT '入职时间',
`SAL` double DEFAULT NULL COMMENT '工资',
`COMM` double DEFAULT NULL COMMENT '奖金',
`DEPTNO` int DEFAULT NULL COMMENT '部门编号',
PRIMARY KEY (`EMPNO`),
KEY `DEPTNO` (`DEPTNO`),
CONSTRAINT `EMP_ibfk_1` FOREIGN KEY (`DEPTNO`) REFERENCES `DEPT` (`DEPTNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf16 COMMENT='员工';
INSERT INTO vanna.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES
(7369,'SMITH','CLERK',7902.0,'1980-12-17',800.0,NULL,20),
(7499,'ALLEN','SALESMAN',7698.0,'1981-02-20',1600.0,300.0,30),
(7521,'WARD','SALESMAN',7698.0,'1981-02-22',1250.0,500.0,30),
(7566,'JONES','MANAGER',7839.0,'1981-04-02',2975.0,NULL,20),
(7654,'MARTIN','SALESMAN',7698.0,'1981-09-28',1250.0,1400.0,30),
(7698,'BLAKE','MANAGER',7839.0,'1981-05-01',2850.0,NULL,30),
(7782,'CLARK','MANAGER',7839.0,'1981-06-09',2450.0,NULL,10),
(7788,'SCOTT','ANALYST',7566.0,'1987-07-13',3000.0,NULL,20),
(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000.0,NULL,10),
(7844,'TURNER','SALESMAN',7698.0,'1981-09-08',1500.0,0.0,30),
(7876,'ADAMS','CLERK',7788.0,'1987-07-13',1100.0,NULL,20),
(7900,'JAMES','CLERK',7698.0,'1981-12-03',950.0,NULL,30),
(7902,'FORD','ANALYST',7566.0,'1981-12-03',3000.0,NULL,20),
(7934,'MILLER','CLERK',7782.0,'1982-01-23',1300.0,NULL,10);
INSERT INTO vanna.SALGRADE (GRADE,LOSAL,HISAL) VALUES
(1,700.0,1200.0),
(2,1201.0,1400.0),
(3,1401.0,2000.0),
(4,2001.0,3000.0),
(5,3001.0,9999.0);
INSERT INTO vanna.DEPT (DEPTNO,DNAME,LOC) VALUES
(10,'ACCOUNTING','NEW YORK'),
(20,'RESEARCH','DALLAS'),
(30,'SALES','CHICAGO'),
(40,'OPERATIONS','BOSTON');
6. 安装Vanna。
参照Vanna的github指导:
https://github.com/vanna-ai/vanna
pip install vanna
安装完成后,根据官网介绍,如果使用在线大模型、向量数据库和数据库,几行代码就可以run起来,前提是需要vanna.ai网站申请api key.
https://vanna.ai/docs/app/
7. 安装开源向量数据库Chromadb。我们把向量数据库安装到本地,pip install即可,但是安装过程中会有一些问题,建议可以根据报错在在网上搜索答案。
8. 装PyCharm,远程连接虚拟机的Python环境。具体安装细节网上自行搜索,我电脑安装后的效果如下:
9. Python代码开发,连接qwen大模型,连接mysql,训练数据,启动vanna。
完整代码如下:
from vanna.ollama import Ollama
from vanna.chromadb import ChromaDB_VectorStore
import pandas as pd
import mysql.connector
from vanna.flask import VannaFlaskApp
class MyVanna(ChromaDB_VectorStore, Ollama):
def __init__(self, config=None):
ChromaDB_VectorStore.__init__(self, config=config)
Ollama.__init__(self, config=config)
#vn = MyVanna(config={'model': 'llama3.2:latest','ollama_host':'http://192.168.112.164:11434'})
vn = MyVanna(config={'model': 'qwen2.5:3b','ollama_host':'http://192.168.112.164:11434'})
def run_sql(sql: str) -> pd.DataFrame:
cnx = mysql.connector.connect(user='root', password='888888', host='192.168.112.164', database='vanna')
cursor = cnx.cursor()
cursor.execute(sql)
result = cursor.fetchall()
columns = cursor.column_names
#print('columns:',columns)
df = pd.DataFrame(result, columns=columns)
return df
vn.run_sql = run_sql
vn.run_sql_is_set = True
#给模型训练ddl语句
df_count = vn.run_sql("show tables")
for i in range(0,len(df_count)):
str = "show create table " + df_count['Tables_in_vanna'].loc[i]
df = vn.run_sql(str)
#print(df['Create Table'].loc[df.index[0]])
vn.train(ddl=df['Create Table'].loc[df.index[0]])
#执行web应用
VannaFlaskApp(vn,allow_llm_to_see_data=True).run()
10. 运行Vanna,测试Text2SQL功能:
可以看到控制台给出了运行的地址,这里的localhost换成虚拟机的ip即可访问:
在Training Data页签可以看到我们代码里添加的DDL训练数据加到向量数据库了。然后通过New Question来向数据库提问题:
由于笔记本性能问题,可能要运行一会才出答案,不得不说大模型也是很烧硬件的。
至此,Text2SQL的本地化部署和实践已完成。下一步有待继续探索真实案例和复杂场景的尝试。
相关文章:

大语言模型应用Text2SQL本地部署实践初探
自从两年前OpenAI公司发布ChatGPT后,大模型(Large Language Model,简称LLM)相关技术在国内外可谓百家争鸣,遍地开花,在传统数据挖掘、机器学习和深度学习的基础上,正式宣告进入快速发展的人工智能(Artificial Intellig…...

每日十题八股-2024年12月7日
1.说说hashmap的负载因子 2.Hashmap和Hashtable有什么不一样的?Hashmap一般怎么用? 3.ConcurrentHashMap怎么实现的? 4.分段锁怎么加锁的? 5.分段锁是可重入的吗? 6.已经用了synchronized,为什么还要用CAS呢…...

VTK编程指南<三>:基于VTK入门程序解析来理解VTK基础知识
1、VTK入门程序 下面是一个完整的Vtk入门程序,我们基于这个程序来对VTK的基本知识进行一个初步了解。 #include <iostream>#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2 VTK_MODULE_INI…...

PyQt5快速开发与实战
PyQt5快速开发与实战相关资源 PyQt5快速开发与实战配套代码资源获取 PyQt5快速开发与实战 第一个要跟大家分享的就是的《PyQt5快速开发与实战》。该书既涵盖了 PyQt5 的基础知识,又包含了实战应用技巧,对 PyQt5 的基本概念和技术细节进行了详细阐述&…...

SpringBoot 开源停车场管理收费系统
一、下载项目文件 下载源码项目文件口令: 【前端小程序地址】(3.0):伏脂火器白泽知洞座/~6f8d356LNL~:/【后台管理地址】(3.0):伏脂火器仇恨篆洞座/~0f4a356Ks2~:/【岗亭端地址】(3.0):动作火器智汇堂多好/~dd69356K6r~:/复制口令…...
cmake: error while loading shared libraries: libssl.so.1.1
在ubuntu22.04中编译c文件时出现如下错误: cmake: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory 解决办法:1.进网站下载对应的.deb文件,链接为:https://sec…...

部署loki,grafana 以及springcloud用法举例
文章目录 场景docker 部署grafanadocker-compose部署loki维护配置文件 local-config.yaml维护docker-compose.yml配置启动 grafana 添加loki数据源springcloud用法举例查看loki的explore,查看日志 场景 小公司缺少运维岗位,需要研发自己部署日志系统,elk…...

后端-编辑按钮的实现
编辑一共要实现两步: 1.点击编辑蹦出来一个弹窗,此时需要回显,根据id查出来这条数据 2.修改某些值之后点击保存的时候调用修改的接口 根据id查询的时候正常操作 修改值的时候要注意一些问题 mapper层的Employee和impl层的接收实体不一样...
uniapp中的@tap与@click:点击事件的微妙差异
在uniapp的开发过程中,我们经常会遇到两种点击事件:tap和click。虽然它们都是点击事件,但在实际使用中却存在一些微妙的差异。本文将详细解析这两种事件的区别,帮助开发者更好地理解和应用。 首先,让我们来看看它们的…...
Uniapp的vue、nvue、uvue后缀名区别
在 UniApp 中,.vue、.nvue 和 .uvue 是不同的文件后缀名,每个文件格式的使用场景和兼容性略有不同。下面是每个文件后缀的详细解释以及它们的兼容性: 1. .vue 文件 定义:.vue 是标准的 Vue 单文件组件格式,主要用于基…...

完美解决Qt Qml窗口全屏软键盘遮挡不显示
1、前提 说明:我使用的是第三方软键盘 QVirtualKeyboard QVirtualKeyboard: Qt5虚拟键盘支持中英文,仿qt官方的virtualkeyboard模块,但使用QWidget实现。 - Gitee.com 由于参考了几篇文章尝试但没有效果,链接如下: 文章一:可能…...
寄存器、缓存、内存三者关系
寄存器、缓存、内存三者关系: 按与CPU远近来分,离得最近的是寄存器,然后缓存(CPU缓存),最后内存。CPU计算时,先预先把要用的数据从硬盘读到内存,然后再把即将要用的数据读到寄存器。于是 CPU<--->…...

九、RNN的变体
RNN的变体 前言一、长短期记忆网络(LSTM)1.1 LSTM结构分析1.1.1 遗忘门1.1.1.1 遗忘门结构图与计算公式1.1.1.2 结构分析1.1.1.3 遗忘门的由来1.1.1.4 遗忘门的内部演示 1.1.2 输入门1.1.2.1 输入门结构图与计算公式1.1.2.2 结构分析1.1.2.3 输入门的内部…...
高级java每日一道面试题-2024年12月07日-JVM篇-如何选择垃圾收集器?
如果有遗漏,评论区告诉我进行补充 面试官: 如何选择垃圾收集器? 我回答: 在Java高级面试中,选择垃圾收集器(Garbage Collector,GC)是一个重要且常见的议题。选择合适的垃圾收集器对于优化应用程序的性能至关重要。以下是对如何…...

棋牌游戏项目ctrl + c无法退出进程问题
棋牌游戏项目ctrl c无法退出进程问题 运行的服务为 user , 启动命令为 cd user && go run main.go启动之前先加入调试语句 在 go func() { metric.Serve(...) } 打日志在 app.Run(...) 打日志 user/main.go var configFile flag.String("config", "…...

论文概览 |《Urban Analytics and City Science》2023.03 Vol.50 Issue.3
本次给大家整理的是《Environment and Planning B: Urban Analytics and City Science》杂志2023年3月第50卷第3期的论文的题目和摘要,一共包括18篇SCI论文! 论文1 A new kind of search 一种新型的搜索 【摘要】 ChatGPT (2022) was first launched o…...

前端知识1html
VScode一些快捷键 Ctrl/——注释 !——生成html框架元素 *n——生成n个标签 直接书写html的名字回车生成对应的标签 常见标签 span: <span style"color: red;">hello</span> <span>demo</span> span实现: 标题…...

Vue03
目录 一、今日目标 1.生命周期 2.综合案例-小黑记账清单 3.工程化开发入门 4.综合案例-小兔仙首页 二、Vue生命周期 三、Vue生命周期钩子 四、生命周期钩子小案例 1.在created中发送数据 六、工程化开发模式和脚手架 1.开发Vue的两种方式 2.Vue CLI脚手架 基本介绍…...

深入浅出:Gin框架路由与HTTP请求处理
深入浅出:Gin框架路由与HTTP请求处理 引言 在Web开发中,路由和HTTP请求处理是构建API的核心部分。Gin框架作为Go语言中最受欢迎的Web框架之一,提供了简洁而强大的工具来处理这些任务。本文将深入浅出地介绍如何使用Gin框架进行路由定义、处…...

C++初阶——模板初阶
目录 1、如何实现一个通用的交换函数 2、函数模板 2.1 函数模板的概念 2.2 函数模板的格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3、类模板 3.1 类模板的格式 3.2 类模板的实例化 1、如何实现一个通用的交换函数 void Swap(int& lef…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...