@@ -15,7 +15,7 @@ RUN pip install -r requirements.txt
|
||||
EXPOSE 3306
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["python", "pilot/server/vicuna_server.py"]
|
||||
CMD ["python", "pilot/server/llmserver.py"]
|
||||
CMD ["python", "pilot/server/webserver.py"]
|
||||
|
||||
|
||||
|
164
README.md
@@ -1,27 +1,30 @@
|
||||
# DB-GPT 
|
||||
|
||||
---
|
||||
|
||||
[English Edition](README.en.md)
|
||||
|
||||
专注于数据库垂直领域的 GPT 项目,提供大模型与数据的本地化使用方案,保障数据的隐私安全,适用企业内和个人。
|
||||
## 背景
|
||||
随着大模型的发布迭代,大模型变得越来越智能,在使用大模型的过程当中,遇到极大的数据安全与隐私挑战。在利用大模型能力的过程中我们的私密数据跟环境需要掌握自己的手里,完全可控,避免任何的数据隐私泄露以及安全风险。基于此,我们发起了DB-GPT项目,为所有以数据库为基础的场景,构建一套完整的私有大模型解决方案。 此方案因为支持本地部署,所以不仅仅可以应用于独立私有环境,而且还可以根据业务模块独立部署隔离,让大模型的能力绝对私有、安全、可控。
|
||||
|
||||
## 愿景
|
||||
DB-GPT 是一个开源的以数据库为基础的GPT实验项目,使用本地化的GPT大模型与您的数据和环境进行交互,无数据泄露风险,100% 私密,100% 安全。
|
||||
|
||||
## 特性一览
|
||||
|
||||
目前我们已经发布了多种关键的特性,这里一一列举展示一下当前发布的能力。
|
||||
- SQL 语言能力
|
||||
- SQL生成
|
||||
- SQL诊断
|
||||
- 私域问答与数据处理
|
||||
- 数据库知识问答
|
||||
- 数据处理
|
||||
|
||||
## 架构方案
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/DB-GPT.png" width="600px" />
|
||||
</p>
|
||||
|
||||
DB-GPT 基于[FastChat](https://github.com/lm-sys/FastChat) 构建大模型运行环境,并提供 vicuna 作为基础的大语言模型。此外,我们通过 langchain 和 llama-index 提供私域知识库问答能力。
|
||||
- 插件模型
|
||||
- 支持自定义插件执行任务,原生支持Auto-GPT插件。如:
|
||||
- SQL自动执行,获取查询结果
|
||||
- 自动爬取学习知识
|
||||
- 知识库统一向量存储/索引
|
||||
- 非结构化数据支持
|
||||
- PDF、MarkDown、CSV、WebURL
|
||||
|
||||
## 效果演示
|
||||
|
||||
@@ -32,15 +35,20 @@ DB-GPT 基于[FastChat](https://github.com/lm-sys/FastChat) 构建大模型运
|
||||
<img src="./assets/演示.gif" width="600px" />
|
||||
</p>
|
||||
|
||||
### SQL 生成
|
||||
|
||||
首先选择对应的数据库, 然后模型即可根据对应的数据库 Schema 信息生成 SQL。
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/SQLGEN.png" width="600px" />
|
||||
<img src="./assets/Auto-DB-GPT.gif" width="600px" />
|
||||
</p>
|
||||
|
||||
运行成功的效果如下面的演示:
|
||||
### SQL 生成
|
||||
|
||||
1. 生成建表语句
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/SQL_Gen_CreateTable.png" width="600px" />
|
||||
</p>
|
||||
|
||||
2. 生成可运行SQL
|
||||
首先选择对应的数据库, 然后模型即可根据对应的数据库 Schema 信息生成 SQL, 运行成功的效果如下面的演示:
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/exeable.png" width="600px" />
|
||||
@@ -52,44 +60,96 @@ DB-GPT 基于[FastChat](https://github.com/lm-sys/FastChat) 构建大模型运
|
||||
<img src="./assets/DB_QA.png" width="600px" />
|
||||
</p>
|
||||
|
||||
基于默认内置知识库。
|
||||
|
||||
# Dependencies
|
||||
1. First you need to install python requirements.
|
||||
```
|
||||
python>=3.10
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
or if you use conda envirenment, you can use this command
|
||||
```
|
||||
cd DB-GPT
|
||||
conda env create -f environment.yml
|
||||
1. 基于默认内置知识库问答
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/VectorDBQA.png" width="600px" />
|
||||
</p>
|
||||
|
||||
## 部署
|
||||
2. 自己新增知识库
|
||||
|
||||
### 1. 安装 Python
|
||||
<p align="center">
|
||||
<img src="./assets/new_knownledge.gif" width="600px" />
|
||||
</p>
|
||||
|
||||
```bash
|
||||
$ python>=3.10
|
||||
$ pip install -r requirements.txt
|
||||
3. 从网络自己爬取数据学习
|
||||
- TODO
|
||||
|
||||
## 架构方案
|
||||
DB-GPT基于[FastChat](https://github.com/lm-sys/FastChat) 构建大模型运行环境,并提供 vicuna 作为基础的大语言模型。此外,我们通过langchain提供私域知识库问答能力。同时我们支持插件模式, 在设计上原生支持Auto-GPT插件。
|
||||
|
||||
整个DB-GPT的架构,如下图所示
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/DB-GPT.png" width="600px" />
|
||||
</p>
|
||||
|
||||
核心能力主要有以下几个部分。
|
||||
1. 知识库能力
|
||||
2. 大模型管理能力
|
||||
3. 统一的数据向量化存储与索引
|
||||
4. 连接模块
|
||||
5. Agent与插件
|
||||
6. Prompt自动生成与优化
|
||||
7. 多端产品界面
|
||||
|
||||
下面对每个模块也做一些简要的介绍:
|
||||
|
||||
### 知识库能力
|
||||
知识库作为当前用户需求最大的场景,我们原生支持知识库的构建与处理。同时在本项目当中,也提供了多种知识库的管理策略。 如: 1. 默认内置知识库 2. 自定义新增知识库 3. 通过插件能力自抓取构建知识库等多种使用场景。 用户只需要整理好知识文档,即可用我们现有的能力构建大模型所需要的知识库能力。
|
||||
|
||||
### 大模型管理能力
|
||||
在底层大模型接入中,设计了开放的接口,支持对接多种大模型。同时对于接入模型的效果,我们有非常严格的把控与评审机制。对大模型能力上与ChatGPT对比,在准确率上需要满足85%以上的能力对齐。我们用更高的标准筛选模型,是期望在用户使用过程中,可以省去前面繁琐的测试评估环节。
|
||||
|
||||
### 统一的数据向量化存储与索引
|
||||
为了方便对知识向量化之后的管理,我们内置了多种向量存储引擎,从基于内存的Chroma到分布式的Milvus, 可以根据自己的场景需求,选择不同的存储引擎,整个知识向量存储是AI能力增强的基石,向量作为人与大语言模型交互的中间语言,在本项目中的作用非常重要。
|
||||
|
||||
### 连接模块
|
||||
为了能够更方便的与用户的私有环境进行交互,项目设计了连接模块,连接模块可以支持连接到数据库、Excel、知识库等等多种环境当中,实现信息与数据交互。
|
||||
|
||||
### Agent与插件
|
||||
Agent与插件能力是大模型能否自动化的核心,在本的项目中,原生支持插件模式,大模型可以自动化完成目标。 同时为了充分发挥社区的优势,本项目中所用的插件原生支持Auto-GPT插件生态,即Auto-GPT的插件可以直接在我们的项目中运行。
|
||||
|
||||
### Prompt自动生成与优化
|
||||
Prompt是与大模型交互过程中非常重要的部分,一定程度上Prompt决定了大模型生成答案的质量与准确性,在本的项目中,我们会根据用户输入与使用场景,自动优化对应的Prompt,让用户使用大语言模型变得更简单、更高效。
|
||||
|
||||
### 多端产品界面
|
||||
TODO: 在终端展示上,我们将提供多端产品界面。包括PC、手机、命令行、slack等多种模式。
|
||||
|
||||
|
||||
## 安装教程
|
||||
### 硬件说明
|
||||
因为我们的项目在效果上具备ChatGPT 85%以上的能力,因此对硬件有一定的要求。 但总体来说,我们在消费级的显卡上即可完成项目的部署使用,具体部署的硬件说明如下:
|
||||
```
|
||||
|
||||
或者直接使用 conda 环境
|
||||
|
||||
```bash
|
||||
$ conda env create -f environment.yml
|
||||
GPU型号 | 显存大小 | 性能
|
||||
-------|----------|------------------------------
|
||||
TRX4090| 24G |可以流畅的进行对话推理,无卡顿
|
||||
TRX3090| 24G |可以流畅进行对话推理,有卡顿感,但好与V100
|
||||
V100 | 16G |可以进行对话推理,有明显卡顿
|
||||
```
|
||||
|
||||
### 2. 安装 MySQL
|
||||
### DB-GPT安装
|
||||
|
||||
本项目依赖一个本地的 MySQL 数据库服务,你需要本地安装,推荐直接使用 Docker 安装。
|
||||
```
|
||||
docker run --name=mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=aa12345678 -dit mysql:latest
|
||||
```
|
||||
向量数据库我们默认使用的是Chroma内存数据库,所以无需特殊安装,如果有需要连接其他的同学,可以按照我们的教程进行安装配置。整个DB-GPT的安装过程,我们使用的是miniconda3的虚拟环境。创建虚拟环境,并安装python依赖包
|
||||
|
||||
```bash
|
||||
$ docker run --name=mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=aa12345678 -dit mysql:latest
|
||||
```
|
||||
python>=3.10
|
||||
conda create -n dbgpt_env python=3.10
|
||||
conda activate dbgpt_env
|
||||
pip install -r requirements.txt
|
||||
|
||||
```
|
||||
或者也可以使用命令:
|
||||
```
|
||||
cd DB-GPT
|
||||
conda env create -f environment.yml
|
||||
```
|
||||
另外需要设置一下python包路径, 避免出现运行时找不到包
|
||||
```
|
||||
echo "/root/workspace/DB-GPT" > /root/miniconda3/env/dbgpt_env/lib/python3.10/site-packages/dbgpt.pth
|
||||
```
|
||||
|
||||
### 3. 运行大模型
|
||||
@@ -97,7 +157,7 @@ $ docker run --name=mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=aa12345678 -dit my
|
||||
关于基础模型, 可以根据[vicuna](https://github.com/lm-sys/FastChat/blob/main/README.md#model-weights)合成教程进行合成。
|
||||
如果此步有困难的同学,也可以直接使用[Hugging Face](https://huggingface.co/)上的模型进行替代. [替代模型](https://huggingface.co/Tribbiani/vicuna-7b)
|
||||
|
||||
2. Run model server
|
||||
2. 运行模型服务
|
||||
```
|
||||
cd pilot/server
|
||||
python llmserver.py
|
||||
@@ -109,7 +169,12 @@ python llmserver.py
|
||||
$ python webserver.py
|
||||
```
|
||||
|
||||
可以通过阿里云部署大模型,请参考[阿里云部署指南](https://open.oceanbase.com/blog/3278046208)。
|
||||
## 使用说明
|
||||
|
||||
我们提供了gradio的用户界面,可以通过我们的用户界面使用DB-GPT, 同时关于我们项目相关的一些代码跟原理介绍,我们也准备了以下几篇参考文章。
|
||||
1. [大模型实战系列(1) —— 强强联合Langchain-Vicuna应用实战](https://zhuanlan.zhihu.com/p/628750042)
|
||||
2. [大模型实战系列(2) —— DB-GPT 阿里云部署指南](https://zhuanlan.zhihu.com/p/629467580)
|
||||
3. [大模型实战系列(3) —— DB-GPT插件模型原理与使用](https://zhuanlan.zhihu.com/p/629623125)
|
||||
|
||||
## 感谢
|
||||
|
||||
@@ -118,21 +183,26 @@ $ python webserver.py
|
||||
- [FastChat](https://github.com/lm-sys/FastChat) 提供 chat 服务
|
||||
- [vicuna-13b](https://huggingface.co/Tribbiani/vicuna-13b) 作为基础模型
|
||||
- [langchain](https://github.com/hwchase17/langchain) 工具链
|
||||
- [AutoGPT](https://github.com/Significant-Gravitas/Auto-GPT) 通用的插件模版
|
||||
- [HuggingFace](https://huggingface.co/) 大模型管理
|
||||
- [Chroma](https://github.com/chroma-core/chroma) 向量存储
|
||||
- [Milvus](https://milvus.io/) 分布式向量存储
|
||||
- [ChatGLM](https://github.com/THUDM/ChatGLM-6B) 基础模型
|
||||
- [llama-index](https://github.com/jerryjliu/llama_index) 基于现有知识库进行[In-Context Learning](https://arxiv.org/abs/2301.00234)来对其进行数据库相关知识的增强。
|
||||
|
||||
<!-- GITCONTRIBUTOR_START -->
|
||||
|
||||
## Contributors
|
||||
|
||||
|[<img src="https://avatars.githubusercontent.com/u/17919400?v=4" width="100px;"/><br/><sub><b>csunny</b></sub>](https://github.com/csunny)<br/>|[<img src="https://avatars.githubusercontent.com/u/1011681?v=4" width="100px;"/><br/><sub><b>xudafeng</b></sub>](https://github.com/xudafeng)<br/>|
|
||||
| :---: | :---: |
|
||||
|[<img src="https://avatars.githubusercontent.com/u/17919400?v=4" width="100px;"/><br/><sub><b>csunny</b></sub>](https://github.com/csunny)<br/>|[<img src="https://avatars.githubusercontent.com/u/1011681?v=4" width="100px;"/><br/><sub><b>xudafeng</b></sub>](https://github.com/xudafeng)<br/>|[<img src="https://avatars.githubusercontent.com/u/7636723?s=96&v=4" width="100px;"/><br/><sub><b>明天</b></sub>](https://github.com/yhjun1026)<br/> | [<img src="https://avatars.githubusercontent.com/u/13723926?v=4" width="100px;"/><br/><sub><b>Aries-ckt</b></sub>](https://github.com/Aries-ckt)<br/>|[<img src="https://avatars.githubusercontent.com/u/95130644?v=4" width="100px;"/><br/><sub><b>thebigbone</b></sub>](https://github.com/thebigbone)<br/>|
|
||||
| :---: | :---: | :---: | :---: |:---: |
|
||||
|
||||
|
||||
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sun May 14 2023 23:02:43 GMT+0800`.
|
||||
|
||||
<!-- GITCONTRIBUTOR_END -->
|
||||
|
||||
这是一个用于数据库的复杂且创新的工具,如有任何具体问题,请联系如下微信,我会尽力提供帮助,同时也欢迎参与到项目建设中。
|
||||
这是一个用于数据库的复杂且创新的工具, 我们的项目也在紧急的开发当中, 会陆续发布一些新的feature。如在使用当中有任何具体问题, 优先在项目下提issue, 如有需要, 请联系如下微信,我会尽力提供帮助,同时也非常欢迎大家参与到项目建设中。
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/wechat.jpg" width="320px" />
|
||||
|
BIN
assets/Auto-DB-GPT.gif
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
assets/DB_QA_en.png
Normal file
After Width: | Height: | Size: 300 KiB |
BIN
assets/SQL_Gen_CreateTable.png
Normal file
After Width: | Height: | Size: 297 KiB |
BIN
assets/SQL_Gen_CreateTable_en.png
Normal file
After Width: | Height: | Size: 567 KiB |
BIN
assets/demo_en.gif
Normal file
After Width: | Height: | Size: 2.5 MiB |
BIN
assets/exeable_en.png
Normal file
After Width: | Height: | Size: 947 KiB |
BIN
assets/new_knownledge.gif
Normal file
After Width: | Height: | Size: 2.1 MiB |
@@ -1,4 +1,4 @@
|
||||
version: '3.9'
|
||||
version: '3.10'
|
||||
|
||||
services:
|
||||
db-gpt:
|
||||
|
@@ -4,7 +4,7 @@ channels:
|
||||
- defaults
|
||||
- anaconda
|
||||
dependencies:
|
||||
- python=3.9
|
||||
- python=3.10
|
||||
- cudatoolkit
|
||||
- pip
|
||||
- pytorch-mutex=1.0=cuda
|
||||
|
@@ -69,7 +69,7 @@ def execute_ai_response_json(
|
||||
arguments,
|
||||
prompt,
|
||||
)
|
||||
result = f"Command {command_name} returned: " f"{command_result}"
|
||||
result = f"{command_result}"
|
||||
return result
|
||||
|
||||
|
||||
|
@@ -231,8 +231,8 @@ auto_dbgpt_without_shot = Conversation(
|
||||
sep2="</s>",
|
||||
)
|
||||
|
||||
conv_qa_prompt_template = """ 基于以下已知的信息, 专业、详细的回答用户的问题,
|
||||
如果无法从提供的恶内容中获取答案, 请说: "知识库中提供的内容不足以回答此问题", 但是你可以给出一些与问题相关答案的建议。
|
||||
conv_qa_prompt_template = """ 基于以下已知的信息, 专业、简要的回答用户的问题,
|
||||
如果无法从提供的恶内容中获取答案, 请说: "知识库中提供的内容不足以回答此问题" 禁止胡乱编造。
|
||||
已知内容:
|
||||
{context}
|
||||
问题:
|
||||
|
@@ -7,7 +7,7 @@ from pathlib import Path
|
||||
import distro
|
||||
import yaml
|
||||
from pilot.configs.config import Config
|
||||
from pilot.prompts.prompt import build_default_prompt_generator, DEFAULT_PROMPT_OHTER
|
||||
from pilot.prompts.prompt import build_default_prompt_generator, DEFAULT_PROMPT_OHTER, DEFAULT_TRIGGERING_PROMPT
|
||||
|
||||
|
||||
class AutoModePrompt:
|
||||
|
@@ -11,6 +11,9 @@ import gradio as gr
|
||||
import datetime
|
||||
import requests
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from langchain import PromptTemplate
|
||||
|
||||
from pilot.configs.model_config import DB_SETTINGS, KNOWLEDGE_UPLOAD_ROOT_PATH, LLM_MODEL_CONFIG
|
||||
from pilot.server.vectordb_qa import KnownLedgeBaseQA
|
||||
from pilot.connections.mysql import MySQLOperator
|
||||
@@ -22,7 +25,7 @@ from pilot.configs.model_config import LOGDIR, VICUNA_MODEL_SERVER, LLM_MODEL, D
|
||||
from pilot.plugins import scan_plugins
|
||||
from pilot.configs.config import Config
|
||||
from pilot.commands.command_mange import CommandRegistry
|
||||
from pilot.prompts.auto_mode_prompt import AutoModePrompt
|
||||
from pilot.prompts.auto_mode_prompt import AutoModePrompt
|
||||
from pilot.prompts.generator import PromptGenerator
|
||||
|
||||
from pilot.commands.exception_not_commands import NotCommands
|
||||
@@ -32,7 +35,7 @@ from pilot.conversation import (
|
||||
conv_templates,
|
||||
conversation_types,
|
||||
conversation_sql_mode,
|
||||
SeparatorStyle
|
||||
SeparatorStyle, conv_qa_prompt_template
|
||||
)
|
||||
|
||||
from pilot.utils import (
|
||||
@@ -57,19 +60,22 @@ models = []
|
||||
dbs = []
|
||||
vs_list = ["新建知识库"] + get_vector_storelist()
|
||||
autogpt = False
|
||||
vector_store_client = None
|
||||
vector_store_name = {"vs_name": ""}
|
||||
|
||||
priority = {
|
||||
"vicuna-13b": "aaa"
|
||||
}
|
||||
|
||||
|
||||
def get_simlar(q):
|
||||
|
||||
docsearch = knownledge_tovec_st(os.path.join(DATASETS_DIR, "plan.md"))
|
||||
docs = docsearch.similarity_search_with_score(q, k=1)
|
||||
|
||||
contents = [dc.page_content for dc, _ in docs]
|
||||
return "\n".join(contents)
|
||||
|
||||
|
||||
|
||||
def gen_sqlgen_conversation(dbname):
|
||||
mo = MySQLOperator(
|
||||
**DB_SETTINGS
|
||||
@@ -82,10 +88,12 @@ def gen_sqlgen_conversation(dbname):
|
||||
message += s["schema_info"] + ";"
|
||||
return f"数据库{dbname}的Schema信息如下: {message}\n"
|
||||
|
||||
|
||||
def get_database_list():
|
||||
mo = MySQLOperator(**DB_SETTINGS)
|
||||
return mo.get_db_list()
|
||||
|
||||
|
||||
get_window_url_params = """
|
||||
function() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
@@ -98,10 +106,12 @@ function() {
|
||||
return url_params;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def load_demo(url_params, request: gr.Request):
|
||||
logger.info(f"load_demo. ip: {request.client.host}. params: {url_params}")
|
||||
|
||||
dbs = get_database_list()
|
||||
# dbs = get_database_list()
|
||||
dropdown_update = gr.Dropdown.update(visible=True)
|
||||
if dbs:
|
||||
gr.Dropdown.update(choices=dbs)
|
||||
@@ -115,6 +125,7 @@ def load_demo(url_params, request: gr.Request):
|
||||
gr.Row.update(visible=True),
|
||||
gr.Accordion.update(visible=True))
|
||||
|
||||
|
||||
def get_conv_log_filename():
|
||||
t = datetime.datetime.now()
|
||||
name = os.path.join(LOGDIR, f"{t.year}-{t.month:02d}-{t.day:02d}-conv.json")
|
||||
@@ -127,9 +138,8 @@ def regenerate(state, request: gr.Request):
|
||||
state.skip_next = False
|
||||
return (state, state.to_gradio_chatbot(), "") + (disable_btn,) * 5
|
||||
|
||||
def clear_history(request: gr.Request):
|
||||
|
||||
|
||||
def clear_history(request: gr.Request):
|
||||
logger.info(f"clear_history. ip: {request.client.host}")
|
||||
state = None
|
||||
return (state, [], "") + (disable_btn,) * 5
|
||||
@@ -142,12 +152,13 @@ def add_text(state, text, request: gr.Request):
|
||||
return (state, state.to_gradio_chatbot(), "") + (no_change_btn,) * 5
|
||||
|
||||
""" Default support 4000 tokens, if tokens too lang, we will cut off """
|
||||
text = text[:4000]
|
||||
text = text[:4000]
|
||||
state.append_message(state.roles[0], text)
|
||||
state.append_message(state.roles[1], None)
|
||||
state.skip_next = False
|
||||
return (state, state.to_gradio_chatbot(), "") + (disable_btn,) * 5
|
||||
|
||||
|
||||
def post_process_code(code):
|
||||
sep = "\n```"
|
||||
if sep in code:
|
||||
@@ -158,6 +169,7 @@ def post_process_code(code):
|
||||
code = sep.join(blocks)
|
||||
return code
|
||||
|
||||
|
||||
def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, request: gr.Request):
|
||||
if sql_mode == conversation_sql_mode["auto_execute_ai_response"]:
|
||||
print("AUTO DB-GPT模式.")
|
||||
@@ -185,7 +197,8 @@ def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, re
|
||||
# 第一轮对话需要加入提示Prompt
|
||||
if sql_mode == conversation_sql_mode["auto_execute_ai_response"]:
|
||||
# autogpt模式的第一轮对话需要 构建专属prompt
|
||||
system_prompt = auto_prompt.construct_first_prompt(fisrt_message=[query], db_schemes= gen_sqlgen_conversation(dbname))
|
||||
system_prompt = auto_prompt.construct_first_prompt(fisrt_message=[query],
|
||||
db_schemes=gen_sqlgen_conversation(dbname))
|
||||
logger.info("[TEST]:" + system_prompt)
|
||||
template_name = "auto_dbgpt_one_shot"
|
||||
new_state = conv_templates[template_name].copy()
|
||||
@@ -212,21 +225,37 @@ def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, re
|
||||
# 第一轮对话需要加入提示Prompt
|
||||
if sql_mode == conversation_sql_mode["auto_execute_ai_response"]:
|
||||
## 获取最后一次插件的返回
|
||||
follow_up_prompt = auto_prompt.construct_follow_up_prompt([query])
|
||||
follow_up_prompt = auto_prompt.construct_follow_up_prompt([query])
|
||||
state.messages[0][0] = ""
|
||||
state.messages[0][1] = ""
|
||||
state.messages[-2][1] = follow_up_prompt
|
||||
|
||||
|
||||
prompt = state.get_prompt()
|
||||
skip_echo_len = len(prompt.replace("</s>", " ")) + 1
|
||||
if mode == conversation_types["default_knownledge"] and not db_selector:
|
||||
query = state.messages[-2][1]
|
||||
knqa = KnownLedgeBaseQA()
|
||||
state.messages[-2][1] = knqa.get_similar_answer(query)
|
||||
|
||||
prompt = state.get_prompt()
|
||||
state.messages[-2][1] = query
|
||||
skip_echo_len = len(prompt.replace("</s>", " ")) + 1
|
||||
|
||||
prompt = state.get_prompt()
|
||||
|
||||
skip_echo_len = len(prompt.replace("</s>", " ")) + 1
|
||||
if mode == conversation_types["custome"] and not db_selector:
|
||||
persist_dir = os.path.join(KNOWLEDGE_UPLOAD_ROOT_PATH, vector_store_name["vs_name"] + ".vectordb")
|
||||
print("向量数据库持久化地址: ", persist_dir)
|
||||
knowledge_embedding_client = KnowledgeEmbedding(file_path="", model_name=LLM_MODEL_CONFIG["sentence-transforms"], vector_store_config={"vector_store_name": vector_store_name["vs_name"],
|
||||
"vector_store_path": KNOWLEDGE_UPLOAD_ROOT_PATH})
|
||||
query = state.messages[-2][1]
|
||||
docs = knowledge_embedding_client.similar_search(query, 1)
|
||||
context = [d.page_content for d in docs]
|
||||
prompt_template = PromptTemplate(
|
||||
template=conv_qa_prompt_template,
|
||||
input_variables=["context", "question"]
|
||||
)
|
||||
result = prompt_template.format(context="\n".join(context), question=query)
|
||||
state.messages[-2][1] = result
|
||||
prompt = state.get_prompt()
|
||||
state.messages[-2][1] = query
|
||||
skip_echo_len = len(prompt.replace("</s>", " ")) + 1
|
||||
|
||||
# Make requests
|
||||
payload = {
|
||||
@@ -245,11 +274,6 @@ def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, re
|
||||
print(response.json())
|
||||
print(str(response))
|
||||
try:
|
||||
# response = """{"thoughts":{"text":"thought","reasoning":"reasoning","plan":"- short bulleted\n- list that conveys\n- long-term plan","criticism":"constructive self-criticism","speak":"thoughts summary to say to user"},"command":{"name":"db_sql_executor","args":{"sql":"select count(*) as user_count from users u where create_time >= DATE_SUB(NOW(), INTERVAL 1 MONTH);"}}}"""
|
||||
# response = response.replace("\n", "\\n")
|
||||
|
||||
# response = """{"thoughts":{"text":"In order to get the number of users who have grown in the last three days, I need to analyze the create\_time of each user and see if it is within the last three days. I will use the SQL query to filter the users who have created their account in the last three days.","reasoning":"I can use the SQL query to filter the users who have created their account in the last three days. I will get the current date and then subtract three days from it, and then use this as the filter for the query. This will give me the number of users who have created their account in the last three days.","plan":"- Get the current date and subtract three days from it\n- Use the SQL query to filter the users who have created their account in the last three days\n- Count the number of users who match the filter to get the number of users who have grown in the last three days","criticism":"None"},"command":{"name":"db_sql_executor","args":{"sql":"SELECT COUNT(DISTINCT(ID)) FROM users WHERE create_time >= DATE_SUB(NOW(), INTERVAL 3 DAY);"}}}"""
|
||||
# response = response.replace("\n", "\\)
|
||||
text = response.text.strip()
|
||||
text = text.rstrip()
|
||||
respObj = json.loads(text)
|
||||
@@ -259,7 +283,7 @@ def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, re
|
||||
respObj_ex = json.loads(xx)
|
||||
if respObj_ex['error_code'] == 0:
|
||||
ai_response = None
|
||||
all_text = respObj_ex['text']
|
||||
all_text = respObj_ex['text']
|
||||
### 解析返回文本,获取AI回复部分
|
||||
tmpResp = all_text.split(state.sep)
|
||||
last_index = -1
|
||||
@@ -279,11 +303,11 @@ def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, re
|
||||
plugin_resp = execute_ai_response_json(auto_prompt.prompt_generator, ai_response)
|
||||
cfg.set_last_plugin_return(plugin_resp)
|
||||
print(plugin_resp)
|
||||
state.messages[-1][-1] = "Model推理信息:\n"+ ai_response +"\n\nDB-GPT执行结果:\n" + plugin_resp
|
||||
state.messages[-1][-1] = "Model推理信息:\n" + ai_response + "\n\nDB-GPT执行结果:\n" + plugin_resp
|
||||
yield (state, state.to_gradio_chatbot()) + (no_change_btn,) * 5
|
||||
except NotCommands as e:
|
||||
print("命令执行:" + e.message)
|
||||
state.messages[-1][-1] = "命令执行:" + e.message +"\n模型输出:\n" + str(ai_response)
|
||||
state.messages[-1][-1] = "命令执行:" + e.message + "\n模型输出:\n" + str(ai_response)
|
||||
yield (state, state.to_gradio_chatbot()) + (no_change_btn,) * 5
|
||||
else:
|
||||
# 流式输出
|
||||
@@ -306,7 +330,7 @@ def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, re
|
||||
output = data["text"] + f" (error_code: {data['error_code']})"
|
||||
state.messages[-1][-1] = output
|
||||
yield (state, state.to_gradio_chatbot()) + (
|
||||
disable_btn, disable_btn, disable_btn, enable_btn, enable_btn)
|
||||
disable_btn, disable_btn, disable_btn, enable_btn, enable_btn)
|
||||
return
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
@@ -335,8 +359,8 @@ def http_bot(state, mode, sql_mode, db_selector, temperature, max_new_tokens, re
|
||||
|
||||
|
||||
block_css = (
|
||||
code_highlight_css
|
||||
+ """
|
||||
code_highlight_css
|
||||
+ """
|
||||
pre {
|
||||
white-space: pre-wrap; /* Since CSS 2.1 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
@@ -350,23 +374,26 @@ block_css = (
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def change_sql_mode(sql_mode):
|
||||
if sql_mode in ["直接执行结果"]:
|
||||
return gr.update(visible=True)
|
||||
else:
|
||||
return gr.update(visible=False)
|
||||
|
||||
|
||||
def change_mode(mode):
|
||||
if mode in ["默认知识库对话", "LLM原生对话"]:
|
||||
return gr.update(visible=False)
|
||||
else:
|
||||
return gr.update(visible=True)
|
||||
|
||||
|
||||
def change_tab():
|
||||
autogpt = True
|
||||
|
||||
autogpt = True
|
||||
|
||||
|
||||
def build_single_model_ui():
|
||||
|
||||
notice_markdown = """
|
||||
# DB-GPT
|
||||
|
||||
@@ -398,7 +425,7 @@ def build_single_model_ui():
|
||||
interactive=True,
|
||||
label="最大输出Token数",
|
||||
)
|
||||
tabs= gr.Tabs()
|
||||
tabs = gr.Tabs()
|
||||
with tabs:
|
||||
tab_sql = gr.TabItem("SQL生成与诊断", elem_id="SQL")
|
||||
with tab_sql:
|
||||
@@ -414,9 +441,6 @@ def build_single_model_ui():
|
||||
sql_mode = gr.Radio(["直接执行结果", "不执行结果"], show_label=False, value="不执行结果")
|
||||
sql_vs_setting = gr.Markdown("自动执行模式下, DB-GPT可以具备执行SQL、从网络读取知识自动化存储学习的能力")
|
||||
sql_mode.change(fn=change_sql_mode, inputs=sql_mode, outputs=sql_vs_setting)
|
||||
tab_auto = gr.TabItem("AUTO-GPT", elem_id="auto")
|
||||
with tab_auto:
|
||||
gr.Markdown("自动执行模式下, DB-GPT可以具备执行SQL、从网络读取知识自动化存储学习的能力")
|
||||
|
||||
tab_qa = gr.TabItem("知识问答", elem_id="QA")
|
||||
with tab_qa:
|
||||
@@ -429,7 +453,7 @@ def build_single_model_ui():
|
||||
with gr.Column() as doc2vec:
|
||||
gr.Markdown("向知识库中添加文件")
|
||||
with gr.Tab("上传文件"):
|
||||
files = gr.File(label="添加文件",
|
||||
files = gr.File(label="添加文件",
|
||||
file_types=[".txt", ".md", ".docx", ".pdf"],
|
||||
file_count="multiple",
|
||||
show_label=False
|
||||
@@ -437,12 +461,12 @@ def build_single_model_ui():
|
||||
|
||||
load_file_button = gr.Button("上传并加载到知识库")
|
||||
with gr.Tab("上传文件夹"):
|
||||
folder_files = gr.File(label="添加文件",
|
||||
file_count="directory",
|
||||
folder_files = gr.File(label="添加文件夹",
|
||||
accept_multiple_files=True,
|
||||
file_count="directory",
|
||||
show_label=False)
|
||||
load_folder_button = gr.Button("上传并加载到知识库")
|
||||
|
||||
|
||||
|
||||
with gr.Blocks():
|
||||
chatbot = grChatbot(elem_id="chatbot", visible=False).style(height=550)
|
||||
with gr.Row():
|
||||
@@ -451,9 +475,9 @@ def build_single_model_ui():
|
||||
show_label=False,
|
||||
placeholder="Enter text and press ENTER",
|
||||
visible=False,
|
||||
).style(container=False)
|
||||
).style(container=False)
|
||||
with gr.Column(scale=2, min_width=50):
|
||||
send_btn = gr.Button(value="发送", visible=False)
|
||||
send_btn = gr.Button(value="发送", visible=False)
|
||||
|
||||
with gr.Row(visible=False) as button_row:
|
||||
regenerate_btn = gr.Button(value="重新生成", interactive=False)
|
||||
@@ -467,7 +491,7 @@ def build_single_model_ui():
|
||||
[state, chatbot] + btn_list,
|
||||
)
|
||||
clear_btn.click(clear_history, None, [state, chatbot, textbox] + btn_list)
|
||||
|
||||
|
||||
textbox.submit(
|
||||
add_text, [state, textbox], [state, chatbot, textbox] + btn_list
|
||||
).then(
|
||||
@@ -483,24 +507,26 @@ def build_single_model_ui():
|
||||
[state, mode, sql_mode, db_selector, temperature, max_output_tokens],
|
||||
[state, chatbot] + btn_list
|
||||
)
|
||||
vs_add.click(fn=save_vs_name, show_progress=True,
|
||||
inputs=[vs_name],
|
||||
outputs=[vs_name])
|
||||
load_file_button.click(fn=knowledge_embedding_store,
|
||||
show_progress=True,
|
||||
inputs=[vs_name, files],
|
||||
outputs=[vs_name])
|
||||
# load_folder_button.click(get_vector_store,
|
||||
# show_progress=True,
|
||||
# inputs=[vs_name, folder_files, 100 , chatbot, vs_add,
|
||||
# vs_add],
|
||||
# outputs=["db-out", folder_files, chatbot])
|
||||
load_folder_button.click(fn=knowledge_embedding_store,
|
||||
show_progress=True,
|
||||
inputs=[vs_name, folder_files],
|
||||
outputs=[vs_name])
|
||||
return state, chatbot, textbox, send_btn, button_row, parameter_row
|
||||
|
||||
|
||||
def build_webdemo():
|
||||
with gr.Blocks(
|
||||
title="数据库智能助手",
|
||||
# theme=gr.themes.Base(),
|
||||
theme=gr.themes.Default(),
|
||||
css=block_css,
|
||||
title="数据库智能助手",
|
||||
# theme=gr.themes.Base(),
|
||||
theme=gr.themes.Default(),
|
||||
css=block_css,
|
||||
) as demo:
|
||||
url_params = gr.JSON(visible=False)
|
||||
(
|
||||
@@ -531,6 +557,10 @@ def build_webdemo():
|
||||
return demo
|
||||
|
||||
|
||||
def save_vs_name(vs_name):
|
||||
vector_store_name["vs_name"] = vs_name
|
||||
return vs_name
|
||||
|
||||
def knowledge_embedding_store(vs_id, files):
|
||||
# vs_path = os.path.join(VS_ROOT_PATH, vs_id)
|
||||
if not os.path.exists(os.path.join(KNOWLEDGE_UPLOAD_ROOT_PATH, vs_id)):
|
||||
@@ -538,14 +568,18 @@ def knowledge_embedding_store(vs_id, files):
|
||||
for file in files:
|
||||
filename = os.path.split(file.name)[-1]
|
||||
shutil.move(file.name, os.path.join(KNOWLEDGE_UPLOAD_ROOT_PATH, vs_id, filename))
|
||||
knowledge_embedding_client = KnowledgeEmbedding(
|
||||
file_path=os.path.join(KNOWLEDGE_UPLOAD_ROOT_PATH, vs_id, filename),
|
||||
model_name=LLM_MODEL_CONFIG["sentence-transforms"],
|
||||
vector_store_config={
|
||||
"vector_store_name": vector_store_name["vs_name"],
|
||||
"vector_store_path": KNOWLEDGE_UPLOAD_ROOT_PATH})
|
||||
knowledge_embedding_client.knowledge_embedding()
|
||||
|
||||
|
||||
knowledge_embedding = KnowledgeEmbedding.knowledge_embedding(os.path.join(KNOWLEDGE_UPLOAD_ROOT_PATH, vs_id, filename), LLM_MODEL_CONFIG["sentence-transforms"], {"vector_store_name": vs_id,
|
||||
"vector_store_path": KNOWLEDGE_UPLOAD_ROOT_PATH})
|
||||
knowledge_embedding.source_embedding()
|
||||
logger.info("knowledge embedding success")
|
||||
return os.path.join(KNOWLEDGE_UPLOAD_ROOT_PATH, vs_id, vs_id + ".vectordb")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--host", type=str, default="0.0.0.0")
|
||||
@@ -559,7 +593,7 @@ if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
logger.info(f"args: {args}")
|
||||
|
||||
dbs = get_database_list()
|
||||
# dbs = get_database_list()
|
||||
|
||||
# 加载插件
|
||||
cfg = Config()
|
||||
@@ -579,7 +613,7 @@ if __name__ == "__main__":
|
||||
for command_category in command_categories:
|
||||
command_registry.import_commands(command_category)
|
||||
|
||||
cfg.command_registry =command_registry
|
||||
cfg.command_registry = command_registry
|
||||
|
||||
logger.info(args)
|
||||
demo = build_webdemo()
|
||||
@@ -587,4 +621,4 @@ if __name__ == "__main__":
|
||||
concurrency_count=args.concurrency_count, status_update_rate=10, api_open=False
|
||||
).launch(
|
||||
server_name=args.host, server_port=args.port, share=args.share, max_threads=200,
|
||||
)
|
||||
)
|
||||
|
@@ -10,6 +10,7 @@ class CSVEmbedding(SourceEmbedding):
|
||||
|
||||
def __init__(self, file_path, model_name, vector_store_config, embedding_args: Optional[Dict] = None):
|
||||
"""Initialize with csv path."""
|
||||
super().__init__(file_path, model_name, vector_store_config)
|
||||
self.file_path = file_path
|
||||
self.model_name = model_name
|
||||
self.vector_store_config = vector_store_config
|
||||
|
@@ -4,17 +4,31 @@ from pilot.source_embedding.pdf_embedding import PDFEmbedding
|
||||
|
||||
|
||||
class KnowledgeEmbedding:
|
||||
@staticmethod
|
||||
def knowledge_embedding(file_path:str, model_name, vector_store_config):
|
||||
if file_path.endswith(".pdf"):
|
||||
embedding = PDFEmbedding(file_path=file_path, model_name=model_name,
|
||||
vector_store_config=vector_store_config)
|
||||
elif file_path.endswith(".md"):
|
||||
embedding = MarkdownEmbedding(file_path=file_path, model_name=model_name,
|
||||
vector_store_config=vector_store_config)
|
||||
def __init__(self, file_path, model_name, vector_store_config):
|
||||
"""Initialize with Loader url, model_name, vector_store_config"""
|
||||
self.file_path = file_path
|
||||
self.model_name = model_name
|
||||
self.vector_store_config = vector_store_config
|
||||
self.vector_store_type = "default"
|
||||
self.knowledge_embedding_client = self.init_knowledge_embedding()
|
||||
|
||||
elif file_path.endswith(".csv"):
|
||||
embedding = CSVEmbedding(file_path=file_path, model_name=model_name,
|
||||
vector_store_config=vector_store_config)
|
||||
def knowledge_embedding(self):
|
||||
self.knowledge_embedding_client.source_embedding()
|
||||
|
||||
return embedding
|
||||
def init_knowledge_embedding(self):
|
||||
if self.file_path.endswith(".pdf"):
|
||||
embedding = PDFEmbedding(file_path=self.file_path, model_name=self.model_name,
|
||||
vector_store_config=self.vector_store_config)
|
||||
elif self.file_path.endswith(".md"):
|
||||
embedding = MarkdownEmbedding(file_path=self.file_path, model_name=self.model_name, vector_store_config=self.vector_store_config)
|
||||
|
||||
elif self.file_path.endswith(".csv"):
|
||||
embedding = CSVEmbedding(file_path=self.file_path, model_name=self.model_name,
|
||||
vector_store_config=self.vector_store_config)
|
||||
elif self.vector_store_type == "default":
|
||||
embedding = MarkdownEmbedding(file_path=self.file_path, model_name=self.model_name, vector_store_config=self.vector_store_config)
|
||||
|
||||
return embedding
|
||||
|
||||
def similar_search(self, text, topk):
|
||||
return self.knowledge_embedding_client.similar_search(text, topk)
|
@@ -15,6 +15,7 @@ class MarkdownEmbedding(SourceEmbedding):
|
||||
|
||||
def __init__(self, file_path, model_name, vector_store_config):
|
||||
"""Initialize with markdown path."""
|
||||
super().__init__(file_path, model_name, vector_store_config)
|
||||
self.file_path = file_path
|
||||
self.model_name = model_name
|
||||
self.vector_store_config = vector_store_config
|
||||
|
@@ -13,9 +13,12 @@ class PDFEmbedding(SourceEmbedding):
|
||||
|
||||
def __init__(self, file_path, model_name, vector_store_config):
|
||||
"""Initialize with pdf path."""
|
||||
super().__init__(file_path, model_name, vector_store_config)
|
||||
self.file_path = file_path
|
||||
self.model_name = model_name
|
||||
self.vector_store_config = vector_store_config
|
||||
# SourceEmbedding(file_path =file_path, );
|
||||
SourceEmbedding(file_path, model_name, vector_store_config)
|
||||
|
||||
@register
|
||||
def read(self):
|
||||
|
@@ -22,12 +22,16 @@ class SourceEmbedding(ABC):
|
||||
Implementations should implement the method
|
||||
"""
|
||||
|
||||
def __init__(self, yuque_path, model_name, vector_store_config, embedding_args: Optional[Dict] = None):
|
||||
"""Initialize with YuqueLoader url, model_name, vector_store_config"""
|
||||
self.yuque_path = yuque_path
|
||||
def __init__(self, file_path, model_name, vector_store_config, embedding_args: Optional[Dict] = None):
|
||||
"""Initialize with Loader url, model_name, vector_store_config"""
|
||||
self.file_path = file_path
|
||||
self.model_name = model_name
|
||||
self.vector_store_config = vector_store_config
|
||||
self.embedding_args = embedding_args
|
||||
self.embeddings = HuggingFaceEmbeddings(model_name=self.model_name)
|
||||
persist_dir = os.path.join(self.vector_store_config["vector_store_path"],
|
||||
self.vector_store_config["vector_store_name"] + ".vectordb")
|
||||
self.vector_store_client = Chroma(persist_directory=persist_dir, embedding_function=self.embeddings)
|
||||
|
||||
@abstractmethod
|
||||
@register
|
||||
@@ -50,18 +54,16 @@ class SourceEmbedding(ABC):
|
||||
@register
|
||||
def index_to_store(self, docs):
|
||||
"""index to vector store"""
|
||||
embeddings = HuggingFaceEmbeddings(model_name=self.model_name)
|
||||
|
||||
persist_dir = os.path.join(self.vector_store_config["vector_store_path"],
|
||||
self.vector_store_config["vector_store_name"] + ".vectordb")
|
||||
self.vector_store = Chroma.from_documents(docs, embeddings, persist_directory=persist_dir)
|
||||
self.vector_store = Chroma.from_documents(docs, self.embeddings, persist_directory=persist_dir)
|
||||
self.vector_store.persist()
|
||||
|
||||
@register
|
||||
def similar_search(self, doc, topk):
|
||||
"""vector store similarity_search"""
|
||||
|
||||
return self.vector_store.similarity_search(doc, topk)
|
||||
return self.vector_store_client.similarity_search(doc, topk)
|
||||
|
||||
def source_embedding(self):
|
||||
if 'read' in registered_methods:
|
||||
|
2
run.sh
@@ -15,7 +15,7 @@ function find_python_command() {
|
||||
|
||||
PYTHONCMD=$(find_python_command)
|
||||
|
||||
nohup PYTHONCMD pilot/server/vicuna_server.py >> /root/server.log 2>&1 &
|
||||
nohup PYTHONCMD pilot/server/llmserver.py >> /root/server.log 2>&1 &
|
||||
while [ `grep -c "Uvicorn running on" /root/server.log` -eq '0' ];do
|
||||
sleep 1s;
|
||||
echo "wait server running"
|
||||
|