Compare commits
349 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f4e62ad5b | ||
|
|
2123569598 | ||
|
|
3ecff4bce7 | ||
|
|
4cd8d0e97c | ||
|
|
200f9fb481 | ||
|
|
1ab62ad339 | ||
|
|
7cb8b96ed5 | ||
|
|
b9827529aa | ||
|
|
8ca9e8ff28 | ||
|
|
ede538bfe2 | ||
|
|
2c146aff74 | ||
|
|
703d0f6aa7 | ||
|
|
8e2515f768 | ||
|
|
d9323ea3f6 | ||
|
|
24faba561b | ||
|
|
cbc28d7296 | ||
|
|
f9beb142c8 | ||
|
|
781b782f73 | ||
|
|
160f0b8af4 | ||
|
|
26672ffeda | ||
|
|
0078cdc724 | ||
|
|
9c0820c94a | ||
|
|
cf049511cf | ||
|
|
c52e89d92a | ||
|
|
2c7feae7bb | ||
|
|
52f2a2a046 | ||
|
|
9bf0612e3d | ||
|
|
7da7636abc | ||
|
|
326a9652aa | ||
|
|
b6e1f208e9 | ||
|
|
4815a6c92e | ||
|
|
448e79576c | ||
|
|
3902f6d235 | ||
|
|
72a6878287 | ||
|
|
5eb37ea2e3 | ||
|
|
f29ab1e67f | ||
|
|
341ee9db44 | ||
|
|
2f2221ca47 | ||
|
|
6d128f24f0 | ||
|
|
8721aad18d | ||
|
|
13377191e7 | ||
|
|
110b5694da | ||
|
|
da1c1a225c | ||
|
|
5eb025d9dc | ||
|
|
6003d8dd83 | ||
|
|
b0f5fb2d3e | ||
|
|
6dd066ca72 | ||
|
|
c0dafb95cc | ||
|
|
487235259e | ||
|
|
a592b1cd3f | ||
|
|
6011bac07f | ||
|
|
ae9f4d208e | ||
|
|
78290d360f | ||
|
|
966c582a2a | ||
|
|
bfb76faadb | ||
|
|
40263dd403 | ||
|
|
825e4976ae | ||
|
|
253d4b9b9a | ||
|
|
07b7c966ed | ||
|
|
d78b14721c | ||
|
|
5ad4d520dd | ||
|
|
d879e86cab | ||
|
|
cd54eeb137 | ||
|
|
021d635af0 | ||
|
|
f40d415f07 | ||
|
|
7198654611 | ||
|
|
818f87b5e4 | ||
|
|
c6d91c3e3d | ||
|
|
5c74a28de9 | ||
|
|
e48f4a24c9 | ||
|
|
279fe9c659 | ||
|
|
bab93690fc | ||
|
|
54bed50713 | ||
|
|
caf502d141 | ||
|
|
76e82a9b8f | ||
|
|
574ea4f4d5 | ||
|
|
cf1c853b19 | ||
|
|
fb8fbe96e4 | ||
|
|
7c89f88513 | ||
|
|
1fa714ee71 | ||
|
|
b2fabe211b | ||
|
|
d5edb08b24 | ||
|
|
051c599bb5 | ||
|
|
cd13aee97d | ||
|
|
8146279bbe | ||
|
|
c49c6923a1 | ||
|
|
041e964b30 | ||
|
|
f75ae3ea5f | ||
|
|
0522a42ab7 | ||
|
|
5460b93ba2 | ||
|
|
ab650253d1 | ||
|
|
670131c886 | ||
|
|
2756996125 | ||
|
|
f04a2bfcc7 | ||
|
|
9c5aa5bf2f | ||
|
|
36956520ea | ||
|
|
4f67f4a841 | ||
|
|
e042a76f11 | ||
|
|
13628c5f9a | ||
|
|
5afbae56fc | ||
|
|
2504ea3393 | ||
|
|
07906751c1 | ||
|
|
b7a249f46a | ||
|
|
cbfbbe5e6b | ||
|
|
845adfbc0b | ||
|
|
53ff5040e2 | ||
|
|
77914386b0 | ||
|
|
03edc3e501 | ||
|
|
3f70a0d18c | ||
|
|
b0708c7a8d | ||
|
|
887cf95db7 | ||
|
|
b39b585867 | ||
|
|
042a70c09a | ||
|
|
ffbfcd41f2 | ||
|
|
22ee1a0c97 | ||
|
|
4157201c2c | ||
|
|
6eab501baf | ||
|
|
268bb68122 | ||
|
|
4f5824e964 | ||
|
|
25f5f103c1 | ||
|
|
0c465faf8b | ||
|
|
c94938bc83 | ||
|
|
147b4c0688 | ||
|
|
e1e8b0f056 | ||
|
|
38bc4050ac | ||
|
|
ae31e6dd8b | ||
|
|
e1f125be4e | ||
|
|
597ca146d0 | ||
|
|
9c525b7fa5 | ||
|
|
a5e758bf82 | ||
|
|
370dbfef37 | ||
|
|
1c3b928223 | ||
|
|
454d82b2e4 | ||
|
|
ee6a28b565 | ||
|
|
f50400a204 | ||
|
|
852ca5f849 | ||
|
|
f9a5ae99ee | ||
|
|
7248163b07 | ||
|
|
60d5f7d439 | ||
|
|
088a27df27 | ||
|
|
481d1c4b3a | ||
|
|
6df6ed2920 | ||
|
|
57c73b1424 | ||
|
|
c9c867664e | ||
|
|
65a2ccdc64 | ||
|
|
31631e56ca | ||
|
|
56d32a9908 | ||
|
|
1adff316e5 | ||
|
|
c50e988f5a | ||
|
|
85771825ba | ||
|
|
54e5b41647 | ||
|
|
17803cb7c1 | ||
|
|
64378837ef | ||
|
|
b6d2bc71ce | ||
|
|
fb6c84bc57 | ||
|
|
80c26e4a24 | ||
|
|
eeba2e2665 | ||
|
|
c0968fb581 | ||
|
|
8483c0bc96 | ||
|
|
6b61d917a1 | ||
|
|
8ac255fc55 | ||
|
|
56c2a70a74 | ||
|
|
71deed93df | ||
|
|
3057c29e47 | ||
|
|
554d6b4820 | ||
|
|
e5b4bb41d8 | ||
|
|
0cf65d5933 | ||
|
|
8c2019f8b9 | ||
|
|
4a77880ee1 | ||
|
|
dc07cba1d4 | ||
|
|
b058e1906f | ||
|
|
2ab944996e | ||
|
|
e5acf3d2e6 | ||
|
|
1b5efecc89 | ||
|
|
b2ea386f60 | ||
|
|
d83de508cc | ||
|
|
0a4dfe58a4 | ||
|
|
2c92cd00ae | ||
|
|
67ae61d567 | ||
|
|
cb3822651b | ||
|
|
241690d593 | ||
|
|
f28cd59557 | ||
|
|
991e824bcd | ||
|
|
f031ebc19e | ||
|
|
ebda1056e5 | ||
|
|
0a37fe93b8 | ||
|
|
6df4554c8b | ||
|
|
3e959e5b0f | ||
|
|
e55f8cf7a9 | ||
|
|
c5985ae5be | ||
|
|
3333007e13 | ||
|
|
ff91508d8b | ||
|
|
4ac510ff4a | ||
|
|
269090ea66 | ||
|
|
75ff268e88 | ||
|
|
e615932e7e | ||
|
|
a5b52e1bd1 | ||
|
|
29ef5dda64 | ||
|
|
03eb5e9d2e | ||
|
|
4f07384c66 | ||
|
|
3da68b5ce3 | ||
|
|
b653c25fbc | ||
|
|
e7bba6bd0a | ||
|
|
b5064813af | ||
|
|
01bac077bc | ||
|
|
448c99f969 | ||
|
|
6f85119f03 | ||
|
|
440307fa94 | ||
|
|
17e8bc072b | ||
|
|
67034669a9 | ||
|
|
3d66899b0f | ||
|
|
ce29d14f46 | ||
|
|
50aeb24582 | ||
|
|
fc75c4513a | ||
|
|
aeb7a7e93f | ||
|
|
61bc815540 | ||
|
|
7d4a6b5edf | ||
|
|
3c33ca7b89 | ||
|
|
f1ae95c8ca | ||
|
|
719e2713ed | ||
|
|
349de9b955 | ||
|
|
e6c376fba0 | ||
|
|
c179230ce0 | ||
|
|
3b28f40c6a | ||
|
|
5cccd5e7aa | ||
|
|
af38f75b29 | ||
|
|
a8f94dd595 | ||
|
|
1f3a32ebaf | ||
|
|
9ff7bef2c2 | ||
|
|
2e1442a5c1 | ||
|
|
4e5bc8b399 | ||
|
|
4e69033d33 | ||
|
|
778d2d906a | ||
|
|
d77f778e0d | ||
|
|
129c765a74 | ||
|
|
5891f94c88 | ||
|
|
60510ff2f0 | ||
|
|
c1a32d9f1a | ||
|
|
fdea406101 | ||
|
|
bba4754994 | ||
|
|
9fdeb475e9 | ||
|
|
a870076051 | ||
|
|
7e01e82470 | ||
|
|
7e8391eb55 | ||
|
|
332e1ccfaa | ||
|
|
e7410e40df | ||
|
|
1cbad32b6e | ||
|
|
f45d6ab49c | ||
|
|
9c5b81cb2b | ||
|
|
472a97a616 | ||
|
|
c8fef3380c | ||
|
|
db008c1af8 | ||
|
|
2604c9e761 | ||
|
|
95c09981a6 | ||
|
|
db1c1e2ee4 | ||
|
|
2e9319846e | ||
|
|
7b70776810 | ||
|
|
fdd6eb5f6d | ||
|
|
bcbeb9d8ac | ||
|
|
ad0b133ac8 | ||
|
|
4c2fda7200 | ||
|
|
d1f94c2846 | ||
|
|
1fac51fe35 | ||
|
|
6547005073 | ||
|
|
5fe933fa44 | ||
|
|
67b7c99d03 | ||
|
|
cf65f44eb6 | ||
|
|
7d2de47bcf | ||
|
|
dcb76984bc | ||
|
|
023cb22da7 | ||
|
|
2d0615aede | ||
|
|
643cc6c5be | ||
|
|
12113be6ec | ||
|
|
6558647b65 | ||
|
|
f9348326f5 | ||
|
|
4fa28c71b1 | ||
|
|
0cc1be224d | ||
|
|
60f8e1d55e | ||
|
|
c34b4136c0 | ||
|
|
f2d917d1e4 | ||
|
|
89b07ba55d | ||
|
|
072e0a2a32 | ||
|
|
7e99cc12b3 | ||
|
|
d55f53d8c0 | ||
|
|
120dc50004 | ||
|
|
5ac77e5089 | ||
|
|
8b70b1db7e | ||
|
|
40918c21de | ||
|
|
0ca6f40c45 | ||
|
|
c4fe3393b3 | ||
|
|
7487af3bad | ||
|
|
c4bf8c48ec | ||
|
|
b7a50daa0f | ||
|
|
509dee0425 | ||
|
|
7d580d9a47 | ||
|
|
6076ab1198 | ||
|
|
02c33e6ce9 | ||
|
|
8b695dba03 | ||
|
|
75a2cba078 | ||
|
|
279ffdf117 | ||
|
|
33374bd9f2 | ||
|
|
248db46187 | ||
|
|
f57837c07a | ||
|
|
08530edb3d | ||
|
|
92dcb11b26 | ||
|
|
abb32722fe | ||
|
|
717355bf1e | ||
|
|
a83e03011d | ||
|
|
f9f16edd13 | ||
|
|
63bdca1343 | ||
|
|
3c4d4a5345 | ||
|
|
1de4258aa0 | ||
|
|
1b0cf67a57 | ||
|
|
dfcebf7bc3 | ||
|
|
3839c212db | ||
|
|
1d3a69ff86 | ||
|
|
824c29a6d2 | ||
|
|
76151e884a | ||
|
|
1b9b777eaf | ||
|
|
aae4144476 | ||
|
|
7a85fe74e9 | ||
|
|
1c97673d41 | ||
|
|
274e7a9c0a | ||
|
|
7eee9212e0 | ||
|
|
569209289b | ||
|
|
17c9632942 | ||
|
|
3cf7422c21 | ||
|
|
ce7255dce1 | ||
|
|
a9cf191532 | ||
|
|
700c4ad170 | ||
|
|
262c1fc8c3 | ||
|
|
33f43f7a96 | ||
|
|
1a291d9db9 | ||
|
|
ad7a6fd438 | ||
|
|
68a544ea33 | ||
|
|
4ed8f049ab | ||
|
|
51c43122cb | ||
|
|
fbe214471b | ||
|
|
3b3d948d27 | ||
|
|
2adfa4277c | ||
|
|
21b079d751 | ||
|
|
c094b5f91c | ||
|
|
e78a804ec6 | ||
|
|
94d4304638 | ||
|
|
4e8e6de7ff | ||
|
|
861510a92b | ||
|
|
e4ffa2f93b | ||
|
|
91ff0574df | ||
|
|
0586f94c5a |
19
.dockerignore
Normal file
@ -0,0 +1,19 @@
|
||||
.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
|
||||
155
.github/workflows/docker-build.yaml
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
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 }}
|
||||
4
.gitignore
vendored
@ -173,4 +173,8 @@ cython_debug/
|
||||
.pytest_cache
|
||||
.DS_Store
|
||||
|
||||
# Test File
|
||||
test.py
|
||||
configs/*.py
|
||||
|
||||
|
||||
|
||||
27
Dockerfile
Normal file
@ -0,0 +1,27 @@
|
||||
# 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"]
|
||||
107
README.md
@ -1,12 +1,17 @@
|
||||

|
||||
|
||||
|
||||
🌍 [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`分支,而不再进行版本更新。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
@ -14,23 +19,31 @@
|
||||
* [介绍](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#联系我们)
|
||||
|
||||
|
||||
## 介绍
|
||||
|
||||
🤖️ 一种利用 [langchain](https://github.com/hwchase17/langchain) 思想实现的基于本地知识库的问答应用,目标期望建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。
|
||||
🤖️ 一种利用 [langchain](https://github.com/langchain-ai/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)
|
||||
|
||||
@ -42,37 +55,46 @@
|
||||
|
||||
🚩 本项目未涉及微调、训练过程,但可利用微调或训练对本项目效果进行优化。
|
||||
|
||||
🌐 [AutoDL 镜像](https://www.codewithgpu.com/i/chatchat-space/Langchain-Chatchat/Langchain-Chatchat) 中 `v11` 版本所使用代码已更新至本项目 `v0.2.7` 版本。
|
||||
🌐 [AutoDL 镜像](https://www.codewithgpu.com/i/chatchat-space/Langchain-Chatchat/Langchain-Chatchat) 中 `0.2.10`
|
||||
|
||||
🐳 [Docker 镜像](registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.6) 已经更新到 ```0.2.7``` 版本。
|
||||
版本所使用代码已更新至本项目 `v0.2.10` 版本。
|
||||
|
||||
🌲 一行命令运行 Docker :
|
||||
🐳 [Docker 镜像](isafetech/chatchat:0.2.10) 已经更新到 ```0.2.10``` 版本。
|
||||
|
||||
🌲 本次更新后同时支持DockerHub、阿里云、腾讯云镜像源:
|
||||
|
||||
```shell
|
||||
docker run -d --gpus all -p 80:8501 registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.7
|
||||
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```,可以免费商用,无需付费。
|
||||
|
||||
我们支持市面上主流的本地大预言模型和Embedding模型,支持开源的本地向量数据库。
|
||||
我们支持市面上主流的本地大语言模型和Embedding模型,支持开源的本地向量数据库。
|
||||
支持列表详见[Wiki](https://github.com/chatchat-space/Langchain-Chatchat/wiki/)
|
||||
|
||||
|
||||
## 快速上手
|
||||
|
||||
### 1. 环境配置
|
||||
|
||||
+ 首先,确保你的机器安装了 Python 3.10
|
||||
+ 首先,确保你的机器安装了 Python 3.8 - 3.11 (我们强烈推荐使用 Python3.11)。
|
||||
|
||||
```
|
||||
$ python --version
|
||||
Python 3.10.12
|
||||
Python 3.11.7
|
||||
```
|
||||
|
||||
接着,创建一个虚拟环境,并在虚拟环境内安装项目的依赖
|
||||
|
||||
```shell
|
||||
|
||||
# 拉取仓库
|
||||
@ -88,32 +110,44 @@ $ pip install -r requirements_webui.txt
|
||||
|
||||
# 默认依赖包括基本运行环境(FAISS向量库)。如果要使用 milvus/pg_vector 等向量库,请将 requirements.txt 中相应依赖取消注释再安装。
|
||||
```
|
||||
### 2, 模型下载
|
||||
|
||||
如需在本地或离线环境下运行本项目,需要首先将项目所需的模型下载至本地,通常开源 LLM 与 Embedding 模型可以从 [HuggingFace](https://huggingface.co/models) 下载。
|
||||
请注意,LangChain-Chatchat `0.2.x` 系列是针对 Langchain `0.0.x` 系列版本的,如果你使用的是 Langchain `0.1.x`
|
||||
系列版本,需要降级您的`Langchain`版本。
|
||||
|
||||
以本项目中默认使用的 LLM 模型 [THUDM/ChatGLM2-6B](https://huggingface.co/THUDM/chatglm2-6b) 与 Embedding 模型 [moka-ai/m3e-base](https://huggingface.co/moka-ai/m3e-base) 为例:
|
||||
### 2. 模型下载
|
||||
|
||||
下载模型需要先[安装 Git LFS](https://docs.github.com/zh/repositories/working-with-files/managing-large-files/installing-git-large-file-storage),然后运行
|
||||
如需在本地或离线环境下运行本项目,需要首先将项目所需的模型下载至本地,通常开源 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)
|
||||
,然后运行
|
||||
|
||||
```Shell
|
||||
$ git lfs install
|
||||
$ git clone https://huggingface.co/THUDM/chatglm2-6b
|
||||
$ git clone https://huggingface.co/moka-ai/m3e-base
|
||||
$ git clone https://huggingface.co/THUDM/chatglm3-6b
|
||||
$ git clone https://huggingface.co/BAAI/bge-large-zh
|
||||
```
|
||||
|
||||
### 3. 初始化知识库和配置文件
|
||||
|
||||
按照下列方式初始化自己的知识库和简单的复制配置文件
|
||||
|
||||
```shell
|
||||
$ python copy_config_example.py
|
||||
$ python init_database.py --recreate-vs
|
||||
```
|
||||
|
||||
### 4. 一键启动
|
||||
|
||||
按照以下命令启动项目
|
||||
|
||||
```shell
|
||||
$ python startup.py -a
|
||||
```
|
||||
|
||||
### 5. 启动界面示例
|
||||
|
||||
如果正常启动,你将能看到以下界面
|
||||
@ -132,23 +166,36 @@ $ python startup.py -a
|
||||
|
||||

|
||||
|
||||
|
||||
### 注意
|
||||
|
||||
以上方式只是为了快速上手,如果需要更多的功能和自定义启动方式 ,请参考[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
|
||||
|
||||
[](https://t.me/+RjliQ3jnJ1YyN2E9)
|
||||
|
||||
### 项目交流群
|
||||
<img src="img/qr_code_72.jpg" alt="二维码" width="300" />
|
||||
<img src="img/qr_code_108.jpg" alt="二维码" width="300" />
|
||||
|
||||
🎉 Langchain-Chatchat 项目微信交流群,如果你也对本项目感兴趣,欢迎加入群聊参与讨论交流。
|
||||
|
||||
|
||||
47
README_en.md
@ -1,12 +1,18 @@
|
||||

|
||||
|
||||
🌍 [中文文档](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
|
||||
@ -24,7 +30,8 @@ LLM API.
|
||||
## Introduction
|
||||
|
||||
🤖️ A Q&A application based on local knowledge base implemented using the idea
|
||||
of [langchain](https://github.com/hwchase17/langchain). The goal is to build a KBQA(Knowledge based Q&A) solution that
|
||||
of [langchain](https://github.com/langchain-ai/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)
|
||||
@ -55,10 +62,17 @@ The main process analysis from the aspect of document process:
|
||||
🚩 The training or fine-tuning are not involved in the project, but still, one always can improve performance by do
|
||||
these.
|
||||
|
||||
🌐 [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.
|
||||
🌐 [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.
|
||||
|
||||
🐳 [Docker image](registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.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
|
||||
```
|
||||
|
||||
## Pain Points Addressed
|
||||
|
||||
@ -99,6 +113,9 @@ $ 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
|
||||
@ -157,15 +174,33 @@ 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`.
|
||||
|
||||
|
||||
+ 🔥 Let’s look forward to the future Chatchat stories together···
|
||||
|
||||
---
|
||||
|
||||
## Contact Us
|
||||
|
||||
### Telegram
|
||||
|
||||
[](https://t.me/+RjliQ3jnJ1YyN2E9)
|
||||
|
||||
### WeChat Group、
|
||||
### WeChat Group
|
||||
|
||||
<img src="img/qr_code_67.jpg" alt="二维码" width="300" height="300" />
|
||||
<img src="img/qr_code_90.jpg" alt="二维码" width="300" height="300" />
|
||||
|
||||
### WeChat Official Account
|
||||
|
||||
|
||||
200
README_ja.md
Normal file
@ -0,0 +1,200 @@
|
||||

|
||||
|
||||
🌍 [中文文档](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)
|
||||
|
||||

|
||||
|
||||
文書プロセスの側面からの主なプロセス分析:
|
||||
|
||||

|
||||
|
||||
🚩 トレーニングやファインチューニングはプロジェクトには含まれないが、これらを行うことで必ずパフォーマンスを向上させることができます。
|
||||
|
||||
🌐 [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 インターフェース
|
||||
|
||||

|
||||
|
||||
2. webui ページ
|
||||
|
||||
- Web UI ダイアログページ:
|
||||
|
||||

|
||||
|
||||
- Web UI ナレッジベースマネジメントページ:
|
||||
|
||||

|
||||
|
||||
### 注
|
||||
|
||||
上記の手順はクイックスタートのために提供されています。より多くの機能が必要な場合や、起動方法をカスタマイズしたい場合は、[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
|
||||
|
||||
[](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" />
|
||||
@ -5,4 +5,4 @@ from .server_config import *
|
||||
from .prompt_config import *
|
||||
|
||||
|
||||
VERSION = "v0.2.7"
|
||||
VERSION = "v0.2.10"
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
import logging
|
||||
import os
|
||||
import langchain
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
|
||||
# 是否显示详细日志
|
||||
log_verbose = False
|
||||
langchain.verbose = False
|
||||
|
||||
# 是否保存聊天记录
|
||||
SAVE_CHAT_HISTORY = False
|
||||
|
||||
# 通常情况下不需要更改以下内容
|
||||
|
||||
# 日志格式
|
||||
@ -23,3 +22,11 @@ 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)
|
||||
|
||||
@ -3,12 +3,15 @@ import os
|
||||
# 默认使用的知识库
|
||||
DEFAULT_KNOWLEDGE_BASE = "samples"
|
||||
|
||||
# 默认向量库/全文检索引擎类型。可选:faiss, milvus(离线) & zilliz(在线), pgvector,全文检索引擎es
|
||||
# 默认向量库/全文检索引擎类型。可选:faiss, milvus(离线) & zilliz(在线), pgvector, chromadb 全文检索引擎es
|
||||
DEFAULT_VS_TYPE = "faiss"
|
||||
|
||||
# 缓存向量库数量(针对FAISS)
|
||||
CACHED_VS_NUM = 1
|
||||
|
||||
# 缓存临时向量库数量(针对FAISS),用于文件对话
|
||||
CACHED_MEMO_VS_NUM = 10
|
||||
|
||||
# 知识库中单段文本长度(不适用MarkdownHeaderTextSplitter)
|
||||
CHUNK_SIZE = 250
|
||||
|
||||
@ -18,8 +21,9 @@ OVERLAP_SIZE = 50
|
||||
# 知识库匹配向量数量
|
||||
VECTOR_SEARCH_TOP_K = 3
|
||||
|
||||
# 知识库匹配相关度阈值,取值范围在0-1之间,SCORE越小,相关度越高,取到1相当于不筛选,建议设置在0.5左右
|
||||
SCORE_THRESHOLD = 1
|
||||
# 知识库匹配的距离阈值,一般取值范围在0-1之间,SCORE越小,距离越小从而相关度越高。
|
||||
# 但有用户报告遇到过匹配分值超过1的情况,为了兼容性默认设为1,在WEBUI中调整范围为0-2
|
||||
SCORE_THRESHOLD = 1.0
|
||||
|
||||
# 默认搜索引擎。可选:bing, duckduckgo, metaphor
|
||||
DEFAULT_SEARCH_ENGINE = "duckduckgo"
|
||||
@ -44,12 +48,17 @@ 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 = {
|
||||
@ -97,13 +106,18 @@ kbs_config = {
|
||||
"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": {
|
||||
|
||||
@ -1,59 +1,58 @@
|
||||
import os
|
||||
|
||||
|
||||
# 可以指定一个绝对路径,统一存放所有的Embedding和LLM模型。
|
||||
# 每个模型可以是一个单独的目录,也可以是某个目录下的二级子目录。
|
||||
# 如果模型目录名称和 MODEL_PATH 中的 key 或 value 相同,程序会自动检测加载,无需修改 MODEL_PATH 中的路径。
|
||||
MODEL_ROOT_PATH = ""
|
||||
|
||||
# 选用的 Embedding 名称
|
||||
EMBEDDING_MODEL = "m3e-base" # bge-large-zh
|
||||
EMBEDDING_MODEL = "bge-large-zh-v1.5"
|
||||
|
||||
# Embedding 模型运行设备。设为"auto"会自动检测,也可手动设定为"cuda","mps","cpu"其中之一。
|
||||
# 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 的默认模型
|
||||
LLM_MODELS = ["chatglm2-6b", "zhipu-api", "openai-api"]
|
||||
# 要运行的 LLM 名称,可以包括本地模型和在线模型。列表中本地模型将在启动项目时全部加载。
|
||||
# 列表中第一个模型将作为 API 和 WEBUI 的默认模型。
|
||||
# 在这里,我们使用目前主流的两个离线模型,其中,chatglm3-6b 为默认加载模型。
|
||||
# 如果你的显存不足,可使用 Qwen-1_8B-Chat, 该模型 FP16 仅需 3.8G显存。
|
||||
|
||||
# AgentLM模型的名称 (可以不指定,指定之后就锁定进入Agent之后的Chain的模型,不指定就是LLM_MODELS[0])
|
||||
LLM_MODELS = ["chatglm3-6b", "zhipu-api", "openai-api"]
|
||||
Agent_MODEL = None
|
||||
|
||||
# LLM 运行设备。设为"auto"会自动检测,也可手动设定为"cuda","mps","cpu"其中之一。
|
||||
# LLM 模型运行设备。设为"auto"会自动检测(会有警告),也可手动设定为 "cuda","mps","cpu","xpu" 其中之一。
|
||||
LLM_DEVICE = "auto"
|
||||
|
||||
# 历史对话轮数
|
||||
HISTORY_LEN = 3
|
||||
|
||||
# 大模型最长支持的长度,如果不填写,则使用模型默认的最大长度,如果填写,则为用户设定的最大长度
|
||||
MAX_TOKENS = None
|
||||
MAX_TOKENS = 2048
|
||||
|
||||
# LLM通用对话参数
|
||||
TEMPERATURE = 0.7
|
||||
# TOP_P = 0.95 # ChatOpenAI暂不支持该参数
|
||||
|
||||
ONLINE_LLM_MODEL = {
|
||||
# 线上模型。请在server_config中为每个在线API设置不同的端口
|
||||
|
||||
"openai-api": {
|
||||
"model_name": "gpt-35-turbo",
|
||||
"model_name": "gpt-4",
|
||||
"api_base_url": "https://api.openai.com/v1",
|
||||
"api_key": "",
|
||||
"openai_proxy": "",
|
||||
},
|
||||
|
||||
# 具体注册及api key获取请前往 http://open.bigmodel.cn
|
||||
# 智谱AI API,具体注册及api key获取请前往 http://open.bigmodel.cn
|
||||
"zhipu-api": {
|
||||
"api_key": "",
|
||||
"version": "chatglm_turbo", # 可选包括 "chatglm_turbo"
|
||||
"version": "glm-4",
|
||||
"provider": "ChatGLMWorker",
|
||||
},
|
||||
|
||||
|
||||
# 具体注册及api key获取请前往 https://api.minimax.chat/
|
||||
"minimax-api": {
|
||||
"group_id": "",
|
||||
@ -62,13 +61,12 @@ ONLINE_LLM_MODEL = {
|
||||
"provider": "MiniMaxWorker",
|
||||
},
|
||||
|
||||
|
||||
# 具体注册及api key获取请前往 https://xinghuo.xfyun.cn/
|
||||
"xinghuo-api": {
|
||||
"APPID": "",
|
||||
"APISecret": "",
|
||||
"api_key": "",
|
||||
"version": "v1.5", # 你使用的讯飞星火大模型版本,可选包括 "v3.0", "v1.5", "v2.0"
|
||||
"version": "v3.5", # 你使用的讯飞星火大模型版本,可选包括 "v3.5","v3.0", "v2.0", "v1.5"
|
||||
"provider": "XingHuoWorker",
|
||||
},
|
||||
|
||||
@ -83,8 +81,8 @@ ONLINE_LLM_MODEL = {
|
||||
|
||||
# 火山方舟 API,文档参考 https://www.volcengine.com/docs/82379
|
||||
"fangzhou-api": {
|
||||
"version": "chatglm-6b-model", # 当前支持 "chatglm-6b-model", 更多的见文档模型支持列表中方舟部分。
|
||||
"version_url": "", # 可以不填写version,直接填写在方舟申请模型发布的API地址
|
||||
"version": "", # 对应火山方舟的 endpoint_id
|
||||
"version_url": "",
|
||||
"api_key": "",
|
||||
"secret_key": "",
|
||||
"provider": "FangZhouWorker",
|
||||
@ -92,14 +90,15 @@ ONLINE_LLM_MODEL = {
|
||||
|
||||
# 阿里云通义千问 API,文档参考 https://help.aliyun.com/zh/dashscope/developer-reference/api-details
|
||||
"qwen-api": {
|
||||
"version": "qwen-turbo", # 可选包括 "qwen-turbo", "qwen-plus"
|
||||
"api_key": "", # 请在阿里云控制台模型服务灵积API-KEY管理页面创建
|
||||
"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", # 当前支持 "Baichuan2-53B", 见官方文档。
|
||||
"version": "Baichuan2-53B",
|
||||
"api_key": "",
|
||||
"secret_key": "",
|
||||
"provider": "BaiChuanWorker",
|
||||
@ -114,6 +113,32 @@ ONLINE_LLM_MODEL = {
|
||||
"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种设置方法:
|
||||
@ -124,6 +149,7 @@ 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",
|
||||
@ -137,42 +163,84 @@ 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",
|
||||
},
|
||||
|
||||
"llm_model": {
|
||||
# 以下部分模型并未完全测试,仅根据fastchat和vllm模型的模型列表推定支持
|
||||
"chatglm2-6b": "THUDM/chatglm2-6b",
|
||||
"chatglm2-6b-32k": "THUDM/chatglm2-6b-32k",
|
||||
"chatglm3-6b": "THUDM/chatglm3-6b",
|
||||
"chatglm3-6b-32k": "THUDM/chatglm3-6b-32k",
|
||||
|
||||
"baichuan2-13b": "baichuan-inc/Baichuan2-13B-Chat",
|
||||
"baichuan2-7b": "baichuan-inc/Baichuan2-7B-Chat",
|
||||
"Orion-14B-Chat": "OrionStarAI/Orion-14B-Chat",
|
||||
"Orion-14B-Chat-Plugin": "OrionStarAI/Orion-14B-Chat-Plugin",
|
||||
"Orion-14B-LongChat": "OrionStarAI/Orion-14B-LongChat",
|
||||
|
||||
"baichuan-7b": "baichuan-inc/Baichuan-7B",
|
||||
"baichuan-13b": "baichuan-inc/Baichuan-13B",
|
||||
'baichuan-13b-chat': 'baichuan-inc/Baichuan-13B-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",
|
||||
|
||||
"aquila-7b": "BAAI/Aquila-7B",
|
||||
"aquilachat-7b": "BAAI/AquilaChat-7B",
|
||||
"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",
|
||||
|
||||
# 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",
|
||||
|
||||
"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",
|
||||
|
||||
"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",
|
||||
|
||||
"BlueLM-7B-Chat": "vivo-ai/BlueLM-7B-Chat",
|
||||
"BlueLM-7B-Chat-32k": "vivo-ai/BlueLM-7B-Chat-32k",
|
||||
|
||||
"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",
|
||||
@ -180,50 +248,51 @@ MODEL_PATH = {
|
||||
"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",
|
||||
|
||||
"Qwen-7B": "Qwen/Qwen-7B",
|
||||
"Qwen-14B": "Qwen/Qwen-14B",
|
||||
"Qwen-7B-Chat": "Qwen/Qwen-7B-Chat",
|
||||
"Qwen-14B-Chat": "Qwen/Qwen-14B-Chat",
|
||||
"Qwen-14B-Chat-Int8": "Qwen/Qwen-14B-Chat-Int8", # 确保已经安装了auto-gptq optimum flash-attn
|
||||
"Qwen-14B-Chat-Int4": "Qwen/Qwen-14B-Chat-Int4", # 确保已经安装了auto-gptq optimum flash-attn
|
||||
},
|
||||
}
|
||||
|
||||
"reranker": {
|
||||
"bge-reranker-large": "BAAI/bge-reranker-large",
|
||||
"bge-reranker-base": "BAAI/bge-reranker-base",
|
||||
}
|
||||
}
|
||||
|
||||
# 通常情况下不需要更改以下内容
|
||||
|
||||
# nltk 模型存储路径
|
||||
NLTK_DATA_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "nltk_data")
|
||||
|
||||
# 使用VLLM可能导致模型推理能力下降,无法完成Agent任务
|
||||
VLLM_MODEL_DICT = {
|
||||
"aquila-7b": "BAAI/Aquila-7B",
|
||||
"aquilachat-7b": "BAAI/AquilaChat-7B",
|
||||
"chatglm2-6b": "THUDM/chatglm2-6b",
|
||||
"chatglm2-6b-32k": "THUDM/chatglm2-6b-32k",
|
||||
"chatglm3-6b": "THUDM/chatglm3-6b",
|
||||
"chatglm3-6b-32k": "THUDM/chatglm3-6b-32k",
|
||||
|
||||
"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",
|
||||
"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",
|
||||
|
||||
"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",
|
||||
|
||||
"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",
|
||||
|
||||
"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",
|
||||
@ -236,8 +305,6 @@ VLLM_MODEL_DICT = {
|
||||
"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",
|
||||
@ -247,27 +314,14 @@ VLLM_MODEL_DICT = {
|
||||
"opt-66b": "facebook/opt-66b",
|
||||
"opt-iml-max-30b": "facebook/opt-iml-max-30b",
|
||||
|
||||
"Qwen-7B": "Qwen/Qwen-7B",
|
||||
"Qwen-14B": "Qwen/Qwen-14B",
|
||||
"Qwen-7B-Chat": "Qwen/Qwen-7B-Chat",
|
||||
"Qwen-14B-Chat": "Qwen/Qwen-14B-Chat",
|
||||
|
||||
"agentlm-7b": "THUDM/agentlm-7b",
|
||||
"agentlm-13b": "THUDM/agentlm-13b",
|
||||
"agentlm-70b": "THUDM/agentlm-70b",
|
||||
|
||||
}
|
||||
|
||||
# 你认为支持Agent能力的模型,可以在这里添加,添加后不会出现可视化界面的警告
|
||||
SUPPORT_AGENT_MODEL = [
|
||||
"azure-api",
|
||||
"openai-api",
|
||||
"claude-api",
|
||||
"zhipu-api",
|
||||
"qwen-api",
|
||||
"Qwen",
|
||||
"baichuan-api",
|
||||
"agentlm",
|
||||
"chatglm3",
|
||||
"xinghuo-api",
|
||||
"openai-api", # GPT4 模型
|
||||
"qwen-api", # Qwen Max模型
|
||||
"zhipu-api", # 智谱AI GLM4模型
|
||||
"Qwen", # 所有Qwen系列本地模型
|
||||
"chatglm3-6b",
|
||||
"internlm2-chat-20b",
|
||||
"Orion-14B-Chat-Plugin",
|
||||
]
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
# prompt模板使用Jinja2语法,简单点就是用双大括号代替f-string的单大括号
|
||||
# 本配置文件支持热加载,修改prompt模板后无需重启服务。
|
||||
|
||||
|
||||
# LLM对话支持的变量:
|
||||
# - input: 用户输入内容
|
||||
|
||||
@ -18,141 +17,111 @@
|
||||
# - agent_scratchpad: Agent的思维记录
|
||||
|
||||
PROMPT_TEMPLATES = {
|
||||
"completion": {
|
||||
"default": "{input}"
|
||||
},
|
||||
|
||||
"llm_chat": {
|
||||
"default": "{{ input }}",
|
||||
"default":
|
||||
'{{ input }}',
|
||||
|
||||
"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:',
|
||||
|
||||
"py":
|
||||
"""
|
||||
你是一个聪明的代码助手,请你给我写出简单的py代码。 \n
|
||||
{{ input }}
|
||||
"""
|
||||
,
|
||||
'你是一个聪明的代码助手,请你给我写出简单的py代码。 \n'
|
||||
'{{ input }}',
|
||||
},
|
||||
|
||||
|
||||
"knowledge_base_chat": {
|
||||
"default":
|
||||
"""
|
||||
<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,不允许在答案中添加编造成分,答案请使用中文。 </指令>
|
||||
<已知信息>{{ context }}</已知信息>、
|
||||
<问题>{{ question }}</问题>
|
||||
""",
|
||||
'<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,'
|
||||
'不允许在答案中添加编造成分,答案请使用中文。 </指令>\n'
|
||||
'<已知信息>{{ context }}</已知信息>\n'
|
||||
'<问题>{{ question }}</问题>\n',
|
||||
|
||||
"text":
|
||||
"""
|
||||
<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>
|
||||
<已知信息>{{ context }}</已知信息>、
|
||||
<问题>{{ question }}</问题>
|
||||
""",
|
||||
"Empty": # 搜不到内容的时候调用,此时没有已知信息,这个Empty可以更改,但不能删除,会影响程序使用
|
||||
"""
|
||||
<指令>请根据用户的问题,进行简洁明了的回答</指令>
|
||||
<问题>{{ question }}</问题>
|
||||
""",
|
||||
'<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>\n'
|
||||
'<已知信息>{{ context }}</已知信息>\n'
|
||||
'<问题>{{ question }}</问题>\n',
|
||||
|
||||
"empty": # 搜不到知识库的时候使用
|
||||
'请你回答我的问题:\n'
|
||||
'{{ question }}\n\n',
|
||||
},
|
||||
|
||||
|
||||
"search_engine_chat": {
|
||||
"default":
|
||||
"""
|
||||
<指令>这是我搜索到的互联网信息,请你根据这些信息进行提取并有调理,简洁的回答问题。如果无法从中得到答案,请说 “无法搜索到能回答问题的内容”。 </指令>
|
||||
<已知信息>{{ context }}</已知信息>、
|
||||
<问题>{{ question }}</问题>
|
||||
""",
|
||||
'<指令>这是我搜索到的互联网信息,请你根据这些信息进行提取并有调理,简洁的回答问题。'
|
||||
'如果无法从中得到答案,请说 “无法搜索到能回答问题的内容”。 </指令>\n'
|
||||
'<已知信息>{{ context }}</已知信息>\n'
|
||||
'<问题>{{ question }}</问题>\n',
|
||||
|
||||
"search":
|
||||
"""
|
||||
<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>
|
||||
<已知信息>{{ context }}</已知信息>、
|
||||
<问题>{{ question }}</问题>
|
||||
""",
|
||||
"Empty": # 搜不到内容的时候调用,此时没有已知信息,这个Empty可以更改,但不能删除,会影响程序使用
|
||||
"""
|
||||
<指令>请根据用户的问题,进行简洁明了的回答</指令>
|
||||
<问题>{{ question }}</问题>
|
||||
""",
|
||||
'<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,答案请使用中文。 </指令>\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:
|
||||
'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',
|
||||
|
||||
{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}
|
||||
""",
|
||||
|
||||
"AgentLM":
|
||||
"""
|
||||
<SYS>>\n
|
||||
You are a helpful, respectful and honest assistant.
|
||||
</SYS>>\n
|
||||
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}.
|
||||
|
||||
Use the following steps and think step by step!:
|
||||
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! let's think step by step!
|
||||
history:
|
||||
{history}
|
||||
Question: {input}
|
||||
Thought: {agent_scratchpad}
|
||||
|
||||
""",
|
||||
|
||||
"中文版本":
|
||||
"""
|
||||
你的知识不一定正确,所以你一定要用提供的工具来思考,并给出用户答案。
|
||||
你有以下工具可以使用:
|
||||
{tools}
|
||||
|
||||
请请严格按照提供的思维方式来思考,所有的关键词都要输出,例如Action,Action Input,Observation等
|
||||
```
|
||||
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}
|
||||
""",
|
||||
},
|
||||
"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}',
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ FSCHAT_MODEL_WORKERS = {
|
||||
# "no_register": False,
|
||||
# "embed_in_truncate": False,
|
||||
|
||||
# 以下为vllm_woker配置参数,注意使用vllm必须有gpu,仅在Linux测试通过
|
||||
# 以下为vllm_worker配置参数,注意使用vllm必须有gpu,仅在Linux测试通过
|
||||
|
||||
# tokenizer = model_path # 如果tokenizer与model_path不一致在此处添加
|
||||
# 'tokenizer_mode':'auto',
|
||||
@ -90,12 +90,13 @@ FSCHAT_MODEL_WORKERS = {
|
||||
# 'disable_log_requests': False
|
||||
|
||||
},
|
||||
# 可以如下示例方式更改默认配置
|
||||
# "baichuan-7b": { # 使用default中的IP和端口
|
||||
# "device": "cpu",
|
||||
# },
|
||||
|
||||
#以下配置可以不用修改,在model_config中设置启动的模型
|
||||
"chatglm3-6b": {
|
||||
"device": "cuda",
|
||||
},
|
||||
"Qwen1.5-0.5B-Chat": {
|
||||
"device": "cuda",
|
||||
},
|
||||
# 以下配置可以不用修改,在model_config中设置启动的模型
|
||||
"zhipu-api": {
|
||||
"port": 21001,
|
||||
},
|
||||
@ -120,14 +121,17 @@ FSCHAT_MODEL_WORKERS = {
|
||||
"azure-api": {
|
||||
"port": 21008,
|
||||
},
|
||||
"tiangong-api": {
|
||||
"port": 21009,
|
||||
},
|
||||
"gemini-api": {
|
||||
"port": 21010,
|
||||
},
|
||||
"claude-api": {
|
||||
"port": 21011,
|
||||
},
|
||||
}
|
||||
|
||||
# fastchat multi model worker server
|
||||
FSCHAT_MULTI_MODEL_WORKERS = {
|
||||
# TODO:
|
||||
}
|
||||
|
||||
# fastchat controller server
|
||||
FSCHAT_CONTROLLER = {
|
||||
"host": DEFAULT_BIND_HOST,
|
||||
"port": 20001,
|
||||
|
||||
@ -54,27 +54,31 @@ class FilteredCSVLoader(CSVLoader):
|
||||
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):
|
||||
if self.columns_to_read[0] in row:
|
||||
content = row[self.columns_to_read[0]]
|
||||
# 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}
|
||||
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]
|
||||
for col in self.metadata_columns:
|
||||
if col in row:
|
||||
metadata[col] = row[col]
|
||||
|
||||
doc = Document(page_content=content, metadata=metadata)
|
||||
docs.append(doc)
|
||||
else:
|
||||
raise ValueError(f"Column '{self.columns_to_read[0]}' not found in CSV file.")
|
||||
doc = Document(page_content=content, metadata=metadata)
|
||||
docs.append(doc)
|
||||
|
||||
return docs
|
||||
return docs
|
||||
|
||||
@ -1,2 +1,4 @@
|
||||
from .mypdfloader import RapidOCRPDFLoader
|
||||
from .myimgloader import RapidOCRLoader
|
||||
from .myimgloader import RapidOCRLoader
|
||||
from .mydocloader import RapidOCRDocLoader
|
||||
from .mypptloader import RapidOCRPPTLoader
|
||||
|
||||
71
document_loaders/mydocloader.py
Normal file
@ -0,0 +1,71 @@
|
||||
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)
|
||||
@ -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 = RapidOCR()
|
||||
ocr = get_ocr()
|
||||
result, _ = ocr(filepath)
|
||||
if result:
|
||||
ocr_result = [line[1] for line in result]
|
||||
|
||||
@ -1,37 +1,76 @@
|
||||
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 = RapidOCR()
|
||||
ocr = get_ocr()
|
||||
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_images()
|
||||
img_list = page.get_image_info(xrefs=True)
|
||||
for img in img_list:
|
||||
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)
|
||||
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)
|
||||
|
||||
# 更新进度
|
||||
b_unit.update(1)
|
||||
@ -43,6 +82,6 @@ class RapidOCRPDFLoader(UnstructuredFileLoader):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
loader = RapidOCRPDFLoader(file_path="../tests/samples/ocr_test.pdf")
|
||||
loader = RapidOCRPDFLoader(file_path="/Users/tonysong/Desktop/test.pdf")
|
||||
docs = loader.load()
|
||||
print(docs)
|
||||
|
||||
59
document_loaders/mypptloader.py
Normal file
@ -0,0 +1,59 @@
|
||||
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)
|
||||
18
document_loaders/ocr.py
Normal file
@ -0,0 +1,18 @@
|
||||
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
|
||||
@ -7,31 +7,35 @@
|
||||
保存的模型的位置位于原本嵌入模型的目录下,模型的名称为原模型名称+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,
|
||||
)
|
||||
import os
|
||||
import torch
|
||||
|
||||
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)
|
||||
|
||||
# No need to manually convert to tensor as we've set return_tensors="pt"
|
||||
input_ids = tokenizer_output['input_ids']
|
||||
|
||||
# Remove the first and last token for each sequence in the batch
|
||||
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
|
||||
|
||||
|
||||
@ -47,14 +51,11 @@ def add_keyword_to_model(model_name=EMBEDDING_MODEL, keyword_file: str = "", out
|
||||
bert_model = word_embedding_model.auto_model
|
||||
tokenizer = word_embedding_model.tokenizer
|
||||
key_words_embedding = get_keyword_embedding(bert_model, tokenizer, key_words)
|
||||
# key_words_embedding = st_model.encode(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)
|
||||
|
||||
# key_words_embedding_tensor = torch.from_numpy(key_words_embedding)
|
||||
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
|
||||
@ -76,46 +77,3 @@ def add_keyword_to_embedding_model(path: str = EMBEDDING_KEYWORD_FILE):
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
add_keyword_to_embedding_model(EMBEDDING_KEYWORD_FILE)
|
||||
|
||||
# input_model_name = ""
|
||||
# output_model_path = ""
|
||||
# # 以下为加入关键字前后tokenizer的测试用例对比
|
||||
# def print_token_ids(output, tokenizer, sentences):
|
||||
# for idx, ids in enumerate(output['input_ids']):
|
||||
# print(f'sentence={sentences[idx]}')
|
||||
# print(f'ids={ids}')
|
||||
# for id in ids:
|
||||
# decoded_id = tokenizer.decode(id)
|
||||
# print(f' {decoded_id}->{id}')
|
||||
#
|
||||
# sentences = [
|
||||
# '数据科学与大数据技术',
|
||||
# 'Langchain-Chatchat'
|
||||
# ]
|
||||
#
|
||||
# st_no_keywords = SentenceTransformer(input_model_name)
|
||||
# tokenizer_without_keywords = st_no_keywords.tokenizer
|
||||
# print("===== tokenizer with no keywords added =====")
|
||||
# output = tokenizer_without_keywords(sentences)
|
||||
# print_token_ids(output, tokenizer_without_keywords, sentences)
|
||||
# print(f'-------- embedding with no keywords added -----')
|
||||
# embeddings = st_no_keywords.encode(sentences)
|
||||
# print(embeddings)
|
||||
#
|
||||
# print("--------------------------------------------")
|
||||
# print("--------------------------------------------")
|
||||
# print("--------------------------------------------")
|
||||
#
|
||||
# st_with_keywords = SentenceTransformer(output_model_path)
|
||||
# tokenizer_with_keywords = st_with_keywords.tokenizer
|
||||
# print("===== tokenizer with keyword added =====")
|
||||
# output = tokenizer_with_keywords(sentences)
|
||||
# print_token_ids(output, tokenizer_with_keywords, sentences)
|
||||
#
|
||||
# print(f'-------- embedding with keywords added -----')
|
||||
# embeddings = st_with_keywords.encode(sentences)
|
||||
# print(embeddings)
|
||||
BIN
img/qr_code_100.jpg
Normal file
|
After Width: | Height: | Size: 281 KiB |
BIN
img/qr_code_101.jpg
Normal file
|
After Width: | Height: | Size: 244 KiB |
BIN
img/qr_code_102.jpg
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
img/qr_code_103.jpg
Normal file
|
After Width: | Height: | Size: 196 KiB |
BIN
img/qr_code_104.jpg
Normal file
|
After Width: | Height: | Size: 185 KiB |
BIN
img/qr_code_105.jpg
Normal file
|
After Width: | Height: | Size: 252 KiB |
BIN
img/qr_code_106.jpg
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
img/qr_code_106_2.jpg
Normal file
|
After Width: | Height: | Size: 208 KiB |
BIN
img/qr_code_107.jpg
Normal file
|
After Width: | Height: | Size: 181 KiB |
BIN
img/qr_code_108.jpg
Normal file
|
After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 198 KiB |
BIN
img/qr_code_90.jpg
Normal file
|
After Width: | Height: | Size: 273 KiB |
BIN
img/qr_code_90.png
Normal file
|
After Width: | Height: | Size: 439 KiB |
BIN
img/qr_code_91.jpg
Normal file
|
After Width: | Height: | Size: 227 KiB |
BIN
img/qr_code_92.jpg
Normal file
|
After Width: | Height: | Size: 213 KiB |
BIN
img/qr_code_93.jpg
Normal file
|
After Width: | Height: | Size: 226 KiB |
BIN
img/qr_code_94.jpg
Normal file
|
After Width: | Height: | Size: 244 KiB |
BIN
img/qr_code_95.jpg
Normal file
|
After Width: | Height: | Size: 252 KiB |
BIN
img/qr_code_96.jpg
Normal file
|
After Width: | Height: | Size: 222 KiB |
BIN
img/qr_code_97.jpg
Normal file
|
After Width: | Height: | Size: 200 KiB |
BIN
img/qr_code_98.jpg
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
img/qr_code_99.jpg
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
img/qrcode_90_2.jpg
Normal file
|
After Width: | Height: | Size: 232 KiB |
@ -6,7 +6,6 @@ from configs.model_config import NLTK_DATA_PATH, EMBEDDING_MODEL
|
||||
import nltk
|
||||
nltk.data.path = [NLTK_DATA_PATH] + nltk.data.path
|
||||
from datetime import datetime
|
||||
import sys
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@ -50,11 +49,11 @@ if __name__ == "__main__":
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--increament",
|
||||
"--increment",
|
||||
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 increamentally.
|
||||
use this option if you want to create vectors incrementally.
|
||||
'''
|
||||
)
|
||||
)
|
||||
@ -100,7 +99,7 @@ if __name__ == "__main__":
|
||||
|
||||
if args.clear_tables:
|
||||
reset_tables()
|
||||
print("database talbes reseted")
|
||||
print("database tables reset")
|
||||
|
||||
if args.recreate_vs:
|
||||
create_tables()
|
||||
@ -110,8 +109,8 @@ if __name__ == "__main__":
|
||||
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.increament:
|
||||
folder2db(kb_names=args.kb_name, mode="increament", 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:
|
||||
|
||||
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 227 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 154 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 331 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 227 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 177 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 266 KiB |
|
After Width: | Height: | Size: 88 KiB |
74
knowledge_base/samples/content/llm/分布式训练技术原理.md
Normal file
@ -0,0 +1,74 @@
|
||||
# 分布式训练技术原理
|
||||
- 数据并行
|
||||
- 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后,各得一份梯度,对梯度做一次 **AllReduce(reduce-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,取回完整的W,backward做完,立刻把不是自己维护的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计算量高** ,因此和它们相关的部分,例如参数W(fp16),activation,就全放入GPU
|
||||
- **update的部分计算量低** ,因此和它相关的部分,全部放入CPU中。例如W(fp32),optimizer states(fp32)和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切分
|
||||
- 对第一个线性层按列切分,对第二个线性层按行切分
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- self-attention切分
|
||||
- attention的多头计算天然适合tensor并行,因为每个头上都可以独立计算最后再将结果concat起来,从而 **可以把每个头的参数放到一块GPU上**
|
||||
- 对线性层, **按照“行切割”** 。切割的方式和MLP层基本一致,其forward与backward原理也一致
|
||||
- 输入层Embedding切分
|
||||
- 对positional embedding来说,max_s本身不会太长,因此每个GPU上都拷贝一份,对显存的压力也不会太大
|
||||
- 将word embedding拆分到不同GPU上,每块GPU维护一分部词表。当输入X去GPU上查找时,能找到的词,就正常返回词向量,找到不到就把词向量中的全部全素都置0。按此方式查找完毕后,每块GPU上的数据做一次AllReduce,就能得到最终的输入。
|
||||
- 
|
||||
- 输出层Embedding切分
|
||||
- **输入层和输出层共用一个word embeding**
|
||||
- **当模型的输入层到输入层都在一块GPU上时(即流水线并行深度=1),我们不必担心这点(实践中大部分用Megatron做并行的项目也是这么做的)。但若模型输入层和输出层在不同的GPU上时,我们就要保证在权重更新前,两块GPU上的word embedding梯度做了一次AllReduce** 。
|
||||
- 
|
||||
- cross-entroy
|
||||
- 
|
||||
- 
|
||||
- [pipeline paralelism]("https://zhuanlan.zhihu.com/p/629637468")
|
||||
- GPipe
|
||||
- PipeDream
|
||||
- 1F1B
|
||||
- 每个 GPU 以交替的方式执行每个 micro batch 的正向和反向过程,以尽早释放其占用的显存,进而减少显存占用
|
||||
- 
|
||||
- 1F1B 并不能减少 bubble time, **为了进一步减少 bubble time,Megatron 又提出了 interleaved 1F1B 模式** 。也就是原本每个 GPU 负责连续 4 个层的计算,现在变成负责连续两个层的计算,只有原来的一半,从而 bubble time 也变成了原来的一半,即把一个设备上连续的层划分为若干不连续的层,负责的数量不变,但顺序变了。
|
||||
- 
|
||||
- DAPPLE
|
||||
- 
|
||||
- layer-wise parallelism
|
||||
- sequence parallelism
|
||||
- Sequence 并行的好处在于不会增加通信量,并且可以大大减少显存占用
|
||||
- Layer-norm 和 Dropout 沿着序列的维度是独立的,因此可以按照 Sequence 维度进行拆分
|
||||
- 使用了 Sequence 并行之后,对于超大规模的模型而言,其实显存占用量还是很大的。因此,Megatron 又引入了激活重计算技术,找到一些计算量很少但显存占用很大的算子,比如 Attention 里的 Softmax、Dropout 等算子,对这些算子进行激活重计算就可以显著减少显存,并且计算开销增加不大
|
||||
- MoE
|
||||
- 核心思想:将大模型拆分成多个小模型。每个样本只需要激活部分专家模型进行计算,从而大大节省计算资源。 **MoE 的基本思路是通过宽度换取深度,因为模型深度越深,计算层数越多,进而推理时间越长**
|
||||
- Hard Gate MoE
|
||||
- Sparse MoE
|
||||
97
knowledge_base/samples/content/llm/大模型应用技术原理.md
Normal file
@ -0,0 +1,97 @@
|
||||
# 大模型应用技术原理
|
||||
- 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)
|
||||
- 
|
||||
- 
|
||||
- Hashing-based
|
||||
- LSH
|
||||
- Spherical Hashing
|
||||
- Spectral Hashing
|
||||
- 量化
|
||||
- PQ(Product Quantization)
|
||||
- PQ 将特征空间分解为多个低维子空间的笛卡尔乘积,然后单独地对每一个子空间进行量化
|
||||
- SQ(Scalar 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在推理阶段可控。
|
||||
- 
|
||||
- 
|
||||
- 训练
|
||||
- 首先,训练评论家,使用检索器检索到的段落以及反思令牌增强指令-输出数据,然后,使用标准的下一个 token 预测目标来训练生成器 LM,以学习生成 自然延续(continuations)以及特殊 tokens (用来检索或批评其自己的生成内容).
|
||||
- 推理
|
||||
- 它可以适应性地使用检索令牌进行检索,因此模型可以自发判断是不是有必要进行检索。它引入了多种细粒度的批评令牌,这些令牌用于评估生成内容的各个方面的质量。在生成过程中,作者使用期望的批评令牌概率的线性插值进行segment级的beam search,以在每一个时间步骤中确定最佳的K个续写方案
|
||||
- Agent
|
||||
- function call
|
||||
- ToolFormer
|
||||
44
knowledge_base/samples/content/llm/大模型技术栈-实战与应用.md
Normal file
@ -0,0 +1,44 @@
|
||||
# 大模型技术栈-实战与应用
|
||||
- 训练框架
|
||||
- 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
|
||||
301
knowledge_base/samples/content/llm/大模型技术栈-算法与原理.md
Normal file
@ -0,0 +1,301 @@
|
||||
# 大模型技术栈-算法与原理
|
||||
- 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后,各得一份梯度,对梯度做一次 **AllReduce(reduce-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,取回完整的W,backward做完,立刻把不是自己维护的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计算量高** ,因此和它们相关的部分,例如参数W(fp16),activation,就全放入GPU
|
||||
- **update的部分计算量低** ,因此和它相关的部分,全部放入CPU中。例如W(fp32),optimizer states(fp32)和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)
|
||||
- 利用二阶导数信息度量模型参数的显著性,剪掉影响小的参数降低模型复杂度提高泛化能力
|
||||
- 
|
||||
- OBS(Optimal Brain Surgeon )
|
||||
- OBD粗暴的只考虑海森矩阵对角线元素。OBS考虑海森矩阵全局信息,由此也获得参数相互之间的影响。
|
||||
- OBC(OPTIMAL BRAIN COMPRESSION )
|
||||
- OBS对整个神经网络进行剪枝,OBC对神经网络模型分层剪枝或者量化
|
||||
- ExactOBS
|
||||
- 参数更新和代价评估不需要使用整个海森矩阵,仅使用和剪枝参数所在行相关的 d_col\time d_col大小的海森矩阵。
|
||||
- 量化 
|
||||
- GPTQ
|
||||
- 1.是对OBC的改进
|
||||
- 2. 取消了贪心算法,采用固定位置优化
|
||||
- 3. 分组量化,并行加速
|
||||
- 
|
||||
- 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越大
|
||||
- 
|
||||
- OBC(OPTIMAL BRAIN COMPRESSION )
|
||||
- 
|
||||
- SmoothQuant
|
||||
- 1. 当模型规模更大时,单个token的值变化范围较大,难以量化,相比之下 weight 的变化范围较小,即 weight 较易量化,而 activation 较难量化
|
||||
- 2. SmoothQuant 核心思想是引入一个超参,减小激活值的变化范围,增大权重的变化范围,从而均衡两者的量化难度
|
||||
- 3. 得到smooth变换之后的 activation 和 weight 矩阵,可以再采用 per-token 或 per-tensor 的量化方式,
|
||||
- 
|
||||
- LLM.int8
|
||||
- 采用混合精度分解的量化方法:将包含了Emergent Features的几个维度从矩阵中分离出来,对其做高精度的矩阵乘法;其余部分进行量化
|
||||
- ZeroQuant
|
||||
- 1. 对权重使用分组量化,对激活使用token量化
|
||||
- 2. 开发了高度优化的推理后端,消除了量化/反量化运算符昂贵的计算成本,在现代GPU硬件上实现INT8 Tensor内核的延迟加速
|
||||
- 3. 提出了一种用于INT4/INT8混合精度量化的新的逐层知识蒸馏方法(LKD),其中神经网络通过蒸馏逐层量化,迭代最小,甚至不访问原始训练数据
|
||||
- 分类学
|
||||
- 对称量化vs非对称量化
|
||||
- 量化是否均衡,原点是否为0
|
||||
- 动态量化vs静态量化
|
||||
- 输入的缩放因子计算方法不同
|
||||
- 静态量化的模型在使用前有“calibrate”的过程(校准缩放因子),量化模型的缩放因子会根据输入数据的分布进行调整
|
||||
- Weights量化vsActivation量化
|
||||
- feature map(fm)就是每一层网络的输入tensor,featuremap量化就是我们常说的激活量化
|
||||
- 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
|
||||
- log(n)注意力缩放
|
||||
- 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**
|
||||
- Let’s 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),而是在脑中构建一个复杂的思维网络。人类在思考时会沿着一个链式的推理,回溯,再尝试一个新的方向,并把之前的链的优点保留,缺点剔除,与当前探索的链的方向结合生成一个新的解决方案
|
||||
30
knowledge_base/samples/content/llm/大模型指令对齐训练原理.md
Normal file
@ -0,0 +1,30 @@
|
||||
# 大模型指令对齐训练原理
|
||||
- RLHF
|
||||
- SFT
|
||||
- RM
|
||||
- PPO
|
||||
- AIHF-based
|
||||
- RLAIF
|
||||
- 核心在于通过AI 模型监督其他 AI 模型,即在SFT阶段,从初始模型中采样,然后生成自我批评和修正,然后根据修正后的反应微调原始模型。在 RL 阶段,从微调模型中采样,使用一个模型来评估生成的样本,并从这个 AI 偏好数据集训练一个偏好模型。然后使用偏好模型作为奖励信号对 RL 进行训练
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- RRHF
|
||||
- RRHF( **R** ank **R** esponse from **H** uman **F** eedback) 不需要强化学习,可以利用不同语言模型生成的回复,包括 ChatGPT、GPT-4 或当前的训练模型。RRHF通过对回复进行评分,并通过排名损失来使回复与人类偏好对齐。RRHF 通过通过排名损失使评分与人类的偏好(或者代理的奖励模型)对齐。RRHF 训练好的模型可以同时作为生成语言模型和奖励模型使用。
|
||||
- 
|
||||
- SFT-only
|
||||
- LIMA
|
||||
- LIMA(Less Is More for Alignment) 即浅层对齐假说,即一 **个模型的知识和能力几乎完全是在预训练中学习的,而对齐则是教会它与用户交互时如何选择子分布** 。如果假说正确,对齐主要有关于学习方式,那么该假说的一个推论是,人们可以用相当少的样本充分调整预训练的语言模型。因此, **该工作假设,对齐可以是一个简单的过程,模型学习与用户互动的风格或格式,以揭示在预训练中已经获得的知识和能力。**
|
||||
- LTD Instruction Tuning
|
||||
- 
|
||||
- Reward-only
|
||||
- DPO
|
||||
- DPO(Direct Preference Optimization) 提出了一种使用二进制交叉熵目标来精确优化LLM的方法,以替代基于 RL HF 的优化目标,从而大大简化偏好学习 pipeline。也就是说,完全可以直接优化语言模型以实现人类的偏好,而不需要明确的奖励模型或强化学习。
|
||||
- DPO 也依赖于理论上的偏好模型(如 Bradley-Terry 模型),以此衡量给定的奖励函数与经验偏好数据的吻合程度。然而,现有的方法使用偏好模型定义偏好损失来训练奖励模型,然后训练优化所学奖励模型的策略,而 DPO 使用变量的变化来直接定义偏好损失作为策略的一个函数。鉴于人类对模型响应的偏好数据集,DPO 因此可以使用一个简单的二进制交叉熵目标来优化策略,而不需要明确地学习奖励函数或在训练期间从策略中采样。
|
||||
- RAFT
|
||||
- 
|
||||
- 参考文献
|
||||
- [反思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")
|
||||
63
knowledge_base/samples/content/llm/大模型推理优化策略.md
Normal file
@ -0,0 +1,63 @@
|
||||
# 大模型推理优化策略
|
||||
- 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 
|
||||
- 
|
||||
- [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/OP;pi=平台的算力,单位FLOP/s;beta=内存带宽,单位byte/s;P=实际实现计算速度,单位为FLOP/s;优化目标为O=P/N每秒钟实现的运算次数,单位为OP/s.由于N固定,故优化目标转而为P,P=min{beta_r*I_max=beta_r*pi/beta,pi},故优化目标转而为beta,即改变内存访问策略,实现beta最大化。
|
||||
- 注意力操作中,S和P的计算空间复杂度都是O(N^2),此外,scale,mask,softmax,dropout都是带宽约束操作。 
|
||||
- 
|
||||
- 可以看出,O(N^2)空间复杂度的矩阵计算对HBM的读写是主要的内存瓶颈,因此主要优化点是:1. 在不访问整个输入的情况下计算softmax;2. 不为反向传播存储大的中间attention矩阵。FlashAttention提出两种方法来分步解决上述问题:tiling,recomputation.tiling - 注意力计算被重新构造,将输入分割成块,并通过在输入块上进行多次传递来递增地执行softmax操作。recomputation - 存储来自前向的 softmax 归一化因子,以便在反向中快速重新计算芯片上的 attention,这比从HBM读取中间矩阵的标准注意力方法更快。由于重新计算,这确实导致FLOPs增加,但是由于大量减少HBM访问,FlashAttention运行速度更快。该算法背后的主要思想是分割输入,将它们从慢速HBM加载到快速SRAM,然后计算这些块的 attention 输出。在将每个块的输出相加之前,将其按正确的归一化因子进行缩放,从而得到正确的结果。
|
||||
- 
|
||||
- 
|
||||
- 参考文献
|
||||
- [推理优化]("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
|
||||
- 
|
||||
- Blockwise *Parallel* *Decoding*
|
||||
- Medusa
|
||||
- SOT - Parallel Decoding
|
||||
- SpecInfer
|
||||
- StreamingLLM
|
||||
- 参考资料
|
||||
- [最佳实践]("https://mp.weixin.qq.com/s/nJLrE9Dzj1mmTeQDiqNdzA")
|
||||
6446
knowledge_base/samples/content/test_files/langchain.pdf
Normal file
@ -1 +1 @@
|
||||
Subproject commit b705cf80e4150cb900c77b343f0f9c62ec9a0278
|
||||
Subproject commit 28f664aa08f8191a70339c9ecbe7a89b35a1032a
|
||||
107
markdown_docs/document_loaders/FilteredCSVloader.md
Normal file
@ -0,0 +1,107 @@
|
||||
## 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})
|
||||
]
|
||||
```
|
||||
***
|
||||
106
markdown_docs/document_loaders/mydocloader.md
Normal file
@ -0,0 +1,106 @@
|
||||
## ClassDef RapidOCRDocLoader
|
||||
**RapidOCRDocLoader**: RapidOCRDocLoader的功能是从Word文档中提取文本和图片内容,并使用OCR技术转换图片中的文本。
|
||||
|
||||
**属性**:
|
||||
- 无特定公开属性,此类主要通过继承和方法实现功能。
|
||||
|
||||
**代码描述**:
|
||||
RapidOCRDocLoader类继承自UnstructuredFileLoader,专门用于处理Word文档(.docx)文件,提取其中的文本和图片内容。它通过定义一个内部函数`_get_elements`来实现这一功能。该函数首先定义了一个辅助函数`doc2text`,用于打开和解析Word文档,然后提取文档中的文本和图片内容。
|
||||
|
||||
在`doc2text`函数中,使用了python-docx库来遍历文档中的所有段落和表格。对于文档中的每个段落,直接提取其文本内容;对于表格,遍历每个单元格并提取其中的文本。此外,对于段落中包含的图片,使用了PIL库和RapidOCR库来识别图片中的文本。
|
||||
|
||||
RapidOCR是一个基于ONNX Runtime的OCR工具,能够从图片中识别文本。在本类中,对于每个找到的图片,首先将其转换为numpy数组,然后使用RapidOCR进行文本识别,最后将识别的文本添加到响应字符串中。
|
||||
|
||||
最终,`_get_elements`函数通过调用`doc2text`函数获取文档中的所有文本(包括OCR识别的文本),然后使用`partition_text`函数对文本进行分段处理,返回处理后的文本列表。
|
||||
|
||||
**注意**:
|
||||
- 使用RapidOCRDocLoader类之前,需要确保已安装python-docx、PIL、numpy和rapidocr_onnxruntime等依赖库。
|
||||
- 该类专门处理.docx格式的Word文档,不适用于其他类型的文档或图片文件。
|
||||
- OCR识别准确度受到图片质量的影响,对于低分辨率或图文混排的图片,识别结果可能不理想。
|
||||
|
||||
**输出示例**:
|
||||
假设一个Word文档包含以下内容:
|
||||
- 文本段落:“这是一个示例文档。”
|
||||
- 包含文本的图片:图片中的文本为“图片中的示例文本”。
|
||||
|
||||
使用RapidOCRDocLoader处理该文档后,可能的返回值为:
|
||||
```
|
||||
["这是一个示例文档。", "图片中的示例文本。"]
|
||||
```
|
||||
这个返回值是一个列表,包含了文档中所有文本内容,包括通过OCR技术识别出的图片中的文本。
|
||||
### FunctionDef _get_elements(self)
|
||||
**_get_elements**: 此函数的功能是从给定的Word文档中提取文本和图片内容,并将图片内容通过OCR技术转换为文本,最后将所有文本内容进行结构化分割。
|
||||
|
||||
**参数**: 此函数没有显式参数,但依赖于`self.file_path`和`self.unstructured_kwargs`两个对象属性。
|
||||
- `self.file_path`: 需要处理的Word文档的路径。
|
||||
- `self.unstructured_kwargs`: 用于文本结构化分割的参数。
|
||||
|
||||
**代码描述**:
|
||||
1. `_get_elements`函数首先定义了一个内部函数`doc2text`,用于将Word文档转换为文本。
|
||||
2. `doc2text`函数利用`python-docx`库来解析Word文档,通过迭代文档中的段落和表格来提取文本内容。
|
||||
3. 对于文档中的图片,`doc2text`使用`xpath`来定位,并通过`PIL`库和`ImagePart`来读取图片内容。然后,使用`RapidOCR`库将图片内容转换为文本。
|
||||
4. 文档中的文本和通过OCR转换得到的文本被累加到一个字符串中。
|
||||
5. 使用`tqdm`库来显示处理进度,提高用户体验。
|
||||
6. `_get_elements`函数通过调用`doc2text`函数获取文本内容,然后使用`partition_text`函数对文本进行结构化分割,分割依据是`self.unstructured_kwargs`中的参数。
|
||||
7. 最终,函数返回一个包含分割后文本块的列表。
|
||||
|
||||
**注意**:
|
||||
- 确保`self.file_path`指向的是一个有效的Word文档路径。
|
||||
- OCR转换对图片质量有一定要求,图片质量过低可能影响识别结果。
|
||||
- `self.unstructured_kwargs`参数需要正确配置以适应不同的文本结构化需求。
|
||||
|
||||
**输出示例**:
|
||||
```python
|
||||
[
|
||||
"这是文档的第一部分文本。",
|
||||
"这是从图片中通过OCR技术识别出的文本。",
|
||||
"这是文档的另一部分文本。"
|
||||
]
|
||||
```
|
||||
此输出示例展示了函数可能返回的分割后的文本块列表,包括直接从Word文档中提取的文本和通过OCR技术从图片中识别出的文本。
|
||||
#### FunctionDef doc2text(filepath)
|
||||
**doc2text**: 该函数的功能是将Word文档中的文本和图片内容转换为纯文本字符串。
|
||||
|
||||
**参数**:
|
||||
- filepath: Word文档的文件路径。
|
||||
|
||||
**代码描述**:
|
||||
`doc2text`函数首先导入了必要的库和模块,包括处理Word文档的`docx`库,图像处理库`PIL`,以及用于执行OCR(光学字符识别)的`rapidocr_onnxruntime`库。函数接收一个文件路径作为参数,用于指定需要转换的Word文档。
|
||||
|
||||
函数内部,首先使用`Document`类从给定的文件路径加载Word文档。然后,定义了一个`iter_block_items`内部函数,用于遍历文档中的所有段落和表格。这个遍历过程利用了`docx`库的类型判断功能,以确定当前处理的是段落还是表格,并据此进行相应的处理。
|
||||
|
||||
在遍历文档内容的过程中,函数使用了`ocr`对象(由`RapidOCR`类实例化)对文档中的图片进行OCR处理,将图片中的文本转换为可读的字符串。对于文档中的文本内容,直接将其文本值添加到响应字符串中。
|
||||
|
||||
此外,函数还处理了文档中的表格,遍历每个表格中的行和单元格,将单元格中的文本内容提取出来,同样添加到响应字符串中。
|
||||
|
||||
最后,函数返回一个包含了文档中所有文本内容和图片中识别出的文本内容的字符串。
|
||||
|
||||
**注意**:
|
||||
- 该函数依赖于`docx`、`PIL`和`rapidocr_onnxruntime`等库,使用前需要确保这些库已正确安装。
|
||||
- OCR处理可能不会100%准确,特别是对于图像质量较低或字体较小的图片,识别结果可能会有误差。
|
||||
- 函数的性能(包括OCR处理时间)会受到文档大小和内容复杂度的影响。
|
||||
|
||||
**输出示例**:
|
||||
```
|
||||
这是文档中的一段文本。
|
||||
|
||||
这是从文档中的一张图片中识别出的文本。
|
||||
```
|
||||
##### FunctionDef iter_block_items(parent)
|
||||
**iter_block_items**: 此函数的功能是遍历并生成文档中的段落和表格对象。
|
||||
|
||||
**参数**:
|
||||
- **parent**: 可以是`Document`对象或`_Cell`对象,表示要遍历的文档或单元格。
|
||||
|
||||
**代码描述**:
|
||||
`iter_block_items`函数是用于从Word文档中提取段落和表格的迭代器。它首先判断传入的`parent`参数类型。如果`parent`是`Document`类型,即整个文档,它会获取文档的主体部分。如果`parent`是`_Cell`类型,即表格中的单元格,它会获取该单元格的内容。函数通过遍历`parent_elm`的子元素,根据子元素的类型(段落或表格),生成对应的`Paragraph`或`Table`对象并返回。
|
||||
|
||||
在遍历过程中,使用`isinstance`函数检查每个子元素的类型。如果子元素是`CT_P`类型,表示它是一个段落,则创建并返回一个`Paragraph`对象。如果子元素是`CT_Tbl`类型,表示它是一个表格,则创建并返回一个`Table`对象。这样,使用此函数可以方便地从文档中提取出所有的段落和表格,以便进一步处理。
|
||||
|
||||
**注意**:
|
||||
- 传入的`parent`参数必须是`Document`或`_Cell`类型,否则函数会抛出`ValueError`异常,提示"RapidOCRDocLoader parse fail"。
|
||||
- 此函数依赖于`docx.document.Document`、`_Cell`、`CT_P`(段落类型)和`CT_Tbl`(表格类型)等类,因此在使用前需要确保这些类已正确导入和定义。
|
||||
- 生成的`Paragraph`和`Table`对象可以用于进一步的文本提取或格式化操作,但需要注意处理它们的方法可能依赖于具体的实现细节。
|
||||
***
|
||||
***
|
||||
***
|
||||
71
markdown_docs/document_loaders/myimgloader.md
Normal file
@ -0,0 +1,71 @@
|
||||
## ClassDef RapidOCRLoader
|
||||
**RapidOCRLoader**: RapidOCRLoader的功能是将图像文件中的文本通过OCR技术提取出来,并将提取的文本进行结构化处理。
|
||||
|
||||
**属性**:
|
||||
- 无特定公开属性,继承自UnstructuredFileLoader的属性。
|
||||
|
||||
**代码描述**:
|
||||
RapidOCRLoader是一个继承自UnstructuredFileLoader的类,专门用于处理图像文件中的文本提取。它通过定义一个内部函数`img2text`来实现OCR(光学字符识别)功能。`img2text`函数接受一个文件路径作为输入,使用`get_ocr`函数获取OCR处理器,然后对指定的图像文件进行文本识别。识别结果是一个列表,其中每个元素包含识别的文本行。这些文本行随后被连接成一个字符串,作为函数的返回值。
|
||||
|
||||
在`_get_elements`方法中,调用了`img2text`函数处理类初始化时指定的文件路径,将图像文件中的文本提取出来。提取出的文本随后通过`partition_text`函数进行结构化处理,这个函数根据提供的参数(通过`self.unstructured_kwargs`传递)对文本进行分区,最终返回一个文本分区列表。
|
||||
|
||||
在项目中,RapidOCRLoader类被用于测试模块`test_imgloader.py`中,通过`test_rapidocrloader`函数进行测试。测试函数创建了一个RapidOCRLoader实例,传入了一个OCR测试用的图像文件路径,然后调用`load`方法加载处理结果。测试验证了RapidOCRLoader能够成功提取图像中的文本,并且返回值是一个包含至少一个元素的列表,列表中的每个元素都是一个包含提取文本的对象。
|
||||
|
||||
**注意**:
|
||||
- 使用RapidOCRLoader之前,需要确保OCR处理器(通过`get_ocr`函数获取)已正确配置并可用。
|
||||
- 该类主要用于处理图像文件中的文本提取,不适用于非图像文件。
|
||||
|
||||
**输出示例**:
|
||||
```python
|
||||
[
|
||||
{
|
||||
"page_content": "这是通过OCR技术提取的文本内容。"
|
||||
}
|
||||
]
|
||||
```
|
||||
此输出示例展示了RapidOCRLoader处理图像文件并通过OCR技术提取文本后的可能返回值。返回值是一个列表,列表中的每个元素都是一个字典,其中`page_content`键对应的值是提取的文本内容。
|
||||
### FunctionDef _get_elements(self)
|
||||
**_get_elements**: 该函数的功能是将图片文件中的文本内容提取出来,并根据给定的参数对提取出的文本进行分段处理。
|
||||
|
||||
**参数**:
|
||||
- 无直接参数,但函数通过`self.file_path`访问图片路径,通过`self.unstructured_kwargs`访问用于文本分段的参数。
|
||||
|
||||
**代码描述**:
|
||||
该函数首先定义了一个内部函数`img2text`,用于将指定路径的图片文件转换为文本。`img2text`函数通过调用`get_ocr()`函数获取OCR(光学字符识别)服务的实例,然后使用此实例对图片文件进行识别,将识别结果中的文本内容提取出来并返回。
|
||||
|
||||
在`_get_elements`函数的主体中,首先调用`img2text`函数,将`self.file_path`指定的图片文件转换为文本。然后,使用`partition_text`函数对提取的文本进行分段处理。`partition_text`函数接受一个文本字符串和一组分段参数(通过`self.unstructured_kwargs`提供),并返回分段后的文本列表。
|
||||
|
||||
**注意**:
|
||||
- 确保`self.file_path`正确指向了需要处理的图片文件。
|
||||
- `self.unstructured_kwargs`应包含适用于`partition_text`函数的所有必要参数,以确保文本可以按预期进行分段处理。
|
||||
- OCR识别的准确性可能受到图片质量和内容复杂度的影响,因此在处理极其复杂或低质量的图片时可能会遇到识别准确度下降的问题。
|
||||
|
||||
**输出示例**:
|
||||
假设图片中包含以下文本内容:“Hello World! Welcome to OCR processing.”,并且`partition_text`函数的参数设置为按句子分段,那么该函数可能返回如下列表:
|
||||
```python
|
||||
["Hello World!", "Welcome to OCR processing."]
|
||||
```
|
||||
#### FunctionDef img2text(filepath)
|
||||
**img2text**: 此函数的功能是将图片文件中的文字通过OCR技术识别出来,并以字符串形式返回。
|
||||
|
||||
**参数**:
|
||||
- filepath: 字符串类型,指定需要进行文字识别的图片文件路径。
|
||||
|
||||
**代码描述**:
|
||||
`img2text`函数是一个用于图像文字识别的高级封装。它首先调用`get_ocr`函数获取一个OCR对象,该对象是根据系统配置(是否使用CUDA加速)动态选择的OCR实现。随后,使用该OCR对象对传入的图片文件路径`filepath`指向的图片进行文字识别。识别结果是一个列表,其中每个元素是一个包含识别区域坐标和识别出的文字的元组。函数进一步处理这个列表,提取出所有识别到的文字,并将它们连接成一个单一的字符串,每行文字之间用换行符`\n`分隔。最后,返回这个字符串。
|
||||
|
||||
从功能角度看,`img2text`与其调用的`get_ocr`函数紧密相关。`get_ocr`负责提供OCR服务的对象,而`img2text`则利用这个对象完成具体的图像文字识别任务。这种设计使得`img2text`能够灵活适应不同的OCR技术实现,同时也便于在项目中重用OCR服务。
|
||||
|
||||
**注意**:
|
||||
- 确保传入的`filepath`是有效的图片文件路径,且文件存在。否则,OCR识别过程可能失败。
|
||||
- OCR识别的准确性受到多种因素的影响,包括图片质量、文字清晰度和字体大小等,因此在使用时应考虑这些因素可能对识别结果的影响。
|
||||
- 根据`get_ocr`函数的说明,如果系统中未安装支持CUDA的OCR包或在不支持CUDA的环境中运行,应确保`get_ocr`函数的`use_cuda`参数被设置为False,以避免运行时错误。
|
||||
|
||||
**输出示例**:
|
||||
```
|
||||
这是一个OCR识别的示例文本。
|
||||
第二行文字。
|
||||
```
|
||||
此输出示例展示了`img2text`函数处理后的可能输出,其中包含了从图片中识别出的文字,每行文字之间用换行符分隔。实际输出将根据输入图片中的文字内容而有所不同。
|
||||
***
|
||||
***
|
||||
89
markdown_docs/document_loaders/mypdfloader.md
Normal file
@ -0,0 +1,89 @@
|
||||
## ClassDef RapidOCRPDFLoader
|
||||
**RapidOCRPDFLoader**: RapidOCRPDFLoader的功能是从PDF文件中提取文本和图片内容,并通过OCR技术将图片内容转换为文本。
|
||||
|
||||
**属性**:
|
||||
- 无特定公开属性,该类主要通过方法实现功能。
|
||||
|
||||
**代码描述**:
|
||||
RapidOCRPDFLoader类继承自UnstructuredFileLoader,专门用于处理PDF文件的加载和内容提取。该类通过定义的`_get_elements`方法实现了从PDF中提取文本和图片的功能,并且能够处理图片的旋转和OCR识别,最终将识别的文本内容进行结构化处理。
|
||||
|
||||
在`_get_elements`方法中,首先定义了`rotate_img`函数用于处理图片旋转,接着定义了`pdf2text`函数用于将PDF文件中的文本和图片内容提取出来。`pdf2text`函数使用了fitz库(pyMuPDF)来打开和处理PDF文件,通过遍历每一页,提取页面文本和图片信息。对于图片内容,首先检查图片尺寸是否超过设定的阈值,然后根据页面的旋转角度决定是否需要旋转图片,最后使用OCR技术将图片内容转换为文本。
|
||||
|
||||
该类的使用场景在于需要从PDF文件中提取文本信息,同时也需要处理PDF中的图片内容,尤其是当图片中包含了重要的文本信息时。通过OCR技术,可以将这些图片中的文本信息转换为可读的文本格式,进一步增强文本提取的准确性和完整性。
|
||||
|
||||
**注意**:
|
||||
- 使用RapidOCRPDFLoader类之前,需要确保已经安装了fitz(pyMuPDF)库和OpenCV库,因为这两个库是处理PDF文件和图片旋转的关键。
|
||||
- OCR技术的准确性受到图片质量的影响,因此在处理高度压缩或质量较低的图片时,OCR的结果可能不够理想。
|
||||
- 该类在处理大型PDF文件时可能会消耗较多的计算资源,因此在资源受限的环境下使用时需要注意。
|
||||
|
||||
**输出示例**:
|
||||
假设处理一个包含文本和图片的PDF文件,RapidOCRPDFLoader可能会返回如下格式的文本内容:
|
||||
```
|
||||
第一页文本内容...
|
||||
图片1识别的文本内容...
|
||||
图片2识别的文本内容...
|
||||
第二页文本内容...
|
||||
图片3识别的文本内容...
|
||||
...
|
||||
```
|
||||
这个输出示例展示了RapidOCRPDFLoader如何将PDF文件中的文本和图片内容结合起来,提供一个连续的文本流,便于后续的处理和分析。
|
||||
### FunctionDef _get_elements(self)
|
||||
**_get_elements**: 该函数的功能是从PDF文件中提取文本和图像内容,并对图像进行OCR识别,最后将识别的文本内容进行结构化处理。
|
||||
|
||||
**参数**: 此函数没有直接的参数,它通过类的实例访问成员变量。
|
||||
|
||||
**代码描述**:
|
||||
- `_get_elements` 函数首先定义了两个内部函数:`rotate_img` 和 `pdf2text`。
|
||||
- `rotate_img` 函数用于旋转图像,接受图像和旋转角度作为参数,返回旋转后的图像。它通过OpenCV库计算旋转矩阵,并应用于输入图像以获得旋转后的图像。
|
||||
- `pdf2text` 函数负责将PDF文件的内容转换为文本。它使用`fitz`库(即PyMuPDF)打开PDF文件,遍历每一页,提取文本内容,并使用进度条(`tqdm`库)显示处理进度。对于每个页面上的图像,如果图像的尺寸超过了设定的阈值(`PDF_OCR_THRESHOLD`),则使用OCR(光学字符识别)技术识别图像中的文本。如果页面有旋转,则先对图像进行旋转校正,再进行OCR识别。
|
||||
- 在提取完所有页面的文本和图像内容后,`_get_elements` 函数使用`partition_text`函数对提取到的文本进行结构化处理,以便于后续的数据处理和分析。
|
||||
|
||||
**注意**:
|
||||
- 本函数依赖于OpenCV和PyMuPDF库进行图像处理和PDF文件的读取,需要确保这些库已正确安装和配置。
|
||||
- OCR识别的准确性受到图像质量的影响,图像的清晰度和旋转校正的准确性对识别结果有重要影响。
|
||||
- 函数中使用的`PDF_OCR_THRESHOLD`变量需要根据实际情况进行调整,以优化OCR识别的效果和性能。
|
||||
|
||||
**输出示例**:
|
||||
由于`_get_elements`函数的输出依赖于输入的PDF文件内容和OCR识别的结果,因此无法提供一个固定的输出示例。通常,该函数会返回一个包含结构化文本内容的列表,列表中的每个元素代表PDF中的一段文本内容,这些内容已经过OCR识别和结构化处理。
|
||||
#### FunctionDef rotate_img(img, angle)
|
||||
**rotate_img**: 该函数的功能是旋转图像。
|
||||
|
||||
**参数**:
|
||||
- img: 待旋转的图像。
|
||||
- angle: 旋转角度,正值表示逆时针旋转,负值表示顺时针旋转。
|
||||
|
||||
**代码描述**:
|
||||
`rotate_img` 函数接收一个图像和一个旋转角度作为输入,返回旋转后的图像。首先,它计算图像的高度和宽度,然后确定旋转中心,即图像的中心点。接着,使用 `cv2.getRotationMatrix2D` 方法获取旋转矩阵,该方法需要旋转中心、旋转角度和缩放比例(本例中为1.0,表示保持原始大小)作为输入。然后,计算旋转后图像的新边界,以确保旋转后的图像不会丢失任何部分。最后,通过调整旋转矩阵中的平移参数,使用 `cv2.warpAffine` 方法应用旋转矩阵,得到旋转后的图像并返回。
|
||||
|
||||
在项目中,`rotate_img` 函数被 `pdf2text` 函数调用,用于处理PDF文档中的图像。当PDF页面有旋转角度时,`pdf2text` 函数会提取页面中的图像,然后调用 `rotate_img` 函数将图像旋转回正常的方向,以便进行后续的OCR(光学字符识别)处理。这样可以确保OCR处理的准确性,特别是在处理扫描文档和图像密集型PDF文件时。
|
||||
|
||||
**注意**:
|
||||
- 在使用 `cv2.getRotationMatrix2D` 和 `cv2.warpAffine` 方法时,需要确保已经导入了OpenCV库(即cv2)。
|
||||
- 旋转图像可能会导致图像边缘的一部分被裁剪。因此,计算新边界并调整平移参数是确保图像完整性的关键步骤。
|
||||
|
||||
**输出示例**:
|
||||
假设有一个图像 `img` 和旋转角度 `angle=90`,调用 `rotate_img(img, 90)` 后,将返回一个新的图像,其中原始图像已经逆时针旋转了90度。
|
||||
***
|
||||
#### FunctionDef pdf2text(filepath)
|
||||
**pdf2text**: 该函数的功能是将PDF文件中的文本和图片内容转换为文本格式。
|
||||
|
||||
**参数**:
|
||||
- filepath: PDF文件的路径。
|
||||
|
||||
**代码描述**:
|
||||
`pdf2text` 函数首先导入必要的库,包括`fitz`(用于处理PDF文件)和`numpy`(用于处理图像数据)。然后,它调用`get_ocr`函数获取OCR对象,用于后续的图像文字识别。通过打开指定路径的PDF文件,函数遍历每一页,使用`fitz`库提取页面上的文本内容,并将其累加到响应字符串中。
|
||||
|
||||
对于每个页面上的图像,函数通过`get_image_info`方法获取图像信息,并检查每个图像的尺寸是否超过预设的阈值(`PDF_OCR_THRESHOLD`)。如果图像尺寸合适,函数将使用`fitz.Pixmap`读取图像数据。如果页面有旋转角度,函数会调用`rotate_img`函数将图像旋转回正常方向,以确保OCR的准确性。随后,使用OCR对象对图像进行文字识别,并将识别结果添加到响应字符串中。
|
||||
|
||||
整个过程中,使用`tqdm`库显示处理进度,为用户提供友好的进度反馈。
|
||||
|
||||
**注意**:
|
||||
- 确保安装了`fitz`(也就是`PyMuPDF`)、`numpy`、`tqdm`等库。
|
||||
- `PDF_OCR_THRESHOLD`是一个预设的阈值,用于决定哪些图像需要进行OCR处理。该阈值需要根据实际情况进行调整。
|
||||
- 函数依赖于`get_ocr`和`rotate_img`两个函数,确保这些依赖函数正确实现并可用。
|
||||
- 由于OCR处理可能耗时,对于包含大量图像的PDF文件,执行该函数可能需要较长时间。
|
||||
|
||||
**输出示例**:
|
||||
调用`pdf2text(filepath)`函数后,将返回一个字符串,其中包含了PDF文件中所有页面的文本内容,以及通过OCR识别的图像中的文字。例如,如果PDF文件包含了文本“欢迎使用OCR”和一张包含文字“图像识别” 的图片,函数将返回一个包含“欢迎使用OCR\n图像识别” 的字符串。
|
||||
***
|
||||
***
|
||||
93
markdown_docs/document_loaders/mypptloader.md
Normal file
@ -0,0 +1,93 @@
|
||||
## ClassDef RapidOCRPPTLoader
|
||||
**RapidOCRPPTLoader**: RapidOCRPPTLoader的功能是从PowerPoint文件中提取文本和图片内容,并使用OCR技术转换图片中的文本。
|
||||
|
||||
**属性**:
|
||||
- 无特定公开属性,此类主要通过方法实现功能。
|
||||
|
||||
**代码描述**:
|
||||
RapidOCRPPTLoader类继承自UnstructuredFileLoader,专门用于处理PowerPoint文件(.pptx)。它通过内部定义的`_get_elements`方法实现主要功能。该方法首先定义了一个内部函数`ppt2text`,用于将PowerPoint文件中的文本和图片内容提取出来。`ppt2text`函数使用了`python-pptx`库来读取PowerPoint文件,`PIL`库处理图片,以及`rapidocr_onnxruntime`库来执行图片中的文字识别(OCR)。
|
||||
|
||||
在提取过程中,`ppt2text`函数会遍历所有幻灯片,并对每个幻灯片中的形状(包括文本框、表格、图片和组合形状)进行处理。对于文本框和表格,直接提取文本内容;对于图片,使用RapidOCR进行文字识别;对于组合形状,递归地对其子形状进行相同的处理。所有提取的文本内容将被拼接成一个字符串。
|
||||
|
||||
最后,`_get_elements`方法使用`partition_text`函数(来自`unstructured.partition.text`模块)对提取的文本进行分段处理,返回一个分段后的文本列表,以便后续处理。
|
||||
|
||||
**注意**:
|
||||
- 使用RapidOCRPPTLoader之前,需要确保安装了`python-pptx`、`PIL`、`numpy`、`tqdm`和`rapidocr_onnxruntime`等依赖库。
|
||||
- OCR技术的准确性受到图片质量的影响,因此在图片质量较低的情况下,文字识别的准确率可能会下降。
|
||||
- 由于OCR处理可能耗时较长,特别是在处理包含大量图片的PowerPoint文件时,应考虑执行时间和资源消耗。
|
||||
|
||||
**输出示例**:
|
||||
由于RapidOCRPPTLoader的输出依赖于输入的PowerPoint文件内容,因此无法提供一个固定的输出示例。一般而言,如果输入的PowerPoint文件包含文本和图片,输出将是一个包含提取文本(包括图片中识别的文字)的字符串列表。每个列表项代表PowerPoint中的一段文本内容。
|
||||
### FunctionDef _get_elements(self)
|
||||
**_get_elements**: 该函数的功能是从PPT文件中提取文本和图片内容,并将图片内容通过OCR技术转换为文本。
|
||||
|
||||
**参数**: 该函数没有显式参数,它是一个对象的方法,依赖于对象的状态。
|
||||
|
||||
**代码描述**:
|
||||
- `_get_elements` 方法首先定义了一个内部函数 `ppt2text`,该函数负责打开并读取PPT文件的内容。
|
||||
- 使用 `pptx.Presentation` 加载PPT文件,遍历每一页幻灯片。
|
||||
- 对于幻灯片中的每个元素,根据其类型(文本框、表格、图片、组合),采取不同的处理方式来提取文本。
|
||||
- 文本框和表格中的文本直接提取。
|
||||
- 对于图片,使用 `RapidOCR` 进行图像识别,将图片内容转换为文本。
|
||||
- 对于组合类型的元素,递归地调用 `extract_text` 函数,处理组合内的每个子元素。
|
||||
- 使用 `tqdm` 库显示处理进度。
|
||||
- 最后,通过调用 `partition_text` 函数,对提取出的文本进行进一步的处理或分割,具体取决于 `self.unstructured_kwargs` 参数的配置。
|
||||
|
||||
**注意**:
|
||||
- 该方法依赖于外部库 `pptx`、`PIL`、`numpy`、`io` 和 `rapidocr_onnxruntime`,在使用前需要确保这些库已经被安装。
|
||||
- OCR技术的准确性受到图片质量的影响,因此在图片质量较低的情况下,识别出的文本可能会有误差。
|
||||
- `partition_text` 函数的行为和输出取决于 `self.unstructured_kwargs` 参数的配置,这意味着该方法的输出可能会根据不同的配置而有所不同。
|
||||
|
||||
**输出示例**:
|
||||
由于 `_get_elements` 函数的输出依赖于输入的PPT文件内容以及OCR的准确性,因此很难提供一个具体的输出示例。一般而言,输出将是一个文本列表,其中包含了从PPT文件中提取并通过OCR技术转换的文本内容。例如,如果PPT中包含了一张包含文字“欢迎来到AI世界”的图片,那么该方法可能会输出一个包含字符串“欢迎来到AI世界”的列表(假设OCR识别准确)。
|
||||
#### FunctionDef ppt2text(filepath)
|
||||
**ppt2text**: 此函数的功能是将PowerPoint文件中的文本和图片转换为纯文本格式。
|
||||
|
||||
**参数**:
|
||||
- filepath: PowerPoint文件的路径。
|
||||
|
||||
**代码描述**:
|
||||
`ppt2text`函数首先导入必要的库,包括`pptx`用于读取PowerPoint文件,`PIL.Image`用于处理图片,`numpy`用于图片数据处理,`io.BytesIO`用于将字节流转换为文件,以及`rapidocr_onnxruntime.RapidOCR`用于执行OCR(光学字符识别)。
|
||||
|
||||
函数接收一个参数`filepath`,这是要处理的PowerPoint文件的路径。函数内部创建了一个`Presentation`对象来加载PowerPoint文件,并初始化一个空字符串`resp`用于存储最终的文本结果。
|
||||
|
||||
定义了一个内部函数`extract_text`,用于提取PowerPoint中的文本和图片。这个内部函数检查每个形状是否包含文本框、表格或图片,并相应地提取文本。对于图片,使用OCR技术将图片中的文本转换为可读文本。特别地,形状类型13代表图片,形状类型6代表组合。
|
||||
|
||||
使用`tqdm`库创建一个进度条,遍历所有幻灯片,并对每个幻灯片中的形状进行排序,以确保按照从上到下、从左到右的顺序处理形状。对于每个形状,调用`extract_text`函数提取文本。
|
||||
|
||||
最后,函数返回包含所有提取文本的字符串`resp`。
|
||||
|
||||
**注意**:
|
||||
- 确保安装了`python-pptx`、`Pillow`、`numpy`、`tqdm`和`rapidocr_onnxruntime`等依赖库。
|
||||
- OCR准确性受到图片质量的影响,可能无法100%准确识别图片中的文本。
|
||||
- 函数处理大型文件时可能需要较长时间。
|
||||
|
||||
**输出示例**:
|
||||
```
|
||||
"这是第一页的文本内容。
|
||||
这是从第一张图片中识别的文本。
|
||||
这是第二页的文本内容。
|
||||
这是从第二页的表格中提取的文本。"
|
||||
```
|
||||
此输出示例展示了从一个包含文本、图片和表格的PowerPoint文件中提取的文本内容。
|
||||
##### FunctionDef extract_text(shape)
|
||||
**extract_text**: 此函数的功能是从PowerPoint的特定形状中提取文本和图片中的文字。
|
||||
|
||||
**参数**:
|
||||
- shape: 需要从中提取文本的PowerPoint形状对象。
|
||||
|
||||
**代码描述**:
|
||||
`extract_text` 函数是为了从PowerPoint演示文稿中的不同形状(如文本框、表格、图片和组合形状)提取文本信息而设计的。该函数通过递归的方式处理形状,确保即使在组合形状中也能有效提取文本。
|
||||
|
||||
1. 首先,函数检查传入的形状是否有文本框(`has_text_frame`),如果有,则提取其中的文本并去除前后空格,之后添加到响应变量`resp`中。
|
||||
2. 接下来,函数检查形状是否包含表格(`has_table`)。对于表格中的每一行和每一个单元格,函数遍历其文本框中的段落,提取并清理文本,然后添加到`resp`。
|
||||
3. 函数还能处理图片类型的形状(形状类型代码为13)。对于图片,使用OCR(光学字符识别)技术提取图片中的文字。提取的文字结果被添加到`resp`中。
|
||||
4. 对于组合形状(形状类型代码为6),函数递归地调用自身,以提取组合内各个子形状的文本。
|
||||
|
||||
**注意**:
|
||||
- 该函数使用了`nonlocal`关键字声明的`resp`变量来累积提取的文本。这意味着`resp`变量应在函数外部定义,并在调用`extract_text`之前初始化。
|
||||
- 对于图片中的文字提取,函数依赖于OCR技术。因此,需要确保相关的OCR库(如在代码中使用的`ocr`函数)已正确安装并配置。
|
||||
- 形状类型代码(如13代表图片,6代表组合形状)是根据PowerPoint对象模型定义的。了解这些代码有助于理解函数如何区分处理不同类型的形状。
|
||||
***
|
||||
***
|
||||
***
|
||||
17
markdown_docs/document_loaders/ocr.md
Normal file
@ -0,0 +1,17 @@
|
||||
## FunctionDef get_ocr(use_cuda)
|
||||
**get_ocr**: 此函数的功能是获取一个OCR对象,用于执行图像或PDF中的文字识别。
|
||||
|
||||
**参数**:
|
||||
- use_cuda: 布尔值,指定是否使用CUDA加速。默认为True。
|
||||
|
||||
**代码描述**:
|
||||
`get_ocr`函数旨在提供一个灵活的方式来获取文字识别(OCR)的功能对象。它首先尝试从`rapidocr_paddle`模块导入`RapidOCR`类,如果成功,将创建一个`RapidOCR`实例,其中的CUDA加速设置将根据`use_cuda`参数来决定。如果在尝试导入`rapidocr_paddle`时发生`ImportError`异常,表明可能未安装相应的包,函数则会尝试从`rapidocr_onnxruntime`模块导入`RapidOCR`类,并创建一个不指定CUDA加速的`RapidOCR`实例。这种设计使得函数能够在不同的环境配置下灵活工作,即使在缺少某些依赖的情况下也能尽可能地提供OCR服务。
|
||||
|
||||
在项目中,`get_ocr`函数被用于不同的场景来执行OCR任务。例如,在`document_loaders/myimgloader.py`的`img2text`方法中,它被用来将图片文件中的文字识别出来;而在`document_loaders/mypdfloader.py`的`pdf2text`方法中,它被用于识别PDF文件中的文字以及PDF中嵌入图片的文字。这显示了`get_ocr`函数在项目中的多功能性和重要性,它为处理不同类型的文档提供了统一的OCR解决方案。
|
||||
|
||||
**注意**:
|
||||
- 在使用`get_ocr`函数时,需要确保至少安装了`rapidocr_paddle`或`rapidocr_onnxruntime`中的一个包,以便函数能够成功返回一个OCR对象。
|
||||
- 如果计划在没有CUDA支持的环境中使用,应将`use_cuda`参数设置为False,以避免不必要的错误。
|
||||
|
||||
**输出示例**:
|
||||
由于`get_ocr`函数返回的是一个`RapidOCR`对象,因此输出示例将依赖于该对象的具体实现。一般而言,可以预期该对象提供了执行OCR任务的方法,如对图片或PDF中的文字进行识别,并返回识别结果。
|
||||
58
markdown_docs/embeddings/add_embedding_keywords.md
Normal file
@ -0,0 +1,58 @@
|
||||
## FunctionDef get_keyword_embedding(bert_model, tokenizer, key_words)
|
||||
**get_keyword_embedding**: 该函数的功能是获取关键词的嵌入表示。
|
||||
|
||||
**参数**:
|
||||
- **bert_model**: 一个预训练的BERT模型,用于生成嵌入表示。
|
||||
- **tokenizer**: 与BERT模型相匹配的分词器,用于将关键词转换为模型能理解的格式。
|
||||
- **key_words**: 一个字符串列表,包含需要获取嵌入表示的关键词。
|
||||
|
||||
**代码描述**:
|
||||
`get_keyword_embedding`函数首先使用传入的`tokenizer`将关键词列表`key_words`转换为模型能够处理的输入格式。这一步骤包括将关键词转换为对应的输入ID,并对输入进行填充和截断以满足模型的要求。随后,函数从`tokenizer`的输出中提取`input_ids`,并去除每个序列的首尾特殊标记,因为这些标记对于关键词的嵌入表示不是必需的。
|
||||
|
||||
接着,函数利用`bert_model`的`embeddings.word_embeddings`属性,根据`input_ids`获取对应的嵌入表示。由于可能传入多个关键词,函数对所有关键词的嵌入表示进行平均,以获得一个统一的表示形式。
|
||||
|
||||
在项目中,`get_keyword_embedding`函数被`add_keyword_to_model`函数调用,用于将自定义关键词的嵌入表示添加到预训练的BERT模型中。这一过程涉及读取关键词文件,生成关键词的嵌入表示,扩展模型的嵌入层以包含这些新的关键词,最后将修改后的模型保存到指定路径。这使得模型能够理解并有效处理这些新增的关键词,从而提高模型在特定任务上的性能。
|
||||
|
||||
**注意**:
|
||||
- 确保传入的`bert_model`和`tokenizer`是匹配的,即它们来源于同一个预训练模型。
|
||||
- 关键词列表`key_words`应该是经过精心挑选的,因为这些关键词将直接影响模型的理解能力和性能。
|
||||
- 在调用此函数之前,应该已经准备好关键词文件,并确保其格式正确。
|
||||
|
||||
**输出示例**:
|
||||
假设传入了两个关键词`["AI", "机器学习"]`,函数可能返回一个形状为`(2, embedding_size)`的张量,其中`embedding_size`是模型嵌入层的维度,表示这两个关键词的平均嵌入表示。
|
||||
## FunctionDef add_keyword_to_model(model_name, keyword_file, output_model_path)
|
||||
**add_keyword_to_model**: 该函数的功能是将自定义关键词添加到预训练的嵌入模型中。
|
||||
|
||||
**参数**:
|
||||
- **model_name**: 字符串类型,默认为`EMBEDDING_MODEL`。指定要使用的预训练嵌入模型的名称。
|
||||
- **keyword_file**: 字符串类型,默认为空字符串。指定包含自定义关键词的文件路径。
|
||||
- **output_model_path**: 字符串类型,可为`None`。指定添加了关键词后的模型保存路径。
|
||||
|
||||
**代码描述**:
|
||||
首先,函数通过读取`keyword_file`文件,将文件中的每一行作为一个关键词添加到`key_words`列表中。接着,使用指定的`model_name`加载一个句子转换器模型(SentenceTransformer模型),并从中提取第一个模块作为词嵌入模型。通过这个词嵌入模型,可以获取到BERT模型及其分词器。
|
||||
|
||||
然后,函数调用`get_keyword_embedding`函数,传入BERT模型、分词器和关键词列表,以获取这些关键词的嵌入表示。接下来,函数将这些新的关键词嵌入添加到BERT模型的嵌入层中。这一步骤包括扩展分词器以包含新的关键词,调整BERT模型的嵌入层大小以适应新增的关键词,并将关键词的嵌入表示直接赋值给模型的嵌入层权重。
|
||||
|
||||
最后,如果提供了`output_model_path`参数,则函数会在该路径下创建必要的目录,并将更新后的词嵌入模型以及BERT模型保存到指定位置。这一过程确保了模型能够在后续的使用中,理解并有效处理这些新增的关键词。
|
||||
|
||||
**注意**:
|
||||
- 确保`keyword_file`文件存在且格式正确,每行应包含一个关键词。
|
||||
- 由于模型的嵌入层大小会根据新增关键词进行调整,因此在添加关键词后,模型的大小可能会增加。
|
||||
- 在保存模型时,会使用`safetensors`格式保存BERT模型,确保模型的兼容性和安全性。
|
||||
- 添加关键词到模型是一个影响模型性能的操作,因此应谨慎选择关键词,并考虑到这些关键词在特定任务上的实际应用价值。
|
||||
## FunctionDef add_keyword_to_embedding_model(path)
|
||||
**add_keyword_to_embedding_model**: 该函数的功能是将自定义关键词添加到指定的嵌入模型中。
|
||||
|
||||
**参数**:
|
||||
- **path**: 字符串类型,默认为`EMBEDDING_KEYWORD_FILE`。指定包含自定义关键词的文件路径。
|
||||
|
||||
**代码描述**:
|
||||
此函数首先通过`os.path.join(path)`获取关键词文件的完整路径。然后,它从配置中读取模型的名称和路径,这些配置通过`MODEL_PATH["embed_model"][EMBEDDING_MODEL]`获得。接着,函数计算模型所在的父目录,并生成一个包含当前时间戳的新模型名称,格式为`EMBEDDING_MODEL_Merge_Keywords_当前时间`,以确保输出模型名称的唯一性。
|
||||
|
||||
接下来,函数调用`add_keyword_to_model`,这是一个重要的调用关系,因为`add_keyword_to_model`负责实际将关键词添加到嵌入模型中。在调用`add_keyword_to_model`时,传入当前使用的模型名称、关键词文件路径以及新模型的保存路径。这一步骤完成了将自定义关键词集成到预训练嵌入模型中的核心功能。
|
||||
|
||||
**注意**:
|
||||
- 确保传入的`path`参数指向一个有效的关键词文件,且该文件格式正确,每行包含一个要添加的关键词。
|
||||
- 该函数依赖于`add_keyword_to_model`函数,后者负责实际的关键词添加逻辑,包括读取关键词、更新模型的嵌入层以及保存更新后的模型。因此,了解`add_keyword_to_model`的具体实现对于理解整个关键词添加过程是非常重要的。
|
||||
- 生成的新模型名称包含时间戳,这有助于区分不同时间点生成的模型版本。
|
||||
- 在使用此函数时,应考虑到模型大小可能会因为添加新的关键词而增加,这可能会对模型加载和运行时的性能产生影响。
|
||||
46
markdown_docs/release.md
Normal file
@ -0,0 +1,46 @@
|
||||
## FunctionDef get_latest_tag
|
||||
**get_latest_tag**: 此函数的功能是获取Git仓库中最新的标签。
|
||||
|
||||
**参数**: 此函数不接受任何参数。
|
||||
|
||||
**代码描述**: `get_latest_tag` 函数首先使用 `subprocess.check_output` 方法执行 `git tag` 命令,以获取当前Git仓库中所有的标签。然后,通过对输出结果进行解码(UTF-8)和分割,将其转换成一个标签列表。接下来,使用 `sorted` 函数和一个自定义的排序键,基于标签的版本号(假设遵循 `v主版本号.次版本号.修订号` 的格式)对标签列表进行排序。排序键通过正则表达式 `re.match` 匹配每个标签的版本号,并将其转换为整数元组,以便进行比较。最后,函数返回排序后的最后一个元素,即最新的标签。
|
||||
|
||||
在项目中,`get_latest_tag` 函数被 `main` 函数调用,用于获取当前Git仓库中的最新标签,并在终端中显示。此外,`main` 函数还根据用户的输入决定如何递增版本号,并创建新的标签推送到远程仓库。因此,`get_latest_tag` 函数在自动化版本控制和发布流程中起着关键作用,它确保了版本号的正确递增和新版本标签的生成。
|
||||
|
||||
**注意**: 使用此函数时,需要确保当前环境已安装Git,并且函数调用是在一个Git仓库的根目录下进行的。此外,此函数假定标签遵循 `v主版本号.次版本号.修订号` 的命名约定,如果标签不遵循此格式,可能无法正确排序和识别最新标签。
|
||||
|
||||
**输出示例**: 假设Git仓库中的最新标签为 `v1.2.3`,则函数调用 `get_latest_tag()` 将返回字符串 `"v1.2.3"`。
|
||||
## FunctionDef update_version_number(latest_tag, increment)
|
||||
**update_version_number**: 此函数用于根据最新的Git标签和用户指定的版本号递增规则来更新版本号。
|
||||
|
||||
**参数**:
|
||||
- `latest_tag`: 最新的Git标签,字符串格式,预期为`vX.Y.Z`的形式,其中X、Y、Z分别代表主版本号、次版本号和修订号。
|
||||
- `increment`: 用户指定的版本号递增规则,接受的值为`'X'`、`'Y'`或`'Z'`,分别代表递增主版本号、次版本号或修订号。
|
||||
|
||||
**代码描述**:
|
||||
函数首先通过正则表达式从`latest_tag`中提取出当前的主版本号、次版本号和修订号,并将它们转换为整数。根据`increment`参数的值,函数将相应的版本号部分递增。如果`increment`为`'X'`,则主版本号加一,次版本号和修订号重置为0。如果`increment`为`'Y'`,则次版本号加一,修订号重置为0。如果`increment`为`'Z'`,则修订号加一。最后,函数将更新后的版本号拼接成`vX.Y.Z`的格式并返回。
|
||||
|
||||
此函数在项目中被`main`函数调用。在`main`函数中,首先获取当前最新的Git标签,然后询问用户希望递增哪部分版本号(主版本号、次版本号或修订号)。用户输入后,`update_version_number`函数被调用以生成新的版本号。根据用户的确认,新的版本号可能会被用来创建Git标签并推送到远程仓库。
|
||||
|
||||
**注意**:
|
||||
- 输入的`latest_tag`必须严格遵循`vX.Y.Z`的格式,否则正则表达式匹配将失败,函数将无法正确执行。
|
||||
- `increment`参数仅接受`'X'`、`'Y'`、`'Z'`三个值,任何其他输入都将导致函数无法按预期递增版本号。
|
||||
|
||||
**输出示例**:
|
||||
如果`latest_tag`为`v1.2.3`且`increment`为`'Y'`,则函数将返回`v1.3.0`。
|
||||
## FunctionDef main
|
||||
**main**: 此函数的功能是自动化Git版本控制流程,包括获取最新Git标签,递增版本号,并根据用户确认将新版本号作为标签推送到远程仓库。
|
||||
|
||||
**参数**: 此函数不接受任何参数。
|
||||
|
||||
**代码描述**: `main` 函数首先通过调用 `get_latest_tag` 函数获取当前Git仓库中的最新标签,并将其打印出来。接着,函数提示用户选择要递增的版本号部分(主版本号X、次版本号Y或修订号Z)。用户的选择通过标准输入接收,并转换为大写字母以便后续处理。如果用户输入的不是X、Y或Z中的任何一个,系统会提示错误并要求用户重新输入,直到输入正确为止。
|
||||
|
||||
一旦获得有效输入,`main` 函数将调用 `update_version_number` 函数,传入最新的Git标签和用户选择的递增部分,以生成新的版本号。新版本号随后被打印出来,询问用户是否确认更新版本号并推送到远程仓库。用户的确认通过标准输入接收,并转换为小写字母进行判断。
|
||||
|
||||
如果用户确认(输入'y'),则使用 `subprocess.run` 方法执行Git命令,首先创建新的版本标签,然后将该标签推送到远程仓库。操作完成后,打印出相应的提示信息。如果用户不确认(输入'n'),则打印出操作已取消的信息。
|
||||
|
||||
**注意**:
|
||||
- 在使用此函数之前,需要确保当前环境已安装Git,并且函数调用是在一个Git仓库的根目录下进行的。
|
||||
- 用户输入的处理是大小写不敏感的,即输入'X'、'x'均被视为有效输入,并且都会被转换为大写进行处理。
|
||||
- 在推送新标签到远程仓库之前,函数会要求用户进行确认。这是一个安全措施,以防止意外修改远程仓库。
|
||||
- 此函数依赖于`get_latest_tag`和`update_version_number`两个函数。`get_latest_tag`用于获取最新的Git标签,而`update_version_number`根据用户指定的递增规则更新版本号。这两个函数的正确执行是`main`函数能够正确工作的基础。
|
||||
301
markdown_docs/server/agent/callbacks.md
Normal file
@ -0,0 +1,301 @@
|
||||
## FunctionDef dumps(obj)
|
||||
**dumps**: 该函数的功能是将字典对象转换为JSON格式的字符串。
|
||||
|
||||
**参数**:
|
||||
- obj: 需要被转换为JSON字符串的字典对象。
|
||||
|
||||
**代码描述**:
|
||||
`dumps`函数是一个简单但非常核心的功能,它接受一个字典对象作为输入参数,并使用`json.dumps`方法将该字典转换为一个JSON格式的字符串。在转换过程中,`ensure_ascii=False`参数确保了字符串中的非ASCII字符不会被转义,从而保持了原始数据的可读性和完整性。
|
||||
|
||||
在项目中,`dumps`函数被多个异步回调处理器中的方法调用,这些方法包括`on_tool_start`、`on_tool_end`、`on_tool_error`、`on_llm_new_token`、`on_llm_start`、`on_chat_model_start`、`on_llm_end`、`on_llm_error`和`on_agent_finish`。这些方法通常在处理某些事件(如工具开始、结束、出错等)时,需要将当前工具的状态或其他相关信息序列化为JSON字符串,并将其放入队列中等待进一步处理。通过使用`dumps`函数,确保了这些信息在序列化过程中的格式统一和准确性。
|
||||
|
||||
**注意**:
|
||||
- 在使用`dumps`函数时,需要确保传入的对象是字典类型,因为`json.dumps`方法只能处理字典类型的数据。
|
||||
- 考虑到`ensure_ascii=False`参数的使用,确保在处理JSON字符串的环境中支持非ASCII字符。
|
||||
|
||||
**输出示例**:
|
||||
假设有一个字典对象`{"name": "测试工具", "status": "运行中"}`,使用`dumps`函数处理后的输出示例为:
|
||||
```json
|
||||
{"name": "测试工具", "status": "运行中"}
|
||||
```
|
||||
这个输出是一个标准的JSON格式字符串,可以被进一步用于网络传输、存储或其他需要JSON格式数据的场景中。
|
||||
## ClassDef Status
|
||||
**Status**: Status 类用于定义不同状态的常量。
|
||||
|
||||
**属性**:
|
||||
- `start`: 表示开始状态。
|
||||
- `running`: 表示运行中状态。
|
||||
- `complete`: 表示完成状态。
|
||||
- `agent_action`: 表示代理执行动作状态。
|
||||
- `agent_finish`: 表示代理完成状态。
|
||||
- `error`: 表示错误状态。
|
||||
- `tool_finish`: 表示工具执行完成状态。
|
||||
|
||||
**代码描述**:
|
||||
Status 类在项目中扮演了重要的角色,它通过定义一系列的整型常量来表示不同的状态,这些状态在异步回调处理中被广泛使用,以便于跟踪和管理异步任务的执行流程。例如,在处理工具启动、结束、错误等事件时,会根据不同的事件类型更新当前工具的状态。这些状态不仅帮助开发者理解当前任务的执行阶段,还能够在出现错误或完成任务时提供明确的指示,进而采取相应的处理措施。
|
||||
|
||||
在项目中,Status 类的状态值被用于标识异步操作的不同阶段,如在工具开始执行时标记为 `agent_action`,在工具执行结束时标记为 `tool_finish`,在遇到错误时标记为 `error` 等。这些状态值在 `CustomAsyncIteratorCallbackHandler` 类的各个方法中被引用,以便于在异步操作过程中管理和响应不同的事件。
|
||||
|
||||
例如,在 `on_tool_start` 方法中,使用 `Status.agent_action` 来标记当前工具的状态为代理执行动作状态;在 `on_tool_end` 方法中,使用 `Status.tool_finish` 来更新工具状态为执行完成状态;在 `on_tool_error` 方法中,使用 `Status.error` 来标记错误状态。这种状态管理机制使得异步操作的管理变得更加清晰和有序。
|
||||
|
||||
**注意**:
|
||||
- 在使用 Status 类时,开发者需要确保正确地引用了对应的状态常量,以保证异步操作的状态能够被准确地跟踪和管理。
|
||||
- 状态值的更新应该与实际的异步操作流程相匹配,以避免状态不一致导致的逻辑错误。
|
||||
- 在处理异步操作时,应该根据状态值来决定下一步的操作,如是否继续执行、是否需要处理错误等,以确保程序的健壮性。
|
||||
## ClassDef CustomAsyncIteratorCallbackHandler
|
||||
**CustomAsyncIteratorCallbackHandler**: CustomAsyncIteratorCallbackHandler类的功能是作为异步迭代器回调处理器,用于处理工具的启动、结束、错误以及与长期语言模型(LLM)交互的各个阶段的回调。
|
||||
|
||||
**属性**:
|
||||
- `queue`: 用于存储处理结果的异步队列。
|
||||
- `done`: 一个事件,用于标记处理完成。
|
||||
- `cur_tool`: 当前处理的工具信息。
|
||||
- `out`: 用于控制输出的标志。
|
||||
|
||||
**代码描述**:
|
||||
CustomAsyncIteratorCallbackHandler类继承自AsyncIteratorCallbackHandler,提供了一系列异步方法来处理不同的事件,如工具的启动(on_tool_start)、结束(on_tool_end)、错误(on_tool_error)、与LLM交互的新令牌(on_llm_new_token)、LLM的启动(on_llm_start)和结束(on_llm_end)等。这些方法通过更新`cur_tool`字典和向`queue`队列中添加信息来记录每个事件的处理结果。
|
||||
|
||||
在处理工具启动事件时,该类会对输入字符串进行预处理,移除可能导致处理中断的特定停止词,然后将处理后的信息加入到队列中。在工具结束或发生错误时,也会相应地更新`cur_tool`字典,并将结果加入队列。对于LLM的交互,该类能够处理新令牌的接收、LLM的启动和结束事件,以及错误处理,同样通过更新`cur_tool`字典和队列来记录状态。
|
||||
|
||||
此类在项目中被用于处理与长期语言模型(LLM)的交互过程中的回调,特别是在`server/chat/agent_chat.py/agent_chat/agent_chat_iterator`中,它被用作回调处理器来管理异步聊天迭代器的状态。通过这种方式,它能够收集和整理从LLM和其他工具中得到的输出,为最终的用户交互提供必要的信息。
|
||||
|
||||
**注意**:
|
||||
- 在使用此类时,需要注意其异步特性,确保在适当的异步环境中调用其方法。
|
||||
- 由于它处理的信息可能来自不同的来源(如LLM或其他工具),需要确保输入的数据格式正确,以避免处理过程中的错误。
|
||||
|
||||
**输出示例**:
|
||||
假设处理了一个工具的启动和结束事件,队列中的一个可能的输出示例为:
|
||||
```json
|
||||
{
|
||||
"tool_name": "示例工具",
|
||||
"input_str": "处理前的输入",
|
||||
"output_str": "处理后的输出",
|
||||
"status": "tool_finish",
|
||||
"run_id": "示例运行ID",
|
||||
"llm_token": "",
|
||||
"final_answer": "",
|
||||
"error": ""
|
||||
}
|
||||
```
|
||||
这表示一个工具已经完成了它的任务,其中包含了工具的名称、输入输出字符串、状态、运行ID等信息。
|
||||
### FunctionDef __init__(self)
|
||||
**__init__**: 该函数用于初始化CustomAsyncIteratorCallbackHandler类的实例。
|
||||
|
||||
**参数**: 该函数不接受任何外部参数。
|
||||
|
||||
**代码描述**:
|
||||
此函数是CustomAsyncIteratorCallbackHandler类的构造函数,负责初始化类实例。在这个初始化过程中,首先通过`super().__init__()`调用父类的构造函数来继承父类的初始化逻辑。接着,函数创建了一个异步队列`self.queue`,这个队列用于存储异步操作的结果。此外,`self.done`是一个异步事件(`asyncio.Event`),用于标记异步操作何时完成。`self.cur_tool`是一个字典,用于存储当前工具的状态或数据。最后,`self.out`被设置为True,这可能表示某种输出状态或标志。
|
||||
|
||||
**注意**:
|
||||
- 在使用CustomAsyncIteratorCallbackHandler类之前,了解异步编程和`asyncio`库的基本概念是非常重要的,因为该类的实现依赖于Python的异步编程特性。
|
||||
- `self.queue`用于异步任务之间的通信,确保在使用时正确处理队列中的数据。
|
||||
- `self.done`事件用于控制异步流程,特别是在需要等待某些异步操作完成时。
|
||||
- `self.cur_tool`字典的具体用途和结构应根据实际应用场景进行定义和使用。
|
||||
- `self.out`的具体含义和用途可能根据实际代码逻辑有所不同,开发者应根据上下文来理解和使用它。
|
||||
***
|
||||
### FunctionDef on_tool_start(self, serialized, input_str)
|
||||
**on_tool_start**: 该函数的功能是在工具开始执行时进行初始化和预处理操作。
|
||||
|
||||
**参数**:
|
||||
- serialized: 一个字典,包含序列化后的工具信息。
|
||||
- input_str: 字符串类型,表示工具的输入文本。
|
||||
- run_id: UUID类型,表示当前运行的唯一标识符。
|
||||
- parent_run_id: UUID类型或None,表示父运行的唯一标识符,可选参数。
|
||||
- tags: 字符串列表或None,表示与当前运行相关的标签,可选参数。
|
||||
- metadata: 字典或None,包含与当前运行相关的元数据,可选参数。
|
||||
- **kwargs: 接受任意额外的关键字参数。
|
||||
|
||||
**代码描述**:
|
||||
`on_tool_start`函数是`CustomAsyncIteratorCallbackHandler`类的一个方法,它在工具开始执行时被调用。该方法首先对输入字符串`input_str`进行预处理,移除可能导致处理中断的特定停止词,如"Observation:", "Thought", 等。这一步骤是为了确保输入字符串在后续处理中不会因为包含特定词汇而提前中断。
|
||||
|
||||
接着,方法使用`serialized`参数中的工具名称和处理后的`input_str`,以及其他相关信息(如运行ID、状态等),构建一个表示当前工具状态的字典`cur_tool`。这个字典包括工具名称、输入输出字符串、状态、运行ID等关键信息。
|
||||
|
||||
最后,`on_tool_start`方法调用`dumps`函数将`cur_tool`字典序列化为JSON格式的字符串,并使用`queue.put_nowait`方法将其异步地放入队列中。这一步是为了将当前工具的状态信息传递给其他部分的处理流程,例如用于监控、日志记录或进一步的数据处理。
|
||||
|
||||
在整个过程中,`Status.agent_action`状态被用来标记当前工具的状态,表示代理正在执行动作。这与`Status`类中定义的其他状态一起,帮助系统跟踪和管理异步任务的执行流程。
|
||||
|
||||
**注意**:
|
||||
- 在使用`on_tool_start`方法时,确保传入的`serialized`参数包含必要的工具信息,如工具名称。
|
||||
- 输入字符串`input_str`可能会根据预定义的停止词被截断,这一点在设计输入内容时需要考虑。
|
||||
- 该方法是异步的,因此在调用时需要使用`await`关键字。
|
||||
- 通过`**kwargs`参数,`on_tool_start`方法能够灵活接收并处理额外的关键字参数,这提供了更大的灵活性,但同时也要求调用者注意参数的正确性和相关性。
|
||||
***
|
||||
### FunctionDef on_tool_end(self, output)
|
||||
**on_tool_end**: 该函数的功能是在工具执行结束时更新工具的状态并处理输出。
|
||||
|
||||
**参数**:
|
||||
- `output`: 字符串类型,表示工具执行的输出内容。
|
||||
- `run_id`: UUID类型,表示当前运行的唯一标识符。
|
||||
- `parent_run_id`: UUID类型或None,表示父运行的唯一标识符,可选参数。
|
||||
- `tags`: 字符串列表或None,表示与当前运行相关的标签,可选参数。
|
||||
- `**kwargs`: 接收任意额外的关键字参数。
|
||||
|
||||
**代码描述**:
|
||||
`on_tool_end`函数是`CustomAsyncIteratorCallbackHandler`类的一个异步方法,用于处理工具执行结束后的逻辑。该函数首先将实例变量`out`设置为True,表示输出已经准备好。然后,使用`cur_tool.update`方法更新当前工具的状态为`Status.tool_finish`,表示工具执行完成,并将工具的输出字符串中的"Answer:"部分替换为空字符串。最后,该函数将当前工具的状态和更新后的输出通过`dumps`函数序列化为JSON格式的字符串,并使用`queue.put_nowait`方法将其放入队列中,以便进一步处理。
|
||||
|
||||
该函数与`dumps`函数和`Status`类有直接的关联。`dumps`函数用于将字典对象转换为JSON格式的字符串,确保了工具状态和输出信息在序列化过程中的格式统一和准确性。`Status`类提供了一系列状态常量,其中`Status.tool_finish`表示工具执行完成的状态,用于在工具执行结束时更新当前工具的状态。
|
||||
|
||||
**注意**:
|
||||
- 在调用`on_tool_end`函数时,必须确保传入的`output`和`run_id`参数有效,且`run_id`应为唯一标识符。
|
||||
- 可选参数`parent_run_id`和`tags`可以根据需要传入,以提供更多关于当前运行的上下文信息。
|
||||
- 在处理输出字符串时,`output.replace("Answer:", "")`操作是为了去除可能存在的前缀"Answer:",以获取纯净的输出内容。
|
||||
- 该函数是异步的,因此在调用时需要使用`await`关键字。
|
||||
- 在使用`queue.put_nowait`方法将信息放入队列时,应确保队列已经正确初始化并准备好接收数据。
|
||||
***
|
||||
### FunctionDef on_tool_error(self, error)
|
||||
**on_tool_error**: 该函数的功能是处理工具执行过程中发生的错误。
|
||||
|
||||
**参数**:
|
||||
- `error`: 异常或键盘中断的实例,表示发生的错误。
|
||||
- `run_id`: UUID格式,表示当前运行的唯一标识。
|
||||
- `parent_run_id`: UUID格式或None,表示父运行的唯一标识,如果存在的话。
|
||||
- `tags`: 字符串列表或None,表示与当前错误相关的标签。
|
||||
- `**kwargs`: 接受任意额外的关键字参数。
|
||||
|
||||
**代码描述**:
|
||||
`on_tool_error`函数是`CustomAsyncIteratorCallbackHandler`类中的一个异步方法,用于处理在工具执行过程中发生的错误。当工具执行过程中遇到异常或键盘中断时,此方法会被调用。函数首先使用`self.cur_tool.update`方法更新当前工具的状态为`Status.error`,并记录错误信息。接着,它将当前工具的状态和错误信息序列化为JSON格式的字符串,并使用`self.queue.put_nowait`方法将该字符串放入队列中,以便后续处理。
|
||||
|
||||
该函数与`dumps`函数和`Status`类有直接的关联。`dumps`函数用于将字典对象转换为JSON格式的字符串,确保错误信息和工具状态以正确的格式被序列化和传输。`Status`类则提供了一个`error`状态常量,用于明确标识工具当前处于错误状态。这种设计使得错误处理过程既清晰又高效,便于后续的错误追踪和处理。
|
||||
|
||||
**注意**:
|
||||
- 在调用此函数时,必须确保传入的`error`参数是一个异常或键盘中断的实例,以便正确记录错误信息。
|
||||
- `run_id`和`parent_run_id`参数应为有效的UUID格式,以确保能够准确追踪到具体的运行实例和其父实例(如果有)。
|
||||
- `tags`参数可以用于提供额外的错误上下文信息,有助于错误的分类和分析。
|
||||
- 该函数是异步的,调用时需要使用`await`关键字。
|
||||
***
|
||||
### FunctionDef on_llm_new_token(self, token)
|
||||
**on_llm_new_token**: 该函数的功能是处理新的LLM(Large Language Model)生成的令牌。
|
||||
|
||||
**参数**:
|
||||
- token: 字符串类型,表示LLM生成的新令牌。
|
||||
- **kwargs: 接收任意数量的关键字参数,这些参数可以在函数体内使用,但在当前函数实现中未直接使用。
|
||||
|
||||
**代码描述**:
|
||||
`on_llm_new_token`函数是`CustomAsyncIteratorCallbackHandler`类的一个异步方法,主要用于处理由大型语言模型生成的新令牌。函数首先定义了一个名为`special_tokens`的列表,其中包含了特定的令牌字符串,如"Action"和"<|observation|>"。这些特殊令牌用于识别LLM生成的令牌中是否包含特定的动作或观察结果。
|
||||
|
||||
函数接着遍历`special_tokens`列表,检查传入的`token`是否包含列表中的任一特殊令牌。如果发现`token`中包含特殊令牌,函数将执行以下操作:
|
||||
1. 使用`split`方法分割`token`,以特殊令牌为界,取分割后的第一部分作为`before_action`。
|
||||
2. 调用`self.cur_tool.update`方法更新当前工具的状态为`Status.running`,并将`before_action`加上换行符后设置为`llm_token`。
|
||||
3. 使用`dumps`函数将`self.cur_tool`对象转换为JSON格式的字符串,并通过`self.queue.put_nowait`方法将其放入队列中。
|
||||
4. 设置`self.out`为`False`,并终止循环。
|
||||
|
||||
如果`token`非空且`self.out`为`True`(即未找到特殊令牌),则直接将`token`作为`llm_token`更新到`self.cur_tool`中,并同样将其序列化后放入队列。
|
||||
|
||||
此函数通过检查LLM生成的令牌是否包含特定的动作或观察结果,来决定是否更新当前工具的状态和内容,并将更新后的信息放入队列中,以供后续处理。
|
||||
|
||||
**注意**:
|
||||
- 函数中使用了`dumps`函数将字典对象序列化为JSON字符串,这一步骤是为了确保队列中的数据格式统一,便于后续的处理和传输。
|
||||
- `Status.running`是从`Status`类中引用的一个状态值,表示当前工具或任务正在运行中。在更新工具状态时,需要确保使用正确的状态值。
|
||||
- 函数的异步性质要求调用者在使用时配合`await`关键字,以确保异步操作的正确执行。
|
||||
- 函数实现中未直接使用`**kwargs`参数,这意味着函数设计上允许接收额外的关键字参数,以便于未来扩展或在不同上下文中灵活使用。
|
||||
***
|
||||
### FunctionDef on_llm_start(self, serialized, prompts)
|
||||
**on_llm_start**: 该函数的功能是在长期学习模型(LLM)启动时更新当前工具的状态并将其序列化后放入队列中。
|
||||
|
||||
**参数**:
|
||||
- `serialized`: 一个字典,包含序列化信息,其类型为`Dict[str, Any]`。
|
||||
- `prompts`: 一个字符串列表,包含提示信息,其类型为`List[str]`。
|
||||
- `**kwargs`: 接收任意数量的关键字参数,其类型为`Any`。
|
||||
|
||||
**代码描述**:
|
||||
`on_llm_start`函数是`CustomAsyncIteratorCallbackHandler`类的一个异步方法,主要用于处理长期学习模型(LLM)启动时的逻辑。在该方法中,首先通过调用`self.cur_tool.update`方法更新当前工具的状态为`Status.start`,并将`llm_token`设置为空字符串。这表示当前工具已经开始执行,但尚未生成或接收到任何LLM令牌。
|
||||
|
||||
接下来,该方法使用`dumps`函数将`self.cur_tool`对象序列化为JSON格式的字符串。`dumps`函数是一个核心功能,它接受一个字典对象作为输入,并将其转换为JSON格式的字符串,确保了非ASCII字符的可读性和完整性。在本方法中,`dumps`函数的使用确保了当前工具状态的序列化信息格式统一和准确性。
|
||||
|
||||
最后,序列化后的字符串通过`self.queue.put_nowait`方法立即放入队列中,等待进一步处理。这一步骤是异步操作的一部分,确保了即使在高并发环境下,也能高效地处理大量的任务。
|
||||
|
||||
**注意**:
|
||||
- 在使用`on_llm_start`方法时,需要确保传入的`serialized`参数是正确格式的字典,以及`prompts`参数是一个字符串列表。这些参数对于方法的执行至关重要。
|
||||
- 该方法是异步的,因此在调用时需要使用`await`关键字。
|
||||
- 更新状态和序列化操作应该与实际的LLM启动逻辑相匹配,以确保状态的准确性和信息的完整性。
|
||||
- 在处理异步任务时,应当注意异常处理,确保即使在遇到错误的情况下,也能保证程序的稳定运行。
|
||||
***
|
||||
### FunctionDef on_chat_model_start(self, serialized, messages)
|
||||
**on_chat_model_start**: 该函数的功能是在聊天模型开始时进行初始化设置。
|
||||
|
||||
**参数**:
|
||||
- `serialized`: 一个字典类型参数,包含序列化信息。
|
||||
- `messages`: 一个列表类型参数,包含消息列表。
|
||||
- `run_id`: 一个UUID类型参数,表示运行的唯一标识。
|
||||
- `parent_run_id`: 一个可选的UUID类型参数,表示父运行的唯一标识。
|
||||
- `tags`: 一个可选的字符串列表类型参数,包含标签信息。
|
||||
- `metadata`: 一个可选的字典类型参数,包含元数据信息。
|
||||
- `**kwargs`: 接收任意额外的关键字参数。
|
||||
|
||||
**代码描述**:
|
||||
`on_chat_model_start`函数是`CustomAsyncIteratorCallbackHandler`类的一个方法,它主要用于处理聊天模型开始时的初始化工作。在这个方法中,首先通过`self.cur_tool.update`方法更新当前工具的状态为`Status.start`,并将`llm_token`设置为空字符串。这表示聊天模型开始执行,且当前没有任何长寿命模型(Long-Lived Model)的令牌。接着,使用`self.queue.put_nowait`方法将`self.cur_tool`的序列化信息(通过`dumps`函数转换为JSON格式的字符串)立即放入队列中,以便后续处理。
|
||||
|
||||
这个方法中调用了两个重要的对象:`Status`和`dumps`。`Status`类用于定义不同的状态常量,其中`Status.start`表示开始状态,用于标识聊天模型的启动。`dumps`函数用于将字典对象转换为JSON格式的字符串,这里它被用来序列化`self.cur_tool`的信息,以便将这些信息以字符串形式放入队列中。
|
||||
|
||||
**注意**:
|
||||
- 在调用`on_chat_model_start`方法时,需要确保传入的参数符合要求,特别是`run_id`必须是有效的UUID。
|
||||
- `serialized`参数应包含所有必要的序列化信息,以确保聊天模型可以正确初始化。
|
||||
- 使用`tags`和`metadata`参数可以提供额外的上下文信息,但它们是可选的。
|
||||
- 该方法是异步的,因此在调用时需要使用`await`关键字。
|
||||
- 在实际应用中,应注意`**kwargs`参数的使用,确保不会传入意外的关键字参数,以避免潜在的错误。
|
||||
***
|
||||
### FunctionDef on_llm_end(self, response)
|
||||
**on_llm_end**: 该函数的功能是在LLM(大型语言模型)任务结束时更新当前工具的状态并将其放入队列中。
|
||||
|
||||
**参数**:
|
||||
- `response`: LLMResult类型,表示LLM任务的结果。
|
||||
- `**kwargs`: 接受任意额外的关键字参数,提供了函数调用的灵活性。
|
||||
|
||||
**代码描述**:
|
||||
`on_llm_end`函数是`CustomAsyncIteratorCallbackHandler`类的一个异步方法,它在大型语言模型(LLM)任务结束时被调用。此函数首先使用`self.cur_tool.update`方法更新当前工具的状态为`Status.complete`,表示任务已完成,并设置`llm_token`为换行符("\n")。这一步骤是为了标记当前处理的工具或任务已经完成,准备进行下一步操作。
|
||||
|
||||
接着,函数使用`self.queue.put_nowait`方法将`self.cur_tool`的JSON字符串表示(通过调用`dumps`函数转换得到)放入队列中,以便后续处理。`dumps`函数将`self.cur_tool`字典对象转换为JSON格式的字符串,确保了信息在序列化过程中的格式统一和准确性。这一步骤是异步处理流程中的一个关键环节,它确保了任务状态的更新和信息的传递能够及时且准确地完成。
|
||||
|
||||
在整个项目中,`dumps`函数和`Status`类是与`on_llm_end`函数紧密相关的两个对象。`dumps`函数负责将字典对象序列化为JSON字符串,而`Status`类提供了一组预定义的状态常量,用于标识异步操作的不同阶段。这些工具和机制共同支持了`on_llm_end`函数的实现,使其能够有效地管理和传递LLM任务的结束状态。
|
||||
|
||||
**注意**:
|
||||
- 在调用`on_llm_end`函数时,需要确保传入的`response`参数是`LLMResult`类型,以保证函数能够正确处理LLM任务的结果。
|
||||
- 函数内部使用了`**kwargs`来接受任意额外的关键字参数,这提供了调用时的灵活性,但调用者应注意只传递需要的参数,避免不必要的混淆。
|
||||
- 更新状态和放入队列的操作是异步执行的,调用此函数时应注意处理可能出现的异步执行相关的问题,如并发控制和异常处理。
|
||||
***
|
||||
### FunctionDef on_llm_error(self, error)
|
||||
**on_llm_error**: 该函数的功能是处理LLM错误事件。
|
||||
|
||||
**参数**:
|
||||
- `error`: 接收一个异常对象,可以是`Exception`或`KeyboardInterrupt`类型,表示发生的错误。
|
||||
- `**kwargs`: 接收任意数量的关键字参数,提供额外的灵活性以处理不同的错误情况。
|
||||
|
||||
**代码描述**:
|
||||
`on_llm_error`函数是`CustomAsyncIteratorCallbackHandler`类的一个方法,专门用于处理LLM(长寿命模型)在执行过程中遇到的错误。当LLM执行过程中发生错误时,此函数会被触发。
|
||||
|
||||
在函数内部,首先通过`self.cur_tool.update`方法更新当前工具的状态为`Status.error`,并记录错误信息。这里的`Status.error`是一个从`Status`类中定义的常量,表示当前工具处于错误状态。错误信息则通过将`error`参数转换为字符串形式来记录。
|
||||
|
||||
接下来,函数使用`self.queue.put_nowait`方法将当前工具的状态信息异步地放入队列中。在放入队列之前,使用`dumps`函数将工具状态信息序列化为JSON格式的字符串。`dumps`函数是一个关键的功能,它将字典对象转换为JSON格式的字符串,确保了信息在网络传输或存储过程中的格式统一和准确性。
|
||||
|
||||
**注意**:
|
||||
- 在处理LLM错误时,确保传递给`on_llm_error`函数的`error`参数包含了足够的错误信息,以便于准确记录和后续处理。
|
||||
- 使用`**kwargs`参数提供了额外的灵活性,但在调用时需要注意传递的关键字参数应与错误处理逻辑相匹配。
|
||||
- 在更新工具状态和序列化状态信息时,应确保操作的原子性和错误处理机制,避免因异常处理不当导致的进一步错误。
|
||||
- 考虑到`dumps`函数的使用,确保传入的对象符合JSON序列化的要求,并注意处理非ASCII字符的情况。
|
||||
***
|
||||
### FunctionDef on_agent_finish(self, finish)
|
||||
**on_agent_finish**: 该函数的功能是在代理执行完成时更新当前工具的状态,并将其最终结果放入队列中。
|
||||
|
||||
**参数**:
|
||||
- `finish`: 一个`AgentFinish`类型的对象,包含代理执行的最终结果。
|
||||
- `run_id`: 一个`UUID`类型的对象,表示当前运行的唯一标识。
|
||||
- `parent_run_id`: 一个可选的`UUID`类型的对象,表示父运行的唯一标识。
|
||||
- `tags`: 一个可选的字符串列表,包含与当前运行相关的标签。
|
||||
- `**kwargs`: 接受任意额外的关键字参数。
|
||||
|
||||
**代码描述**:
|
||||
`on_agent_finish`函数是`CustomAsyncIteratorCallbackHandler`类的一个异步方法,它在代理执行完成时被调用。该方法首先使用`finish.return_values["output"]`获取代理执行的最终输出结果,并将当前工具的状态更新为`Status.agent_finish`,同时设置最终答案为代理的输出结果。然后,它使用`dumps`函数将当前工具的状态序列化为JSON格式的字符串,并使用`put_nowait`方法将这个字符串放入队列中,以便后续处理。最后,`cur_tool`被重置为空字典,为下一次代理执行做准备。
|
||||
|
||||
在这个过程中,`dumps`函数负责将字典对象转换为JSON格式的字符串,确保了信息在序列化过程中的格式统一和准确性。`Status`类提供了`agent_finish`状态,标识代理执行已完成,这对于跟踪和管理异步任务的执行流程至关重要。
|
||||
|
||||
**注意**:
|
||||
- 确保`finish`参数提供了有效的代理执行结果,特别是`finish.return_values["output"]`能够正确获取到输出结果。
|
||||
- 使用`dumps`函数时,需要确保传入的对象是字典类型,以避免序列化错误。
|
||||
- 在将信息放入队列时,使用`put_nowait`方法可以避免阻塞,但需要确保队列处理速度足以应对放入的速度,避免队列溢出。
|
||||
|
||||
**输出示例**:
|
||||
由于`on_agent_finish`方法没有返回值,其主要作用是更新状态并将信息放入队列,因此没有直接的输出示例。但可以假设在代理执行完成后,队列中将包含一个类似于以下的JSON格式字符串:
|
||||
```json
|
||||
{"status": 5, "final_answer": "代理执行的输出结果"}
|
||||
```
|
||||
这表示当前工具的状态已更新为代理完成状态,且最终答案已设置为代理的输出结果。
|
||||
***
|
||||
296
markdown_docs/server/agent/custom_agent/ChatGLM3Agent.md
Normal file
@ -0,0 +1,296 @@
|
||||
## ClassDef StructuredChatOutputParserWithRetries
|
||||
**StructuredChatOutputParserWithRetries**: 该类的功能是为结构化聊天代理提供带有重试机制的输出解析。
|
||||
|
||||
**属性**:
|
||||
- base_parser: 使用的基础解析器。
|
||||
- output_fixing_parser: 使用的输出修正解析器,可选。
|
||||
|
||||
**代码描述**:
|
||||
StructuredChatOutputParserWithRetries 类继承自 AgentOutputParser,主要用于解析结构化聊天代理的输出。它通过定义两个主要属性——base_parser 和 output_fixing_parser 来实现其功能。base_parser 是一个 StructuredChatOutputParser 实例,用于基本的输出解析。output_fixing_parser 是一个可选的 OutputFixingParser 实例,用于在必要时修正输出。
|
||||
|
||||
该类的核心方法是 parse,它接受一个字符串 text 作为输入,并尝试解析这个字符串以生成一个代理动作(AgentAction)或代理完成信号(AgentFinish)。解析过程首先尝试找到特殊标记(如 "Action:" 或 "<|observation|>")的位置,然后根据是否包含 "tool_call" 来决定如何处理文本。如果包含 "tool_call",则进一步解析以提取动作和参数;否则,直接将文本作为最终答案处理。解析完成后,根据 output_fixing_parser 的存在与否,选择相应的解析器进行最终解析。
|
||||
|
||||
在项目中,StructuredChatOutputParserWithRetries 被 StructuredGLM3ChatAgent 类作为默认的输出解析器使用。通过 StructuredGLM3ChatAgent 类的 _get_default_output_parser 方法,可以看出 StructuredChatOutputParserWithRetries 被用于构建结构化聊天代理,以处理语言模型(LLM)的输出并将其转换为适合代理处理的格式。
|
||||
|
||||
**注意**:
|
||||
- 在使用 StructuredChatOutputParserWithRetries 类时,需要确保传入的文本格式符合预期,特别是当涉及到特殊标记和工具调用格式时。
|
||||
- 如果提供了 output_fixing_parser,它将用于在基础解析失败或需要修正时进行二次解析。
|
||||
|
||||
**输出示例**:
|
||||
```json
|
||||
Action:
|
||||
```
|
||||
{
|
||||
"action": "Final Answer",
|
||||
"action_input": "这是解析后的文本"
|
||||
}
|
||||
```
|
||||
在这个示例中,假设传入的文本不包含 "tool_call",则 parse 方法将直接将文本视为最终答案,并构建相应的 JSON 字符串作为输出。
|
||||
### FunctionDef parse(self, text)
|
||||
**parse**: 此函数的功能是解析文本并生成相应的动作或最终答案。
|
||||
|
||||
**参数**:
|
||||
- `text`: 需要解析的文本,类型为字符串。
|
||||
|
||||
**代码描述**:
|
||||
此函数首先定义了一个包含特殊标记的列表`special_tokens`,这些特殊标记用于在文本中查找特定的位置。接着,它会找到这些特殊标记中第一个出现的位置,并将文本截断到这个位置,以便进一步处理。
|
||||
|
||||
如果文本中包含"tool_call",则认为这是一个需要执行的动作。函数会找到动作描述结束的位置(即"```"的位置),并提取出动作名称和参数。参数会被解析成键值对的形式,并存储在一个字典中。然后,这些信息会被组织成一个JSON对象,准备进行下一步的解析。
|
||||
|
||||
如果文本中不包含"tool_call",则认为这是一个最终答案,直接将文本作为动作输入,动作名称设为"Final Answer"。
|
||||
|
||||
之后,函数会根据是否存在`output_fixing_parser`来决定使用哪个解析器进行解析。如果存在,就使用`output_fixing_parser`解析器,否则使用`base_parser`解析器。解析的结果会被返回。
|
||||
|
||||
**注意**:
|
||||
- 在使用此函数时,需要确保传入的文本格式正确,特别是当文本中包含动作描述时,需要遵循特定的格式(例如,动作和参数的正确分隔)。
|
||||
- 如果在解析过程中遇到任何异常,函数会抛出`OutputParserException`异常,异常信息中会包含无法解析的原始文本。
|
||||
|
||||
**输出示例**:
|
||||
假设文本内容为一个动作调用,解析后可能的返回值为:
|
||||
```json
|
||||
{
|
||||
"action": "tool_call_example",
|
||||
"action_input": {
|
||||
"param1": "value1",
|
||||
"param2": "value2"
|
||||
}
|
||||
}
|
||||
```
|
||||
如果文本内容为最终答案,解析后可能的返回值为:
|
||||
```json
|
||||
{
|
||||
"action": "Final Answer",
|
||||
"action_input": "这是一个最终答案的示例文本。"
|
||||
}
|
||||
```
|
||||
***
|
||||
### FunctionDef _type(self)
|
||||
**_type**: 该函数的功能是返回一个特定的字符串。
|
||||
|
||||
**参数**: 此函数没有参数。
|
||||
|
||||
**代码描述**: `_type` 函数是一个非常简单的方法,其主要目的是返回一个预定义的字符串。这个字符串代表了一个特定的类型标识,即 "structured_chat_ChatGLM3_6b_with_retries"。这个标识通常用于区分不同的处理逻辑或数据格式。在这个上下文中,它可能表示使用了特定配置或策略的聊天模型,特别是指一个结构化的聊天输出解析器,该解析器配置了重试机制。这种类型的标识对于维护代码的清晰度和可维护性非常重要,因为它允许开发者快速识别和理解代码块的用途和行为。
|
||||
|
||||
**注意**: 使用此函数时,需要注意它返回的字符串是硬编码的,这意味着如果未来需要更改类型标识,将需要直接修改此函数的返回值。因此,维护此部分代码时应谨慎,确保任何更改都不会影响依赖此标识的其他代码逻辑。
|
||||
|
||||
**输出示例**: 调用 `_type` 函数将返回以下字符串:
|
||||
```
|
||||
"structured_chat_ChatGLM3_6b_with_retries"
|
||||
```
|
||||
***
|
||||
## ClassDef StructuredGLM3ChatAgent
|
||||
**StructuredGLM3ChatAgent**: 该类的功能是实现一个结构化的聊天代理,用于处理和响应基于ChatGLM3-6B模型的对话。
|
||||
|
||||
**属性**:
|
||||
- output_parser: 用于解析代理输出的解析器,默认为StructuredChatOutputParserWithRetries实例。
|
||||
- observation_prefix: 用于在ChatGLM3-6B观察结果前添加的前缀字符串。
|
||||
- llm_prefix: 用于在语言模型调用前添加的前缀字符串。
|
||||
|
||||
**代码描述**:
|
||||
StructuredGLM3ChatAgent 类继承自 Agent 类,提供了结构化聊天代理的实现。它通过定义特定的属性和方法来处理与语言模型(LLM)的交互,生成提示(prompt),并解析LLM的输出。
|
||||
|
||||
- **属性定义**:
|
||||
- `output_parser` 属性指定了用于解析代理输出的解析器,其默认值为 StructuredChatOutputParserWithRetries 类的实例,该解析器提供了带有重试机制的输出解析功能。
|
||||
- `observation_prefix` 和 `llm_prefix` 属性分别定义了在观察结果和语言模型调用前添加的前缀字符串,用于格式化生成的提示。
|
||||
|
||||
- **方法分析**:
|
||||
- `_construct_scratchpad` 方法用于构建代理的草稿本,它基于中间步骤生成一个字符串,用于记录代理的工作过程。
|
||||
- `_get_default_output_parser` 类方法返回一个默认的输出解析器实例,用于解析语言模型的输出。
|
||||
- `create_prompt` 类方法用于根据提供的工具和输入变量生成提示模板,该方法将工具的信息和其他输入变量格式化为一个字符串模板,用于生成语言模型的输入。
|
||||
- `from_llm_and_tools` 类方法用于根据语言模型和工具集合构建一个StructuredGLM3ChatAgent实例,它通过组合语言模型、工具和其他参数来初始化代理。
|
||||
|
||||
**注意**:
|
||||
- 在使用 StructuredGLM3ChatAgent 类时,需要确保提供的工具和语言模型与代理的目标任务相匹配。
|
||||
- 输出解析器(output_parser)应该能够准确解析语言模型的输出,以便代理能够正确响应用户的输入。
|
||||
- 在构建提示时,应注意格式化字符串模板,确保它们能够正确地被语言模型理解和处理。
|
||||
|
||||
**输出示例**:
|
||||
假设代理接收到的输入是一个简单的问答任务,输出示例可能如下:
|
||||
```
|
||||
{
|
||||
"action": "Final Answer",
|
||||
"action_input": "这是代理基于语言模型输出解析后的回答"
|
||||
}
|
||||
```
|
||||
在这个示例中,代理通过解析语言模型的输出,生成了一个包含最终回答的动作(Action)和相应输入(action_input)的JSON对象。
|
||||
### FunctionDef observation_prefix(self)
|
||||
**observation_prefix**: 此函数的功能是生成并返回ChatGLM3-6B观察的前缀字符串。
|
||||
|
||||
**参数**: 此函数不接受任何参数。
|
||||
|
||||
**代码描述**: `observation_prefix`函数是`StructuredGLM3ChatAgent`类的一个方法,它的主要作用是为ChatGLM3-6B模型的观察提供一个统一的前缀。这个前缀用于在处理聊天或对话数据时,标识出哪些内容是观察到的信息。在这个函数中,返回的字符串是"Observation:",这意味着所有通过此方法处理的观察数据将以"Observation:"作为开头。这有助于模型识别和处理输入数据,确保数据格式的一致性和准确性。
|
||||
|
||||
**注意**: 使用此函数时,需要注意它返回的前缀字符串是固定的。如果在不同的上下文或应用中需要不同的前缀,可能需要对此函数进行相应的修改或扩展。
|
||||
|
||||
**输出示例**: 调用`observation_prefix`函数将返回以下字符串:
|
||||
```
|
||||
Observation:
|
||||
```
|
||||
***
|
||||
### FunctionDef llm_prefix(self)
|
||||
**llm_prefix函数功能**: 该函数的功能是生成并返回一个用于在调用大型语言模型(llm)时附加的前缀字符串。
|
||||
|
||||
**参数**: 该函数没有参数。
|
||||
|
||||
**代码描述**: `llm_prefix`函数定义在`StructuredGLM3ChatAgent`类中,是一个简单的成员函数,不接受任何参数,并且返回一个固定的字符串`"Thought:"`。这个字符串作为前缀,其目的是在向大型语言模型(llm)发起调用时,附加到实际的查询或命令之前,以此来可能影响或指定模型的回应方式。这种做法在与大型语言模型交互时很常见,用于引导模型的回应更加符合期望的上下文或风格。
|
||||
|
||||
**注意**: 使用`llm_prefix`函数时,需要注意的是,返回的前缀字符串`"Thought:"`是硬编码的,这意味着在不同的应用场景下,如果需要不同的前缀来引导大型语言模型的回应,可能需要修改这个函数的返回值。此外,这个前缀的有效性和适用性可能会随着大型语言模型的不同或者模型训练数据的更新而变化,因此在实际应用中需要根据模型的具体表现来调整。
|
||||
|
||||
**输出示例**: 调用`llm_prefix`函数将返回字符串`"Thought:"`。
|
||||
|
||||
通过上述分析,开发者和初学者可以了解到`llm_prefix`函数的作用、使用方法以及需要注意的事项。这有助于在使用`StructuredGLM3ChatAgent`类与大型语言模型进行交互时,能够更有效地引导模型的回应,从而提高交互的质量和效果。
|
||||
***
|
||||
### FunctionDef _construct_scratchpad(self, intermediate_steps)
|
||||
**_construct_scratchpad**: 此函数的功能是构建并返回一个代表中间步骤的字符串。
|
||||
|
||||
**参数**:
|
||||
- **intermediate_steps**: 一个列表,包含元组,每个元组由AgentAction和字符串组成,代表中间的操作步骤。
|
||||
|
||||
**代码描述**:
|
||||
`_construct_scratchpad` 函数首先调用其父类的 `_construct_scratchpad` 方法,传入中间步骤的数据(`intermediate_steps`),并接收返回的字符串(`agent_scratchpad`)。此字符串代表了到目前为止的工作进展。函数接着检查 `agent_scratchpad` 是否为字符串类型,如果不是,则抛出 `ValueError` 异常,确保后续操作的数据类型正确性。
|
||||
|
||||
如果 `agent_scratchpad` 非空,函数将返回一个格式化的字符串,该字符串以一种友好的方式向用户展示之前的工作成果,即使实际上这个函数并没有直接访问到这些成果,只是通过参数传递得到的信息。如果 `agent_scratchpad` 为空,则直接返回该空字符串。
|
||||
|
||||
**注意**:
|
||||
- 确保传入的 `intermediate_steps` 参数格式正确,即列表中包含的元素为元组,且元组包含的是 `AgentAction` 和字符串。
|
||||
- 此函数假设父类的 `_construct_scratchpad` 方法已正确实现并能返回一个字符串。如果父类方法的实现发生变化,可能需要相应地调整此函数。
|
||||
|
||||
**输出示例**:
|
||||
如果 `intermediate_steps` 包含了一系列的操作步骤,且父类方法返回了这些步骤的字符串表示,例如 "Step 1: Do something; Step 2: Do something else;",那么此函数可能返回的字符串示例为:
|
||||
|
||||
```
|
||||
"This was your previous work (but I haven't seen any of it! I only see what you return as final answer):
|
||||
Step 1: Do something; Step 2: Do something else;"
|
||||
```
|
||||
***
|
||||
### FunctionDef _get_default_output_parser(cls, llm)
|
||||
**_get_default_output_parser**: 该函数的功能是获取默认的输出解析器。
|
||||
|
||||
**参数**:
|
||||
- `llm`: 可选参数,类型为 `BaseLanguageModel`,表示基础语言模型。
|
||||
- `**kwargs`: 接受任意数量的关键字参数。
|
||||
|
||||
**代码描述**: `_get_default_output_parser` 函数是 `StructuredGLM3ChatAgent` 类的一个类方法,用于获取默认的输出解析器。该方法接受一个可选的语言模型实例 `llm` 和任意数量的关键字参数 `**kwargs`。函数体内部,它创建并返回一个 `StructuredChatOutputParserWithRetries` 实例,将 `llm` 作为参数传递给该实例。`StructuredChatOutputParserWithRetries` 类是专门为结构化聊天代理设计的输出解析器,具有重试机制,能够处理语言模型的输出并将其转换为适合代理处理的格式。
|
||||
|
||||
在项目中,`_get_default_output_parser` 方法被 `from_llm_and_tools` 方法调用,以获取默认的输出解析器实例。如果在创建 `StructuredGLM3ChatAgent` 实例时没有明确指定输出解析器,则会通过调用 `_get_default_output_parser` 方法来获取默认的输出解析器实例,并将其用于处理语言模型的输出。
|
||||
|
||||
**注意**:
|
||||
- 在使用 `_get_default_output_parser` 方法时,需要确保传入的 `llm` 参数(如果有)是一个有效的语言模型实例。
|
||||
- 该方法设计为灵活接受任意数量的关键字参数 `**kwargs`,但在当前实现中并未直接使用这些额外的参数。开发者在扩展或修改方法时可以根据需要利用这些参数。
|
||||
|
||||
**输出示例**: 由于 `_get_default_output_parser` 方法返回的是一个 `StructuredChatOutputParserWithRetries` 实例,因此输出示例将依赖于该实例的具体实现。假设 `llm` 参数为 `None`,调用 `_get_default_output_parser` 方法将返回一个不带语言模型实例的 `StructuredChatOutputParserWithRetries` 实例。
|
||||
***
|
||||
### FunctionDef _stop(self)
|
||||
**_stop函数的功能**: `_stop`函数的目的是结束当前的会话并返回一个特定的标记列表。
|
||||
|
||||
**参数**: 此函数没有参数。
|
||||
|
||||
**代码描述**: `_stop`函数是`StructuredGLM3ChatAgent`类的一个私有方法,用于在聊天代理的会话中标记结束点。当调用此函数时,它会返回一个包含单个字符串元素`"<|observation|>"`的列表。这个返回值通常用于指示聊天模型的会话已经结束,或者需要进行某种形式的重置或观察。在聊天代理的上下文中,这个特定的字符串可能被用作一个信号或标记,以触发特定的行为或处理逻辑。
|
||||
|
||||
**注意**: 虽然`_stop`函数的实现看起来简单,但它在聊天代理的逻辑中可能扮演着关键角色。使用时需要确保聊天模型或处理逻辑能够正确识别并处理返回的`"<|observation|>"`标记。此外,由于`_stop`是一个私有方法,它仅在`StructuredGLM3ChatAgent`类的内部被调用,不应该直接从类的实例外部访问或调用。
|
||||
|
||||
**输出示例**: 调用`_stop`函数可能会返回如下列表:
|
||||
```python
|
||||
["<|observation|>"]
|
||||
```
|
||||
这个列表包含一个字符串元素,即`"<|observation|>"`,用于表示聊天会话的结束或需要进行观察的状态。
|
||||
***
|
||||
### FunctionDef create_prompt(cls, tools, prompt, input_variables, memory_prompts)
|
||||
**create_prompt**: 此函数的功能是基于提供的工具和模板参数构建聊天提示模板。
|
||||
|
||||
**参数**:
|
||||
- `tools`: 一个实现了BaseTool接口的对象序列,代表聊天代理可以使用的工具。
|
||||
- `prompt`: 一个字符串模板,用于格式化最终的提示信息。
|
||||
- `input_variables`: 一个字符串列表,指定输入变量的名称,默认为None。
|
||||
- `memory_prompts`: 一个BasePromptTemplate对象的列表,用于提供记忆提示,默认为None。
|
||||
|
||||
**代码描述**:
|
||||
`create_prompt`函数首先遍历`tools`参数中的每个工具,提取其名称、描述和参数模式,并将这些信息格式化为一个简化的JSON结构。这个结构包括工具的名称、描述和参数。接着,函数将这些工具信息格式化为一个字符串,其中每个工具的信息占据一行,包括其名称、描述和参数。这个格式化的字符串以及其他提供的模板参数(如工具名称列表、历史记录、输入和代理草稿板)被用来填充`prompt`模板字符串。
|
||||
|
||||
如果`input_variables`未指定,则默认为`["input", "agent_scratchpad"]`。`memory_prompts`参数允许将额外的提示信息加入到最终的提示模板中,这些信息可以是之前的对话历史或其他重要信息。
|
||||
|
||||
最后,函数使用格式化后的提示信息和输入变量列表创建一个`ChatPromptTemplate`对象,并将其返回。这个返回的对象可以直接用于生成聊天代理的提示信息。
|
||||
|
||||
在项目中,`create_prompt`函数被`from_llm_and_tools`方法调用,用于根据语言模型(LLM)和工具集合构建一个聊天代理。这表明`create_prompt`函数在构建聊天代理的初始化过程中起着核心作用,特别是在准备聊天代理的提示模板方面。
|
||||
|
||||
**注意**:
|
||||
- 确保`prompt`参数提供的模板字符串正确地使用了所有预期的变量,以避免格式化时出现错误。
|
||||
- `tools`参数中的工具对象需要实现`BaseTool`接口,确保它们具有`name`、`description`和`args_schema`属性。
|
||||
|
||||
**输出示例**:
|
||||
假设有两个工具,分别为"Calculator"和"Translator",且`prompt`参数为"Available tools: {tools}\nInput: {input}",则函数可能返回的`ChatPromptTemplate`对象中的`messages`属性可能包含以下字符串:
|
||||
|
||||
```
|
||||
Available tools:
|
||||
Calculator: A simple calculator, args: {'number1': 'Number', 'number2': 'Number'}
|
||||
Translator: Translates text from one language to another, args: {'text': 'String', 'target_language': 'String'}
|
||||
Input: {input}
|
||||
```
|
||||
***
|
||||
### FunctionDef from_llm_and_tools(cls, llm, tools, prompt, callback_manager, output_parser, human_message_template, input_variables, memory_prompts)
|
||||
**from_llm_and_tools**: 该函数的功能是从语言模型(LLM)和工具集合构建一个聊天代理。
|
||||
|
||||
**参数**:
|
||||
- `cls`: 类方法的第一个参数,指代当前类。
|
||||
- `llm`: `BaseLanguageModel`的实例,表示基础语言模型。
|
||||
- `tools`: 实现了`BaseTool`接口的对象序列,代表聊天代理可以使用的工具。
|
||||
- `prompt`: 字符串类型,用于格式化最终的提示信息,默认为None。
|
||||
- `callback_manager`: `BaseCallbackManager`的实例,用于管理回调函数,默认为None。
|
||||
- `output_parser`: `AgentOutputParser`的实例,用于解析代理输出,默认为None。
|
||||
- `human_message_template`: 字符串类型,表示人类消息模板,默认为`HUMAN_MESSAGE_TEMPLATE`。
|
||||
- `input_variables`: 字符串列表,指定输入变量的名称,默认为None。
|
||||
- `memory_prompts`: `BasePromptTemplate`对象的列表,用于提供记忆提示,默认为None。
|
||||
- `**kwargs`: 接受任意数量的关键字参数。
|
||||
|
||||
**代码描述**:
|
||||
`from_llm_and_tools`函数首先验证提供的工具集合是否有效。然后,它调用`create_prompt`方法来创建聊天提示模板,该模板基于提供的工具、提示、输入变量和记忆提示。接着,使用`llm`、生成的`prompt`和`callback_manager`创建一个`LLMChain`实例。此外,函数从工具集合中提取工具名称,并尝试获取默认的输出解析器,如果未提供`output_parser`参数,则调用`_get_default_output_parser`方法获取默认解析器。最后,使用这些组件构建并返回一个`StructuredGLM3ChatAgent`实例。
|
||||
|
||||
**注意**:
|
||||
- 确保提供的`llm`和`tools`参数是有效的实例,且`tools`中的每个工具都实现了`BaseTool`接口。
|
||||
- 如果在调用时未指定`output_parser`,则会自动使用默认的输出解析器。
|
||||
- `**kwargs`参数提供了额外的灵活性,允许在创建代理时传递额外的配置选项。
|
||||
|
||||
**输出示例**:
|
||||
由于`from_llm_and_tools`函数返回的是一个`StructuredGLM3ChatAgent`实例,因此输出示例将依赖于该实例的具体实现。例如,如果使用默认参数调用此函数,将返回一个配置了基础语言模型、指定工具集合和默认输出解析器的`StructuredGLM3ChatAgent`实例。这个实例可以直接用于处理聊天对话,执行工具命令,并解析语言模型的输出。
|
||||
***
|
||||
### FunctionDef _agent_type(self)
|
||||
**_agent_type**: 该函数的功能是抛出一个 ValueError 异常。
|
||||
|
||||
**参数**: 此函数不接受任何参数。
|
||||
|
||||
**代码描述**: `_agent_type` 函数是 `StructuredGLM3ChatAgent` 类的一个私有方法,其设计初衷是为了在子类中被重写,用以指定或返回特定的代理类型字符串。在其原始形态中,此函数直接抛出一个 `ValueError` 异常,这表明如果直接调用此方法而没有在子类中进行适当的重写,则会明确地指出这一点。这是一种常见的编程模式,用于强制要求子类实现特定的方法。
|
||||
|
||||
**注意**: 在使用 `StructuredGLM3ChatAgent` 类或其任何子类时,开发者需要确保 `_agent_type` 方法被正确重写以避免运行时错误。此方法的存在强调了一个设计原则,即某些方法是专门设计给子类来实现的,而不是直接在父类中使用。因此,如果你在开发过程中遇到了 `ValueError`,这可能是因为你尝试调用了一个应该被子类重写的方法,但是没有这样做。
|
||||
***
|
||||
## FunctionDef initialize_glm3_agent(tools, llm, prompt, memory, agent_kwargs)
|
||||
**initialize_glm3_agent**: 该函数的功能是初始化一个基于GLM3模型的聊天代理。
|
||||
|
||||
**参数**:
|
||||
- `tools`: 实现了`BaseTool`接口的对象序列,代表聊天代理可以使用的工具。
|
||||
- `llm`: `BaseLanguageModel`的实例,表示基础语言模型。
|
||||
- `prompt`: 字符串类型,用于格式化最终的提示信息,默认为None。
|
||||
- `memory`: `ConversationBufferWindowMemory`的实例,用于存储聊天历史,默认为None。
|
||||
- `agent_kwargs`: 字典类型,包含创建聊天代理时需要的额外参数,默认为None。
|
||||
- `tags`: 字符串序列,用于标记或分类代理,默认为None。
|
||||
- `**kwargs`: 接受任意数量的关键字参数,提供额外的配置选项。
|
||||
|
||||
**代码描述**:
|
||||
`initialize_glm3_agent`函数首先检查是否提供了`tags`参数,并将其转换为列表形式。然后,检查`agent_kwargs`参数是否为None,如果是,则将其初始化为空字典。接下来,使用`StructuredGLM3ChatAgent.from_llm_and_tools`类方法创建一个`StructuredGLM3ChatAgent`实例,该实例基于提供的语言模型、工具集合、提示信息以及`agent_kwargs`中的其他参数。最后,使用`AgentExecutor.from_agent_and_tools`方法创建并返回一个`AgentExecutor`实例,该实例包含了刚刚创建的聊天代理、工具集合、聊天历史以及标签。
|
||||
|
||||
**注意**:
|
||||
- 在使用`initialize_glm3_agent`函数时,确保提供的`tools`和`llm`参数是有效的实例,且`tools`中的每个工具都实现了`BaseTool`接口。
|
||||
- `prompt`参数允许自定义聊天代理的提示信息,可以根据需要提供。
|
||||
- `memory`参数用于存储和管理聊天历史,有助于实现更连贯的对话。
|
||||
- `agent_kwargs`和`**kwargs`提供了额外的灵活性,允许在创建聊天代理时传递额外的配置选项。
|
||||
|
||||
**输出示例**:
|
||||
假设调用`initialize_glm3_agent`函数并提供了必要的参数,可能会返回如下的`AgentExecutor`实例:
|
||||
```
|
||||
AgentExecutor(
|
||||
agent=StructuredGLM3ChatAgent(...),
|
||||
tools=[...],
|
||||
memory=ConversationBufferWindowMemory(...),
|
||||
tags=['example_tag']
|
||||
)
|
||||
```
|
||||
在这个示例中,`AgentExecutor`实例包含了一个配置好的`StructuredGLM3ChatAgent`聊天代理,以及相关的工具集合、聊天历史和标签。这个实例可以直接用于处理聊天对话,执行工具命令,并解析语言模型的输出。
|
||||
128
markdown_docs/server/agent/custom_template.md
Normal file
@ -0,0 +1,128 @@
|
||||
## ClassDef CustomPromptTemplate
|
||||
**CustomPromptTemplate**: CustomPromptTemplate类的功能是根据提供的模板和工具列表,格式化生成一个定制化的提示字符串。
|
||||
|
||||
**属性**:
|
||||
- `template`: 字符串类型,用于定义提示信息的模板。
|
||||
- `tools`: Tool对象的列表,每个Tool对象包含工具的名称和描述。
|
||||
|
||||
**代码描述**:
|
||||
CustomPromptTemplate类继承自StringPromptTemplate,主要用于生成定制化的提示信息。它通过`format`方法接收关键字参数,其中`intermediate_steps`是一个列表,包含了动作和观察的元组。该方法首先将`intermediate_steps`中的信息格式化为字符串,然后将其以及工具的名称和描述添加到模板中,最后返回格式化后的字符串。
|
||||
|
||||
在项目中,CustomPromptTemplate类被用于`server/chat/agent_chat.py/agent_chat/agent_chat_iterator`中,以生成与用户交互的提示信息。通过提供的模板和工具列表,CustomPromptTemplate能够生成包含工具使用说明和中间步骤描述的提示信息,这对于指导用户如何与代理进行交互是非常有用的。特别是在异步的聊天环境中,准确和详细的提示信息能够极大地提升用户体验。
|
||||
|
||||
**注意**:
|
||||
- 在使用CustomPromptTemplate时,需要确保传递给`format`方法的`intermediate_steps`参数格式正确,即包含动作和观察的元组列表。
|
||||
- 工具列表`tools`应包含所有可能会在提示信息中提及的工具,每个工具都应有名称和描述。
|
||||
|
||||
**输出示例**:
|
||||
假设有以下模板和工具列表:
|
||||
- 模板:`"请使用以下工具:{tools}\n{agent_scratchpad}"`
|
||||
- 工具列表:`[Tool(name="Tool1", description="This is tool 1"), Tool(name="Tool2", description="This is tool 2")]`
|
||||
- `intermediate_steps`:`[("action1", "observation1"), ("action2", "observation2")]`
|
||||
|
||||
调用`format`方法后,可能返回的字符串为:
|
||||
```
|
||||
请使用以下工具:
|
||||
Tool1: This is tool 1
|
||||
Tool2: This is tool 2
|
||||
action1
|
||||
Observation: observation1
|
||||
Thought: action2
|
||||
Observation: observation2
|
||||
Thought:
|
||||
```
|
||||
### FunctionDef format(self)
|
||||
**功能**: `format` 函数的功能是根据提供的参数和内部逻辑,格式化并返回一个字符串。
|
||||
|
||||
**参数**:
|
||||
- `**kwargs`: 关键字参数,可以接受多个命名参数,用于动态传递给模板和内部逻辑处理。
|
||||
|
||||
**代码描述**:
|
||||
该函数首先从传入的关键字参数(`kwargs`)中提取出`intermediate_steps`参数。`intermediate_steps`应该是一个包含动作和观察结果的元组列表。函数遍历这个列表,将每个动作的日志和对应的观察结果格式化为字符串,并拼接到`thoughts`字符串中。
|
||||
|
||||
接下来,函数将`thoughts`字符串添加到`kwargs`字典中,键名为`agent_scratchpad`。此外,还会处理`self.tools`,这是一个工具对象列表。函数将每个工具的名称和描述格式化为字符串,并将这些字符串以换行符连接,结果赋值给`kwargs`字典中的`tools`键。同时,将所有工具的名称提取出来,以逗号和空格连接成一个字符串,赋值给`kwargs`字典中的`tool_names`键。
|
||||
|
||||
最后,函数使用`self.template.format(**kwargs)`语句,将处理好的`kwargs`字典作为参数,传递给模板的`format`方法,并返回格式化后的字符串。
|
||||
|
||||
**注意**:
|
||||
- 确保传入的`kwargs`中包含`intermediate_steps`键,且其值格式正确。
|
||||
- `self.tools`应该是一个包含有`name`和`description`属性的对象列表。
|
||||
- 该函数依赖于`self.template`的`format`方法,确保`self.template`已正确初始化并可以接受`kwargs`作为参数。
|
||||
|
||||
**输出示例**:
|
||||
```plaintext
|
||||
Action: Move Forward
|
||||
Observation: Wall detected
|
||||
Thought:
|
||||
Tool1: Used for cutting
|
||||
Tool2: Used for digging
|
||||
Tool Names: Tool1, Tool2
|
||||
```
|
||||
***
|
||||
## ClassDef CustomOutputParser
|
||||
**CustomOutputParser**: CustomOutputParser类的功能是解析大模型输出,并根据输出内容决定下一步操作。
|
||||
|
||||
**属性**:
|
||||
- `begin`: 一个布尔值,用于指示解析过程是否应该开始或停止。
|
||||
|
||||
**代码描述**:
|
||||
CustomOutputParser类继承自AgentOutputParser,是一个专门用于解析大模型输出的解析器。它通过分析模型的输出内容,来决定是继续执行某些操作,还是结束会话。具体来说,它会检查模型输出中是否包含特定的关键词或短语,如"Final Answer:"或"Action:",并据此返回相应的操作指令。
|
||||
|
||||
在初始化时,`begin`属性被设置为True,表示解析器准备开始解析输出。在`parse`方法中,首先检查是否所有支持的代理模型都不在模型容器中,并且`begin`为True。如果条件满足,它会查找输出中的停止词(如"Observation:"),并根据这些停止词截断输出,以准备进一步的解析。
|
||||
|
||||
如果输出中包含"Final Answer:",则表示大模型已经给出了最终答案,解析器将重置`begin`为True,并返回一个包含最终答案的AgentFinish对象。如果输出中包含"Action:",则解析器会解析出相应的操作和输入,尝试执行该操作,并返回一个AgentAction对象。如果解析过程中遇到异常,或者输出不符合预期的格式,解析器将返回一个包含错误信息的AgentFinish对象。
|
||||
|
||||
**注意**:
|
||||
- 在使用CustomOutputParser时,需要确保大模型的输出格式与解析器预期的格式相匹配,否则可能无法正确解析出操作指令。
|
||||
- 解析器依赖于输出中的特定关键词或短语来决定操作,因此在设计大模型的输出格式时,需要考虑这一点。
|
||||
|
||||
**输出示例**:
|
||||
假设大模型的输出为"Final Answer: 42",CustomOutputParser解析后可能返回的对象为:
|
||||
```
|
||||
AgentFinish(return_values={"output": "42"}, log="Final Answer: 42")
|
||||
```
|
||||
如果大模型的输出为"Action: Calculate Action Input: 42 + 1",解析后可能返回的对象为:
|
||||
```
|
||||
AgentAction(tool="Calculate", tool_input="42 + 1", log="Action: Calculate Action Input: 42 + 1")
|
||||
```
|
||||
|
||||
在项目中,CustomOutputParser被用于解析大模型在与用户交互过程中的输出,以决定是否需要调用特定的工具或服务来辅助完成用户的请求。这使得整个系统能够更加智能和灵活地处理各种不同的用户需求。
|
||||
### FunctionDef __init__(self)
|
||||
**__init__**: 该函数用于初始化CustomOutputParser对象。
|
||||
|
||||
**参数**: 该函数不接受任何外部参数。
|
||||
|
||||
**代码描述**: 在CustomOutputParser类的__init__方法中,首先通过`super().__init__()`调用父类的构造函数来确保父类被正确初始化。接着,该方法设置了一个实例变量`self.begin`并将其初始化为True。这个变量可能用于标记解析开始,或者用于控制某些只在初始化时需要执行的操作。
|
||||
|
||||
**注意**: 在使用CustomOutputParser类时,不需要手动传递任何参数给__init__方法。创建对象后,可以根据实际需求修改`self.begin`的值,但通常情况下,该变量的初始值True已足够满足大多数使用场景。此外,如果CustomOutputParser类继承自一个具有复杂初始化逻辑的父类,`super().__init__()`确保了这些逻辑不会被遗漏。
|
||||
***
|
||||
### FunctionDef parse(self, llm_output)
|
||||
**parse**: 此函数的功能是解析从大型语言模型(LLM)输出的文本,并根据输出内容决定下一步的操作。
|
||||
|
||||
**参数**:
|
||||
- `llm_output`: 字符串类型,代表从大型语言模型(LLM)接收到的输出文本。
|
||||
|
||||
**代码描述**:
|
||||
此函数首先检查是否有支持的代理模型存在于`model_container.MODEL`中,并且是否是开始解析。如果是开始解析且没有支持的代理模型,它会查找输出中的停止词(例如"Observation:"),并截取至第一个停止词之前的文本作为新的输出文本。
|
||||
|
||||
如果输出文本中包含"Final Answer:",则表示大型语言模型已经给出了最终答案。此时,函数会将"Final Answer:"之后的文本作为输出,并标记为解析结束。
|
||||
|
||||
如果输出文本中包含"Action:",则表示需要执行特定的动作。函数会解析出动作名称和动作输入,然后尝试执行该动作。如果执行成功,会返回一个`AgentAction`对象,包含动作名称、动作输入和原始日志。
|
||||
|
||||
如果上述条件都不满足,或者在解析动作时遇到异常,函数会返回一个`AgentFinish`对象,表示解析结束,同时包含错误信息或大模型自身的回答。
|
||||
|
||||
**注意**:
|
||||
- 在使用此函数时,需要确保`model_container.MODEL`和`SUPPORT_AGENT_MODEL`已正确设置,以便函数能够正确判断是否有支持的代理模型。
|
||||
- 函数的返回值类型可能是`AgentFinish`、`tuple[dict[str, str], str]`或`AgentAction`,调用者需要根据返回值类型进行相应的处理。
|
||||
|
||||
**输出示例**:
|
||||
假设`llm_output`为"Final Answer: 42",则函数可能返回的示例为:
|
||||
```python
|
||||
AgentFinish(return_values={"output": "42"}, log="Final Answer: 42")
|
||||
```
|
||||
|
||||
如果`llm_output`为"Action: Email Action Input: john.doe@example.com",则函数可能返回的示例为:
|
||||
```python
|
||||
AgentAction(tool="Email", tool_input="john.doe@example.com", log="Action: Email Action Input: john.doe@example.com")
|
||||
```
|
||||
***
|
||||
29
markdown_docs/server/agent/model_contain.md
Normal file
@ -0,0 +1,29 @@
|
||||
## ClassDef ModelContainer
|
||||
**ModelContainer**: ModelContainer 类的功能是作为模型和数据库的容器。
|
||||
|
||||
**属性**:
|
||||
- MODEL: 用于存储模型实例。初始值为 None,表示在创建 ModelContainer 实例时,并没有预设的模型。
|
||||
- DATABASE: 用于存储数据库连接实例。初始值同样为 None,表示在创建 ModelContainer 实例时,并没有预设的数据库连接。
|
||||
|
||||
**代码描述**:
|
||||
ModelContainer 类是一个简单的容器类,设计用来存储模型实例和数据库连接实例。这个类通过定义两个属性 `MODEL` 和 `DATABASE` 来实现其功能。这两个属性在类的初始化方法 `__init__` 中被设置为 None,这意味着在创建 ModelContainer 的实例时,这两个属性都不会持有任何值。这种设计允许开发者在创建 ModelContainer 实例后,根据需要将模型实例和数据库连接实例分别赋值给这两个属性。
|
||||
|
||||
**注意**:
|
||||
- 在使用 ModelContainer 类时,开发者需要注意,`MODEL` 和 `DATABASE` 属性在初始状态下是 None。因此,在尝试访问这些属性或其方法之前,需要确保它们已被正确赋值,以避免遇到 `NoneType` 对象没有该方法的错误。
|
||||
- ModelContainer 类提供了一种灵活的方式来管理模型和数据库连接,但它本身不提供任何方法来初始化 `MODEL` 和 `DATABASE` 属性。开发者需要根据自己的需求,手动为这两个属性赋值。
|
||||
- 由于 ModelContainer 类的设计相对简单,它可以根据项目的需要进行扩展,例如添加更多的属性或方法来满足更复杂的需求。
|
||||
### FunctionDef __init__(self)
|
||||
**__init__**: 此函数用于初始化ModelContainer类的实例。
|
||||
|
||||
**参数**: 此函数不接受任何外部参数。
|
||||
|
||||
**代码描述**: 在ModelContainer类的实例被创建时,`__init__`函数会被自动调用。此函数主要完成以下几点初始化操作:
|
||||
- 将`MODEL`属性设置为`None`。这意味着在实例化后,该属性暂时不关联任何模型,需要后续根据具体需求进行赋值。
|
||||
- 将`DATABASE`属性也设置为`None`。这表明在实例化的初始阶段,该属性不关联任何数据库,同样需要在后续操作中根据需要进行关联。
|
||||
|
||||
通过这种方式,`__init__`函数为ModelContainer类的实例提供了一个清晰、干净的初始状态,便于后续的属性赋值和方法调用。
|
||||
|
||||
**注意**:
|
||||
- 在使用ModelContainer类创建实例后,需要根据实际情况给`MODEL`和`DATABASE`属性赋予具体的模型和数据库实例,以便于进行后续的操作。
|
||||
- 由于`MODEL`和`DATABASE`在初始化时都被设置为`None`,在对这两个属性进行操作前,建议先检查它们是否已被正确赋值,以避免在使用未初始化的属性时引发错误。
|
||||
***
|
||||
36
markdown_docs/server/agent/tools/arxiv.md
Normal file
@ -0,0 +1,36 @@
|
||||
## FunctionDef arxiv(query)
|
||||
**arxiv**: 该函数用于执行对Arxiv的查询操作。
|
||||
|
||||
**参数**:
|
||||
- **query**: 字符串类型,表示要在Arxiv上执行的查询内容。
|
||||
|
||||
**代码描述**:
|
||||
`arxiv`函数是一个简单但功能强大的接口,用于在Arxiv数据库中执行查询。它首先创建了一个`ArxivQueryRun`的实例,然后调用该实例的`run`方法来执行查询。查询的具体内容由参数`query`指定,该参数应为一个字符串,表示用户希望在Arxiv上搜索的关键词或查询表达式。
|
||||
|
||||
在项目结构中,`arxiv`函数位于`server/agent/tools/arxiv.py`路径下,并且是`arxiv.py`模块中定义的核心功能之一。尽管在当前项目的其他部分,如`server/agent/tools/__init__.py`和`server/agent/tools_select.py`中没有直接的调用示例,但可以推断`arxiv`函数设计为被这些模块或其他项目部分调用,以实现对Arxiv数据库的查询功能。
|
||||
|
||||
**注意**:
|
||||
- 在使用`arxiv`函数时,需要确保传入的查询字符串`query`是有效的,即它应该符合Arxiv的查询语法和要求。
|
||||
- 该函数的执行结果依赖于`ArxivQueryRun`类的`run`方法的实现,因此需要确保该方法能够正确处理传入的查询字符串,并返回期望的查询结果。
|
||||
|
||||
**输出示例**:
|
||||
假设对`arxiv`函数的调用如下:
|
||||
```python
|
||||
result = arxiv("deep learning")
|
||||
```
|
||||
则该函数可能返回一个包含查询结果的对象,例如包含多篇关于深度学习的论文的列表。具体的返回值格式将取决于`ArxivQueryRun`类的`run`方法的实现细节。
|
||||
## ClassDef ArxivInput
|
||||
**ArxivInput**: ArxivInput类的功能是定义一个用于搜索查询的输入模型。
|
||||
|
||||
**属性**:
|
||||
- query: 表示搜索查询标题的字符串。
|
||||
|
||||
**代码描述**:
|
||||
ArxivInput类继承自BaseModel,这意味着它是一个模型类,用于定义数据结构。在这个类中,定义了一个名为`query`的属性,该属性是一个字符串类型,用于存储用户的搜索查询标题。通过使用`Field`函数,为`query`属性提供了一个描述,即"The search query title",这有助于理解该属性的用途。
|
||||
|
||||
在项目中,ArxivInput类作为一个数据模型,被用于处理与arXiv相关的搜索查询。尽管在提供的代码调用情况中没有直接的示例,但可以推断,该类可能会被用于在`server/agent/tools`目录下的其他模块中,作为接收用户搜索请求的输入参数。这样的设计使得代码更加模块化,便于维护和扩展。
|
||||
|
||||
**注意**:
|
||||
- 在使用ArxivInput类时,需要确保传入的`query`参数是一个有效的字符串,因为它将直接影响搜索结果的相关性和准确性。
|
||||
- 由于ArxivInput继承自BaseModel,可以利用Pydantic库提供的数据验证功能,确保输入数据的合法性。
|
||||
- 考虑到ArxivInput类可能会被用于网络请求,应当注意处理潜在的安全问题,如SQL注入或跨站脚本攻击(XSS),确保用户输入被适当地清理和验证。
|
||||