当前位置: 首页 > news >正文

大语言模型应用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入门程序&#xff0c;我们基于这个程序来对VTK的基本知识进行一个初步了解。 #include <iostream>#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2 VTK_MODULE_INI…...

PyQt5快速开发与实战

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

SpringBoot 开源停车场管理收费系统

一、下载项目文件 下载源码项目文件口令&#xff1a; 【前端小程序地址】(3.0)&#xff1a;伏脂火器白泽知洞座/~6f8d356LNL~:/【后台管理地址】(3.0)&#xff1a;伏脂火器仇恨篆洞座/~0f4a356Ks2~:/【岗亭端地址】(3.0)&#xff1a;动作火器智汇堂多好/~dd69356K6r~:/复制口令…...

cmake: error while loading shared libraries: libssl.so.1.1

在ubuntu22.04中编译c文件时出现如下错误&#xff1a; cmake: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory 解决办法&#xff1a;1.进网站下载对应的.deb文件&#xff0c;链接为&#xff1a;https://sec…...

部署loki,grafana 以及springcloud用法举例

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

后端-编辑按钮的实现

编辑一共要实现两步&#xff1a; 1.点击编辑蹦出来一个弹窗&#xff0c;此时需要回显&#xff0c;根据id查出来这条数据 2.修改某些值之后点击保存的时候调用修改的接口 根据id查询的时候正常操作 修改值的时候要注意一些问题 mapper层的Employee和impl层的接收实体不一样...

uniapp中的@tap与@click:点击事件的微妙差异

在uniapp的开发过程中&#xff0c;我们经常会遇到两种点击事件&#xff1a;tap和click。虽然它们都是点击事件&#xff0c;但在实际使用中却存在一些微妙的差异。本文将详细解析这两种事件的区别&#xff0c;帮助开发者更好地理解和应用。 首先&#xff0c;让我们来看看它们的…...

Uniapp的vue、nvue、uvue后缀名区别

在 UniApp 中&#xff0c;.vue、.nvue 和 .uvue 是不同的文件后缀名&#xff0c;每个文件格式的使用场景和兼容性略有不同。下面是每个文件后缀的详细解释以及它们的兼容性&#xff1a; 1. .vue 文件 定义&#xff1a;.vue 是标准的 Vue 单文件组件格式&#xff0c;主要用于基…...

完美解决Qt Qml窗口全屏软键盘遮挡不显示

1、前提 说明&#xff1a;我使用的是第三方软键盘 QVirtualKeyboard QVirtualKeyboard: Qt5虚拟键盘支持中英文,仿qt官方的virtualkeyboard模块,但使用QWidget实现。 - Gitee.com 由于参考了几篇文章尝试但没有效果&#xff0c;链接如下&#xff1a; 文章一&#xff1a;可能…...

寄存器、缓存、内存三者关系

寄存器、缓存、内存三者关系&#xff1a; 按与CPU远近来分&#xff0c;离得最近的是寄存器&#xff0c;然后缓存(CPU缓存)&#xff0c;最后内存。CPU计算时&#xff0c;先预先把要用的数据从硬盘读到内存&#xff0c;然后再把即将要用的数据读到寄存器。于是 CPU<--->…...

九、RNN的变体

RNN的变体 前言一、长短期记忆网络&#xff08;LSTM&#xff09;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高级面试中&#xff0c;选择垃圾收集器&#xff08;Garbage Collector&#xff0c;GC&#xff09;是一个重要且常见的议题。选择合适的垃圾收集器对于优化应用程序的性能至关重要。以下是对如何…...

棋牌游戏项目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期的论文的题目和摘要&#xff0c;一共包括18篇SCI论文&#xff01; 论文1 A new kind of search 一种新型的搜索 【摘要】 ChatGPT (2022) was first launched o…...

前端知识1html

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

Vue03

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

深入浅出:Gin框架路由与HTTP请求处理

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

C++初阶——模板初阶

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

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...