Compare commits

..

No commits in common. "master" and "v0.2.6" have entirely different histories.

298 changed files with 3110 additions and 30062 deletions

View File

@ -1,19 +0,0 @@
.idea
# Langchain-Chatchat
docs
.github
tests
Dockerfile
.dockerignore
.gitignore
.gitmodules
README.md
README_en.md
README_ja.md
LICENSE
requirements_api.txt
requirements_lite.txt
requirements_webui.txt
# bge-large-zh-v1.5
bge-large-zh-v1.5/README.md
# chatglm3-6b

View File

@ -1,155 +0,0 @@
name: docker-build
on:
push:
branches:
- master
paths-ignore:
- 'README.md'
- 'README_en.md'
- 'README_ja.md'
env:
TZ: Asia/Shanghai
jobs:
docker-build:
runs-on: ubuntu-latest
# if: github.event.pull_request.merged == true
steps:
- name: Optimize Disk Space
uses: hugoalh/disk-space-optimizer-ghaction@v0.8.0
with:
operate_sudo: "True"
general_include: ".+"
general_exclude: |-
^GCC$
^G\+\+$
Clang
LLVM
docker_include: ".+"
docker_prune: "True"
docker_clean: "True"
apt_prune: "True"
apt_clean: "True"
homebrew_prune: "True"
homebrew_clean: "True"
npm_prune: "True"
npm_clean: "True"
os_swap: "True"
- name: Remove Unnecessary Tools And Files
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get remove -y '^dotnet-.*' '^llvm-.*' 'php.*' azure-cli google-chrome-stable firefox powershell mono-devel
sudo apt-get autoremove --purge -y
sudo find /var/log -name "*.gz" -type f -delete
sudo rm -rf /var/cache/apt/archives
sudo rm -rf /tmp/*
sudo rm -rf /etc/apt/sources.list.d/* /usr/share/dotnet /usr/local/lib/android /opt/ghc /etc/mysql /etc/php
sudo -E apt-get -y purge azure-cli* docker* ghc* zulu* hhvm* llvm* firefox* google* dotnet* aspnetcore* powershell* openjdk* adoptopenjdk* mysql* php* mongodb* moby* snap* || true
sudo rm -rf /etc/apt/sources.list.d/* /usr/local/lib/android /opt/ghc /usr/share/dotnet /usr/local/graalvm /usr/local/.ghcup \
/usr/local/share/powershell /usr/local/share/chromium /usr/local/lib/node_modules
sudo rm -rf /etc/apt/sources.list.d/* /usr/share/dotnet /usr/local/lib/android /opt/ghc /etc/mysql /etc/php
sudo -E apt-get -y purge azure-cli* docker* ghc* zulu* hhvm* llvm* firefox* google* dotnet* aspnetcore* powershell* openjdk* adoptopenjdk* mysql* php* mongodb* moby* snap* || true
sudo -E apt-get -qq update
sudo -E apt-get -qq install libfuse-dev $(curl -fsSL git.io/depends-ubuntu-2204)
sudo -E apt-get -qq autoremove --purge
sudo -E apt-get -qq clean
sudo apt-get clean
rm -rf /opt/hostedtoolcache
sudo timedatectl set-timezone "$TZ"
- name: Free Up Disk Space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 62464 # 给 / 预留 61GiB 空间( docker 预留)
swap-size-mb: 1
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
remove-docker-images: 'true'
- name: Checkout Repository
uses: actions/checkout@v4
- name: Get Latest Release
id: get_version
run: |
VERSION=$(curl --silent "https://api.github.com/repos/${{ github.repository }}/releases/latest" | jq -r .tag_name)
echo "RELEASE_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Set Image Tag
id: imageTag
run: echo "::set-output name=image_tag::$RELEASE_VERSION-$(date +%Y%m%d)-$(git rev-parse --short HEAD)"
- name: Set Up QEMU
uses: docker/setup-qemu-action@v2
- name: Set Up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Clone Model
run: |
sudo mkdir -p $GITHUB_WORKSPACE/bge-large-zh-v1.5
cd $GITHUB_WORKSPACE/bge-large-zh-v1.5
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/.gitattributes &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/config.json &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/config_sentence_transformers.json &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/modules.json &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/pytorch_model.bin &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/sentence_bert_config.json &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/special_tokens_map.json &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/tokenizer.json &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/tokenizer_config.json &> /dev/null
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/vocab.txt &> /dev/null
sudo mkdir -p $GITHUB_WORKSPACE/bge-large-zh-v1.5/1_Pooling
cd $GITHUB_WORKSPACE/bge-large-zh-v1.5/1_Pooling
sudo wget https://huggingface.co/BAAI/bge-large-zh-v1.5/resolve/main/1_Pooling/config.json &> /dev/null
sudo mkdir -p $GITHUB_WORKSPACE/chatglm3-6b
cd $GITHUB_WORKSPACE/chatglm3-6b
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/config.json &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/configuration_chatglm.py &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model-00001-of-00007.safetensors &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model-00002-of-00007.safetensors &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model-00003-of-00007.safetensors &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model-00004-of-00007.safetensors &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model-00005-of-00007.safetensors &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model-00006-of-00007.safetensors &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model-00007-of-00007.safetensors &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/model.safetensors.index.json &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/modeling_chatglm.py &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/pytorch_model.bin.index.json &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/quantization.py &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/special_tokens_map.json &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/tokenization_chatglm.py &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/tokenizer.model &> /dev/null
sudo wget https://huggingface.co/THUDM/chatglm3-6b/resolve/main/tokenizer_config.json &> /dev/null
du -sh $GITHUB_WORKSPACE
du -sh $GITHUB_WORKSPACE/*
du -sh $GITHUB_WORKSPACE/bge-large-zh-v1.5/*
du -sh $GITHUB_WORKSPACE/chatglm3-6b/*
- name: Show Runner Disk
run: df -hT
- name: Docker Build
run: |
docker build -t uswccr.ccs.tencentyun.com/chatchat/chatchat:${{ steps.imageTag.outputs.image_tag }} -f Dockerfile .
- name: Show Images Size
run: docker images
- name: Login To Tencent CCR
uses: docker/login-action@v2
with:
registry: uswccr.ccs.tencentyun.com
username: ${{ secrets.CCR_REGISTRY_USERNAME }}
password: ${{ secrets.CCR_REGISTRY_PASSWORD }}
- name: Docker Push
run: docker push uswccr.ccs.tencentyun.com/chatchat/chatchat:${{ steps.imageTag.outputs.image_tag }}
# - name: Login to Docker Hub
# uses: docker/login-action@v2
# with:
# username: ${{ secrets.DOCKERHUB_USERNAME }}
# password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Update README.md
run: |
sed -i "s|uswccr.ccs.tencentyun.com/chatchat/chatchat:[^ ]*|uswccr.ccs.tencentyun.com/chatchat/chatchat:${{ steps.imageTag.outputs.image_tag }}|g" README.md
sed -i "s|uswccr.ccs.tencentyun.com/chatchat/chatchat:[^ ]*|uswccr.ccs.tencentyun.com/chatchat/chatchat:${{ steps.imageTag.outputs.image_tag }}|g" README_en.md
sed -i "s|uswccr.ccs.tencentyun.com/chatchat/chatchat:[^ ]*|uswccr.ccs.tencentyun.com/chatchat/chatchat:${{ steps.imageTag.outputs.image_tag }}|g" README_ja.md
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git commit -am "feat:update docker image:tag"
- name: Push README.md
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GH_PAT }}
branch: ${{ github.ref }}

13
.gitignore vendored
View File

@ -2,10 +2,7 @@
*.log.*
*.bak
logs
/knowledge_base/*
!/knowledge_base/samples
/knowledge_base/samples/vector_store
/knowledge_base/
/configs/*.py
.vscode/
@ -170,11 +167,3 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
.pytest_cache
.DS_Store
# Test File
test.py
configs/*.py

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "knowledge_base/samples/content/wiki"]
path = knowledge_base/samples/content/wiki
url = https://github.com/chatchat-space/Langchain-Chatchat.wiki.git

View File

@ -1,27 +0,0 @@
# Base Image
FROM nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04
# Labels
LABEL maintainer=chatchat
# Environment Variables
ENV HOME=/Langchain-Chatchat
# Commands
WORKDIR /
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
apt-get update -y && \
apt-get install -y --no-install-recommends python3.11 python3-pip curl libgl1 libglib2.0-0 jq && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
rm -f /usr/bin/python3 && \
ln -s /usr/bin/python3.11 /usr/bin/python3 && \
mkdir -p $HOME
# Copy the application files
COPY . $HOME
WORKDIR $HOME
# Install dependencies from requirements.txt
RUN pip3 install -r requirements.txt -i https://pypi.org/simple && \
python3 copy_config_example.py && \
sed -i 's|MODEL_ROOT_PATH = ""|MODEL_ROOT_PATH = "/Langchain-Chatchat"|' configs/model_config.py && \
python3 init_database.py --recreate-vs
EXPOSE 22 7861 8501
ENTRYPOINT ["python3", "startup.py", "-a"]

124
README.md
View File

@ -1,16 +1,11 @@
![](img/logo-long-chatchat-trans-v2.png)
🌍 [READ THIS IN ENGLISH](README_en.md)
🌍 [日本語で読む](README_ja.md)
📃 **LangChain-Chatchat** (原 Langchain-ChatGLM)
基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现,开源、可离线部署的检索增强生成(RAG)大模型知识库项目。
### ⚠️ 重要提示
`0.2.10`将会是`0.2.x`系列的最后一个版本,`0.2.x`系列版本将会停止更新和技术支持,全力研发具有更强应用性的 `Langchain-Chatchat 0.3.x`
`0.2.10` 的后续 bug 修复将会直接推送到`master`分支,而不再进行版本更新。
基于 Langchain 与 ChatGLM 等大语言模型的本地知识库问答应用实现。
---
@ -19,31 +14,24 @@
* [介绍](README.md#介绍)
* [解决的痛点](README.md#解决的痛点)
* [快速上手](README.md#快速上手)
* [1. 环境配置](README.md#1-环境配置)
* [2. 模型下载](README.md#2-模型下载)
* [3. 初始化知识库和配置文件](README.md#3-初始化知识库和配置文件)
* [4. 一键启动](README.md#4-一键启动)
* [5. 启动界面示例](README.md#5-启动界面示例)
* [1. 环境配置](README.md#1-环境配置)
* [2. 模型下载](README.md#2-模型下载)
* [3. 初始化知识库和配置文件](README.md#3-初始化知识库和配置文件)
* [4. 一键启动](README.md#4-一键启动)
* [5. 启动界面示例](README.md#5-启动界面示例)
* [联系我们](README.md#联系我们)
* [合作伙伴名单](README.md#合作伙伴名单)
## 介绍
🤖️ 一种利用 [langchain](https://github.com/langchain-ai/langchain)
思想实现的基于本地知识库的问答应用,目标期望建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。
🤖️ 一种利用 [langchain](https://github.com/hwchase17/langchain) 思想实现的基于本地知识库的问答应用,目标期望建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。
💡 受 [GanymedeNil](https://github.com/GanymedeNil) 的项目 [document.ai](https://github.com/GanymedeNil/document.ai)
和 [AlexZhangji](https://github.com/AlexZhangji)
创建的 [ChatGLM-6B Pull Request](https://github.com/THUDM/ChatGLM-6B/pull/216)
启发,建立了全流程可使用开源模型实现的本地知识库问答应用。本项目的最新版本中通过使用 [FastChat](https://github.com/lm-sys/FastChat)
接入 Vicuna, Alpaca, LLaMA, Koala, RWKV 等模型,依托于 [langchain](https://github.com/langchain-ai/langchain)
框架支持通过基于 [FastAPI](https://github.com/tiangolo/fastapi) 提供的 API
调用服务,或使用基于 [Streamlit](https://github.com/streamlit/streamlit) 的 WebUI 进行操作。
💡 受 [GanymedeNil](https://github.com/GanymedeNil) 的项目 [document.ai](https://github.com/GanymedeNil/document.ai) 和 [AlexZhangji](https://github.com/AlexZhangji) 创建的 [ChatGLM-6B Pull Request](https://github.com/THUDM/ChatGLM-6B/pull/216) 启发,建立了全流程可使用开源模型实现的本地知识库问答应用。本项目的最新版本中通过使用 [FastChat](https://github.com/lm-sys/FastChat) 接入 Vicuna, Alpaca, LLaMA, Koala, RWKV 等模型,依托于 [langchain](https://github.com/langchain-ai/langchain) 框架支持通过基于 [FastAPI](https://github.com/tiangolo/fastapi) 提供的 API 调用服务,或使用基于 [Streamlit](https://github.com/streamlit/streamlit) 的 WebUI 进行操作。
✅ 依托于本项目支持的开源 LLM 与 Embedding 模型,本项目可实现全部使用**开源**模型**离线私有部署**。与此同时,本项目也支持
OpenAI GPT API 的调用,并将在后续持续扩充对各类模型及模型 API 的接入。
✅ 依托于本项目支持的开源 LLM 与 Embedding 模型,本项目可实现全部使用**开源**模型**离线私有部署**。与此同时,本项目也支持 OpenAI GPT API 的调用,并将在后续持续扩充对各类模型及模型 API 的接入。
⛓️ 本项目实现原理如下图所示,过程包括加载文件 -> 读取文本 -> 文本分割 -> 文本向量化 -> 问句向量化 ->
在文本向量中匹配出与问句向量最相似的 `top k`个 -> 匹配出的文本作为上下文和问题一起添加到 `prompt`中 -> 提交给 `LLM`生成回答。
⛓️ 本项目实现原理如下图所示,过程包括加载文件 -> 读取文本 -> 文本分割 -> 文本向量化 -> 问句向量化 -> 在文本向量中匹配出与问句向量最相似的 `top k`个 -> 匹配出的文本作为上下文和问题一起添加到 `prompt`中 -> 提交给 `LLM`生成回答。
📺 [原理介绍视频](https://www.bilibili.com/video/BV13M4y1e7cN/?share_source=copy_web&vd_source=e6c5aafe684f30fbe41925d61ca6d514)
@ -55,46 +43,31 @@ OpenAI GPT API 的调用,并将在后续持续扩充对各类模型及模型 A
🚩 本项目未涉及微调、训练过程,但可利用微调或训练对本项目效果进行优化。
🌐 [AutoDL 镜像](https://www.codewithgpu.com/i/chatchat-space/Langchain-Chatchat/Langchain-Chatchat) 中 `0.2.10`
🌐 [AutoDL 镜像](https://www.codewithgpu.com/i/chatchat-space/Langchain-Chatchat/Langchain-Chatchat) 中 `v9` 版本所使用代码已更新至本项目 `v0.2.5` 版本。
版本所使用代码已更新至本项目 `v0.2.10` 版本
🐳 [Docker 镜像](registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.3) 已经更新到 ```0.2.3``` 版本, 如果想体验最新内容请源码安装
🐳 [Docker 镜像](isafetech/chatchat:0.2.10) 已经更新到 ```0.2.10``` 版本。
🌲 本次更新后同时支持DockerHub、阿里云、腾讯云镜像源
```shell
docker run -d --gpus all -p 80:8501 isafetech/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 uswccr.ccs.tencentyun.com/chatchat/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.10
```
🧩 本项目有一个非常完整的[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/) README只是一个简单的介绍_
_仅仅是入门教程能够基础运行__。
如果你想要更深入的了解本项目,或者想对本项目做出贡献。请移步 [Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/)
界面
🧩 本项目有一个非常完整的[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/) README只是一个简单的介绍__仅仅是入门教程能够基础运行__。 如果你想要更深入的了解本项目,或者对相对本项目做出共享。请移步 [Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/) 界面
## 解决的痛点
该项目是一个可以实现 __完全本地化__推理的知识库增强方案, 重点解决数据安全保护,私域化部署的企业痛点。
本开源方案采用```Apache License```,可以免费商用,无需付费。
该项目是一个可以实现 __完全本地化__推理的知识库增强方案, 重点解决数数据安全保护,私域化部署的企业痛点。
本开源方案采用```Apache License``,可以免费商用,无需付费。
我们支持市面上主流的本地大言模型和Embedding模型支持开源的本地向量数据库。
我们支持市面上主流的本地大预言模型和Embedding模型支持开源的本地向量数据库。
支持列表详见[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/)
## 快速上手
### 1. 环境配置
+ 首先,确保你的机器安装了 Python 3.8 - 3.11 (我们强烈推荐使用 Python3.11)。
+ 首先,确保你的机器安装了 Python 3.10
```
$ python --version
Python 3.11.7
Python 3.10.12
```
接着,创建一个虚拟环境,并在虚拟环境内安装项目的依赖
```shell
# 拉取仓库
@ -110,44 +83,32 @@ $ pip install -r requirements_webui.txt
# 默认依赖包括基本运行环境FAISS向量库。如果要使用 milvus/pg_vector 等向量库,请将 requirements.txt 中相应依赖取消注释再安装。
```
### 2 模型下载
请注意LangChain-Chatchat `0.2.x` 系列是针对 Langchain `0.0.x` 系列版本的,如果你使用的是 Langchain `0.1.x`
系列版本,需要降级您的`Langchain`版本。
如需在本地或离线环境下运行本项目,需要首先将项目所需的模型下载至本地,通常开源 LLM 与 Embedding 模型可以从 [HuggingFace](https://huggingface.co/models) 下载。
### 2. 模型下载
以本项目中默认使用的 LLM 模型 [THUDM/ChatGLM2-6B](https://huggingface.co/THUDM/chatglm2-6b) 与 Embedding 模型 [moka-ai/m3e-base](https://huggingface.co/moka-ai/m3e-base) 为例:
如需在本地或离线环境下运行本项目,需要首先将项目所需的模型下载至本地,通常开源 LLM 与 Embedding
模型可以从 [HuggingFace](https://huggingface.co/models) 下载。
以本项目中默认使用的 LLM 模型 [THUDM/ChatGLM3-6B](https://huggingface.co/THUDM/chatglm3-6b) 与 Embedding
模型 [BAAI/bge-large-zh](https://huggingface.co/BAAI/bge-large-zh) 为例:
下载模型需要先[安装 Git LFS](https://docs.github.com/zh/repositories/working-with-files/managing-large-files/installing-git-large-file-storage)
,然后运行
下载模型需要先[安装 Git LFS](https://docs.github.com/zh/repositories/working-with-files/managing-large-files/installing-git-large-file-storage),然后运行
```Shell
$ git lfs install
$ git clone https://huggingface.co/THUDM/chatglm3-6b
$ git clone https://huggingface.co/BAAI/bge-large-zh
$ git clone https://huggingface.co/THUDM/chatglm2-6b
$ git clone https://huggingface.co/moka-ai/m3e-base
```
### 3. 初始化知识库和配置文件
按照下列方式初始化自己的知识库和简单的复制配置文件
```shell
$ python copy_config_example.py
$ python init_database.py --recreate-vs
```
### 4. 一键启动
按照以下命令启动项目
```shell
$ python startup.py -a
```
### 5. 启动界面示例
如果正常启动,你将能看到以下界面
@ -166,41 +127,22 @@ $ python startup.py -a
![](img/init_knowledge_base.jpg)
### 注意
以上方式只是为了快速上手,如果需要更多的功能和自定义启动方式
,请参考[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/)
以上方式只是为了快速上手,如果需要更多的功能和自定义启动方式 ,请参考[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/)
---
## 项目里程碑
+ `2023年4月`: `Langchain-ChatGLM 0.1.0` 发布,支持基于 ChatGLM-6B 模型的本地知识库问答。
+ `2023年8月`: `Langchain-ChatGLM` 改名为 `Langchain-Chatchat``0.2.0` 发布,使用 `fastchat` 作为模型加载方案,支持更多的模型和数据库。
+ `2023年10月`: `Langchain-Chatchat 0.2.5` 发布,推出 Agent 内容,开源项目在`Founder Park & Zhipu AI & Zilliz`
举办的黑客马拉松获得三等奖。
+ `2023年12月`: `Langchain-Chatchat` 开源项目获得超过 **20K** stars.
+ `2024年1月`: `LangChain 0.1.x` 推出,`Langchain-Chatchat 0.2.x` 发布稳定版本`0.2.10`
后将停止更新和技术支持,全力研发具有更强应用性的 `Langchain-Chatchat 0.3.x`
+ 🔥 让我们一起期待未来 Chatchat 的故事 ···
---
## 联系我们
### Telegram
[![Telegram](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white "langchain-chatglm")](https://t.me/+RjliQ3jnJ1YyN2E9)
### 项目交流群
<img src="img/qr_code_108.jpg" alt="二维码" width="300" />
<img src="img/qr_code_67.jpg" alt="二维码" width="300" />
🎉 Langchain-Chatchat 项目微信交流群,如果你也对本项目感兴趣,欢迎加入群聊参与讨论交流。
### 公众号
<img src="img/official_wechat_mp_account.png" alt="二维码" width="300" />
![](img/official_wechat_mp_account.png)
🎉 Langchain-Chatchat 项目官方公众号,欢迎扫码关注。

View File

@ -1,18 +1,12 @@
![](img/logo-long-chatchat-trans-v2.png)
🌍 [中文文档](README.md)
🌍 [日本語で読む](README_ja.md)
📃 **LangChain-Chatchat** (formerly Langchain-ChatGLM):
A LLM application aims to implement knowledge and search engine based QA based on Langchain and open-source or remote
LLM API.
⚠️`0.2.10` will be the last version of the `0.2.x` series. The `0.2.x` series will stop updating and technical support,
and strive to develop `Langchain-Chachat 0.3.x` with stronger applicability.
Subsequent bug fixes for `0.2.10` will be pushed directly to the `master` branch without version updates.
---
## Table of Contents
@ -26,15 +20,15 @@ Subsequent bug fixes for `0.2.10` will be pushed directly to the `master` branch
- [4. One-Click Startup](README.md#4-One-Click-Startup)
- [5. Startup Interface Examples](README.md#5-Startup-Interface-Examples)
- [Contact Us](README.md#Contact-Us)
- [List of Partner Organizations](README.md#List-of-Partner-Organizations)
## Introduction
🤖️ A Q&A application based on local knowledge base implemented using the idea
of [langchain](https://github.com/langchain-ai/langchain). The goal is to build a KBQA(Knowledge based Q&A) solution
that
of [langchain](https://github.com/hwchase17/langchain). The goal is to build a KBQA(Knowledge based Q&A) solution that
is friendly to Chinese scenarios and open source models and can run both offline and online.
💡 Inspired by [document.ai](https://github.com/GanymedeNil/document.ai)
💡 Inspried by [document.ai](https://github.com/GanymedeNil/document.ai)
and [ChatGLM-6B Pull Request](https://github.com/THUDM/ChatGLM-6B/pull/216) , we build a local knowledge base question
answering application that can be implemented using an open source model or remote LLM api throughout the process. In
the latest version of this project, [FastChat](https://github.com/lm-sys/FastChat) is used to access Vicuna, Alpaca,
@ -48,10 +42,10 @@ to expand the access to various models and remote APIs in the future.
⛓️ The implementation principle of this project is shown in the graph below. The main process includes: loading files ->
reading text -> text segmentation -> text vectorization -> question vectorization -> matching the `top-k` most similar
to the question vector in the text vector -> The matched text is added to `prompt `as context and question -> submitte
to the question vector in the text vector -> The matched text is added to `prompt `as context and question -> submitted
to `LLM` to generate an answer.
📺[video introduction](https://www.bilibili.com/video/BV13M4y1e7cN/?share_source=copy_web&vd_source=e6c5aafe684f30fbe41925d61ca6d514)
📺[video introdution](https://www.bilibili.com/video/BV13M4y1e7cN/?share_source=copy_web&vd_source=e6c5aafe684f30fbe41925d61ca6d514)
![实现原理图](img/langchain+chatglm.png)
@ -59,20 +53,13 @@ The main process analysis from the aspect of document process:
![实现原理图2](img/langchain+chatglm2.png)
🚩 The training or fine-tuning are not involved in the project, but still, one always can improve performance by do
🚩 The training or fined-tuning are not involved in the project, but still, one always can improve performance by do
these.
🌐 [AutoDL image](https://www.codewithgpu.com/i/chatchat-space/Langchain-Chatchat/Langchain-Chatchat) is supported, and in `0.2.10` the codes are update to v0.2.10.
🌐 [AutoDL image](registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.5) is supported, and in v9 the codes are update
to v0.2.5.
🐳 [Docker image](isafetech/chatchat:0.2.10) is supported to ```0.2.10```.
🌲 The latest update also provides support for image sources from DockerHub, Ali Cloud, and Tencent Cloud:
```shell
docker run -d --gpus all -p 80:8501 isafetech/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 uswccr.ccs.tencentyun.com/chatchat/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.10
```
🐳 [Docker image](registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.5)
## Pain Points Addressed
@ -113,9 +100,6 @@ $ pip install -r requirements_webui.txt
# 默认依赖包括基本运行环境FAISS向量库。如果要使用 milvus/pg_vector 等向量库,请将 requirements.txt 中相应依赖取消注释再安装。
```
Please note that the LangChain-Chachat `0.2.x` series is for the Langchain `0.0.x` series version. If you are using the
Langchain `0.1.x` series version, you need to downgrade.
### Model Download
If you need to run this project locally or in an offline environment, you must first download the required models for
@ -174,33 +158,15 @@ please refer to the [Wiki](https://github.com/chatchat-space/Langchain-Chatchat/
---
## Project Milestones
+ `April 2023`: `Langchain-ChatGLM 0.1.0` released, supporting local knowledge base question and answer based on the
ChatGLM-6B model.
+ `August 2023`: `Langchain-ChatGLM` was renamed to `Langchain-Chatchat`, `0.2.0` was released, using `fastchat` as the
model loading solution, supporting more models and databases.
+ `October 2023`: `Langchain-Chachat 0.2.5` was released, Agent content was launched, and the open source project won
the third prize in the hackathon held by `Founder Park & Zhipu AI & Zilliz`.
+ `December 2023`: `Langchain-Chachat` open source project received more than **20K** stars.
+ `January 2024`: `LangChain 0.1.x` is launched, `Langchain-Chachat 0.2.x` is released. After the stable
version `0.2.10` is released, updates and technical support will be stopped, and all efforts will be made to
develop `Langchain with stronger applicability -Chat 0.3.x`.
+ 🔥 Lets look forward to the future Chatchat stories together···
---
## Contact Us
### Telegram
[![Telegram](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white "langchain-chatglm")](https://t.me/+RjliQ3jnJ1YyN2E9)
### WeChat Group
### WeChat Group、
<img src="img/qr_code_90.jpg" alt="二维码" width="300" height="300" />
<img src="img/qr_code_67.jpg" alt="二维码" width="300" height="300" />
### WeChat Official Account

View File

@ -1,200 +0,0 @@
![](img/logo-long-chatchat-trans-v2.png)
🌍 [中文文档](README.md)
🌍 [READ THIS IN ENGLISH](README_en.md)
📃 **LangChain-Chatchat** (旧名 Langchain-ChatGLM)
ChatGLM などの大規模な言語モデルや Langchain などのアプリケーション フレームワークに基づいた、オープン
ソースのオフライン展開可能な検索拡張生成 (RAG) 大規模モデル ナレッジ ベース プロジェクトです。
⚠️`0.2.10``0.2.x` シリーズの最終バージョンとなり、`0.2.x`
シリーズはアップデートと技術サポートを終了し、より適用性の高い `Langchain-Chachat 0.3.x` の開発に努めます。 。
`0.2.10` のその後のバグ修正は、バージョン更新なしで `master` ブランチに直接プッシュされます。
---
## 目次
- [イントロ](README_ja.md#イントロ)
- [ペインポイントへの対応](README_ja.md#ペインポイントへの対応)
- [クイックスタート](README_ja.md#クイックスタート)
- [1. 環境セットアップ](README_ja.md#環境セットアップ)
- [2. モデルをダウンロード](README_ja.md#モデルをダウンロード)
- [3. ナレッジベースと設定ファイルの初期化](README_ja.md#ナレッジベースと設定ファイルの初期化)
- [4. ワンクリック起動](README_ja.md#ワンクリック起動)
- [5. 起動インターフェースの例](README_ja.md#起動インターフェースの例)
- [お問い合わせ](README_ja.md#お問い合わせ)
## イントロ
🤖️ [langchain](https://github.com/hwchase17/langchain) のアイデアを用いて実装された、ローカルナレッジベースに基づく Q&A
アプリケーション。
目標は、中国のシナリオとオープンソースモデルに親和性があり、オフラインとオンラインの両方で実行可能な KBQAナレッジベースの
Q&Aソリューションを構築することです。
💡 [document.ai](https://github.com/GanymedeNil/document.ai)
と [ChatGLM-6B Pull Request](https://github.com/THUDM/ChatGLM-6B/pull/216) に触発され、
プロセス全体を通してオープンソースモデルまたはリモート LLM api を使用して実装することができるローカルナレッジベースの質問応答アプリケーションを構築します。
このプロジェクトの最新バージョンでは、[FastChat](https://github.com/lm-sys/FastChat)
を使用して、Vicuna、Alpaca、LLaMA、Koala、RWKV、その他多くのモデルにアクセスしています。
このプロジェクトは [langchain](https://github.com/langchain-ai/langchain)
に依存し、[FastAPI](https://github.com/tiangolo/fastapi) に基づいて提供されるAPIを通してサービスを呼び出したり、
[Streamlit](https://github.com/streamlit/streamlit) に基づいて WebUI を使ったりすることをサポートしています。
✅ オープンソースの LLM と Embedding モデルに依存して、このプロジェクトはフルプロセスの **オフラインプライベートデプロイメント
** を実現することができます。
同時に、本プロジェクトは OpenAI GPT API や Zhipu API の呼び出しにも対応しており、今後も様々な機種やリモート API
へのアクセスを拡大していきます。
⛓️ このプロジェクトの実施原則を下のグラフに示します。主なプロセスは以下の通りです:
ファイルの読み込み -> テキストの読み込み -> テキストのセグメンテーション -> テキストのベクトル化 -> 質問のベクトル化 ->
質問ベクトルと最も似ている `top-k` をテキストベクトルでマッチング ->
マッチしたテキストをコンテキストと質問として `prompt` に追加 -> 回答を生成するために `LLM` に送信。
📺[video introduction](https://www.bilibili.com/video/BV13M4y1e7cN/?share_source=copy_web&vd_source=e6c5aafe684f30fbe41925d61ca6d514)
![实现原理图](img/langchain+chatglm.png)
文書プロセスの側面からの主なプロセス分析:
![实现原理图2](img/langchain+chatglm2.png)
🚩 トレーニングやファインチューニングはプロジェクトには含まれないが、これらを行うことで必ずパフォーマンスを向上させることができます。
🌐 [AutoDL イメージ](registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.5)がサポートされ、`0.2.10` では v0.2.10
にアップデートされました。
🐳 [Docker イメージ](isafetech/chatchat:0.2.10)
🌲 今回のアップデートにより、DockerHub、阿里雲、騰訊のクラウドにも対応しました。より広範なクラウド環境で利用可能となりました。
```shell
docker run -d --gpus all -p 80:8501 isafetech/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 uswccr.ccs.tencentyun.com/chatchat/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.10
```
## ペインポイントへの対応
このプロジェクトは、完全にローカライズされた推論によってナレッジベースを強化するソリューションであり、特にデータセキュリティと企業向けのプライベートな展開の問題に取り組んでいます。
このオープンソースソリューションは Apache ライセンスに基づき、無償で商用利用できます。
私たちは、市場で入手可能な主流のローカル大予言モデルや Embedding モデル、オープンソースのローカルベクターデータベースをサポートしています。
対応機種とデータベースの詳細については、[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/) をご参照ください。
## クイックスタート
### 環境セットアップ
まず、マシンにPython 3.10がインストールされていることを確認してください。
```
$ python --version
Python 3.11.7
```
次に、仮想環境を作成し、プロジェクトの依存関係を仮想環境内にインストールする。
```shell
# リポジトリをクローン
$ git clone https://github.com/chatchat-space/Langchain-Chatchat.git
# ディレクトリに移動
$ cd Langchain-Chatchat
# すべての依存関係をインストール
$ pip install -r requirements.txt
$ pip install -r requirements_api.txt
$ pip install -r requirements_webui.txt
# デフォルトの依存関係には、基本的な実行環境(FAISS ベクターライブラリ)が含まれます。milvus/pg_vector などのベクターライブラリを使用する場合は、requirements.txt 内の対応する依存関係のコメントを解除してからインストールしてください。
```
LangChain-Chachat `0.2.x` シリーズは Langchain `0.0.x` シリーズ用です。Langchain `0.1.x` シリーズをお使いの場合は、ダウングレードする必要があります。
### モデルをダウンロード
このプロジェクトをローカルまたはオフライン環境で実行する必要がある場合は、まずプロジェクトに必要なモデルをダウンロードする必要があります。
通常、オープンソースの LLM と Embedding モデルは Hugging Face からダウンロードできる。
このプロジェクトで使用されているデフォルトの LLM
モデルである [THUDM/chatglm2-6b](https://huggingface.co/THUDM/chatglm2-6b)と、Embedding
モデル [moka-ai/m3e-base](https://huggingface.co/moka-ai/m3e-base) を例にとると、次のようになります:
モデルをダウンロードするには、まず [Git LFS](https://docs.github.com/zh/repositories/working-with-files/managing-large-files/installing-git-large-file-storage)
をインストールし、次のように実行する必要があります:
```Shell
$ git lfs install
$ git clone https://huggingface.co/THUDM/chatglm2-6b
$ git clone https://huggingface.co/moka-ai/m3e-base
```
### ナレッジベースと設定ファイルの初期化
以下の手順に従って、ナレッジベースと設定ファイルを初期化してください:
```shell
$ python copy_config_example.py
$ python init_database.py --recreate-vs
```
### ワンクリック起動
プロジェクトを開始するには、次のコマンドを実行します:
```shell
$ python startup.py -a
```
### 起動インターフェースの例
1. FastAPI docs インターフェース
![](img/fastapi_docs_026.png)
2. webui ページ
- Web UI ダイアログページ:
![img](img/LLM_success.png)
- Web UI ナレッジベースマネジメントページ:
![](img/init_knowledge_base.jpg)
### 注
上記の手順はクイックスタートのために提供されています。より多くの機能が必要な場合や、起動方法をカスタマイズしたい場合は、[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/)
を参照してください。
---
## プロジェクトのマイルストーン
+ `2023 年 4 月`: `Langchain-ChatGLM 0.1.0` がリリースされ、ChatGLM-6B モデルに基づくローカル ナレッジ ベースの質問と回答がサポートされました。
+ `2023 年 8 月`: `Langchain-ChatGLM``Langchain-Chatchat` に名前変更され、モデル読み込みソリューションとして `fastchat` を使用し、より多くのモデルとデータベースをサポートする `0.2.0` がリリースされました。
+ `2023 年 10 月`: `Langchain-Chachat 0.2.5` リリース、エージェント コンテンツ、オープンソース プロジェクトを`Founder Park & Zhipu AI & Zilliz`で開始
開催したハッカソンでは3位に入賞しました。
+ `2023 年 12 月`: `Langchain-Chachat`オープンソース プロジェクトは **20,000** つ以上のスターを獲得しました。
+ `2024 年 1 月`: `LangChain 0.1.x` がリリースされ、`Langchain-Chachat 0.2.x` が安定版 `0.2.10` をリリースしました。
今後はアップデートと技術サポートを停止し、より適用性の高い`Langchain-Chachat 0.3.x`の開発に努める予定です。
+ 🔥 これからのChatchatストーリーを一緒に楽しみにしましょう···
---
## お問い合わせ
### Telegram
[![Telegram](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white "langchain-chatglm")](https://t.me/+RjliQ3jnJ1YyN2E9)
### WeChat グループ
<img src="img/qr_code_90.jpg" alt="二维码" width="300" height="300" />
### WeChat 公式アカウント
<img src="img/official_wechat_mp_account.png" alt="图片" width="900" height="300" />

View File

@ -1,12 +1,12 @@
from server.utils import get_ChatOpenAI
from configs.model_config import LLM_MODELS, TEMPERATURE
from configs.model_config import LLM_MODEL, TEMPERATURE
from langchain.chains import LLMChain
from langchain.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
model = get_ChatOpenAI(model_name=LLM_MODELS[0], temperature=TEMPERATURE)
model = get_ChatOpenAI(model_name=LLM_MODEL, temperature=TEMPERATURE)
human_prompt = "{input}"

View File

@ -5,4 +5,4 @@ from .server_config import *
from .prompt_config import *
VERSION = "v0.2.10"
VERSION = "v0.2.6"

View File

@ -1,14 +1,12 @@
import logging
import os
import langchain
import tempfile
import shutil
# 是否显示详细日志
log_verbose = False
langchain.verbose = False
# 通常情况下不需要更改以下内容
# 日志格式
@ -22,11 +20,3 @@ logging.basicConfig(format=LOG_FORMAT)
LOG_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "logs")
if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
# 临时文件目录,主要用于文件对话
BASE_TEMP_DIR = os.path.join(tempfile.gettempdir(), "chatchat")
try:
shutil.rmtree(BASE_TEMP_DIR)
except Exception:
pass
os.makedirs(BASE_TEMP_DIR, exist_ok=True)

View File

@ -3,15 +3,12 @@ import os
# 默认使用的知识库
DEFAULT_KNOWLEDGE_BASE = "samples"
# 默认向量库/全文检索引擎类型。可选faiss, milvus(离线) & zilliz(在线), pgvector, chromadb 全文检索引擎es
# 默认向量库类型。可选faiss, milvus(离线) & zilliz(在线), pg.
DEFAULT_VS_TYPE = "faiss"
# 缓存向量库数量针对FAISS
CACHED_VS_NUM = 1
# 缓存临时向量库数量针对FAISS用于文件对话
CACHED_MEMO_VS_NUM = 10
# 知识库中单段文本长度(不适用MarkdownHeaderTextSplitter)
CHUNK_SIZE = 250
@ -21,9 +18,8 @@ OVERLAP_SIZE = 50
# 知识库匹配向量数量
VECTOR_SEARCH_TOP_K = 3
# 知识库匹配的距离阈值一般取值范围在0-1之间SCORE越小距离越小从而相关度越高。
# 但有用户报告遇到过匹配分值超过1的情况为了兼容性默认设为1在WEBUI中调整范围为0-2
SCORE_THRESHOLD = 1.0
# 知识库匹配相关度阈值取值范围在0-1之间SCORE越小相关度越高取到1相当于不筛选建议设置在0.5左右
SCORE_THRESHOLD = 1
# 默认搜索引擎。可选bing, duckduckgo, metaphor
DEFAULT_SEARCH_ENGINE = "duckduckgo"
@ -48,27 +44,19 @@ BING_SUBSCRIPTION_KEY = ""
# metaphor搜索需要KEY
METAPHOR_API_KEY = ""
# 心知天气 API KEY用于天气Agent。申请https://www.seniverse.com/
SENIVERSE_API_KEY = ""
# 是否开启中文标题加强,以及标题增强的相关配置
# 通过增加标题判断判断哪些文本为标题并在metadata中进行标记
# 然后将文本与往上一级的标题进行拼合,实现文本信息的增强。
ZH_TITLE_ENHANCE = False
# PDF OCR 控制:只对宽高超过页面一定比例(图片宽/页面宽,图片高/页面高)的图片进行 OCR。
# 这样可以避免 PDF 中一些小图片的干扰,提高非扫描版 PDF 处理速度
PDF_OCR_THRESHOLD = (0.6, 0.6)
# 每个知识库的初始化介绍用于在初始化知识库时显示和Agent调用没写则没有介绍不会被Agent调用。
KB_INFO = {
"知识库名称": "知识库介绍",
"samples": "关于本项目issue的解答",
}
# 通常情况下不需要更改以下内容
# 知识库默认存储路径
KB_ROOT_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "knowledge_base")
if not os.path.exists(KB_ROOT_PATH):
@ -98,26 +86,13 @@ kbs_config = {
},
"pg": {
"connection_uri": "postgresql://postgres:postgres@127.0.0.1:5432/langchain_chatchat",
},
"es": {
"host": "127.0.0.1",
"port": "9200",
"index_name": "test_index",
"user": "",
"password": ""
},
"milvus_kwargs":{
"search_params":{"metric_type": "L2"}, #在此处增加search_params
"index_params":{"metric_type": "L2","index_type": "HNSW"} # 在此处增加index_params
},
"chromadb": {}
}
}
# TextSplitter配置项如果你不明白其中的含义就不要修改。
text_splitter_dict = {
"ChineseRecursiveTextSplitter": {
"source": "huggingface", # 选择tiktoken则使用openai的方法
"source": "huggingface", ## 选择tiktoken则使用openai的方法
"tokenizer_name_or_path": "",
},
"SpacyTextSplitter": {
@ -141,6 +116,3 @@ text_splitter_dict = {
# TEXT_SPLITTER 名称
TEXT_SPLITTER_NAME = "ChineseRecursiveTextSplitter"
# Embedding模型定制词语的词表文件
EMBEDDING_KEYWORD_FILE = "embedding_keywords.txt"

View File

@ -1,146 +1,10 @@
import os
# 可以指定一个绝对路径统一存放所有的Embedding和LLM模型。
# 每个模型可以是一个单独的目录,也可以是某个目录下的二级子目录。
# 如果模型目录名称和 MODEL_PATH 中的 key 或 value 相同,程序会自动检测加载,无需修改 MODEL_PATH 中的路径。
# 每个模型可以是一个单独的目录,也可以是某个目录下的二级子目录
MODEL_ROOT_PATH = ""
# 选用的 Embedding 名称
EMBEDDING_MODEL = "bge-large-zh-v1.5"
# Embedding 模型运行设备。设为 "auto" 会自动检测(会有警告),也可手动设定为 "cuda","mps","cpu","xpu" 其中之一。
EMBEDDING_DEVICE = "auto"
# 选用的reranker模型
RERANKER_MODEL = "bge-reranker-large"
# 是否启用reranker模型
USE_RERANKER = False
RERANKER_MAX_LENGTH = 1024
# 如果需要在 EMBEDDING_MODEL 中增加自定义的关键字时配置
EMBEDDING_KEYWORD_FILE = "keywords.txt"
EMBEDDING_MODEL_OUTPUT_PATH = "output"
# 要运行的 LLM 名称,可以包括本地模型和在线模型。列表中本地模型将在启动项目时全部加载。
# 列表中第一个模型将作为 API 和 WEBUI 的默认模型。
# 在这里我们使用目前主流的两个离线模型其中chatglm3-6b 为默认加载模型。
# 如果你的显存不足,可使用 Qwen-1_8B-Chat, 该模型 FP16 仅需 3.8G显存。
LLM_MODELS = ["chatglm3-6b", "zhipu-api", "openai-api"]
Agent_MODEL = None
# LLM 模型运行设备。设为"auto"会自动检测(会有警告),也可手动设定为 "cuda","mps","cpu","xpu" 其中之一。
LLM_DEVICE = "auto"
HISTORY_LEN = 3
MAX_TOKENS = 2048
TEMPERATURE = 0.7
ONLINE_LLM_MODEL = {
"openai-api": {
"model_name": "gpt-4",
"api_base_url": "https://api.openai.com/v1",
"api_key": "",
"openai_proxy": "",
},
# 智谱AI API,具体注册及api key获取请前往 http://open.bigmodel.cn
"zhipu-api": {
"api_key": "",
"version": "glm-4",
"provider": "ChatGLMWorker",
},
# 具体注册及api key获取请前往 https://api.minimax.chat/
"minimax-api": {
"group_id": "",
"api_key": "",
"is_pro": False,
"provider": "MiniMaxWorker",
},
# 具体注册及api key获取请前往 https://xinghuo.xfyun.cn/
"xinghuo-api": {
"APPID": "",
"APISecret": "",
"api_key": "",
"version": "v3.5", # 你使用的讯飞星火大模型版本,可选包括 "v3.5","v3.0", "v2.0", "v1.5"
"provider": "XingHuoWorker",
},
# 百度千帆 API申请方式请参考 https://cloud.baidu.com/doc/WENXINWORKSHOP/s/4lilb2lpf
"qianfan-api": {
"version": "ERNIE-Bot", # 注意大小写。当前支持 "ERNIE-Bot" 或 "ERNIE-Bot-turbo" 更多的见官方文档。
"version_url": "", # 也可以不填写version直接填写在千帆申请模型发布的API地址
"api_key": "",
"secret_key": "",
"provider": "QianFanWorker",
},
# 火山方舟 API文档参考 https://www.volcengine.com/docs/82379
"fangzhou-api": {
"version": "", # 对应火山方舟的 endpoint_id
"version_url": "",
"api_key": "",
"secret_key": "",
"provider": "FangZhouWorker",
},
# 阿里云通义千问 API文档参考 https://help.aliyun.com/zh/dashscope/developer-reference/api-details
"qwen-api": {
"version": "qwen-max",
"api_key": "",
"provider": "QwenWorker",
"embed_model": "text-embedding-v1" # embedding 模型名称
},
# 百川 API申请方式请参考 https://www.baichuan-ai.com/home#api-enter
"baichuan-api": {
"version": "Baichuan2-53B",
"api_key": "",
"secret_key": "",
"provider": "BaiChuanWorker",
},
# Azure API
"azure-api": {
"deployment_name": "", # 部署容器的名字
"resource_name": "", # https://{resource_name}.openai.azure.com/openai/ 填写resource_name的部分其他部分不要填写
"api_version": "", # API的版本不是模型版本
"api_key": "",
"provider": "AzureWorker",
},
# 昆仑万维天工 API https://model-platform.tiangong.cn/
"tiangong-api": {
"version": "SkyChat-MegaVerse",
"api_key": "",
"secret_key": "",
"provider": "TianGongWorker",
},
# Gemini API https://makersuite.google.com/app/apikey
"gemini-api": {
"api_key": "",
"provider": "GeminiWorker",
},
# Claude API : https://www.anthropic.com/api
# Available models:
# Claude 3 Opus: claude-3-opus-20240229
# Claude 3 Sonnet claude-3-sonnet-20240229
# Claude 3 Haiku claude-3-haiku-20240307
"claude-api": {
"api_key": "",
"version": "2023-06-01",
"model_name":"claude-3-opus-20240229",
"provider": "ClaudeWorker",
}
}
# 在以下字典中修改属性值以指定本地embedding模型存储位置。支持3种设置方法
# 1、将对应的值修改为模型绝对路径
# 2、不修改此处的值以 text2vec 为例):
@ -149,7 +13,6 @@ ONLINE_LLM_MODEL = {
# - GanymedeNil/text2vec-large-chinese
# - text2vec-large-chinese
# 2.2 如果以上本地路径不存在则使用huggingface模型
MODEL_PATH = {
"embed_model": {
"ernie-tiny": "nghuyong/ernie-3.0-nano-zh",
@ -163,165 +26,234 @@ MODEL_PATH = {
"m3e-small": "moka-ai/m3e-small",
"m3e-base": "moka-ai/m3e-base",
"m3e-large": "moka-ai/m3e-large",
"bge-small-zh": "BAAI/bge-small-zh",
"bge-base-zh": "BAAI/bge-base-zh",
"bge-large-zh": "BAAI/bge-large-zh",
"bge-large-zh-noinstruct": "BAAI/bge-large-zh-noinstruct",
"bge-base-zh-v1.5": "BAAI/bge-base-zh-v1.5",
"bge-large-zh-v1.5": "BAAI/bge-large-zh-v1.5",
"bge-m3": "BAAI/bge-m3",
"piccolo-base-zh": "sensenova/piccolo-base-zh",
"piccolo-large-zh": "sensenova/piccolo-large-zh",
"nlp_gte_sentence-embedding_chinese-large": "damo/nlp_gte_sentence-embedding_chinese-large",
"text-embedding-ada-002": "your OPENAI_API_KEY",
},
# TODO: add all supported llm models
"llm_model": {
# 以下部分模型并未完全测试仅根据fastchat和vllm模型的模型列表推定支持
"chatglm-6b": "THUDM/chatglm-6b",
"chatglm2-6b": "THUDM/chatglm2-6b",
"chatglm2-6b-int4": "THUDM/chatglm2-6b-int4",
"chatglm2-6b-32k": "THUDM/chatglm2-6b-32k",
"chatglm3-6b": "THUDM/chatglm3-6b",
"chatglm3-6b-32k": "THUDM/chatglm3-6b-32k",
"Orion-14B-Chat": "OrionStarAI/Orion-14B-Chat",
"Orion-14B-Chat-Plugin": "OrionStarAI/Orion-14B-Chat-Plugin",
"Orion-14B-LongChat": "OrionStarAI/Orion-14B-LongChat",
"baichuan2-13b": "baichuan-inc/Baichuan2-13B-Chat",
"baichuan2-7b":"baichuan-inc/Baichuan2-7B-Chat",
"Llama-2-7b-chat-hf": "meta-llama/Llama-2-7b-chat-hf",
"Llama-2-13b-chat-hf": "meta-llama/Llama-2-13b-chat-hf",
"Llama-2-70b-chat-hf": "meta-llama/Llama-2-70b-chat-hf",
"baichuan-7b": "baichuan-inc/Baichuan-7B",
"baichuan-13b": "baichuan-inc/Baichuan-13B",
'baichuan-13b-chat':'baichuan-inc/Baichuan-13B-Chat',
"Qwen-1_8B-Chat": "Qwen/Qwen-1_8B-Chat",
"Qwen-7B-Chat": "Qwen/Qwen-7B-Chat",
"Qwen-14B-Chat": "Qwen/Qwen-14B-Chat",
"Qwen-72B-Chat": "Qwen/Qwen-72B-Chat",
"aquila-7b":"BAAI/Aquila-7B",
"aquilachat-7b":"BAAI/AquilaChat-7B",
# Qwen1.5 模型 VLLM可能出现问题
"Qwen1.5-0.5B-Chat": "Qwen/Qwen1.5-0.5B-Chat",
"Qwen1.5-1.8B-Chat": "Qwen/Qwen1.5-1.8B-Chat",
"Qwen1.5-4B-Chat": "Qwen/Qwen1.5-4B-Chat",
"Qwen1.5-7B-Chat": "Qwen/Qwen1.5-7B-Chat",
"Qwen1.5-14B-Chat": "Qwen/Qwen1.5-14B-Chat",
"Qwen1.5-72B-Chat": "Qwen/Qwen1.5-72B-Chat",
"internlm-7b":"internlm/internlm-7b",
"internlm-chat-7b":"internlm/internlm-chat-7b",
"baichuan-7b-chat": "baichuan-inc/Baichuan-7B-Chat",
"baichuan-13b-chat": "baichuan-inc/Baichuan-13B-Chat",
"baichuan2-7b-chat": "baichuan-inc/Baichuan2-7B-Chat",
"baichuan2-13b-chat": "baichuan-inc/Baichuan2-13B-Chat",
"falcon-7b":"tiiuae/falcon-7b",
"falcon-40b":"tiiuae/falcon-40b",
"falcon-rw-7b":"tiiuae/falcon-rw-7b",
"internlm-7b": "internlm/internlm-7b",
"internlm-chat-7b": "internlm/internlm-chat-7b",
"internlm2-chat-7b": "internlm/internlm2-chat-7b",
"internlm2-chat-20b": "internlm/internlm2-chat-20b",
"gpt2":"gpt2",
"gpt2-xl":"gpt2-xl",
"gpt-j-6b":"EleutherAI/gpt-j-6b",
"gpt4all-j":"nomic-ai/gpt4all-j",
"gpt-neox-20b":"EleutherAI/gpt-neox-20b",
"pythia-12b":"EleutherAI/pythia-12b",
"oasst-sft-4-pythia-12b-epoch-3.5":"OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5",
"dolly-v2-12b":"databricks/dolly-v2-12b",
"stablelm-tuned-alpha-7b":"stabilityai/stablelm-tuned-alpha-7b",
"BlueLM-7B-Chat": "vivo-ai/BlueLM-7B-Chat",
"BlueLM-7B-Chat-32k": "vivo-ai/BlueLM-7B-Chat-32k",
"Llama-2-13b-hf":"meta-llama/Llama-2-13b-hf",
"Llama-2-70b-hf":"meta-llama/Llama-2-70b-hf",
"open_llama_13b":"openlm-research/open_llama_13b",
"vicuna-13b-v1.3":"lmsys/vicuna-13b-v1.3",
"koala":"young-geng/koala",
"mpt-7b":"mosaicml/mpt-7b",
"mpt-7b-storywriter":"mosaicml/mpt-7b-storywriter",
"mpt-30b":"mosaicml/mpt-30b",
"opt-66b":"facebook/opt-66b",
"opt-iml-max-30b":"facebook/opt-iml-max-30b",
"Yi-34B-Chat": "https://huggingface.co/01-ai/Yi-34B-Chat",
"agentlm-7b": "THUDM/agentlm-7b",
"agentlm-13b": "THUDM/agentlm-13b",
"agentlm-70b": "THUDM/agentlm-70b",
"falcon-7b": "tiiuae/falcon-7b",
"falcon-40b": "tiiuae/falcon-40b",
"falcon-rw-7b": "tiiuae/falcon-rw-7b",
"aquila-7b": "BAAI/Aquila-7B",
"aquilachat-7b": "BAAI/AquilaChat-7B",
"open_llama_13b": "openlm-research/open_llama_13b",
"vicuna-13b-v1.5": "lmsys/vicuna-13b-v1.5",
"koala": "young-geng/koala",
"mpt-7b": "mosaicml/mpt-7b",
"mpt-7b-storywriter": "mosaicml/mpt-7b-storywriter",
"mpt-30b": "mosaicml/mpt-30b",
"opt-66b": "facebook/opt-66b",
"opt-iml-max-30b": "facebook/opt-iml-max-30b",
"gpt2": "gpt2",
"gpt2-xl": "gpt2-xl",
"gpt-j-6b": "EleutherAI/gpt-j-6b",
"gpt4all-j": "nomic-ai/gpt4all-j",
"gpt-neox-20b": "EleutherAI/gpt-neox-20b",
"pythia-12b": "EleutherAI/pythia-12b",
"oasst-sft-4-pythia-12b-epoch-3.5": "OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5",
"dolly-v2-12b": "databricks/dolly-v2-12b",
"stablelm-tuned-alpha-7b": "stabilityai/stablelm-tuned-alpha-7b",
"Qwen-7B":"Qwen/Qwen-7B",
"Qwen-14B":"Qwen/Qwen-14B",
"Qwen-7B-Chat":"Qwen/Qwen-7B-Chat",
"Qwen-14B-Chat":"Qwen/Qwen-14B-Chat",
},
}
# 选用的 Embedding 名称
EMBEDDING_MODEL = "m3e-base" # 可以尝试最新的嵌入式sota模型bge-large-zh-v1.5
"reranker": {
"bge-reranker-large": "BAAI/bge-reranker-large",
"bge-reranker-base": "BAAI/bge-reranker-base",
# Embedding 模型运行设备。设为"auto"会自动检测,也可手动设定为"cuda","mps","cpu"其中之一。
EMBEDDING_DEVICE = "auto"
# LLM 名称
LLM_MODEL = "chatglm2-6b"
# LLM 运行设备。设为"auto"会自动检测,也可手动设定为"cuda","mps","cpu"其中之一。
LLM_DEVICE = "auto"
# 历史对话轮数
HISTORY_LEN = 3
# LLM通用对话参数
TEMPERATURE = 0.7
# TOP_P = 0.95 # ChatOpenAI暂不支持该参数
LANGCHAIN_LLM_MODEL = {
# 不需要走Fschat封装的Langchain直接支持的模型。
# 调用chatgpt时如果报出 urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='api.openai.com', port=443):
# Max retries exceeded with url: /v1/chat/completions
# 则需要将urllib3版本修改为1.25.11
# 如果依然报urllib3.exceptions.MaxRetryError: HTTPSConnectionPool则将https改为http
# 参考https://zhuanlan.zhihu.com/p/350015032
# 如果报出raise NewConnectionError(
# urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x000001FE4BDB85E0>:
# Failed to establish a new connection: [WinError 10060]
# 则是因为内地和香港的IP都被OPENAI封了需要切换为日本、新加坡等地
# 如果出现WARNING: Retrying langchain.chat_models.openai.acompletion_with_retry.<locals>._completion_with_retry in
# 4.0 seconds as it raised APIConnectionError: Error communicating with OpenAI.
# 需要添加代理访问(正常开的代理软件可能会拦截不上)需要设置配置openai_proxy 或者 使用环境遍历OPENAI_PROXY 进行设置
# 比如: "openai_proxy": 'http://127.0.0.1:4780'
# 这些配置文件的名字不能改动
"Azure-OpenAI": {
"deployment_name": "your Azure deployment name",
"model_version": "0701",
"openai_api_type": "azure",
"api_base_url": "https://your Azure point.azure.com",
"api_version": "2023-07-01-preview",
"api_key": "your Azure api key",
"openai_proxy": "",
},
"OpenAI": {
"model_name": "your openai model name(such as gpt-4)",
"api_base_url": "https://api.openai.com/v1",
"api_key": "your OPENAI_API_KEY",
"openai_proxy": "",
},
"Anthropic": {
"model_name": "your claude model name(such as claude2-100k)",
"api_key":"your ANTHROPIC_API_KEY",
}
}
ONLINE_LLM_MODEL = {
# 线上模型。请在server_config中为每个在线API设置不同的端口
# 具体注册及api key获取请前往 http://open.bigmodel.cn
"zhipu-api": {
"api_key": "",
"version": "chatglm_pro", # 可选包括 "chatglm_lite", "chatglm_std", "chatglm_pro"
"provider": "ChatGLMWorker",
},
# 具体注册及api key获取请前往 https://api.minimax.chat/
"minimax-api": {
"group_id": "",
"api_key": "",
"is_pro": False,
"provider": "MiniMaxWorker",
},
# 具体注册及api key获取请前往 https://xinghuo.xfyun.cn/
"xinghuo-api": {
"APPID": "",
"APISecret": "",
"api_key": "",
"is_v2": False,
"provider": "XingHuoWorker",
},
# 百度千帆 API申请方式请参考 https://cloud.baidu.com/doc/WENXINWORKSHOP/s/4lilb2lpf
"qianfan-api": {
"version": "ernie-bot-turbo", # 当前支持 "ernie-bot" 或 "ernie-bot-turbo" 更多的见官方文档。
"version_url": "", # 也可以不填写version直接填写在千帆申请模型发布的API地址
"api_key": "",
"secret_key": "",
"provider": "QianFanWorker",
},
# 火山方舟 API文档参考 https://www.volcengine.com/docs/82379
"fangzhou-api": {
"version": "chatglm-6b-model", # 当前支持 "chatglm-6b-model" 更多的见文档模型支持列表中方舟部分。
"version_url": "", # 可以不填写version直接填写在方舟申请模型发布的API地址
"api_key": "",
"secret_key": "",
"provider": "FangZhouWorker",
},
# 阿里云通义千问 API文档参考 https://help.aliyun.com/zh/dashscope/developer-reference/api-details
"qwen-api": {
"version": "qwen-turbo", # 可选包括 "qwen-turbo", "qwen-plus"
"api_key": "", # 请在阿里云控制台模型服务灵积API-KEY管理页面创建
"provider": "QwenWorker",
},
# 百川 API申请方式请参考 https://www.baichuan-ai.com/home#api-enter
"baichuan-api": {
"version": "Baichuan2-53B", # 当前支持 "Baichuan2-53B" 见官方文档。
"api_key": "",
"secret_key": "",
"provider": "BaiChuanWorker",
},
}
# 通常情况下不需要更改以下内容
# nltk 模型存储路径
NLTK_DATA_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "nltk_data")
# 使用VLLM可能导致模型推理能力下降无法完成Agent任务
VLLM_MODEL_DICT = {
"chatglm2-6b": "THUDM/chatglm2-6b",
"chatglm2-6b-32k": "THUDM/chatglm2-6b-32k",
"chatglm3-6b": "THUDM/chatglm3-6b",
"chatglm3-6b-32k": "THUDM/chatglm3-6b-32k",
"aquila-7b":"BAAI/Aquila-7B",
"aquilachat-7b":"BAAI/AquilaChat-7B",
"Llama-2-7b-chat-hf": "meta-llama/Llama-2-7b-chat-hf",
"Llama-2-13b-chat-hf": "meta-llama/Llama-2-13b-chat-hf",
"Llama-2-70b-chat-hf": "meta-llama/Llama-2-70b-chat-hf",
"baichuan-7b": "baichuan-inc/Baichuan-7B",
"baichuan-13b": "baichuan-inc/Baichuan-13B",
'baichuan-13b-chat':'baichuan-inc/Baichuan-13B-Chat',
# 注意bloom系列的tokenizer与model是分离的因此虽然vllm支持但与fschat框架不兼容
# "bloom":"bigscience/bloom",
# "bloomz":"bigscience/bloomz",
# "bloomz-560m":"bigscience/bloomz-560m",
# "bloomz-7b1":"bigscience/bloomz-7b1",
# "bloomz-1b7":"bigscience/bloomz-1b7",
"Qwen-1_8B-Chat": "Qwen/Qwen-1_8B-Chat",
"Qwen-7B-Chat": "Qwen/Qwen-7B-Chat",
"Qwen-14B-Chat": "Qwen/Qwen-14B-Chat",
"Qwen-72B-Chat": "Qwen/Qwen-72B-Chat",
"internlm-7b":"internlm/internlm-7b",
"internlm-chat-7b":"internlm/internlm-chat-7b",
"falcon-7b":"tiiuae/falcon-7b",
"falcon-40b":"tiiuae/falcon-40b",
"falcon-rw-7b":"tiiuae/falcon-rw-7b",
"gpt2":"gpt2",
"gpt2-xl":"gpt2-xl",
"gpt-j-6b":"EleutherAI/gpt-j-6b",
"gpt4all-j":"nomic-ai/gpt4all-j",
"gpt-neox-20b":"EleutherAI/gpt-neox-20b",
"pythia-12b":"EleutherAI/pythia-12b",
"oasst-sft-4-pythia-12b-epoch-3.5":"OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5",
"dolly-v2-12b":"databricks/dolly-v2-12b",
"stablelm-tuned-alpha-7b":"stabilityai/stablelm-tuned-alpha-7b",
"Llama-2-13b-hf":"meta-llama/Llama-2-13b-hf",
"Llama-2-70b-hf":"meta-llama/Llama-2-70b-hf",
"open_llama_13b":"openlm-research/open_llama_13b",
"vicuna-13b-v1.3":"lmsys/vicuna-13b-v1.3",
"koala":"young-geng/koala",
"mpt-7b":"mosaicml/mpt-7b",
"mpt-7b-storywriter":"mosaicml/mpt-7b-storywriter",
"mpt-30b":"mosaicml/mpt-30b",
"opt-66b":"facebook/opt-66b",
"opt-iml-max-30b":"facebook/opt-iml-max-30b",
"baichuan-7b-chat": "baichuan-inc/Baichuan-7B-Chat",
"baichuan-13b-chat": "baichuan-inc/Baichuan-13B-Chat",
"baichuan2-7b-chat": "baichuan-inc/Baichuan-7B-Chat",
"baichuan2-13b-chat": "baichuan-inc/Baichuan-13B-Chat",
"Qwen-7B":"Qwen/Qwen-7B",
"Qwen-14B":"Qwen/Qwen-14B",
"Qwen-7B-Chat":"Qwen/Qwen-7B-Chat",
"Qwen-14B-Chat":"Qwen/Qwen-14B-Chat",
"BlueLM-7B-Chat": "vivo-ai/BlueLM-7B-Chat",
"BlueLM-7B-Chat-32k": "vivo-ai/BlueLM-7B-Chat-32k",
"internlm-7b": "internlm/internlm-7b",
"internlm-chat-7b": "internlm/internlm-chat-7b",
"internlm2-chat-7b": "internlm/Models/internlm2-chat-7b",
"internlm2-chat-20b": "internlm/Models/internlm2-chat-20b",
"aquila-7b": "BAAI/Aquila-7B",
"aquilachat-7b": "BAAI/AquilaChat-7B",
"falcon-7b": "tiiuae/falcon-7b",
"falcon-40b": "tiiuae/falcon-40b",
"falcon-rw-7b": "tiiuae/falcon-rw-7b",
"gpt2": "gpt2",
"gpt2-xl": "gpt2-xl",
"gpt-j-6b": "EleutherAI/gpt-j-6b",
"gpt4all-j": "nomic-ai/gpt4all-j",
"gpt-neox-20b": "EleutherAI/gpt-neox-20b",
"pythia-12b": "EleutherAI/pythia-12b",
"oasst-sft-4-pythia-12b-epoch-3.5": "OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5",
"dolly-v2-12b": "databricks/dolly-v2-12b",
"stablelm-tuned-alpha-7b": "stabilityai/stablelm-tuned-alpha-7b",
"open_llama_13b": "openlm-research/open_llama_13b",
"vicuna-13b-v1.3": "lmsys/vicuna-13b-v1.3",
"koala": "young-geng/koala",
"mpt-7b": "mosaicml/mpt-7b",
"mpt-7b-storywriter": "mosaicml/mpt-7b-storywriter",
"mpt-30b": "mosaicml/mpt-30b",
"opt-66b": "facebook/opt-66b",
"opt-iml-max-30b": "facebook/opt-iml-max-30b",
}
SUPPORT_AGENT_MODEL = [
"openai-api", # GPT4 模型
"qwen-api", # Qwen Max模型
"zhipu-api", # 智谱AI GLM4模型
"Qwen", # 所有Qwen系列本地模型
"chatglm3-6b",
"internlm2-chat-20b",
"Orion-14B-Chat-Plugin",
]
}

View File

@ -1,6 +1,7 @@
# prompt模板使用Jinja2语法简单点就是用双大括号代替f-string的单大括号
# 本配置文件支持热加载修改prompt模板后无需重启服务。
# LLM对话支持的变量
# - input: 用户输入内容
@ -16,112 +17,98 @@
# - input: 用户输入内容
# - agent_scratchpad: Agent的思维记录
PROMPT_TEMPLATES = {
"llm_chat": {
"default":
'{{ input }}',
PROMPT_TEMPLATES = {}
"with_history":
'The following is a friendly conversation between a human and an AI. '
'The AI is talkative and provides lots of specific details from its context. '
'If the AI does not know the answer to a question, it truthfully says it does not know.\n\n'
'Current conversation:\n'
'{history}\n'
'Human: {input}\n'
'AI:',
PROMPT_TEMPLATES["llm_chat"] = {
"default": "{{ input }}",
"py":
'你是一个聪明的代码助手请你给我写出简单的py代码。 \n'
'{{ input }}',
},
"knowledge_base_chat": {
"default":
'<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,'
'不允许在答案中添加编造成分,答案请使用中文。 </指令>\n'
'<已知信息>{{ context }}</已知信息>\n'
'<问题>{{ question }}</问题>\n',
"text":
'<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>\n'
'<已知信息>{{ context }}</已知信息>\n'
'<问题>{{ question }}</问题>\n',
"empty": # 搜不到知识库的时候使用
'请你回答我的问题:\n'
'{{ question }}\n\n',
},
"search_engine_chat": {
"default":
'<指令>这是我搜索到的互联网信息,请你根据这些信息进行提取并有调理,简洁的回答问题。'
'如果无法从中得到答案,请说 “无法搜索到能回答问题的内容”。 </指令>\n'
'<已知信息>{{ context }}</已知信息>\n'
'<问题>{{ question }}</问题>\n',
"search":
'<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>\n'
'<已知信息>{{ context }}</已知信息>\n'
'<问题>{{ question }}</问题>\n',
},
"agent_chat": {
"default":
'Answer the following questions as best you can. If it is in order, you can use some tools appropriately. '
'You have access to the following tools:\n\n'
'{tools}\n\n'
'Use the following format:\n'
'Question: the input question you must answer1\n'
'Thought: you should always think about what to do and what tools to use.\n'
'Action: the action to take, should be one of [{tool_names}]\n'
'Action Input: the input to the action\n'
'Observation: the result of the action\n'
'... (this Thought/Action/Action Input/Observation can be repeated zero or more times)\n'
'Thought: I now know the final answer\n'
'Final Answer: the final answer to the original input question\n'
'Begin!\n\n'
'history: {history}\n\n'
'Question: {input}\n\n'
'Thought: {agent_scratchpad}\n',
"ChatGLM3":
'You can answer using the tools, or answer directly using your knowledge without using the tools. '
'Respond to the human as helpfully and accurately as possible.\n'
'You have access to the following tools:\n'
'{tools}\n'
'Use a json blob to specify a tool by providing an action key (tool name) '
'and an action_input key (tool input).\n'
'Valid "action" values: "Final Answer" or [{tool_names}]'
'Provide only ONE action per $JSON_BLOB, as shown:\n\n'
'```\n'
'{{{{\n'
' "action": $TOOL_NAME,\n'
' "action_input": $INPUT\n'
'}}}}\n'
'```\n\n'
'Follow this format:\n\n'
'Question: input question to answer\n'
'Thought: consider previous and subsequent steps\n'
'Action:\n'
'```\n'
'$JSON_BLOB\n'
'```\n'
'Observation: action result\n'
'... (repeat Thought/Action/Observation N times)\n'
'Thought: I know what to respond\n'
'Action:\n'
'```\n'
'{{{{\n'
' "action": "Final Answer",\n'
' "action_input": "Final response to human"\n'
'}}}}\n'
'Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. '
'Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.\n'
'history: {history}\n\n'
'Question: {input}\n\n'
'Thought: {agent_scratchpad}',
}
"py":
"""
你是一个聪明的代码助手请你给我写出简单的py代码。 \n
{{ input }}
"""
,
}
PROMPT_TEMPLATES["knowledge_base_chat"] = {
"default":
"""
<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,不允许在答案中添加编造成分,答案请使用中文。 </指令>
<已知信息>{{ context }}</已知信息>、
<问题>{{ question }}</问题>
""",
"text":
"""
<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>
<已知信息>{{ context }}</已知信息>、
<问题>{{ question }}</问题>
""",
}
PROMPT_TEMPLATES["search_engine_chat"] = {
"default":
"""
<指令>这是我搜索到的互联网信息,请你根据这些信息进行提取并有调理,简洁的回答问题。如果无法从中得到答案,请说 “无法搜索到能回答问题的内容”。 </指令>
<已知信息>{{ context }}</已知信息>、
<问题>{{ question }}</问题>
""",
"search":
"""
<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>
<已知信息>{{ context }}</已知信息>、
<问题>{{ question }}</问题>
""",
}
PROMPT_TEMPLATES["agent_chat"] = {
"default":
"""
Answer the following questions as best you can. If it is in order, you can use some tools appropriately.You have access to the following tools:
{tools}
Please note that the "知识库查询工具" is information about the "西交利物浦大学" ,and if a question is asked about it, you must answer with the knowledge base
Please note that the "天气查询工具" can only be used once since Question begin.
Use the following format:
Question: the input question you must answer1
Thought: you should always think about what to do and what tools to use.
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
history:
{history}
Question: {input}
Thought: {agent_scratchpad}
""",
"ChatGLM":
"""
请请严格按照提供的思维方式来思考。你的知识不一定正确,所以你一定要用提供的工具来思考,并给出用户答案。
你有以下工具可以使用:
{tools}
```
Question: 用户的提问或者观察到的信息,
Thought: 你应该思考该做什么,是根据工具的结果来回答问题,还是决定使用什么工具。
Action: 需要使用的工具,应该是在[{tool_names}]中的一个。
Action Input: 传入工具的内容
Observation: 工具给出的答案(不是你生成的)
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: 通过工具给出的答案你是否能回答Question。
Final Answer是你的答案
现在,我们开始!
你和用户的历史记录:
History:
{history}
用户开始以提问:
Question: {input}
Thought: {agent_scratchpad}
""",
}

View File

@ -31,7 +31,8 @@ FSCHAT_OPENAI_API = {
# fastchat model_worker server
# 这些模型必须是在model_config.MODEL_PATH或ONLINE_MODEL中正确配置的。
# 在启动startup.py时可用通过`--model-name xxxx yyyy`指定模型不指定则为LLM_MODELS
# 在启动startup.py时可用通过`--model-worker --model-name xxxx`指定模型不指定则为LLM_MODEL
# 必须在这里添加的模型才会出现在WEBUI中可选模型列表里LLM_MODEL会自动添加
FSCHAT_MODEL_WORKERS = {
# 所有模型共用的默认配置,可在模型专项配置中进行覆盖。
"default": {
@ -57,14 +58,14 @@ FSCHAT_MODEL_WORKERS = {
# "awq_ckpt": None,
# "awq_wbits": 16,
# "awq_groupsize": -1,
# "model_names": LLM_MODELS,
# "model_names": [LLM_MODEL],
# "conv_template": None,
# "limit_worker_concurrency": 5,
# "stream_interval": 2,
# "no_register": False,
# "embed_in_truncate": False,
# 以下为vllm_worker配置参数,注意使用vllm必须有gpu仅在Linux测试通过
# 以下为vllm_woker配置参数,注意使用vllm必须有gpu仅在Linux测试通过
# tokenizer = model_path # 如果tokenizer与model_path不一致在此处添加
# 'tokenizer_mode':'auto',
@ -90,48 +91,40 @@ FSCHAT_MODEL_WORKERS = {
# 'disable_log_requests': False
},
"chatglm3-6b": {
"device": "cuda",
},
"Qwen1.5-0.5B-Chat": {
"device": "cuda",
},
# 以下配置可以不用修改在model_config中设置启动的模型
"zhipu-api": {
# 可以如下示例方式更改默认配置
# "baichuan-7b": { # 使用default中的IP和端口
# "device": "cpu",
# },
"zhipu-api": { # 请为每个要运行的在线API设置不同的端口
"port": 21001,
},
"minimax-api": {
"port": 21002,
},
"xinghuo-api": {
"port": 21003,
},
"qianfan-api": {
"port": 21004,
},
"fangzhou-api": {
"port": 21005,
},
"qwen-api": {
"port": 21006,
},
"baichuan-api": {
"port": 21007,
},
"azure-api": {
"port": 21008,
},
"tiangong-api": {
"port": 21009,
},
"gemini-api": {
"port": 21010,
},
"claude-api": {
"port": 21011,
},
# "minimax-api": {
# "port": 21002,
# },
# "xinghuo-api": {
# "port": 21003,
# },
# "qianfan-api": {
# "port": 21004,
# },
# "fangzhou-api": {
# "port": 21005,
# },
# "qwen-api": {
# "port": 21006,
# },
# "baichuan-api": {
# "port": 21007,
# },
}
# fastchat multi model worker server
FSCHAT_MULTI_MODEL_WORKERS = {
# TODO:
}
# fastchat controller server
FSCHAT_CONTROLLER = {
"host": DEFAULT_BIND_HOST,
"port": 20001,

View File

@ -1,12 +1,13 @@
# 用于批量将configs下的.example文件复制并命名为.py文件
import os
import shutil
files = os.listdir("configs")
if __name__ == "__main__":
files = os.listdir("configs")
src_files = [os.path.join("configs",file) for file in files if ".example" in file]
for src_file in src_files:
tar_file = src_file.replace(".example","")
shutil.copy(src_file,tar_file)
src_files = [os.path.join("configs", file) for file in files if ".example" in file]
for src_file in src_files:
tar_file = src_file.replace(".example", "")
shutil.copy(src_file, tar_file)

View File

@ -1,29 +0,0 @@
# 实现基于ES的数据插入、检索、删除、更新
```shell
author: 唐国梁Tommy
e-mail: flytang186@qq.com
如果遇到任何问题,可以与我联系,我这边部署后服务是没有问题的。
```
## 第1步ES docker部署
```shell
docker network create elastic
docker run -id --name elasticsearch --net elastic -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "xpack.security.enabled=false" -e "xpack.security.http.ssl.enabled=false" -t docker.elastic.co/elasticsearch/elasticsearch:8.8.2
```
### 第2步Kibana docker部署
**注意Kibana版本与ES保持一致**
```shell
docker pull docker.elastic.co/kibana/kibana:{version}
docker run --name kibana --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:{version}
```
### 第3步核心代码
```shell
1. 核心代码路径
server/knowledge_base/kb_service/es_kb_service.py
2. 需要在 configs/model_config.py 中 配置 ES参数IP PORT
```

View File

@ -1,84 +0,0 @@
## 指定制定列的csv文件加载器
from langchain.document_loaders import CSVLoader
import csv
from io import TextIOWrapper
from typing import Dict, List, Optional
from langchain.docstore.document import Document
from langchain.document_loaders.helpers import detect_file_encodings
class FilteredCSVLoader(CSVLoader):
def __init__(
self,
file_path: str,
columns_to_read: List[str],
source_column: Optional[str] = None,
metadata_columns: List[str] = [],
csv_args: Optional[Dict] = None,
encoding: Optional[str] = None,
autodetect_encoding: bool = False,
):
super().__init__(
file_path=file_path,
source_column=source_column,
metadata_columns=metadata_columns,
csv_args=csv_args,
encoding=encoding,
autodetect_encoding=autodetect_encoding,
)
self.columns_to_read = columns_to_read
def load(self) -> List[Document]:
"""Load data into document objects."""
docs = []
try:
with open(self.file_path, newline="", encoding=self.encoding) as csvfile:
docs = self.__read_file(csvfile)
except UnicodeDecodeError as e:
if self.autodetect_encoding:
detected_encodings = detect_file_encodings(self.file_path)
for encoding in detected_encodings:
try:
with open(
self.file_path, newline="", encoding=encoding.encoding
) as csvfile:
docs = self.__read_file(csvfile)
break
except UnicodeDecodeError:
continue
else:
raise RuntimeError(f"Error loading {self.file_path}") from e
except Exception as e:
raise RuntimeError(f"Error loading {self.file_path}") from e
return docs
def __read_file(self, csvfile: TextIOWrapper) -> List[Document]:
docs = []
csv_reader = csv.DictReader(csvfile, **self.csv_args) # type: ignore
for i, row in enumerate(csv_reader):
content = []
for col in self.columns_to_read:
if col in row:
content.append(f'{col}:{str(row[col])}')
else:
raise ValueError(f"Column '{self.columns_to_read[0]}' not found in CSV file.")
content = '\n'.join(content)
# Extract the source if available
source = (
row.get(self.source_column, None)
if self.source_column is not None
else self.file_path
)
metadata = {"source": source, "row": i}
for col in self.metadata_columns:
if col in row:
metadata[col] = row[col]
doc = Document(page_content=content, metadata=metadata)
docs.append(doc)
return docs

View File

@ -1,4 +1,2 @@
from .mypdfloader import RapidOCRPDFLoader
from .myimgloader import RapidOCRLoader
from .mydocloader import RapidOCRDocLoader
from .mypptloader import RapidOCRPPTLoader
from .myimgloader import RapidOCRLoader

View File

@ -1,71 +0,0 @@
from langchain.document_loaders.unstructured import UnstructuredFileLoader
from typing import List
import tqdm
class RapidOCRDocLoader(UnstructuredFileLoader):
def _get_elements(self) -> List:
def doc2text(filepath):
from docx.table import _Cell, Table
from docx.oxml.table import CT_Tbl
from docx.oxml.text.paragraph import CT_P
from docx.text.paragraph import Paragraph
from docx import Document, ImagePart
from PIL import Image
from io import BytesIO
import numpy as np
from rapidocr_onnxruntime import RapidOCR
ocr = RapidOCR()
doc = Document(filepath)
resp = ""
def iter_block_items(parent):
from docx.document import Document
if isinstance(parent, Document):
parent_elm = parent.element.body
elif isinstance(parent, _Cell):
parent_elm = parent._tc
else:
raise ValueError("RapidOCRDocLoader parse fail")
for child in parent_elm.iterchildren():
if isinstance(child, CT_P):
yield Paragraph(child, parent)
elif isinstance(child, CT_Tbl):
yield Table(child, parent)
b_unit = tqdm.tqdm(total=len(doc.paragraphs)+len(doc.tables),
desc="RapidOCRDocLoader block index: 0")
for i, block in enumerate(iter_block_items(doc)):
b_unit.set_description(
"RapidOCRDocLoader block index: {}".format(i))
b_unit.refresh()
if isinstance(block, Paragraph):
resp += block.text.strip() + "\n"
images = block._element.xpath('.//pic:pic') # 获取所有图片
for image in images:
for img_id in image.xpath('.//a:blip/@r:embed'): # 获取图片id
part = doc.part.related_parts[img_id] # 根据图片id获取对应的图片
if isinstance(part, ImagePart):
image = Image.open(BytesIO(part._blob))
result, _ = ocr(np.array(image))
if result:
ocr_result = [line[1] for line in result]
resp += "\n".join(ocr_result)
elif isinstance(block, Table):
for row in block.rows:
for cell in row.cells:
for paragraph in cell.paragraphs:
resp += paragraph.text.strip() + "\n"
b_unit.update(1)
return resp
text = doc2text(self.file_path)
from unstructured.partition.text import partition_text
return partition_text(text=text, **self.unstructured_kwargs)
if __name__ == '__main__':
loader = RapidOCRDocLoader(file_path="../tests/samples/ocr_test.docx")
docs = loader.load()
print(docs)

View File

@ -1,13 +1,13 @@
from typing import List
from langchain.document_loaders.unstructured import UnstructuredFileLoader
from document_loaders.ocr import get_ocr
class RapidOCRLoader(UnstructuredFileLoader):
def _get_elements(self) -> List:
def img2text(filepath):
from rapidocr_onnxruntime import RapidOCR
resp = ""
ocr = get_ocr()
ocr = RapidOCR()
result, _ = ocr(filepath)
if result:
ocr_result = [line[1] for line in result]

View File

@ -1,76 +1,37 @@
from typing import List
from langchain.document_loaders.unstructured import UnstructuredFileLoader
import cv2
from PIL import Image
import numpy as np
from configs import PDF_OCR_THRESHOLD
from document_loaders.ocr import get_ocr
import tqdm
class RapidOCRPDFLoader(UnstructuredFileLoader):
def _get_elements(self) -> List:
def rotate_img(img, angle):
'''
img --image
angle --rotation angle
return--rotated img
'''
h, w = img.shape[:2]
rotate_center = (w/2, h/2)
#获取旋转矩阵
# 参数1为旋转中心点;
# 参数2为旋转角度,正值-逆时针旋转;负值-顺时针旋转
# 参数3为各向同性的比例因子,1.0原图2.0变成原来的2倍0.5变成原来的0.5倍
M = cv2.getRotationMatrix2D(rotate_center, angle, 1.0)
#计算图像新边界
new_w = int(h * np.abs(M[0, 1]) + w * np.abs(M[0, 0]))
new_h = int(h * np.abs(M[0, 0]) + w * np.abs(M[0, 1]))
#调整旋转矩阵以考虑平移
M[0, 2] += (new_w - w) / 2
M[1, 2] += (new_h - h) / 2
rotated_img = cv2.warpAffine(img, M, (new_w, new_h))
return rotated_img
def pdf2text(filepath):
import fitz # pyMuPDF里面的fitz包不要与pip install fitz混淆
from rapidocr_onnxruntime import RapidOCR
import numpy as np
ocr = get_ocr()
ocr = RapidOCR()
doc = fitz.open(filepath)
resp = ""
b_unit = tqdm.tqdm(total=doc.page_count, desc="RapidOCRPDFLoader context page index: 0")
for i, page in enumerate(doc):
# 更新描述
b_unit.set_description("RapidOCRPDFLoader context page index: {}".format(i))
# 立即显示进度条更新结果
b_unit.refresh()
# TODO: 依据文本与图片顺序调整处理方式
text = page.get_text("")
resp += text + "\n"
img_list = page.get_image_info(xrefs=True)
img_list = page.get_images()
for img in img_list:
if xref := img.get("xref"):
bbox = img["bbox"]
# 检查图片尺寸是否超过设定的阈值
if ((bbox[2] - bbox[0]) / (page.rect.width) < PDF_OCR_THRESHOLD[0]
or (bbox[3] - bbox[1]) / (page.rect.height) < PDF_OCR_THRESHOLD[1]):
continue
pix = fitz.Pixmap(doc, xref)
samples = pix.samples
if int(page.rotation)!=0: #如果Page有旋转角度则旋转图片
img_array = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, -1)
tmp_img = Image.fromarray(img_array);
ori_img = cv2.cvtColor(np.array(tmp_img),cv2.COLOR_RGB2BGR)
rot_img = rotate_img(img=ori_img, angle=360-page.rotation)
img_array = cv2.cvtColor(rot_img, cv2.COLOR_RGB2BGR)
else:
img_array = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, -1)
result, _ = ocr(img_array)
if result:
ocr_result = [line[1] for line in result]
resp += "\n".join(ocr_result)
pix = fitz.Pixmap(doc, img[0])
img_array = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, -1)
result, _ = ocr(img_array)
if result:
ocr_result = [line[1] for line in result]
resp += "\n".join(ocr_result)
# 更新进度
b_unit.update(1)
@ -82,6 +43,6 @@ class RapidOCRPDFLoader(UnstructuredFileLoader):
if __name__ == "__main__":
loader = RapidOCRPDFLoader(file_path="/Users/tonysong/Desktop/test.pdf")
loader = RapidOCRPDFLoader(file_path="../tests/samples/ocr_test.pdf")
docs = loader.load()
print(docs)

View File

@ -1,59 +0,0 @@
from langchain.document_loaders.unstructured import UnstructuredFileLoader
from typing import List
import tqdm
class RapidOCRPPTLoader(UnstructuredFileLoader):
def _get_elements(self) -> List:
def ppt2text(filepath):
from pptx import Presentation
from PIL import Image
import numpy as np
from io import BytesIO
from rapidocr_onnxruntime import RapidOCR
ocr = RapidOCR()
prs = Presentation(filepath)
resp = ""
def extract_text(shape):
nonlocal resp
if shape.has_text_frame:
resp += shape.text.strip() + "\n"
if shape.has_table:
for row in shape.table.rows:
for cell in row.cells:
for paragraph in cell.text_frame.paragraphs:
resp += paragraph.text.strip() + "\n"
if shape.shape_type == 13: # 13 表示图片
image = Image.open(BytesIO(shape.image.blob))
result, _ = ocr(np.array(image))
if result:
ocr_result = [line[1] for line in result]
resp += "\n".join(ocr_result)
elif shape.shape_type == 6: # 6 表示组合
for child_shape in shape.shapes:
extract_text(child_shape)
b_unit = tqdm.tqdm(total=len(prs.slides),
desc="RapidOCRPPTLoader slide index: 1")
# 遍历所有幻灯片
for slide_number, slide in enumerate(prs.slides, start=1):
b_unit.set_description(
"RapidOCRPPTLoader slide index: {}".format(slide_number))
b_unit.refresh()
sorted_shapes = sorted(slide.shapes,
key=lambda x: (x.top, x.left)) # 从上到下、从左到右遍历
for shape in sorted_shapes:
extract_text(shape)
b_unit.update(1)
return resp
text = ppt2text(self.file_path)
from unstructured.partition.text import partition_text
return partition_text(text=text, **self.unstructured_kwargs)
if __name__ == '__main__':
loader = RapidOCRPPTLoader(file_path="../tests/samples/ocr_test.pptx")
docs = loader.load()
print(docs)

View File

@ -1,18 +0,0 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
try:
from rapidocr_paddle import RapidOCR
except ImportError:
from rapidocr_onnxruntime import RapidOCR
def get_ocr(use_cuda: bool = True) -> "RapidOCR":
try:
from rapidocr_paddle import RapidOCR
ocr = RapidOCR(det_use_cuda=use_cuda, cls_use_cuda=use_cuda, rec_use_cuda=use_cuda)
except ImportError:
from rapidocr_onnxruntime import RapidOCR
ocr = RapidOCR()
return ocr

View File

@ -1,79 +0,0 @@
'''
该功能是为了将关键词加入到embedding模型中以便于在embedding模型中进行关键词的embedding
该功能的实现是通过修改embedding模型的tokenizer来实现的
该功能仅仅对EMBEDDING_MODEL参数对应的的模型有效输出后的模型保存在原本模型
感谢@CharlesJu1和@charlesyju的贡献提出了想法和最基础的PR
保存的模型的位置位于原本嵌入模型的目录下模型的名称为原模型名称+Merge_Keywords_时间戳
'''
import sys
sys.path.append("..")
import os
import torch
from datetime import datetime
from configs import (
MODEL_PATH,
EMBEDDING_MODEL,
EMBEDDING_KEYWORD_FILE,
)
from safetensors.torch import save_model
from sentence_transformers import SentenceTransformer
from langchain_core._api import deprecated
@deprecated(
since="0.3.0",
message="自定义关键词 Langchain-Chatchat 0.3.x 重写, 0.2.x中相关功能将废弃",
removal="0.3.0"
)
def get_keyword_embedding(bert_model, tokenizer, key_words):
tokenizer_output = tokenizer(key_words, return_tensors="pt", padding=True, truncation=True)
input_ids = tokenizer_output['input_ids']
input_ids = input_ids[:, 1:-1]
keyword_embedding = bert_model.embeddings.word_embeddings(input_ids)
keyword_embedding = torch.mean(keyword_embedding, 1)
return keyword_embedding
def add_keyword_to_model(model_name=EMBEDDING_MODEL, keyword_file: str = "", output_model_path: str = None):
key_words = []
with open(keyword_file, "r") as f:
for line in f:
key_words.append(line.strip())
st_model = SentenceTransformer(model_name)
key_words_len = len(key_words)
word_embedding_model = st_model._first_module()
bert_model = word_embedding_model.auto_model
tokenizer = word_embedding_model.tokenizer
key_words_embedding = get_keyword_embedding(bert_model, tokenizer, key_words)
embedding_weight = bert_model.embeddings.word_embeddings.weight
embedding_weight_len = len(embedding_weight)
tokenizer.add_tokens(key_words)
bert_model.resize_token_embeddings(len(tokenizer), pad_to_multiple_of=32)
embedding_weight = bert_model.embeddings.word_embeddings.weight
with torch.no_grad():
embedding_weight[embedding_weight_len:embedding_weight_len + key_words_len, :] = key_words_embedding
if output_model_path:
os.makedirs(output_model_path, exist_ok=True)
word_embedding_model.save(output_model_path)
safetensors_file = os.path.join(output_model_path, "model.safetensors")
metadata = {'format': 'pt'}
save_model(bert_model, safetensors_file, metadata)
print("save model to {}".format(output_model_path))
def add_keyword_to_embedding_model(path: str = EMBEDDING_KEYWORD_FILE):
keyword_file = os.path.join(path)
model_name = MODEL_PATH["embed_model"][EMBEDDING_MODEL]
model_parent_directory = os.path.dirname(model_name)
current_time = datetime.now().strftime('%Y%m%d_%H%M%S')
output_model_name = "{}_Merge_Keywords_{}".format(EMBEDDING_MODEL, current_time)
output_model_path = os.path.join(model_parent_directory, output_model_name)
add_keyword_to_model(model_name, keyword_file, output_model_path)

View File

@ -1,3 +0,0 @@
Langchain-Chatchat
数据科学与大数据技术
人工智能与先进计算

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

BIN
img/qr_code_67.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

View File

@ -1,11 +1,11 @@
import sys
sys.path.append(".")
from server.knowledge_base.migrate import (create_tables, reset_tables, import_from_db,
folder2db, prune_db_docs, prune_folder_files)
from configs.model_config import NLTK_DATA_PATH, EMBEDDING_MODEL
from server.knowledge_base.migrate import create_tables, reset_tables, folder2db, prune_db_docs, prune_folder_files
from configs.model_config import NLTK_DATA_PATH
import nltk
nltk.data.path = [NLTK_DATA_PATH] + nltk.data.path
from datetime import datetime
import sys
if __name__ == "__main__":
@ -23,20 +23,6 @@ if __name__ == "__main__":
'''
)
)
parser.add_argument(
"--create-tables",
action="store_true",
help=("create empty tables if not existed")
)
parser.add_argument(
"--clear-tables",
action="store_true",
help=("create empty tables, or drop the database tables before recreate vector stores")
)
parser.add_argument(
"--import-db",
help="import tables from specified sqlite database"
)
parser.add_argument(
"-u",
"--update-in-db",
@ -49,11 +35,11 @@ if __name__ == "__main__":
)
parser.add_argument(
"-i",
"--increment",
"--increament",
action="store_true",
help=('''
update vector store for files exist in local folder and not exist in database.
use this option if you want to create vectors incrementally.
use this option if you want to create vectors increamentally.
'''
)
)
@ -76,45 +62,33 @@ if __name__ == "__main__":
)
)
parser.add_argument(
"-n",
"--kb-name",
type=str,
nargs="+",
default=[],
help=("specify knowledge base names to operate on. default is all folders exist in KB_ROOT_PATH.")
)
parser.add_argument(
"-e",
"--embed-model",
type=str,
default=EMBEDDING_MODEL,
help=("specify embeddings model.")
)
args = parser.parse_args()
start_time = datetime.now()
if len(sys.argv) <= 1:
parser.print_help()
else:
args = parser.parse_args()
start_time = datetime.now()
if args.create_tables:
create_tables() # confirm tables exist
if args.recreate_vs:
reset_tables()
print("database talbes reseted")
print("recreating all vector stores")
folder2db(kb_names=args.kb_name, mode="recreate_vs")
elif args.update_in_db:
folder2db(kb_names=args.kb_name, mode="update_in_db")
elif args.increament:
folder2db(kb_names=args.kb_name, mode="increament")
elif args.prune_db:
prune_db_docs(args.kb_name)
elif args.prune_folder:
prune_folder_files(args.kb_name)
if args.clear_tables:
reset_tables()
print("database tables reset")
if args.recreate_vs:
create_tables()
print("recreating all vector stores")
folder2db(kb_names=args.kb_name, mode="recreate_vs", embed_model=args.embed_model)
elif args.import_db:
import_from_db(args.import_db)
elif args.update_in_db:
folder2db(kb_names=args.kb_name, mode="update_in_db", embed_model=args.embed_model)
elif args.increment:
folder2db(kb_names=args.kb_name, mode="increment", embed_model=args.embed_model)
elif args.prune_db:
prune_db_docs(args.kb_name)
elif args.prune_folder:
prune_folder_files(args.kb_name)
end_time = datetime.now()
print(f"总计用时: {end_time-start_time}")
end_time = datetime.now()
print(f"总计用时: {end_time-start_time}")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 KiB

View File

@ -1,74 +0,0 @@
# 分布式训练技术原理
- 数据并行
- FSDP
- FSDP算法是由来自DeepSpeed的ZeroRedundancyOptimizer技术驱动的但经过修改的设计和实现与PyTorch的其他组件保持一致。FSDP将模型实例分解为更小的单元然后将每个单元内的所有参数扁平化和分片。分片参数在计算前按需通信和恢复计算结束后立即丢弃。这种方法确保FSDP每次只需要实现一个单元的参数这大大降低了峰值内存消耗。(数据并行+Parameter切分)
- DDP
- DistributedDataParallel (DDP) **在每个设备上维护一个模型副本并通过向后传递的集体AllReduce操作同步梯度从而确保在训练期间跨副本的模型一致性** 。为了加快训练速度, **DDP将梯度通信与向后计算重叠** ,促进在不同资源上并发执行工作负载。
- ZeRO
- Model state
- Optimizer->ZeRO1
- 将optimizer state分成若干份每块GPU上各自维护一份
- 每块GPU上存一份完整的参数W,做完一轮foward和backward后各得一份梯度,对梯度做一次 **AllReducereduce-scatter + all-gather** **得到完整的梯度G,由于每块GPU上只保管部分optimizer states因此只能将相应的W进行更新,对W做一次All-Gather**
- Gradient+Optimzer->ZeRO2
- 每个GPU维护一块梯度
- 每块GPU上存一份完整的参数W,做完一轮foward和backward后 **算得一份完整的梯度,对梯度做一次Reduce-Scatter保证每个GPU上所维持的那块梯度是聚合梯度,每块GPU用自己对应的O和G去更新相应的W。更新完毕后每块GPU维持了一块更新完毕的W。同理对W做一次All-Gather将别的GPU算好的W同步到自己这来**
- Parameter+Gradient+Optimizer->ZeRO3
- 每个GPU维护一块模型状态
- 每块GPU上只保存部分参数W做forward时对W做一次 **All-Gather** 取回分布在别的GPU上的W得到一份完整的W **forward做完立刻把不是自己维护的W抛弃做backward时对W做一次All-Gather取回完整的Wbackward做完立刻把不是自己维护的W抛弃. 做完backward算得一份完整的梯度G对G做一次Reduce-Scatter从别的GPU上聚合自己维护的那部分梯度,聚合操作结束后立刻把不是自己维护的G抛弃。用自己维护的O和G更新W。由于只维护部分W因此无需再对W做任何AllReduce操作**
- Residual state
- activation->Partitioned Activation Checkpointing
- 每块GPU上只维护部分的activation需要时再从别的地方聚合过来就行。需要注意的是activation对显存的占用一般会远高于模型本身通讯量也是巨大的
- temporary buffer->Constant Size Buffer
- 提升带宽利用率。当GPU数量上升GPU间的通讯次数也上升每次的通讯量可能下降但总通讯量不会变。数据切片小了就不能很好利用带宽了。所以这个buffer起到了积攒数据的作用等数据积攒到一定大小再进行通讯。
- 使得存储大小可控。在每次通讯前,积攒的存储大小是常量,是已知可控的。更方便使用者对训练中的存储消耗和通讯时间进行预估
- unusable fragment->Memory Defragmentation
- 对碎片化的存储空间进行重新整合整出连续的存储空间。防止出现总存储足够但连续存储不够而引起的存储请求fail
- offload
- ZeRO-Offload
- **forward和backward计算量高** 因此和它们相关的部分例如参数Wfp16activation就全放入GPU
- **update的部分计算量低** 因此和它相关的部分全部放入CPU中。例如W(fp32)optimizer statesfp32和gradients(fp16)等
- ZeRO-Offload 分为 Offload Strategy 和 Offload Schedule 两部分,前者解决如何在 GPU 和 CPU 间划分模型的问题,后者解决如何调度计算和通信的问题
- ZeRO-Infinity
- 一是将offload和 ZeRO 的结合从 ZeRO-2 延伸到了 ZeRO-3解决了模型参数受限于单张 GPU 内存的问题
- 二是解决了 ZeRO-Offload 在训练 batch size 较小的时候效率较低的问题
- 三是除 CPU 内存外,进一步尝试利用 NVMe 的空间
- 模型并行
- tensor-wise parallelism
- MLP切分
- 对第一个线性层按列切分,对第二个线性层按行切分
- ![图片](./img/分布式训练技术原理-幕布图片-36114-765327.jpg)
- ![图片](./img/分布式训练技术原理-幕布图片-392521-261326.jpg)
- ![图片](./img/分布式训练技术原理-幕布图片-57107-679259.jpg)
- self-attention切分
- attention的多头计算天然适合tensor并行因为每个头上都可以独立计算最后再将结果concat起来从而 **可以把每个头的参数放到一块GPU上**
- 对线性层, **按照“行切割”** 。切割的方式和MLP层基本一致其forward与backward原理也一致
- 输入层Embedding切分
- 对positional embedding来说max_s本身不会太长因此每个GPU上都拷贝一份对显存的压力也不会太大
- 将word embedding拆分到不同GPU上每块GPU维护一分部词表。当输入X去GPU上查找时能找到的词就正常返回词向量找到不到就把词向量中的全部全素都置0。按此方式查找完毕后每块GPU上的数据做一次AllReduce就能得到最终的输入。
- ![图片](./img/分布式训练技术原理-幕布图片-220157-552735.jpg)
- 输出层Embedding切分
- **输入层和输出层共用一个word embeding**
- **当模型的输入层到输入层都在一块GPU上时即流水线并行深度=1我们不必担心这点实践中大部分用Megatron做并行的项目也是这么做的。但若模型输入层和输出层在不同的GPU上时我们就要保证在权重更新前两块GPU上的word embedding梯度做了一次AllReduce**
- ![图片](./img/分布式训练技术原理-幕布图片-42284-124759.jpg)
- cross-entroy
- ![图片](./img/分布式训练技术原理-幕布图片-124076-270516.jpg)
- ![图片](./img/分布式训练技术原理-幕布图片-838373-426344.jpg)
- [pipeline paralelism]("https://zhuanlan.zhihu.com/p/629637468")
- GPipe
- PipeDream
- 1F1B
- 每个 GPU 以交替的方式执行每个 micro batch 的正向和反向过程,以尽早释放其占用的显存,进而减少显存占用
- ![图片](./img/分布式训练技术原理-幕布图片-20096-279847.jpg)
- 1F1B 并不能减少 bubble time **为了进一步减少 bubble timeMegatron 又提出了 interleaved 1F1B 模式** 。也就是原本每个 GPU 负责连续 4 个层的计算,现在变成负责连续两个层的计算,只有原来的一半,从而 bubble time 也变成了原来的一半,即把一个设备上连续的层划分为若干不连续的层,负责的数量不变,但顺序变了。
- ![图片](./img/分布式训练技术原理-幕布图片-618350-869132.jpg)
- DAPPLE
- ![图片](./img/分布式训练技术原理-幕布图片-906937-836104.jpg)
- layer-wise parallelism
- sequence parallelism
- Sequence 并行的好处在于不会增加通信量,并且可以大大减少显存占用
- Layer-norm 和 Dropout 沿着序列的维度是独立的,因此可以按照 Sequence 维度进行拆分
- 使用了 Sequence 并行之后对于超大规模的模型而言其实显存占用量还是很大的。因此Megatron 又引入了激活重计算技术,找到一些计算量很少但显存占用很大的算子,比如 Attention 里的 Softmax、Dropout 等算子,对这些算子进行激活重计算就可以显著减少显存,并且计算开销增加不大
- MoE
- 核心思想:将大模型拆分成多个小模型。每个样本只需要激活部分专家模型进行计算,从而大大节省计算资源。 **MoE 的基本思路是通过宽度换取深度,因为模型深度越深,计算层数越多,进而推理时间越长**
- Hard Gate MoE
- Sparse MoE

View File

@ -1,97 +0,0 @@
# 大模型应用技术原理
- RAG
- 向量数据库 [对比]("https://www.jianshu.com/p/43cc19426113")
- 选型标准
- 开源vs.闭源vs. 源码可见
- 客户端/SDK语言
- 托管方式
- self-hosted/on-premise
- redis,pgvector,milvus
- managed/cloud-native
- zilliz,pinecone
- embeded+cloud-native
- chroma,lanceDB
- self-hosted+cloud-native
- vald,drant,weaviate,vspa,elasticsearch
- 索引方法
- 算法
- Flat
- Tree-based
- Annoy(Approximate Nearest Neighbors Oh Yeah)
- KD-Tree
- Trinary Projection Trees
- IVF
- IVF
- IVMF(Inverted Multi-index File)
- Graph-based
- HNSW
- NSG
- Vamana(DiskANN)
- ![图片](./img/大模型应用技术原理-幕布图片-793118-735987.jpg)
- ![图片](./img/大模型应用技术原理-幕布图片-580318-260070.jpg)
- Hashing-based
- LSH
- Spherical Hashing
- Spectral Hashing
- 量化
- PQProduct Quantization
- PQ 将特征空间分解为多个低维子空间的笛卡尔乘积,然后单独地对每一个子空间进行量化
- SQScalar Quantization
- SQ是将每一个维度量化成指定位数的一个数
- 主流方案
- professional
- weaviate
- 1. 文档丰富,容易上手
- 2. 提供混合索引
- 3. 支持自托管+云原生
- 4.支持python,js,ts,go,java等客户端
- 5. 支持HNSW,HNSW-PQ,DisANN等索引
- chroma
- LanceDB
- pinecone
- 1. 完全云原生,非常容易上手
- 2. 自建复合索引
- faiss
- 1.来自 Meta AI原 Facebook Research的开源项目
- 2.同时支持cpu和GPU两种设备
- 3. 支持C++,python, go等客户端
- 4. 支持常见的索引方式如IVF,HNSW,支持PQ量化
- 5. in-memory运行
- 6. self-hosted
- milvus
- 1. 通过代理、负载均衡器、消息代理、Kafka和Kubernetes的组合实现了高度可扩展性这使得整个系统变得非常复杂和资源密集
- 2. 截至2023年它是唯一一个提供可工作的DiskANN实现的主要供应商
- 3. 支持在向量相似度检索过程中进行标量字段过滤,实现混合查询
- 4. 采用 **存储与计算分离** 的架构设计
- 5. 提供python,java,go,node.js等语言SDK,也提供milvus lite等in-momery运行
- 6. 提供了图形界面客户端
- traiditional
- ES
- redis
- pgvector
- Embedding模型
- bi-encoder
- cross-encoder
- 【可选】文本检索引擎
- ElasticSearch
- OpenSearch
- 【可选】图数据库
- 检索
- 向量检索
- 关键字检索
- BM25
- NL2Cypher
- NL2SQL
- RAG增强
- Self-RAG
- 框架
- 自反思检索增强生成Self-RAG, Self-Reflective Retrieval-Augmented Generation。这是一个新框架它不仅可以根据需要自适应地检索段落模型可以判断是否有必要进行检索增强还引入了名为反思令牌reflection tokens的特殊令牌使LM在推理阶段可控。
- ![图片](./img/大模型应用技术原理-幕布图片-108319-429731.jpg)
- ![图片](./img/大模型应用技术原理-幕布图片-918388-323086.jpg)
- 训练
- 首先,训练评论家,使用检索器检索到的段落以及反思令牌增强指令-输出数据,然后,使用标准的下一个 token 预测目标来训练生成器 LM以学习生成 自然延续(continuations)以及特殊 tokens (用来检索或批评其自己的生成内容).
- 推理
- 它可以适应性地使用检索令牌进行检索因此模型可以自发判断是不是有必要进行检索。它引入了多种细粒度的批评令牌这些令牌用于评估生成内容的各个方面的质量。在生成过程中作者使用期望的批评令牌概率的线性插值进行segment级的beam search以在每一个时间步骤中确定最佳的K个续写方案
- Agent
- function call
- ToolFormer

View File

@ -1,44 +0,0 @@
# 大模型技术栈-实战与应用
- 训练框架
- deepspeed
- megatron-lm
- colossal-ai
- trlx
- 推理框架
- triton
- vllm
- text-generation-inference
- lit-llama
- lightllm
- TensorRT-LLM(原FasterTransformer)
- fastllm
- inferllm
- llama-cpp
- openPPL-LLM
- 压缩框架
- bitsandbytes
- auto-gptq
- deepspeed
- embedding框架
- sentence-transformer
- FlagEmbedding
- 向量数据库 [向量数据库对比]("https://www.jianshu.com/p/43cc19426113")
- faiss
- pgvector
- milvus
- pinecone
- weaviate
- LanceDB
- Chroma
- 应用框架
- Auto-GPT
- langchain
- llama-index
- quivr
- python前端
- streamlit
- gradio
- python API工具
- FastAPI+uvicorn
- flask
- Django

View File

@ -1,301 +0,0 @@
# 大模型技术栈-算法与原理
- 1. tokenizer方法
- word-level
- char-level
- subword-level
- BPE
- WordPiece
- UniLM
- SentencePiece
- ByteBPE
- 2. position encoding
- 绝对位置编码
- ROPE
- AliBi
- 相对位置编码
- Transformer-XL
- T5/TUPE
- DeBERTa
- 其他位置编码
- 3. 注意力机制
- 稀疏注意力
- flash-attention
-
- 4. 分布式训练
- 数据并行
- FSDP
- DDP
- ZeRO
- Model state
- Optimizer->ZeRO1
- 将optimizer state分成若干份每块GPU上各自维护一份
- 每块GPU上存一份完整的参数W,做完一轮foward和backward后各得一份梯度,对梯度做一次 **AllReducereduce-scatter + all-gather** **得到完整的梯度G,由于每块GPU上只保管部分optimizer states因此只能将相应的W进行更新,对W做一次All-Gather**
- Gradient+Optimzer->ZeRO2
- 每个GPU维护一块梯度
- 每块GPU上存一份完整的参数W,做完一轮foward和backward后 **算得一份完整的梯度,对梯度做一次Reduce-Scatter保证每个GPU上所维持的那块梯度是聚合梯度,每块GPU用自己对应的O和G去更新相应的W。更新完毕后每块GPU维持了一块更新完毕的W。同理对W做一次All-Gather将别的GPU算好的W同步到自己这来**
- Parameter+Gradient+Optimizer->ZeRO3
- 每个GPU维护一块模型状态
- 每块GPU上只保存部分参数W做forward时对W做一次 **All-Gather** 取回分布在别的GPU上的W得到一份完整的W **forward做完立刻把不是自己维护的W抛弃做backward时对W做一次All-Gather取回完整的Wbackward做完立刻把不是自己维护的W抛弃. 做完backward算得一份完整的梯度G对G做一次Reduce-Scatter从别的GPU上聚合自己维护的那部分梯度,聚合操作结束后立刻把不是自己维护的G抛弃。用自己维护的O和G更新W。由于只维护部分W因此无需再对W做任何AllReduce操作**
- Residual state
- activation->Partitioned Activation Checkpointing
- 每块GPU上只维护部分的activation需要时再从别的地方聚合过来就行。需要注意的是activation对显存的占用一般会远高于模型本身通讯量也是巨大的
- temporary buffer->Constant Size Buffer
- 提升带宽利用率。当GPU数量上升GPU间的通讯次数也上升每次的通讯量可能下降但总通讯量不会变。数据切片小了就不能很好利用带宽了。所以这个buffer起到了积攒数据的作用等数据积攒到一定大小再进行通讯。
- 使得存储大小可控。在每次通讯前,积攒的存储大小是常量,是已知可控的。更方便使用者对训练中的存储消耗和通讯时间进行预估
- unusable fragment->Memory Defragmentation
- 对碎片化的存储空间进行重新整合整出连续的存储空间。防止出现总存储足够但连续存储不够而引起的存储请求fail
- offload
- ZeRO-Offload
- **forward和backward计算量高** 因此和它们相关的部分例如参数Wfp16activation就全放入GPU
- **update的部分计算量低** 因此和它相关的部分全部放入CPU中。例如W(fp32)optimizer statesfp32和gradients(fp16)等
- ZeRO-Offload 分为 Offload Strategy 和 Offload Schedule 两部分,前者解决如何在 GPU 和 CPU 间划分模型的问题,后者解决如何调度计算和通信的问题
- ZeRO-Infinity
- 一是将offload和 ZeRO 的结合从 ZeRO-2 延伸到了 ZeRO-3解决了模型参数受限于单张 GPU 内存的问题
- 二是解决了 ZeRO-Offload 在训练 batch size 较小的时候效率较低的问题
- 三是除 CPU 内存外,进一步尝试利用 NVMe 的空间
- 模型并行
- tensor-wise parallelism
- Megatron-LM
- 流水线并行
- GPipe
- PipeDream
- layer-wise parallelism
- sequence parallelism
- 5. PEFT
- Lora类
- LoRA
- 用两个低秩矩阵替代待更新的权重矩阵的增量
- QLoRA
- 4 bit NormalFloat(NF4) 量化和双量化
- 引入了分页优化器,以防止梯度检查点期间的内存峰值
- AdaLoRA
- 用奇异值分解P \ Gamma Q代替AB根据loss梯度评估对角线上值进行重要性评分根据评分动态分配参数预算给权重矩阵
- AdaLoRA将关键的增量矩阵分配高秩以捕捉更精细和任务特定的信息而将较不重要的矩阵的秩降低以防止过拟合并节省计算预算。
- 以奇异值分解的形式对增量更新进行参数化,并根据重要性指标裁剪掉不重要的奇异值,同时保留奇异向量。
- 在训练损失中添加了额外的惩罚项以规范奇异矩阵P和Q的正交性从而避免SVD的大量计算并稳定训练
- IA3
- 通过学习向量来对激活层加权进行缩放
- 学习到的向量被注入到attention和feedforward模块中
- ReLoRA
- **ReLoRA在合并和重新启动期间可以对优化器进行部分重置** 并在随后的预热中过程中将学习率设置为0。 **具体来说,作者提出了一种锯齿状学习率调度算法**
- 出发点通过不断叠加LoRA训练过程来达到更好的训练效果 **首先需要对LoRA过程进行重新启动想要对已经完成的LoRA过程重新启动并不容易这需要对优化器进行精细的调整如果调整不到位会导致模型在重启后立即与之前的优化方向出现分歧**
- Prompt类
- prompt tuning
- 在输入层加一个embedding层
- P-tuning
- 在输入层加一个embedding和一个LSTM或MLP
- prefix tuning
- 在每一层加入一个embedding和一个MLP
- P-tuning v2
- 在每一层都加一个embedding层
- Adapter类
- Adapter Tuning
- 针对每一个Transformer层增加了两个Adapter结构(分别是多头注意力的投影之后和第二个feed-forward层之后)
- Adapter Fusion
- 在 Adapter 的基础上进行优化,通过将学习过程分为两阶段来提升下游任务表现
- 知识提取阶段在不同任务下引入各自的Adapter模块用于学习特定任务的信息。
- 知识组合阶段将预训练模型参数与特定于任务的Adapter参数固定引入新参数AdapterFusion来学习组合多个Adapter中的知识以提高模型在目标任务中的表现
- Adapter Drop
- 在不影响任务性能的情况下对Adapter动态高效的移除尽可能的减少模型的参数量提高模型在反向传播训练和正向传播推理时的效率
- 其他
- BitFit
- 疏的微调方法它训练时只更新bias的参数或者部分bias参数
- 混合式
- MAM Adapter
- 用 FFN 层的并行Adapter和软提示的组合
- UniPELT
- 门控被实现为线性层通过GP参数控制Prefix-tuning方法的开关GL控制LoRA方法的开关GA控制Adapter方法的开关
- 6. 压缩
- 剪枝
- OBD(Optimal Brain Damage)
- 利用二阶导数信息度量模型参数的显著性,剪掉影响小的参数降低模型复杂度提高泛化能力
- ![图片](./img/大模型技术栈-算法与原理-幕布图片-628857-182232.jpg)
- OBSOptimal Brain Surgeon
- OBD粗暴的只考虑海森矩阵对角线元素。OBS考虑海森矩阵全局信息由此也获得参数相互之间的影响。
- OBCOPTIMAL BRAIN COMPRESSION
- OBS对整个神经网络进行剪枝OBC对神经网络模型分层剪枝或者量化
- ExactOBS
- 参数更新和代价评估不需要使用整个海森矩阵,仅使用和剪枝参数所在行相关的 d_col\time d_col大小的海森矩阵。
- 量化 ![图片](./img/大模型技术栈-算法与原理-幕布图片-454007-940199.jpg)
- GPTQ
- 1.是对OBC的改进
- 2. 取消了贪心算法,采用固定位置优化
- 3. 分组量化,并行加速
- ![图片](./img/大模型技术栈-算法与原理-幕布图片-729151-372321.jpg)
- SpQR
- 核心思想参数的对模型的重要程度存在极强的不均衡性。1%的参数可能主导的量化过程中损失的性能假如我们在量化中保护这1%的参数,就能极大程度保护模型的性能不受影响
- 2. 对于每一层它使用一个小的输入数据集X用来计算单个参数w_ij被量化前后造成的的误差s_ij. 有了s_ij之后再取top 1%的参数认为它们是重要参数进行保护。
- 在挑选出参数之后SqQR使用一个稀疏矩阵来单独保存这些参数令这些重要参数的精度仍为fp16。
- SqQR在实验中还观察到重要参数往往以行或者列聚集因此提出使用更小的group_size比如8或16而非GPTQ中常用的128
- AWQ
- 1. AWS是在smoothquant的基础上提出来的
- 2. AWQ针对channel维度来寻找重要参数依据是输入X以及这个参数本身W的绝对大小
- 3.方式是寻找一个缩放比例s在参数量化之前W乘以这个比例计算时输入X除以这个比例以减小误差
- 4. 把s分成两个值S_x和S_w相乘我们需要W越大s越小X越大s越大
- ![图片](./img/大模型技术栈-算法与原理-幕布图片-299768-254064.jpg)
- OBCOPTIMAL BRAIN COMPRESSION
- ![图片](./img/大模型技术栈-算法与原理-幕布图片-19929-302935.jpg)
- SmoothQuant
- 1. 当模型规模更大时单个token的值变化范围较大难以量化相比之下 weight 的变化范围较小,即 weight 较易量化,而 activation 较难量化
- 2. SmoothQuant 核心思想是引入一个超参,减小激活值的变化范围,增大权重的变化范围,从而均衡两者的量化难度
- 3. 得到smooth变换之后的 activation 和 weight 矩阵,可以再采用 per-token 或 per-tensor 的量化方式,
- ![图片](./img/大模型技术栈-算法与原理-幕布图片-81470-404273.jpg)
- LLM.int8
- 采用混合精度分解的量化方法将包含了Emergent Features的几个维度从矩阵中分离出来对其做高精度的矩阵乘法其余部分进行量化
- ZeroQuant
- 1. 对权重使用分组量化对激活使用token量化
- 2. 开发了高度优化的推理后端,消除了量化/反量化运算符昂贵的计算成本在现代GPU硬件上实现INT8 Tensor内核的延迟加速
- 3. 提出了一种用于INT4/INT8混合精度量化的新的逐层知识蒸馏方法LKD其中神经网络通过蒸馏逐层量化迭代最小甚至不访问原始训练数据
- 分类学
- 对称量化vs非对称量化
- 量化是否均衡原点是否为0
- 动态量化vs静态量化
- 输入的缩放因子计算方法不同
- 静态量化的模型在使用前有“calibrate”的过程校准缩放因子量化模型的缩放因子会根据输入数据的分布进行调整
- Weights量化vsActivation量化
- feature map(fm)就是每一层网络的输入tensorfeaturemap量化就是我们常说的激活量化
- per-token vs. per-layer/per-tensor vs. per channel vs. per group vs
- **per-token quantization** :激活每个token对应的tensor共享量化系数
- **per-tensor quantization** : 对一整个tensor设置简单的量化集合
- **per-channel quantization** : 对权重的每个输出通道设置一个量化集合但实际中feature 还是整个 tensor 共用一个 scale 和 zeropoint但每个 kernel 会单独统计一个 scale 和 zeropoint注意是每个 kernel而不是 kernel 的每个 channel
- **group-wise quantization** : 把多个channel合在一起用一组量化系数
- 蒸馏(layer reduction)
- 7. 推理
- 7.1 吞吐量与显存优化
- PagedAttention
- Qunatized KV Cache
- MQA/GQA
- FlashAttention
- 7.2 算子融合
- 7.3 延迟优化
- No Padding优化
- 7.4 调度优化
- Dynamic Batching
- Async Servering
- Inflight Batching
- 7.5 量化
- 7.6 模型并行
- tensor paralellism
- 7.7 请求优化
- rpc
- grpc
- http
- 8. 应用
- RAG
- Agent
- 9. embedding模型
- 分类学
- 对称vs. 非对称 vs. 混合
- 对称 query:qestion, text:text
- sentence-T5
- 非对称:query:text
- GTR
- 混合
- Instructor
- 对比学习+对比学习 vs. 自编码+对比学习
- 对比学习+对比学习
- sentence-T5
- GTR
- E5
- 自编码+对比学习
- bge
- retromae
- bert-based vs. GPT-based
- bert-based
- LLM-based
- PromptEOL+CSE+LLM
- Bert-CLS,Bert-mean
- 双向decoder-encoder的Transformer
- T5 series
- Sentence-T5
- T5-encoder+mean pooling
- 无标注对比学习+有标注对比学习的两阶段训练
- Jina
- 以T5为基本架构
- 去重、语言过滤、一致性过来
- **采用了并行化方法在多个数据集上进行训练** 但设计了一个约束条件每个训练批次batch仅包含来自单一数据集的样本
- 三元组训练enchor,entainment, contraversive
- GTR
- 与sentence-T5结构相同
- 将finetune的数据集从NLI换成检索相关的并且利用百度的rocketqa来获得hard negative
- 对比学习改成双向对比学习每个batch里有两个对比学习损失第一个损失是以query为中心去构建正负样本第二个损失是以positive document为中心去构建正负样本
- simcse
- 无监督Simcse
- 对于同一条语句在训练中使用两次不同的dropout mask把两次dropout后的句子对视为一组互为正例的样本对即相似句子对
- "不相似句子对"通过采样同一批batch内的其余句子即可
- 有监督simcse
- 采用NLI有监督数据集做对比学习训练,NLI即自然语言推理其任务是判断两句话之间的关系可能的关系有entailment (相近), contradiction (矛盾)或neutral (中立)。
- entailment sentence pair作为正例 contradiction sentence pair作为hard negative样本
- 衍生算法
- Esimcse
- ESimCSE选择在句子中随机重复一些单词作为正样本解决模型倾向于判断相同或相似长度的句子在表达上更相近的问题
- 维护了一个队列重用前面紧接的mini-batch的编码嵌入来扩展负对并使用了动量编码器
- CoSENT
- 在正负样本的基础上基于circle loss进一步引入排序
- SNCSE
- 针对模型「无法区分文本相似度和语义相似度,更偏向具有相似文本,而不考虑实际语义差异」的问题,提出了一种「显式添加否定词从而生成软负样本」结合「双向边际损失」的方案。
- EASE
- 强调实体在句向量表征中的重要性。在数据层面,使用正、负实体代替正负样本。
- CLAIF
- 针对训练过程中缺乏细粒度的监督信号, 即没有考虑到正样本对之间的相似性差异引入来自LLM的AI反馈构造具有不同相似度的样本对并对这些样本对给出细粒度的相似度分数作为监督信号帮助文本表示的学习。
- Instructor
- 1. 以GTR为基底模型经过进一步的“instruction tuning”得到
- 2. 将模型输入改成Task Instuction+[X]([X]代表具体的文本输入)
- E5
- E5提出了一个预训练数据过滤的方案consistency-based filter
- 以Bert为基座的embedding模型
- 在模型输入侧加入了Prefix("query:"跟“paragraph:”)从而让模型知道文本的类型跟Instructor的instruction类似
- BGE
- 基于RetroMAE方案
- BGE在finetune阶段针对检索任务需要加入特定的Prefix(只在query侧加"Represent this sentence for searching relevant passages:")
- RetroMAE
- 包括一个以Bert为基底的Encoder跟一个只有一层的Decoder
- Encoder端以30%的比例对原文本进行mask最终得到最后一层[CLS]位置的向量表征作为句向量
- Decoder端则以50%的比例对原文本进行mask联合Encoder端的句向量对原本进行重建
- PromptBert
- 以Bert为基底通过选择合适的prompt“This sentence:"[X]" means [MASK] ”),然后以最后一层[MASK]位置的向量表征作为句向量即便不经过额外的finetune也能取得令人惊艳的效果
- PromptEOL+CLS+LLM
- 语言模型使用的是OPT跟LLaMA
- 构建了另一个新的prompt,"This sentence:”[X]” means in one word:"以下一个生成token的隐层状态作为text embedding
- 还引入了in-context learning为每个语言模型找到了一个最佳的demonstration从而指导语言模型生成更符合要求的text embedding
- 为了进一步提升性能可以采用对比学习的方式作进一步的finetune
- 10. 上下文扩展
- Alibi
- logn注意力缩放
- window attention
- RoPE改进
- Interpolation
- Position Interpolation
- 线性插值
- Extrapolation
- NTK感知缩放RoPE
- dynamic缩放RoPE
- consistent of Dynamically Scaled RoPE
- 混合
- Rectified RoPE
- **N** aive **B** ayes-based **C** ontext **E** xtension
- 只需要修改一下解码函数中的logits构建方式
- 即插即用、模型无关、无须微调、线性效率、实现简单
- NBCE的一大缺点是无序性即无法识别Context的输入顺序这在续写故事等场景可能表现欠佳
- 11. Prompt Engineering
- **Chain of Thought**
- Lets Think step by step
- **Self-Consistency**
- Few-shot + {question} 用几个相似的具有推导步骤的例子
- **Auto-CoT**
- Few-shot + {question} +Chain of Thought相似的具有推导步骤的例子+{问题}+给出具体思考过程。
- **Generation Knowledge**
- 以事实+知识的方式组织样例,再最后提问,要求给出解释和答案
- **Automatic Prompt Engineer**
- Let's work this out in a step by step way to be sure we have the right answer
- **OPRO**
- “Take a deep breath and think step by step.”
- Optimization by PROmpting (OPRO)总体架构最开始输入meta-prompt这个初始的meta-prompt基本上只是对优化任务进行了描述(也会有few-shot example)。输入后LLM便会生成一个solution这个solution由objective function评估并打分。(solution, score)组合成一对添加到meta-prompt中如此完成一个循环。多次循环后取分数最高的solution作为优化结果。
- meta-prompt分为两部分问题描述和优化轨迹问题描述就是用自然语言描述想要优化的问题比如“generate a new instruction that achieves a higher accuracy”。而优化弹道Optimization trajectory则是指之前提到的(solution, score)对,即之前生成的解决方案和对应的分数,可以看作优化的“日志”。但是要注意这个弹道不是按 排的而是按照打分升序排的。因为之前的研究也发现越靠后的样例对输出的影响越大所以把分数高的排在后面有利于LLM向其学习。 [时间顺序]("https://so.csdn.net/so/search?q=%E6%97%B6%E9%97%B4%E9%A1%BA%E5%BA%8F&spm=1001.2101.3001.7020")
- **Tree of Thought**
- f“给定当前的推理状态{state_text}’,生成{k}条连贯的思想来实现推理过程:”
- f“鉴于当前的推理状态{state_text}’,根据其实现 {initial_prompt} 的潜力悲观地将其值评估为 0 到 1 之间的浮点数”
- 利用树的遍历算法BFS, DFS, MC,BF,A*),搜索最佳答案。
- **Graph of Thought**
- 创新点是将大模型生成的信息建模为一个图,节点是 “LLM的思想“边是这些思想的依赖关系。这种方法能够将任意 LLM 思想,组合,提取出这个网络的思想本质。
- **出发点** 人类的思维在解决问题时不是只会链式思维或者尝试不同的链TOT,而是在脑中构建一个复杂的思维网络。人类在思考时会沿着一个链式的推理,回溯,再尝试一个新的方向,并把之前的链的优点保留,缺点剔除,与当前探索的链的方向结合生成一个新的解决方案

View File

@ -1,30 +0,0 @@
# 大模型指令对齐训练原理
- RLHF
- SFT
- RM
- PPO
- AIHF-based
- RLAIF
- 核心在于通过AI 模型监督其他 AI 模型即在SFT阶段从初始模型中采样然后生成自我批评和修正然后根据修正后的反应微调原始模型。在 RL 阶段,从微调模型中采样,使用一个模型来评估生成的样本,并从这个 AI 偏好数据集训练一个偏好模型。然后使用偏好模型作为奖励信号对 RL 进行训练
- ![图片](./img/大模型指令对齐训练原理-幕布图片-17565-176537.jpg)
- ![图片](./img/大模型指令对齐训练原理-幕布图片-95996-523276.jpg)
- ![图片](./img/大模型指令对齐训练原理-幕布图片-349153-657791.jpg)
- RRHF
- RRHF( **R** ank **R** esponse from **H** uman **F** eedback) 不需要强化学习,可以利用不同语言模型生成的回复,包括 ChatGPT、GPT-4 或当前的训练模型。RRHF通过对回复进行评分并通过排名损失来使回复与人类偏好对齐。RRHF 通过通过排名损失使评分与人类的偏好或者代理的奖励模型对齐。RRHF 训练好的模型可以同时作为生成语言模型和奖励模型使用。
- ![图片](./img/大模型指令对齐训练原理-幕布图片-805089-731888.jpg)
- SFT-only
- LIMA
- LIMA(Less Is More for Alignment) 即浅层对齐假说,即一 **个模型的知识和能力几乎完全是在预训练中学习的,而对齐则是教会它与用户交互时如何选择子分布** 。如果假说正确,对齐主要有关于学习方式,那么该假说的一个推论是,人们可以用相当少的样本充分调整预训练的语言模型。因此, **该工作假设,对齐可以是一个简单的过程,模型学习与用户互动的风格或格式,以揭示在预训练中已经获得的知识和能力。**
- LTD Instruction Tuning
- ![图片](./img/大模型指令对齐训练原理-幕布图片-759487-923925.jpg)
- Reward-only
- DPO
- DPO(Direct Preference Optimization) 提出了一种使用二进制交叉熵目标来精确优化LLM的方法以替代基于 RL HF 的优化目标,从而大大简化偏好学习 pipeline。也就是说完全可以直接优化语言模型以实现人类的偏好而不需要明确的奖励模型或强化学习。
- DPO 也依赖于理论上的偏好模型(如 Bradley-Terry 模型),以此衡量给定的奖励函数与经验偏好数据的吻合程度。然而,现有的方法使用偏好模型定义偏好损失来训练奖励模型,然后训练优化所学奖励模型的策略,而 DPO 使用变量的变化来直接定义偏好损失作为策略的一个函数。鉴于人类对模型响应的偏好数据集DPO 因此可以使用一个简单的二进制交叉熵目标来优化策略,而不需要明确地学习奖励函数或在训练期间从策略中采样。
- RAFT
- ![图片](./img/大模型指令对齐训练原理-幕布图片-350029-666381.jpg)
- 参考文献
- [反思RLHF]("https://mp.weixin.qq.com/s/e3E_XsZTiNMNYqzzi6Pbjw")
- [RLHF笔记]("https://mathpretty.com/16017.html")
- [hf-blog]("https://huggingface.co/blog/zh/rlhf")
- ** [RLHF代码详解]("https://zhuanlan.zhihu.com/p/624589622")

View File

@ -1,63 +0,0 @@
# 大模型推理优化策略
- 7.1 显存优化
- [PagedAttention]("https://zhuanlan.zhihu.com/p/638468472")
- KV cache其具有以下特点:1. 显存占用大14b级别的模型每个token需要约0.7M-1M的显存2. 动态变化KV 缓存的大小取决于序列长度,这是高度可变和不可预测的。因此,这对有效管理 KV cache 挑战较大。该研究发现,由于碎片化和过度保留,现有系统浪费了 60% - 80% 的显存。
- 为了解决这个问题,该研究引入了 PagedAttention这是一种受操作系统中虚拟内存和分页经典思想启发的注意力算法。与传统的注意力算法不同PagedAttention 允许在非连续的内存空间中存储连续的 key 和 value 。具体来说PagedAttention 将每个序列的 KV cache 划分为块,每个块包含固定数量 token 的键和值。在注意力计算期间PagedAttention 内核可以有效地识别和获取这些块。因为块在内存中不需要连续,因而可以用一种更加灵活的方式管理 key 和 value ,就像在操作系统的虚拟内存中一样:可以将块视为页面,将 token 视为字节,将序列视为进程。序列的连续逻辑块通过块表映射到非连续物理块中。物理块在生成新 token 时按需分配。在 PagedAttention 中,内存浪费只会发生在序列的最后一个块中。这使得在实践中可以实现接近最佳的内存使用,仅浪费不到 4%。
- PagedAttention 还有另一个关键优势 —— 高效的内存共享。例如在并行采样中,多个输出序列是由同一个 prompt 生成的。在这种情况下prompt 的计算和内存可以在输出序列中共享。PagedAttention 自然地通过其块表格来启动内存共享。与进程共享物理页面的方式类似PagedAttention 中的不同序列可以通过将它们的逻辑块映射到同一个物理块的方式来共享块。为了确保安全共享PagedAttention 会对物理块的引用计数进行跟踪并实现写时复制Copy-on-Write机制。PageAttention 的内存共享大大减少了复杂采样算法的内存开销,例如并行采样和集束搜索的内存使用量降低了 55%。这可以转化为高达 2.2 倍的吞吐量提升。
- continuous batching
- CUDA kernel优化
- Qunatized KV Cache
- MQA/GQA
- 核心思想是检索kv-cache的数量以少量kv-cache对应多个query ![图片](./img/大模型推理优化策略-幕布图片-699343-219844.jpg)
- ![图片](./img/大模型推理优化策略-幕布图片-930255-616209.jpg)
- [FlashAttention]("https://zhuanlan.zhihu.com/p/638468472")
- 解释1记I为模型的计算强度I单位FLOP/byte代表模型进行单位byte数据交互可实现的操作数,则I*带宽beta即模型的计算性能单位为FLOP/s。令I_max=计算平台算力/计算平台带宽当模型的计算强度I小于平台的理论计算强度I_max模型的计算能力P即I*beta,当模型的计算强度大于I_max,则模型的计算性能P等于平台的算力。故若模型的计算强度小则瓶颈在带宽若模型的计算强度大则瓶颈在算力。为提高计算性能需提高计算强度即每bytes数据交互的操作数。
- 解释2记N=每次操作要求的FLOP,单位FLOP/OPpi=平台的算力单位FLOP/s;beta=内存带宽单位byte/sP=实际实现计算速度单位为FLOP/s优化目标为O=P/N每秒钟实现的运算次数单位为OP/s.由于N固定故优化目标转而为PP=min{beta_r*I_max=beta_r*pi/beta,pi}故优化目标转而为beta即改变内存访问策略实现beta最大化。
- 注意力操作中S和P的计算空间复杂度都是O(N^2),此外,scale,mask,softmax,dropout都是带宽约束操作。 ![图片](./img/大模型推理优化策略-幕布图片-380552-579242.jpg)
- ![图片](./img/大模型推理优化策略-幕布图片-789705-122117.jpg)
- 可以看出O(N^2)空间复杂度的矩阵计算对HBM的读写是主要的内存瓶颈因此主要优化点是1. 在不访问整个输入的情况下计算softmax;2. 不为反向传播存储大的中间attention矩阵。FlashAttention提出两种方法来分步解决上述问题tiling,recomputation.tiling - 注意力计算被重新构造将输入分割成块并通过在输入块上进行多次传递来递增地执行softmax操作。recomputation - 存储来自前向的 softmax 归一化因子,以便在反向中快速重新计算芯片上的 attention这比从HBM读取中间矩阵的标准注意力方法更快。由于重新计算这确实导致FLOPs增加但是由于大量减少HBM访问FlashAttention运行速度更快。该算法背后的主要思想是分割输入将它们从慢速HBM加载到快速SRAM然后计算这些块的 attention 输出。在将每个块的输出相加之前,将其按正确的归一化因子进行缩放,从而得到正确的结果。
- ![图片](./img/大模型推理优化策略-幕布图片-590671-36787.jpg)
- ![图片](./img/大模型推理优化策略-幕布图片-276446-401476.jpg)
- 参考文献
- [推理优化]("https://zhuanlan.zhihu.com/p/656485997") [推理优化]("https://zhuanlan.zhihu.com/p/656485997")
- 7.2 算子融合
- 7.3 延迟优化
- No Padding优化
- 7.4 调度优化
- Dynamic Batching
- 批次大小固定不变,无法随计算资源负载动态变化,导致 GPU 资源利用率低
- 通过维护一个作业队列实现,在 batch 维度动态插入新序列
- Async Servering
- Tokenize / Detokenize 过程在 CPU 上执行,期间 GPU 处于空闲状态
- 多线程异步,流水线 overlap 实现降低时延
- Inflight Batching/continuous batching
- 同批次序列推理时,存在“气泡”,导致 GPU 资源利用率低
- 由 batch 粒度的调度细化为 step 级别的调度,在时间轴方向动态插入新序列
- 7.5 量化
- GPTQ
- AWQ
- SmoothQuant
- SpQR
- 7.6 模型并行
- tensor paralellism加速+降显存
- pipeline paralellism减少显存
- 7.7 请求优化
- [网络通信]("https://article.juejin.cn/post/7226374741064892453")
- rpc
- grpc
- http
- [响应模式]("https://blog.csdn.net/weixin_44999716/article/details/128436984")
- SSE
- 轮询
- 长轮询comet
- WebSocket
- 7.8 采样/解码
- speculative decoding
- ![图片](./img/大模型推理优化策略-幕布图片-923924-83386.jpg)
- Blockwise *Parallel* *Decoding*
- Medusa
- SOT - Parallel Decoding
- SpecInfer
- StreamingLLM
- 参考资料
- [最佳实践]("https://mp.weixin.qq.com/s/nJLrE9Dzj1mmTeQDiqNdzA")

File diff suppressed because it is too large Load Diff

@ -1 +0,0 @@
Subproject commit 28f664aa08f8191a70339c9ecbe7a89b35a1032a

View File

@ -1,107 +0,0 @@
## ClassDef FilteredCSVLoader
**FilteredCSVLoader**: FilteredCSVLoader的功能是从CSV文件中加载并筛选指定列的数据然后将这些数据转换为文档对象列表。
**属性**:
- `file_path`: 要加载的CSV文件的路径。
- `columns_to_read`: 需要读取的列名列表。
- `source_column`: 指定作为数据源信息列的列名,如果未指定,则使用文件路径作为数据源信息。
- `metadata_columns`: 需要作为元数据读取的列名列表。
- `csv_args`: 传递给csv阅读器的额外参数字典。
- `encoding`: 文件的编码格式。
- `autodetect_encoding`: 是否自动检测文件编码。
**代码描述**:
FilteredCSVLoader类继承自CSVLoader类用于从CSV文件中加载数据并根据指定的列名筛选数据。它重写了`__init__`方法以接收额外的参数,如`columns_to_read`这是一个字符串列表指定了需要从CSV文件中读取的列名。此外它还提供了`load`方法来实际加载和处理CSV文件。
`load`方法中首先尝试打开指定的CSV文件。如果在读取文件时遇到`UnicodeDecodeError`错误,并且`autodetect_encoding`标志被设置为True则会尝试自动检测文件编码并重新尝试读取文件。读取文件成功后使用`csv.DictReader`读取CSV文件根据`columns_to_read`中指定的列名筛选数据,并将筛选后的数据转换为文档对象列表。每个文档对象包含从指定列读取的内容和元数据,元数据中包含数据源信息和行号,以及`metadata_columns`中指定的任何其他元数据列的值。
**注意**:
- 确保`file_path`指向的CSV文件存在且可读。
- 在`columns_to_read`中指定的列必须存在于CSV文件中否则会抛出`ValueError`
- 如果设置了`autodetect_encoding`为True但自动检测编码失败则会抛出`RuntimeError`
**输出示例**:
```python
[
Document(page_content="这是第一行的内容", metadata={"source": "example.csv", "row": 0, "其他元数据列名": "值"}),
Document(page_content="这是第二行的内容", metadata={"source": "example.csv", "row": 1, "其他元数据列名": "值"}),
...
]
```
此输出示例展示了`load`方法返回的文档对象列表每个文档对象包含从CSV文件指定列读取的内容和元数据。
### FunctionDef __init__(self, file_path, columns_to_read, source_column, metadata_columns, csv_args, encoding, autodetect_encoding)
**__init__**: 此函数的功能是初始化FilteredCSVLoader对象。
**参数**:
- `file_path`: 要读取的CSV文件的路径。
- `columns_to_read`: 需要读取的列名列表。
- `source_column`: 指定作为数据源的列名可选参数默认为None。
- `metadata_columns`: 包含元数据的列名列表,默认为空列表。
- `csv_args`: 传递给CSV读取器的额外参数为字典格式可选参数默认为None。
- `encoding`: 指定文件编码的字符串可选参数默认为None。
- `autodetect_encoding`: 是否自动检测文件编码布尔值默认为False。
**代码描述**:
此函数是`FilteredCSVLoader`类的构造函数,用于初始化一个`FilteredCSVLoader`实例。它首先调用父类的构造函数,传入`file_path``source_column``metadata_columns``csv_args``encoding``autodetect_encoding`参数,以完成基础的初始化工作。然后,它将`columns_to_read`参数的值赋给实例变量`self.columns_to_read`以便后续操作中可以根据这些列名来读取CSV文件中的指定列。
**注意**:
- 在使用此函数时,`file_path``columns_to_read`参数是必需的因为它们分别指定了CSV文件的位置和需要读取的列。
- `metadata_columns`参数允许用户指定哪些列包含元数据,这些元数据列不会被视为数据源的一部分。
- 如果`csv_args`参数被提供它将允许用户自定义CSV读取过程中的行为例如指定分隔符、引号字符等。
- `encoding``autodetect_encoding`参数与文件编码相关如果CSV文件的编码不是标准的UTF-8这两个参数将非常有用。`autodetect_encoding`为True时系统将尝试自动检测文件编码这可能有助于处理编码不明确的文件。
***
### FunctionDef load(self)
**load**: 该函数的功能是加载数据并将其转换为文档对象列表。
**参数**: 该函数不接受任何外部参数,但依赖于类实例中的属性,如`file_path``encoding`
**代码描述**: `load`函数负责从CSV文件中读取数据并将这些数据转换为`Document`对象的列表。首先,函数尝试使用`open`函数以指定的编码方式打开文件路径`self.file_path`指定的CSV文件。文件成功打开后调用`__read_file`私有方法来读取并处理CSV文件的内容。
如果在尝试打开文件时遇到`UnicodeDecodeError`编码错误,并且`self.autodetect_encoding`属性为真,则会尝试自动检测文件编码。这一过程通过调用`detect_file_encodings`函数实现,该函数返回一个可能的编码列表。然后,函数会尝试使用这些编码中的每一个重新打开并读取文件,直到成功读取文件或尝试完所有编码。
如果在文件处理过程中遇到任何其他异常,或者在自动检测编码后仍无法成功读取文件,`load`函数将抛出`RuntimeError`异常,指示文件加载过程中出现错误。
`load`函数调用的`__read_file`方法负责实际从CSV文件中读取数据并将每行数据转换为`Document`对象。这一转换过程包括从CSV行中提取必要的内容和元数据并将它们封装在`Document`对象中。
**注意**:
- `load`函数依赖于类实例的状态,如文件路径和编码设置,因此在调用此函数之前应确保这些属性已正确设置。
- 如果CSV文件的编码不是在初始化时指定的编码并且未启用自动检测编码功能那么读取文件可能会失败。
- 当CSV文件中缺少必需的列或格式不正确时`__read_file`方法可能会抛出`ValueError`异常。
**输出示例**: 假设CSV文件正确读取并处理`load`函数可能返回如下的`Document`对象列表:
```python
[
Document(page_content="示例文本1", metadata={"source": "path/to/file.csv", "row": 0, "其他元数据": "值"}),
Document(page_content="示例文本2", metadata={"source": "path/to/file.csv", "row": 1, "其他元数据": "值"})
]
```
此列表中的每个`Document`对象包含从CSV文件中读取的一行数据其中`page_content`属性存储了该行指定列的内容,而`metadata`字典包含了源信息以及其他可能的元数据信息。
***
### FunctionDef __read_file(self, csvfile)
**__read_file**: 该函数的功能是从CSV文件中读取数据并将其转换为Document对象列表。
**参数**:
- csvfile: TextIOWrapper类型表示打开的CSV文件对象。
**代码描述**:
`__read_file`函数是`FilteredCSVLoader`类的一个私有方法用于读取CSV文件并将每行数据转换为`Document`对象。该函数首先创建一个空列表`docs`来存储转换后的`Document`对象。接着,使用`csv.DictReader`读取`csvfile`参数指定的CSV文件其中`self.csv_args`包含了读取CSV文件时需要的参数设置。
对于CSV文件中的每一行函数首先检查是否包含必需的列`self.columns_to_read[0]`指定)。如果该列存在,则从该列中提取内容作为`Document`对象的`page_content`。同时,尝试从行中获取源信息(由`self.source_column`指定),如果未指定`self.source_column`或该列不存在,则使用文件路径作为源信息。此外,还会从行中提取其他元数据列(由`self.metadata_columns`指定),并将这些信息一起存储在`metadata`字典中。
最后,使用提取的内容和元数据创建一个`Document`对象,并将其添加到`docs`列表中。如果在CSV文件中找不到必需的列则抛出`ValueError`异常。
该函数被`FilteredCSVLoader`类的`load`方法调用用于加载CSV文件并将其内容转换为一系列`Document`对象。`load`方法首先尝试以指定的编码打开文件,如果遇到编码错误且自动检测编码功能被启用,则尝试使用检测到的编码重新打开文件。如果在整个过程中遇到任何异常,`load`方法会抛出`RuntimeError`异常。
**注意**:
- 由于`__read_file`是一个私有方法,因此它仅在`FilteredCSVLoader`类内部使用,不应直接从类外部调用。
- 当CSV文件中缺少必需的列时该函数会抛出`ValueError`异常。
**输出示例**:
假设CSV文件包含以下内容并且`columns_to_read`设置为`['content']``metadata_columns`设置为空列表,那么函数可能返回如下的`Document`对象列表:
```python
[
Document(page_content="Hello, world!", metadata={"source": "path/to/file.csv", "row": 0}),
Document(page_content="Another example.", metadata={"source": "path/to/file.csv", "row": 1})
]
```
***

Some files were not shown because too many files have changed in this diff Show More