大语言模型应用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…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...