├── Dockerfile
├── Dockerfile.Base
├── LICENSE
├── README.md
├── __pycache__
└── config.cpython-39.pyc
├── app.py
├── chatllm.py
├── chinese_text_splitter.py
├── config.py
├── docs
├── deploy.md
├── faq.md
└── update_history.md
├── img
├── bg.jpg
├── demo.jpg
├── demo_hf.jpg
├── demo_ms.jpg
├── demo_new.jpg
└── wechat_group.jpg
├── jina_serving.py
├── model_cache
└── OfflineDeploy.md
├── modelscope
├── README.md
├── app.py
├── chatglm_llm.py
├── modelscope_hub.py
└── requirements.txt
├── nltk_data
├── taggers
│ └── averaged_perceptron_tagger
│ │ └── averaged_perceptron_tagger.pickle
└── tokenizers
│ └── punkt
│ ├── .DS_Store
│ ├── PY3
│ ├── README
│ ├── czech.pickle
│ ├── danish.pickle
│ ├── dutch.pickle
│ ├── english.pickle
│ ├── estonian.pickle
│ ├── finnish.pickle
│ ├── french.pickle
│ ├── german.pickle
│ ├── greek.pickle
│ ├── italian.pickle
│ ├── malayalam.pickle
│ ├── norwegian.pickle
│ ├── polish.pickle
│ ├── portuguese.pickle
│ ├── russian.pickle
│ ├── slovene.pickle
│ ├── spanish.pickle
│ ├── swedish.pickle
│ └── turkish.pickle
│ ├── README
│ ├── czech.pickle
│ ├── danish.pickle
│ ├── dutch.pickle
│ ├── english.pickle
│ ├── estonian.pickle
│ ├── finnish.pickle
│ ├── french.pickle
│ ├── german.pickle
│ ├── greek.pickle
│ ├── italian.pickle
│ ├── malayalam.pickle
│ ├── norwegian.pickle
│ ├── polish.pickle
│ ├── portuguese.pickle
│ ├── russian.pickle
│ ├── slovene.pickle
│ ├── spanish.pickle
│ ├── swedish.pickle
│ └── turkish.pickle
├── paddlepaddle
├── README.md
├── app.py
├── chatllm.py
├── cli.py
├── paddle_embedding.py
└── requirements.txt
├── poetry.lock
├── poetry.toml
├── pyproject.toml
└── requirements.txt
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM registry.cn-beijing.aliyuncs.com/public-development-resources/langchain-chatglm-webui:Base
2 | RUN mkdir -p /pretrainmodel/belle /pretrainmodel/vicuna /pretrainmodel/chatglm
3 | RUN git clone https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui.git /code
4 | WORKDIR /code
5 | RUN pip install -r requirements.txt
6 | CMD ["python3", "app.py"]
--------------------------------------------------------------------------------
/Dockerfile.Base:
--------------------------------------------------------------------------------
1 | FROM nvidia/cuda:11.7.1-devel-ubuntu22.04
2 | RUN apt-get update && \
3 | apt-get install --no-install-recommends -y git python3 python3-dev python3-pip build-essential libmagic-dev poppler-utils tesseract-ocr libreoffice vim libgl1-mesa-glx aria2 unzip && \
4 | rm -rf /var/lib/apt/lists/*
5 | WORKDIR /build
6 | RUN pip install --upgrade pip
7 | RUN pip install --user torch torchvision tensorboard cython PyPDF2 pdfrw -i https://pypi.tuna.tsinghua.edu.cn/simple
8 | COPY requirements.txt requirements.txt
9 | RUN pip install -r requirements.txt && rm -f requirements.txt
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |  [](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/graphs/contributors) [](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/issues) [](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/pulls)
15 |
16 |
17 |
18 |
19 |
20 | 视频链接 | 在线体验 | 部署文档| 更新日志 | 常见问题
21 |
22 |
23 |
24 | ## 🔥 项目体验
25 |
26 | 本项目提供基于[HuggingFace社区](https://huggingface.co/spaces/thomas-yanxin/LangChain-ChatLLM)、[OpenXLab](https://openxlab.org.cn/apps/detail/thomas-yanxin/LangChain-ChatLLM)、[ModelScope魔搭社区](https://modelscope.cn/studios/AI-ModelScope/LangChain-ChatLLM/summary)、[飞桨AIStudio社区](https://aistudio.baidu.com/aistudio/projectdetail/6195067)的在线体验, 欢迎尝试和反馈!
27 |
28 | ## 👏 项目介绍
29 |
30 | 受[langchain-ChatGLM](https://github.com/imClumsyPanda/langchain-ChatGLM)启发, 利用LangChain和ChatGLM-6B系列模型制作的Webui, 提供基于本地知识的大模型应用.
31 |
32 | 目前支持上传 txt、docx、md、pdf等文本格式文件, 提供包括ChatGLM-6B系列、Belle系列等模型文件以及[GanymedeNil/text2vec-large-chinese](https://huggingface.co/GanymedeNil/text2vec-large-chinese)、[nghuyong/ernie-3.0-base-zh](https://huggingface.co/nghuyong/ernie-3.0-base-zh)、[nghuyong/ernie-3.0-nano-zh](https://huggingface.co/nghuyong/ernie-3.0-nano-zh)等Embedding模型.
33 |
34 | HuggingFace效果
35 |
36 | 
37 |
38 |
39 | ModelScope效果
40 |
41 | 
42 |
43 |
44 |
45 | ## 🚀 使用方式
46 |
47 | 提供ModelScope版本和HuggingFace版本.
48 | **需要Python>=3.8.1**
49 |
50 | 详细部署教程可参考: [部署文档](./docs/deploy.md) | [视频教程](https://www.bilibili.com/video/BV1No4y1b7eu/)
51 |
52 | ### 支持模型
53 |
54 | 若存在网络问题可在[此找到本项目涉及的所有模型](https://openi.pcl.ac.cn/Learning-Develop-Union/LangChain-ChatGLM-Webui/datasets):
55 | | large language model | Embedding model |
56 | | :----: | :----: |
57 | | ChatGLM-6B | text2vec-large-chinese |
58 | | ChatGLM-6B-int8 | ernie-3.0-base-zh |
59 | | ChatGLM-6B-int4 | ernie-3.0-nano-zh |
60 | | ChatGLM-6B-int4-qe | ernie-3.0-xbase-zh |
61 | | Vicuna-7b-1.1 | simbert-base-chinese |
62 | | Vicuna-13b-1.1 | paraphrase-multilingual-MiniLM-L12-v2 |
63 | | BELLE-LLaMA-7B-2M | |
64 | | BELLE-LLaMA-13B-2M | |
65 | | internlm-chat-7b-8k | |
66 | | internlm-chat-7b-v1_1 | |
67 | | internlm-chat-7b | |
68 |
69 | ## 💪 更新日志
70 |
71 | 详情请见: [更新日志](./docs/update_history.md)
72 |
73 | 项目处于初期阶段, 有很多可以做的地方和优化的空间, 欢迎感兴趣的社区大佬们一起加入!
74 |
75 | ## ❤️ 引用
76 |
77 | 1. [ChatGLM-6B](https://github.com/THUDM/ChatGLM-6B): ChatGLM-6B: 开源双语对话语言模型
78 | 2. [LangChain](https://github.com/hwchase17/langchain): Building applications with LLMs through composability
79 | 3. [langchain-ChatGLM](https://github.com/imClumsyPanda/langchain-ChatGLM): 基于本地知识的 ChatGLM 应用实现
80 | ChatGLM论文引用
81 |
82 | ```
83 | @inproceedings{
84 | zeng2023glm-130b,
85 | title={{GLM}-130B: An Open Bilingual Pre-trained Model},
86 | author={Aohan Zeng and Xiao Liu and Zhengxiao Du and Zihan Wang and Hanyu Lai and Ming Ding and Zhuoyi Yang and Yifan Xu and Wendi Zheng and Xiao Xia and Weng Lam Tam and Zixuan Ma and Yufei Xue and Jidong Zhai and Wenguang Chen and Zhiyuan Liu and Peng Zhang and Yuxiao Dong and Jie Tang},
87 | booktitle={The Eleventh International Conference on Learning Representations (ICLR)},
88 | year={2023},
89 | url={https://openreview.net/forum?id=-Aw0rrrPUF}
90 | }
91 | ```
92 |
93 | ```
94 | @inproceedings{du2022glm,
95 | title={GLM: General Language Model Pretraining with Autoregressive Blank Infilling},
96 | author={Du, Zhengxiao and Qian, Yujie and Liu, Xiao and Ding, Ming and Qiu, Jiezhong and Yang, Zhilin and Tang, Jie},
97 | booktitle={Proceedings of the 60th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)},
98 | pages={320--335},
99 | year={2022}
100 | }
101 | ```
102 |
103 |
104 | BELLE论文引用
105 |
106 | ```
107 | @misc{BELLE,
108 | author = {Yunjie Ji, Yong Deng, Yan Gong, Yiping Peng, Qiang Niu, Baochang Ma and Xiangang Li},
109 | title = {BELLE: Be Everyone's Large Language model Engine },
110 | year = {2023},
111 | publisher = {GitHub},
112 | journal = {GitHub repository},
113 | howpublished = {\url{https://github.com/LianjiaTech/BELLE}},
114 | }
115 | @article{belle2023exploring,
116 | title={Exploring the Impact of Instruction Data Scaling on Large Language Models: An Empirical Study on Real-World Use Cases},
117 | author={Yunjie Ji, Yong Deng, Yan Gong, Yiping Peng, Qiang Niu, Lei Zhang, Baochang Ma, Xiangang Li},
118 | journal={arXiv preprint arXiv:2303.14742},
119 | year={2023}
120 | }
121 | ```
122 |
123 |
124 |
125 | ## 🙇 感谢
126 |
127 | 1. [langchain-ChatGLM](https://github.com/imClumsyPanda/langchain-ChatGLM)提供的基础框架
128 | 2. [魔搭ModelScope](https://modelscope.cn/home)提供展示空间
129 | 3. [OpenI启智社区](https://openi.pcl.ac.cn/)提供调试算力
130 | 4. [langchain-serve](https://github.com/jina-ai/langchain-serve)提供十分简易的Serving方式
131 | 5. 除此以外, 感谢来自社区的同学们对本项目的关注和支持!
132 |
133 |
134 |
135 |
136 | ## 🌟 Star History
137 |
138 | [](https://star-history.com/#thomas-yanxin/LangChain-ChatGLM-Webui&Date)
139 |
140 | ## 😊 加群沟通
141 |
142 |
143 |
--------------------------------------------------------------------------------
/__pycache__/config.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/__pycache__/config.cpython-39.pyc
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | import os
2 | from typing import List
3 |
4 | import gradio as gr
5 | import nltk
6 | import sentence_transformers
7 | from duckduckgo_search import ddg
8 | from duckduckgo_search.utils import SESSION
9 | from langchain.chains import RetrievalQA
10 | from langchain_community.document_loaders import UnstructuredFileLoader
11 | from langchain.embeddings.huggingface import HuggingFaceEmbeddings
12 | from langchain.prompts import PromptTemplate
13 | from langchain.prompts.prompt import PromptTemplate
14 | from langchain_community.vectorstores import FAISS
15 |
16 | from chatllm import ChatLLM
17 | from chinese_text_splitter import ChineseTextSplitter
18 | from config import *
19 | import torch
20 |
21 | nltk.data.path = [os.path.join(os.path.dirname(__file__), "nltk_data")
22 | ] + nltk.data.path
23 |
24 | embedding_model_dict = embedding_model_dict
25 | llm_model_dict = llm_model_dict
26 | EMBEDDING_DEVICE = EMBEDDING_DEVICE
27 | LLM_DEVICE = LLM_DEVICE
28 | num_gpus = num_gpus
29 | init_llm = init_llm
30 | init_embedding_model = init_embedding_model
31 |
32 | llm_model_list = []
33 | llm_model_dict = llm_model_dict
34 |
35 | for i in llm_model_dict:
36 | for j in llm_model_dict[i]:
37 | llm_model_list.append(j)
38 |
39 |
40 | def search_web(query):
41 |
42 | SESSION.proxies = {
43 | "http": f"socks5h://localhost:7890",
44 | "https": f"socks5h://localhost:7890"
45 | }
46 | results = ddg(query)
47 | web_content = ''
48 | if results:
49 | for result in results:
50 | web_content += result['body']
51 | return web_content
52 |
53 |
54 | class KnowledgeBasedChatLLM:
55 |
56 | llm: object = None
57 | embeddings: object = None
58 |
59 | def init_model_config(
60 | self,
61 | large_language_model: str = init_llm,
62 | embedding_model: str = init_embedding_model,
63 | ):
64 |
65 | self.embeddings = HuggingFaceEmbeddings(
66 | model_name=embedding_model_dict[embedding_model], )
67 | self.embeddings.client = sentence_transformers.SentenceTransformer(
68 | self.embeddings.model_name,
69 | device=EMBEDDING_DEVICE,
70 | cache_folder=os.path.join(MODEL_CACHE_PATH, self.embeddings.model_name),
71 | trust_remote_code=True
72 | )
73 | self.llm = None
74 | torch.cuda.empty_cache()
75 | self.llm = ChatLLM()
76 | if 'chatglm2' in large_language_model.lower():
77 | self.llm.model_type = 'chatglm2'
78 | self.llm.model_name_or_path = llm_model_dict['chatglm2'][
79 | large_language_model]
80 | elif 'chatglm' in large_language_model.lower():
81 | self.llm.model_type = 'chatglm'
82 | self.llm.model_name_or_path = llm_model_dict['chatglm'][
83 | large_language_model]
84 | elif 'belle' in large_language_model.lower():
85 | self.llm.model_type = 'belle'
86 | self.llm.model_name_or_path = llm_model_dict['belle'][
87 | large_language_model]
88 | elif 'vicuna' in large_language_model.lower():
89 | self.llm.model_type = 'vicuna'
90 | self.llm.model_name_or_path = llm_model_dict['vicuna'][
91 | large_language_model]
92 | elif 'internlm' in large_language_model.lower():
93 | self.llm.model_type = 'internlm'
94 | self.llm.model_name_or_path = llm_model_dict['internlm'][
95 | large_language_model]
96 | elif 'yuan2' in large_language_model.lower():
97 | self.llm.model_type = 'yuan2'
98 | self.llm.model_name_or_path = llm_model_dict['yuan2'][large_language_model]
99 |
100 | self.llm.load_llm(llm_device=LLM_DEVICE, num_gpus=num_gpus)
101 |
102 | def init_knowledge_vector_store(self, filepath):
103 |
104 | docs = self.load_file(filepath)
105 |
106 | vector_store = FAISS.from_documents(docs, self.embeddings)
107 | vector_store.save_local('faiss_index')
108 | return vector_store
109 |
110 | def get_knowledge_based_answer(self,
111 | query,
112 | web_content,
113 | top_k: int = 6,
114 | history_len: int = 3,
115 | temperature: float = 0.01,
116 | top_p: float = 0.1,
117 | history=[]):
118 | self.llm.temperature = temperature
119 | self.llm.top_p = top_p
120 | self.history_len = history_len
121 | self.top_k = top_k
122 | if web_content:
123 | prompt_template = f"""基于以下已知信息,简洁和专业的来回答用户的问题。
124 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息",不允许在答案中添加编造成分,答案请使用中文。
125 | 已知网络检索内容:{web_content}""" + """
126 | 已知内容:
127 | {context}
128 | 问题:
129 | {question}"""
130 | else:
131 | prompt_template = """基于以下已知信息,请简洁并专业地回答用户的问题。
132 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息"。不允许在答案中添加编造成分。另外,答案请使用中文。
133 |
134 | 已知内容:
135 | {context}
136 |
137 | 问题:
138 | {question}"""
139 | prompt = PromptTemplate(template=prompt_template,
140 | input_variables=["context", "question"])
141 | self.llm.history = history[
142 | -self.history_len:] if self.history_len > 0 else []
143 | vector_store = FAISS.load_local('faiss_index', self.embeddings)
144 |
145 | knowledge_chain = RetrievalQA.from_llm(
146 | llm=self.llm,
147 | retriever=vector_store.as_retriever(
148 | search_kwargs={"k": self.top_k}),
149 | prompt=prompt)
150 | knowledge_chain.combine_documents_chain.document_prompt = PromptTemplate(
151 | input_variables=["page_content"], template="{page_content}")
152 |
153 | knowledge_chain.return_source_documents = True
154 |
155 | result = knowledge_chain({"query": query})
156 | return result
157 |
158 | def load_file(self, filepath):
159 | if filepath.lower().endswith(".md"):
160 | loader = UnstructuredFileLoader(filepath, mode="elements")
161 | docs = loader.load()
162 | elif filepath.lower().endswith(".pdf"):
163 | loader = UnstructuredFileLoader(filepath)
164 | textsplitter = ChineseTextSplitter(pdf=True)
165 | docs = loader.load_and_split(textsplitter)
166 | elif filepath.lower().endswith(".txt"):
167 | loader = UnstructuredFileLoader(filepath,encoding='utf8')
168 | textsplitter = ChineseTextSplitter(pdf=False)
169 | docs = loader.load_and_split(textsplitter)
170 | else:
171 | loader = UnstructuredFileLoader(filepath, mode="elements")
172 | textsplitter = ChineseTextSplitter(pdf=False)
173 | docs = loader.load_and_split(text_splitter=textsplitter)
174 | return docs
175 |
176 |
177 | def update_status(history, status):
178 | history = history + [[None, status]]
179 | print(status)
180 | return history
181 |
182 |
183 | knowladge_based_chat_llm = KnowledgeBasedChatLLM()
184 |
185 |
186 | def init_model():
187 | try:
188 | print("开始加载模型配置")
189 | knowladge_based_chat_llm.init_model_config()
190 | print("模型配置加载成功")
191 | knowladge_based_chat_llm.llm._call("你好")
192 | return """初始模型已成功加载,可以开始对话"""
193 | except Exception as e:
194 | print(f"加载模型出错: {e}") # 打印详细的异常信息
195 | return """模型未成功加载,请重新选择模型后点击"重新加载模型"按钮"""
196 |
197 |
198 | def clear_session():
199 | return '', None
200 |
201 |
202 | def reinit_model(large_language_model, embedding_model, history):
203 | try:
204 | knowladge_based_chat_llm.init_model_config(
205 | large_language_model=large_language_model,
206 | embedding_model=embedding_model)
207 | model_status = """模型已成功重新加载,可以开始对话"""
208 | except Exception as e:
209 |
210 | model_status = """模型未成功重新加载,请点击重新加载模型"""
211 | return history + [[None, model_status]]
212 |
213 |
214 | def init_vector_store(file_obj):
215 |
216 | vector_store = knowladge_based_chat_llm.init_knowledge_vector_store(
217 | file_obj.name)
218 |
219 | return vector_store
220 |
221 |
222 | def predict(input,
223 | use_web,
224 | top_k,
225 | history_len,
226 | temperature,
227 | top_p,
228 | history=None):
229 | if history == None:
230 | history = []
231 |
232 | if use_web == 'True':
233 | web_content = search_web(query=input)
234 | else:
235 | web_content = ''
236 |
237 | resp = knowladge_based_chat_llm.get_knowledge_based_answer(
238 | query=input,
239 | web_content=web_content,
240 | top_k=top_k,
241 | history_len=history_len,
242 | temperature=temperature,
243 | top_p=top_p,
244 | history=history)
245 | history.append((input, resp['result']))
246 | return '', history, history
247 |
248 |
249 | model_status = init_model()
250 |
251 | if __name__ == "__main__":
252 | block = gr.Blocks()
253 | with block as demo:
254 |
255 | gr.Markdown("""LangChain-ChatLLM-Webui
256 |
257 | 本项目基于LangChain和大型语言模型系列模型, 提供基于本地知识的自动问答应用.
258 | 目前项目提供基于ChatGLM-6B 的LLM和包括GanymedeNil/text2vec-large-chinese、nghuyong/ernie-3.0-base-zh、nghuyong/ernie-3.0-nano-zh在内的多个Embedding模型, 支持上传 txt、docx、md、pdf等文本格式文件.
259 | 后续将提供更加多样化的LLM、Embedding和参数选项供用户尝试, 欢迎关注Github地址.
260 |
261 | """)
262 | model_status = gr.State(model_status)
263 | with gr.Row():
264 | with gr.Column(scale=1):
265 | model_choose = gr.Accordion("模型选择")
266 | with model_choose:
267 | large_language_model = gr.Dropdown(
268 | llm_model_list,
269 | label="large language model",
270 | value=init_llm)
271 |
272 | embedding_model = gr.Dropdown(list(
273 | embedding_model_dict.keys()),
274 | label="Embedding model",
275 | value=init_embedding_model)
276 | load_model_button = gr.Button("重新加载模型")
277 | model_argument = gr.Accordion("模型参数配置")
278 | with model_argument:
279 |
280 | top_k = gr.Slider(1,
281 | 10,
282 | value=6,
283 | step=1,
284 | label="vector search top k",
285 | interactive=True)
286 |
287 | history_len = gr.Slider(0,
288 | 5,
289 | value=3,
290 | step=1,
291 | label="history len",
292 | interactive=True)
293 |
294 | temperature = gr.Slider(0,
295 | 1,
296 | value=0.01,
297 | step=0.01,
298 | label="temperature",
299 | interactive=True)
300 | top_p = gr.Slider(0,
301 | 1,
302 | value=0.9,
303 | step=0.1,
304 | label="top_p",
305 | interactive=True)
306 |
307 | file = gr.File(label='请上传知识库文件',
308 | file_types=['.txt', '.md', '.docx', '.pdf'])
309 |
310 | init_vs = gr.Button("知识库文件向量化")
311 |
312 | use_web = gr.Radio(["True", "False"],
313 | label="Web Search",
314 | value="False")
315 |
316 | with gr.Column(scale=4):
317 | chatbot = gr.Chatbot([[None, model_status.value]],
318 | label='ChatLLM').style(height=750)
319 | message = gr.Textbox(label='请输入问题')
320 | state = gr.State()
321 |
322 | with gr.Row():
323 | clear_history = gr.Button("🧹 清除历史对话")
324 | send = gr.Button("🚀 发送")
325 |
326 | load_model_button.click(
327 | reinit_model,
328 | show_progress=True,
329 | inputs=[large_language_model, embedding_model, chatbot],
330 | outputs=chatbot,
331 | )
332 | init_vs.click(
333 | init_vector_store,
334 | show_progress=True,
335 | inputs=[file],
336 | outputs=[],
337 | )
338 |
339 | send.click(predict,
340 | inputs=[
341 | message, use_web, top_k, history_len, temperature,
342 | top_p, state
343 | ],
344 | outputs=[message, chatbot, state])
345 | clear_history.click(fn=clear_session,
346 | inputs=[],
347 | outputs=[chatbot, state],
348 | queue=False)
349 |
350 | message.submit(predict,
351 | inputs=[
352 | message, use_web, top_k, history_len,
353 | temperature, top_p, state
354 | ],
355 | outputs=[message, chatbot, state])
356 | gr.Markdown("""提醒:
357 | 1. 使用时请先上传自己的知识文件,并且文件中不含某些特殊字符,否则将返回error.
358 | 2. 有任何使用问题,请通过[Github Issue区](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/issues)进行反馈.
359 | """)
360 | # threads to consume the request
361 | demo.queue(concurrency_count=3) \
362 | .launch(server_name='0.0.0.0', # ip for listening, 0.0.0.0 for every inbound traffic, 127.0.0.1 for local inbound
363 | server_port=7860, # the port for listening
364 | show_api=False, # if display the api document
365 | share=False, # if register a public url
366 | inbrowser=False) # if browser would be open automatically
367 |
--------------------------------------------------------------------------------
/chatllm.py:
--------------------------------------------------------------------------------
1 | import os
2 | from typing import Dict, List, Optional, Tuple, Union
3 |
4 | import torch
5 | from fastchat.conversation import (compute_skip_echo_len,
6 | get_default_conv_template)
7 | from fastchat.serve.inference import load_model as load_fastchat_model
8 | from langchain.llms.base import LLM
9 | from langchain.llms.utils import enforce_stop_tokens
10 | from transformers import AutoModel, AutoModelForCausalLM, AutoTokenizer
11 |
12 | from config import *
13 |
14 | os.environ["TOKENIZERS_PARALLELISM"] = "false"
15 |
16 | DEVICE = LLM_DEVICE
17 | DEVICE_ID = "0"
18 | CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE
19 |
20 | init_llm = init_llm
21 | init_embedding_model = init_embedding_model
22 |
23 | def torch_gc():
24 | if torch.cuda.is_available():
25 | with torch.cuda.device(CUDA_DEVICE):
26 | torch.cuda.empty_cache()
27 | torch.cuda.ipc_collect()
28 |
29 |
30 | def auto_configure_device_map(num_gpus: int) -> Dict[str, int]:
31 | num_trans_layers = 28
32 | per_gpu_layers = 30 / num_gpus
33 |
34 | device_map = {
35 | 'transformer.word_embeddings': 0,
36 | 'transformer.final_layernorm': 0,
37 | 'lm_head': 0
38 | }
39 |
40 | used = 2
41 | gpu_target = 0
42 | for i in range(num_trans_layers):
43 | if used >= per_gpu_layers:
44 | gpu_target += 1
45 | used = 0
46 | assert gpu_target < num_gpus
47 | device_map[f'transformer.layers.{i}'] = gpu_target
48 | used += 1
49 |
50 | return device_map
51 |
52 |
53 | class ChatLLM(LLM):
54 | max_token: int = 10000
55 | temperature: float = 0.1
56 | top_p = 0.9
57 | history = []
58 | model_type: str = "chatglm"
59 | model_name_or_path: str = init_llm,
60 | tokenizer: object = None
61 | model: object = None
62 |
63 | def __init__(self):
64 | super().__init__()
65 |
66 | @property
67 | def _llm_type(self) -> str:
68 | return "ChatLLM"
69 |
70 | def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
71 |
72 | if self.model_type == 'vicuna':
73 | conv = get_default_conv_template(self.model_name_or_path).copy()
74 | conv.append_message(conv.roles[0], prompt)
75 | conv.append_message(conv.roles[1], None)
76 | prompt = conv.get_prompt()
77 | inputs = self.tokenizer([prompt])
78 | output_ids = self.model.generate(
79 | torch.as_tensor(inputs.input_ids).cuda(),
80 | do_sample=True,
81 | temperature=self.temperature,
82 | max_new_tokens=self.max_token,
83 | )
84 | outputs = self.tokenizer.batch_decode(output_ids, skip_special_tokens=True)[0]
85 | skip_echo_len = compute_skip_echo_len(self.model_name_or_path, conv, prompt)
86 | response = outputs[skip_echo_len:]
87 | torch_gc()
88 | if stop is not None:
89 | response = enforce_stop_tokens(response, stop)
90 | self.history = [[None, response]]
91 |
92 | elif self.model_type == 'belle':
93 | prompt = "Human: "+ prompt +" \n\nAssistant: "
94 | input_ids = self.tokenizer(prompt, return_tensors="pt").input_ids.to(DEVICE)
95 | generate_ids = self.model.generate(input_ids, max_new_tokens=self.max_token, do_sample = True, top_k = 30, top_p = self.top_p, temperature = self.temperature, repetition_penalty=1., eos_token_id=2, bos_token_id=1, pad_token_id=0)
96 | output = self.tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
97 | response = output[len(prompt)+1:]
98 | torch_gc()
99 | if stop is not None:
100 | response = enforce_stop_tokens(response, stop)
101 | self.history = [[None, response]]
102 |
103 | elif self.model_type == 'chatglm2':
104 | response, _ = self.model.chat(
105 | self.tokenizer,
106 | prompt,
107 | history=self.history,
108 | max_length=self.max_token,
109 | temperature=self.temperature,
110 | top_p = self.top_p,
111 | )
112 | torch_gc()
113 | if stop is not None:
114 | response = enforce_stop_tokens(response, stop)
115 | self.history = self.history + [[None, response]]
116 |
117 | elif self.model_type == 'chatglm':
118 | response, _ = self.model.chat(
119 | self.tokenizer,
120 | prompt,
121 | history=self.history,
122 | max_length=self.max_token,
123 | temperature=self.temperature,
124 | )
125 | torch_gc()
126 | if stop is not None:
127 | response = enforce_stop_tokens(response, stop)
128 | self.history = self.history + [[None, response]]
129 | elif self.model_type == 'internlm':
130 | response, _ = self.model.chat(self.tokenizer, prompt, history=self.history, max_length=self.max_token, temperature=self.temperature)
131 |
132 | elif self.model_type == 'yuan2':
133 | inputs = self.tokenizer(prompt, return_tensors="pt").to(DEVICE)
134 | outputs = self.model.generate(inputs.input_ids, max_length=self.max_token, do_sample=True,
135 | temperature=self.temperature)
136 | output = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
137 | response = output[len(prompt)+1:]
138 | torch_gc()
139 | if stop is not None:
140 | response = enforce_stop_tokens(response, stop)
141 | self.history = self.history + [[None, response]]
142 |
143 | return response
144 |
145 |
146 | def load_llm(self,
147 | llm_device=DEVICE,
148 | num_gpus='auto',
149 | device_map: Optional[Dict[str, int]] = None,
150 | **kwargs):
151 | if 'chatglm2' in self.model_name_or_path.lower():
152 | self.tokenizer = AutoTokenizer.from_pretrained(self.model_name_or_path,
153 | trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path))
154 | if torch.cuda.is_available() and llm_device.lower().startswith("cuda"):
155 |
156 | num_gpus = torch.cuda.device_count()
157 | if num_gpus < 2 and device_map is None:
158 | self.model = (AutoModel.from_pretrained(
159 | self.model_name_or_path, trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path),
160 | **kwargs).half().cuda())
161 | else:
162 | from accelerate import dispatch_model
163 |
164 | model = AutoModel.from_pretrained(self.model_name_or_path,
165 | trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path),
166 | **kwargs).half()
167 |
168 | if device_map is None:
169 | device_map = auto_configure_device_map(num_gpus)
170 |
171 | self.model = dispatch_model(model, device_map=device_map)
172 | else:
173 | self.model = (AutoModel.from_pretrained(
174 | self.model_name_or_path,
175 | trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path)).float().to(llm_device))
176 | self.model = self.model.eval()
177 |
178 | elif 'chatglm' in self.model_name_or_path.lower():
179 | self.tokenizer = AutoTokenizer.from_pretrained(self.model_name_or_path,
180 | trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path))
181 | if torch.cuda.is_available() and llm_device.lower().startswith("cuda"):
182 |
183 | num_gpus = torch.cuda.device_count()
184 | if num_gpus < 2 and device_map is None:
185 | self.model = (AutoModel.from_pretrained(
186 | self.model_name_or_path, trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path),
187 | **kwargs).half().cuda())
188 | else:
189 | from accelerate import dispatch_model
190 |
191 | model = AutoModel.from_pretrained(self.model_name_or_path,
192 | trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path),
193 | **kwargs).half()
194 |
195 | if device_map is None:
196 | device_map = auto_configure_device_map(num_gpus)
197 |
198 | self.model = dispatch_model(model, device_map=device_map)
199 | else:
200 | self.model = (AutoModel.from_pretrained(
201 | self.model_name_or_path,
202 | trust_remote_code=True, cache_dir=os.path.join(MODEL_CACHE_PATH, self.model_name_or_path)).float().to(llm_device))
203 | self.model = self.model.eval()
204 |
205 | elif 'internlm' in self.model_name_or_path.lower():
206 |
207 | self.tokenizer = AutoTokenizer.from_pretrained(self.model_name_or_path, trust_remote_code=True)
208 | self.model = AutoModelForCausalLM.from_pretrained(self.model_name_or_path, trust_remote_code=True).cuda()
209 | self.model = self.model.eval()
210 |
211 | elif 'yuan2' in self.model_name_or_path.lower():
212 | self.tokenizer = AutoTokenizer.from_pretrained(self.model_name_or_path, trust_remote_code=True)
213 | self.model = AutoModelForCausalLM.from_pretrained(self.model_name_or_path, device_map='auto',
214 | torch_dtype=torch.bfloat16, trust_remote_code=True)
215 | self.model = self.model.eval()
216 |
217 | else:
218 | self.model, self.tokenizer = load_fastchat_model(
219 | model_path = self.model_name_or_path,
220 | device = llm_device,
221 | num_gpus = num_gpus
222 | )
223 |
224 |
--------------------------------------------------------------------------------
/chinese_text_splitter.py:
--------------------------------------------------------------------------------
1 | import re
2 | from typing import List
3 |
4 | from langchain.text_splitter import CharacterTextSplitter
5 |
6 |
7 | class ChineseTextSplitter(CharacterTextSplitter):
8 | def __init__(self, pdf: bool = False, **kwargs):
9 | super().__init__(**kwargs)
10 | self.pdf = pdf
11 |
12 | def split_text(self, text: str) -> List[str]:
13 | if self.pdf:
14 | text = re.sub(r"\n{3,}", "\n", text)
15 | text = re.sub('\s', ' ', text)
16 | text = text.replace("\n\n", "")
17 | sent_sep_pattern = re.compile(
18 | '([﹒﹔﹖﹗.。!?]["’”」』]{0,2}|(?=["‘“「『]{1,2}|$))')
19 | sent_list = []
20 | for ele in sent_sep_pattern.split(text):
21 | if sent_sep_pattern.match(ele) and sent_list:
22 | sent_list[-1] += ele
23 | elif ele:
24 | sent_list.append(ele)
25 | return sent_list
26 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import torch
4 |
5 | # device config
6 | EMBEDDING_DEVICE = "cuda" if torch.cuda.is_available(
7 | ) else "mps" if torch.backends.mps.is_available() else "cpu"
8 | LLM_DEVICE = "cuda" if torch.cuda.is_available(
9 | ) else "mps" if torch.backends.mps.is_available() else "cpu"
10 | num_gpus = torch.cuda.device_count()
11 |
12 | # model cache config
13 | MODEL_CACHE_PATH = os.path.join(os.path.dirname(__file__), 'model_cache')
14 |
15 |
16 | # vector storage config
17 | VECTOR_STORE_PATH='./vector_store'
18 | COLLECTION_NAME='my_collection'
19 |
20 |
21 | # init model config
22 | init_llm = "ChatGLM2-6B"
23 | init_embedding_model = "text2vec-base"
24 |
25 | # model config
26 | embedding_model_dict = {
27 | "ernie-tiny": "nghuyong/ernie-3.0-nano-zh",
28 | "ernie-base": "nghuyong/ernie-3.0-base-zh",
29 | "ernie-medium": "nghuyong/ernie-3.0-medium-zh",
30 | "ernie-xbase": "nghuyong/ernie-3.0-xbase-zh",
31 | "text2vec-base": "GanymedeNil/text2vec-base-chinese",
32 | 'simbert-base-chinese': 'WangZeJun/simbert-base-chinese',
33 | 'paraphrase-multilingual-MiniLM-L12-v2': "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
34 | "jina-embeddings-v2-base-zh": "jinaai/jina-embeddings-v2-base-zh",
35 | "bge-m3":"BAAI/bge-m3 "
36 | }
37 |
38 |
39 | llm_model_dict = {
40 | "chatglm2": {
41 | "ChatGLM2-6B": "THUDM/chatglm2-6b",
42 | "ChatGLM2-6B-int4": "THUDM/chatglm2-6b-int4",
43 | },
44 | "chatglm": {
45 | "ChatGLM-6B": "THUDM/chatglm-6b",
46 | "ChatGLM-6B-int4": "THUDM/chatglm-6b-int4",
47 | "ChatGLM-6B-int8": "THUDM/chatglm-6b-int8",
48 | "ChatGLM-6b-int4-qe": "THUDM/chatglm-6b-int4-qe"
49 | },
50 | "belle": {
51 | "BELLE-LLaMA-Local": "/pretrainmodel/belle",
52 | },
53 | "vicuna": {
54 | "Vicuna-Local": "/pretrainmodel/vicuna",
55 | },
56 | "internlm": {
57 | "internlm-chat-7b-8k": "internlm/internlm-chat-7b-8k",
58 | "internlm-chat-7b": "internlm/internlm-chat-7b",
59 | "internlm-chat-7b-v1_1": "internlm/internlm-chat-7b-v1_1",
60 | }
61 | "yuan2":{
62 | "Yuan2-2B-hf":"IEITYuan/Yuan2-2B-hf"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/docs/deploy.md:
--------------------------------------------------------------------------------
1 | # 部署文档
2 |
3 | ## 直接安装
4 |
5 | ### 环境准备
6 |
7 | **项目需要Python>=3.8.1, 默认已安装torch**
8 |
9 | 1. git clone本项目, 您可以在自己的terminal中执行: `git clone https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui.git`. 若国内用户访问Github存在网络问题, 也可以执行: `https://openi.pcl.ac.cn/Learning-Develop-Union/LangChain-ChatGLM-Webui.git`
10 | 2. 进入本项目目录:`cd LangChain-ChatGLM-Webui`
11 | 3. 安装依赖包:`pip install -r requirements.txt`, 国内用户可设置清华源加速下载.
12 |
13 | 另: 若您想要安装测试ModelScope版本, 需要额外安装ModelScope包: `pip install modelscope==1.4.3 -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html `
14 |
15 | [OpenI启智社区](https://openi.pcl.ac.cn/Learning-Develop-Union/LangChain-ChatGLM-Webui)部署推荐的Docker镜像: `dockerhub.pcl.ac.cn:5000/user-images/openi:LangChain-ChatLLM-2.0`
16 |
17 | ### 启动程序
18 |
19 | * Huggingface版本
20 |
21 | 在terminal中执行命令: `python3 app.py`
22 |
23 | * ModelScope版本
24 |
25 | 1. 进入modelscope文件目录:`cd modelscope`
26 | 2. 执行命令:`python3 app.py`
27 |
28 | ## Docker 基础环境运行
29 |
30 | 1. 运行镜像:`docker run -it --rm --runtime=nvidia --gpus all --network host registry.cn-beijing.aliyuncs.com/public-development-resources/langchain-chatglm-webui:Base bash`
31 | 2. git clone项目: `git clone https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui.git`
32 | 3. 进入本项目目录:`cd LangChain-ChatGLM-Webui`
33 | 4. 安装依赖包:`pip3 install -r requirements.txt`
34 | 5. 执行app.py:`python3 app.py`
35 |
36 | ## Docker 小白运行
37 |
38 | 1. 运行镜像:`docker run -d --name langchain-ChatGLM-webui --runtime=nvidia --gpus all --network host registry.cn-beijing.aliyuncs.com/public-development-resources/langchain-chatglm-webui:latest`
39 | 2. 访问服务:`http://ip:7860`
40 | 3. 运行环境,镜像大小约14G。
41 | 4. nvidia-runtime 请参考: [container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)
42 | 5. 本地模型放置目录:
43 | BELLE-LLaMA-Local:/pretrainmodel/belle
44 | Vicuna-Local:/pretrainmodel/vicuna
45 | ChatGLM-Local:/pretrainmodel/chatglm
46 |
47 | 6. 挂载cache目录,容器重启或更新无需重新下载相关模型。
48 | `-v langchain-ChatGLM-webui-cache:/root/.cache/`
49 |
50 | ## Jina Serving API
51 |
52 | 1. 启动服务:`lc-serve deploy local jina_serving`
53 |
54 | 2. 执行curl初始化模型命令
55 |
56 | ```bash
57 | curl -X 'POST' \
58 | 'http://localhost:8080/reinit_model' \
59 | -H 'accept: application/json' \
60 | -H 'Content-Type: application/json' \
61 | -d '{
62 | "large_language_model": "ChatGLM-6B-int8",
63 | "embedding_model": "text2vec-base"
64 | }'
65 | ```
66 |
67 | 3. 执行curl构建向量库命令
68 |
69 | ```bash
70 | curl -X 'POST' \
71 | 'http://localhost:8080/vector_store' \
72 | -H 'accept: application/json' \
73 | -H 'Content-Type: application/json' \
74 | -d '{
75 | "file_path": "./README.md"
76 | }'
77 | ```
78 |
79 | 4. 执行curl发送指令
80 |
81 | ```bash
82 | curl -X 'POST' \
83 | 'http://localhost:8080/predict' \
84 | -H 'accept: application/json' \
85 | -H 'Content-Type: application/json' \
86 | -d '{
87 | "input": "ChatGLM-6B的具体局限性?"
88 | "use_web": true,
89 | "top_k": 3,
90 | "history_len": 1,
91 | "temperature": 0.01,
92 | "top_p": 0.1,
93 | "history": []
94 | }'
95 | ```
96 |
97 | 5. Docker API 服务快速启动
98 |
99 | ```bash
100 | docker run -d --name LangChain-ChatGLM-Webui --runtime=nvidia --gpus all --network host registry.cn-beijing.aliyuncs.com/public-development-resources/langchain-chatglm-webui:api
101 | ```
102 |
--------------------------------------------------------------------------------
/docs/faq.md:
--------------------------------------------------------------------------------
1 | # 常见问题
2 |
3 | ### 模型下载问题
4 |
5 | 对于国内用户来说, 直接从HuggingFace下载模型可能会遇到网络阻碍, 您可以先通过以下链接提前将模型下载并解压到本地:
6 | | large language model | Embedding model |
7 | | :----: | :----: |
8 | | [ChatGLM-6B](https://s3.openi.org.cn/opendata/attachment/b/3/b33c55bb-8e7c-4e9d-90e5-c310dcc776d9?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T014727Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22chatglm-6b.zip%22&X-Amz-Signature=7324f73e66ee6ec9b955023d4f56076e3817b7daf14e874865c45f409094adf3) | [text2vec-large-chinese](https://s3.openi.org.cn/opendata/attachment/a/2/a2f0edca-1b7b-4dfc-b7c8-15730d33cc3e?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T050110Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22text2vec-large-chinese.zip%22&X-Amz-Signature=a2e1bdb16f7b55fa05e134649ea1967c0be32d7afbcd300ea82202cc3a7aae6c) |
9 | | [ChatGLM-6B-int8](https://s3.openi.org.cn/opendata/attachment/3/a/3aad10d1-ac8e-48f8-ac5f-cea8b54cf41b?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T014606Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22chatglm-6b-int8.zip%22&X-Amz-Signature=50f15ed60e4feaffb0984feafd5b2627fa8b5b4105c04a2516b122fb251eedc8) | [ernie-3.0-base-zh](https://s3.openi.org.cn/opendata/attachment/7/3/733fe6e4-2c29-46d8-93e8-6be16194a204?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T050111Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22ernie-3.0-base-zh.zip%22&X-Amz-Signature=92290028b0a64def599f27804e9314972fd115724ed4ad312a48797d20c5feb1) |
10 | | [ChatGLM-6B-int4](https://s3.openi.org.cn/opendata/attachment/b/2/b2c7f23f-6864-40da-9c81-2c0607cb1d02?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T050113Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22chatglm-6b-int4.zip%22&X-Amz-Signature=e8204284dcb2138e6fdce87d1b704a39f0dbe362512c28cef5a51cdea78a2858) | [ernie-3.0-nano-zh](https://s3.openi.org.cn/opendata/attachment/2/2/22833889-1683-422e-a44c-929bc379904c?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230422%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230422T152948Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22ernie-3.0-nano-zh.zip%22&X-Amz-Signature=c8b213d627efb8518c8e54a857c7c323e5e0451a08a3a473d37e2372aabd182f) |
11 | | [ChatGLM-6B-int4-qe](https://s3.openi.org.cn/opendata/attachment/b/f/bf5131da-62e0-4b57-b52a-4135c273b4fc?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T050105Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22chatglm-6b-int4-qe.zip%22&X-Amz-Signature=3205ca3c5690a086eef95bd032a7314b258a7550ad88bb36c4b738cc5059fbee) | [ernie-3.0-xbase-zh](https://s3.openi.org.cn/opendata/attachment/c/5/c5f746c3-4c60-4fb7-8424-8f7e40f3cce8?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T050103Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22ernie-3.0-xbase-zh.zip%22&X-Amz-Signature=edffb1ee1e7729fc45305750e1faaff54546683e1e1a983fce4cbff16d28e219) |
12 | | [Vicuna-7b-1.1](https://s3.openi.org.cn/opendata/attachment/2/5/25854cfb-3d57-44ff-a842-2a98e1a2dafe?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230423%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230423T014232Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22vicuna-7b-1.1.zip%22&X-Amz-Signature=353d6295d5260d5c53ee512680b211b67fe91fab8376aaef4c17e477f09a666a) | [simbert-base-chinese](https://s3.openi.org.cn/opendata/attachment/1/9/19a54b2f-e527-47e1-aa16-62887498b7f7?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230423%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230423T033222Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22simbert-base-chinese.zip%22&X-Amz-Signature=6ba81f63582fcb5a45fdc33415aabd40cd8ce0e803d79388390006f5feec5def) |
13 | | [BELLE-LLaMA-7B-2M](https://s3.openi.org.cn/opendata/attachment/2/6/26f570ea-03c8-4e48-8058-e90b4854edfb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T045945Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22BELLE-LLaMA-7B-2M.zip%22&X-Amz-Signature=a3a06bbce4389e21e384d5831f3a484bfae29a4af5a71fb043c26e6282ac00ee) | |
14 | | [BELLE-LLaMA-13B-2M](https://s3.openi.org.cn/opendata/attachment/a/c/acb0655f-4d3c-49c4-8320-f4b8584cf5bb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=1fa9e58b6899afd26dd3%2F20230424%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230424T014910Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&response-content-disposition=attachment%3B%20filename%3D%22BELLE-LLaMA-13B-2M.zip%22&X-Amz-Signature=7409fd2eba9768e720380759601cd462deabb3ebb24f493b21e1762b5f3410da) | |
15 |
16 | 然后在 `config.py` 文件中对以下字段进行修改:
17 |
18 | ```python
19 |
20 | embedding_model_dict = {
21 | "ernie-tiny": "nghuyong/ernie-3.0-nano-zh",
22 | "ernie-base": "your_model_path",
23 | "ernie-medium": "your_model_path",
24 | "ernie-xbase": "your_model_path",
25 | "text2vec-base": "your_model_path",
26 | 'simbert-base-chinese': 'your_model_path',
27 | 'paraphrase-multilingual-MiniLM-L12-v2': "your_model_path"
28 | }
29 |
30 | ```
31 |
32 | 具体路径仿见[issue 36](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/issues/36)、[issue 37](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/issues/37)
33 |
34 | ### 爆显存问题
35 |
36 | * ChatGLM-6B 模型硬件需求
37 | | **量化等级** | **最低 GPU 显存**(推理) | **最低 GPU 显存**(高效参数微调) |
38 | | -------------- | ------------------------- | --------------------------------- |
39 | | FP16(无量化) | 13 GB | 14 GB |
40 | | INT8 | 8 GB | 9 GB |
41 | | INT4 | 6 GB | 7 GB |
42 |
43 | 若您的设备显存有限
44 |
45 | 1. 可以选择 `ChatGLM-6B-int8` 或者 `ChatGLM-6B-int4` 以及选择较小的Embedding Model进行组合使用.
46 | 2. 参数选择时,可以选择叫小的history进行尝试.
47 |
48 | ### 常见的细节问题
49 |
50 | 1. 需要等文件完全上传之后再进行对话.
51 | 2. 若detectron2安装有问题, 可以执行:`pip install git+https://openi.pcl.ac.cn/Learning-Develop-Union/detectron2.git`.
52 | 3. 目前项目仅在linux环境下进行测试,win/mac下或许存在一些未知问题.
53 |
--------------------------------------------------------------------------------
/docs/update_history.md:
--------------------------------------------------------------------------------
1 | # 更新日志
2 |
3 | ## May 20 2023
4 |
5 | 1. vsctor store 本地存储
6 |
7 | ## May 19 2023
8 |
9 | 1. 提供PaddlePaddle版本和AIStudio环境
10 |
11 | ## Apr 28 2023
12 |
13 | 1. 增加推荐Embedding Model
14 | 2. 修复modelscope引用chatglm_llm错误问题
15 | 3. 修复相关注释问题
16 | 4. 更新微信群二维码
17 | 5. 完善FAQ和部署文档
18 | 6. 增加Vicuna-13B-1.1模型
19 | 7. 更改向量存储为Qdrant(尝试)
20 |
21 | ## Apr 27 2023
22 |
23 | 1. 优化Jina Serving API,支持批量文件
24 |
25 | ## Apr 26 2023
26 |
27 | 1. 增加Jina Serving API调用
28 | 2. 完善Readme描述
29 | 3. 修复切换模型时可能的潜在问题
30 | 4. 修复Jina Serving的Crul命令
31 | 5. 增加model cache目录@[AliscaCL](https://github.com/AliscaCL)
32 | 6. 更新Docker镜像地址@[online2311](https://github.com/online2311)
33 | 7. gradio发布时增加多项参数@[godlockin](https://github.com/godlockin)
34 | 8. 修复安装依赖冲突@[online2311](https://github.com/online2311)
35 |
36 | ## Apr 25 2023
37 |
38 | 1. 上传项目镜像至阿里云:`registry.cn-beijing.aliyuncs.com/public-development-resources/langchain-chatglm-webui:latest`
39 | 2. 优化Docker部署说明
40 | 3. 提供单独的config.py配置文件
41 | 4. Dockerfile增加aria2c unzip
42 | 5. 优化Dockerfile
43 | 6. config.py 增加本地Models参数
44 | 7. 构建基础镜像: `registry.cn-beijing.aliyuncs.com/public-development-resources/langchain-chatglm-webui:Base`
45 |
46 | 上述由[@online2311](https://github.com/online2311)贡献
47 |
48 | ## Apr 24 2023
49 |
50 | 1. 提供群聊沟通
51 | 2. 更新Dockerfile及requirements.txt
52 |
53 | ## Apr 22 2023
54 |
55 | 1. 优化模型加载机制
56 | 2. 修复对不同系列模型推理的bug
57 | 3. 修改参数不参与重新加载模型
58 | 4. 增加对Belle系列模型的支持
59 | 5. 优化UI设计
60 | 6. 完善Readme描述
61 |
62 | ## Apr 21 2023
63 |
64 | 1. 提供对`Vicuna`模型的支持
65 | 2. ModelScope版本支持Web Search
66 | 3. 在[HuggingFace](https://huggingface.co/spaces/thomas-yanxin/LangChain-ChatLLM)和[ModelScope](https://www.modelscope.cn/studios/AI-ModelScope/LangChain-ChatLLM/summary)的APP上支持了由Jina.ai提供的`ViT-B-32::laion2b-s34b-b79k` Embedding Inference
67 |
68 | ## Apr 20 2023
69 |
70 | 1. 优化对`.pdf`的支持
71 | 2. 优化UI设计
72 | 3. 修改对于Docker镜像的描述
73 | 4. 提供HuggingFace的在线体验
74 | 5. 完善Readme描述
75 |
76 | ## Apr 19 2023
77 |
78 | 1. 提供视频部署教程
79 | 2. 提供Docker部署及文字教程
80 | 3. 支持多卡推理ChatGLM-6B
81 | 4. 增加外部访问支持
82 | 5. 增加ChatGLM-6b-local以及本地模型读取路径
83 | 6. 修复text2vec无法加载的错误
84 |
85 | 上述2-6由社区[@online2311](https://github.com/online2311)贡献
86 |
87 | ## Apr 18 2023
88 |
89 | 1. 更新ModelScope版本
90 | 2. 完善Readme描述
91 |
92 | ## Apr 17 2023
93 |
94 | 1. 提供部署文档
95 | 2. 支持`.pdf`格式
96 | 3. 更新Docker镜像地址
97 | 4. 完善Readme描述
98 |
99 | ## Apr 16 2023
100 |
101 | 1. 提供模型下载链接
102 | 2. 完善Prompt设计
103 | 3. 修复上下文的bug
104 | 4. 支持更多的LLM和Embedding Model
105 | 5. 同步更新ModelScope版本
106 | 6. 完善Readme描述
107 |
108 | ## Apr 15 2023
109 |
110 | 1. 完善Readme描述
111 |
112 | ## Apr 14 2023
113 |
114 | 1. 提供离线的`nltk_data`依赖文件, 用户无需再次下载
115 | 2. 支持上下文
116 | 3. 增加支持的Embedding Model
117 | 4. 增加参数`history_len`、`temperature`、`top_p`
118 | 5. 同步更新ModelScope版本
119 | 6. 完善Readme描述
120 |
121 | ## Apr 13 2023
122 |
123 | 1. 提供ModelScope版本,支持在线体验
124 | 2. 使用langchain中的`RetrievalQA`替代之前选用的`ChatVectorDBChain`
125 | 3. 提供选择参数`VECTOR_SEARCH_TOP_K`
126 | 4. 删除提供的错误Docker地址
127 |
128 | ## Apr 12 2023
129 |
130 | 1. 增加对Embedding Model推理设备的定义
131 |
132 | ## Apr 11 2023
133 |
134 | 1. 提供部署镜像
135 | 2. 完善Readme描述
136 |
137 | ## Apr 10 2023
138 |
139 | 1. 提供多种LLM和Embedding Model可选择
140 | 2. 增加显存清理机制
141 | 3. 完善Readme描述
142 |
143 | ## Apr 10 2023
144 |
145 | 1. 初始化仓库, 提交Readme和Licence
146 | 2. 提交基础关键代码: app.py和chatglm_llm.py
147 | 3. 支持ChatGLM-6B的LLM和GanymedeNil/text2vec-large-chinese的Embedding Model
148 |
--------------------------------------------------------------------------------
/img/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/img/bg.jpg
--------------------------------------------------------------------------------
/img/demo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/img/demo.jpg
--------------------------------------------------------------------------------
/img/demo_hf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/img/demo_hf.jpg
--------------------------------------------------------------------------------
/img/demo_ms.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/img/demo_ms.jpg
--------------------------------------------------------------------------------
/img/demo_new.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/img/demo_new.jpg
--------------------------------------------------------------------------------
/img/wechat_group.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/img/wechat_group.jpg
--------------------------------------------------------------------------------
/jina_serving.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import os
3 | from typing import List
4 |
5 | import nltk
6 | import qdrant_client
7 | import sentence_transformers
8 | import torch
9 | from duckduckgo_search import ddg
10 | from duckduckgo_search.utils import SESSION
11 | from langchain.chains import RetrievalQA
12 | from langchain.document_loaders import UnstructuredFileLoader
13 | from langchain.embeddings.huggingface import HuggingFaceEmbeddings
14 | from langchain.prompts import PromptTemplate
15 | from langchain.prompts.prompt import PromptTemplate
16 | from langchain.vectorstores import Qdrant
17 | from lcserve import serving
18 |
19 | from chatllm import ChatLLM
20 | from chinese_text_splitter import ChineseTextSplitter
21 | from config import *
22 |
23 | nltk.data.path = [os.path.join(os.path.dirname(__file__), "nltk_data")
24 | ] + nltk.data.path
25 |
26 | embedding_model_dict = embedding_model_dict
27 | llm_model_dict = llm_model_dict
28 | EMBEDDING_DEVICE = EMBEDDING_DEVICE
29 | LLM_DEVICE = LLM_DEVICE
30 | VECTOR_STORE_PATH = VECTOR_STORE_PATH
31 | COLLECTION_NAME = COLLECTION_NAME
32 | num_gpus = num_gpus
33 | init_llm = init_llm
34 | init_embedding_model = init_embedding_model
35 |
36 |
37 |
38 | def search_web(query):
39 |
40 | SESSION.proxies = {
41 | "http": f"socks5h://localhost:7890",
42 | "https": f"socks5h://localhost:7890"
43 | }
44 | results = ddg(query)
45 | web_content = ''
46 | if results:
47 | for result in results:
48 | web_content += result['body']
49 | return web_content
50 |
51 |
52 | class KnowledgeBasedChatLLM:
53 |
54 | llm: object = None
55 | embeddings: object = None
56 |
57 | def init_model_config(
58 | self,
59 | large_language_model: str = init_llm,
60 | embedding_model: str = init_embedding_model,
61 | ):
62 | self.llm = ChatLLM()
63 | if 'chatglm' in large_language_model.lower():
64 | self.llm.model_type = 'chatglm'
65 | self.llm.model_name_or_path = llm_model_dict['chatglm'][
66 | large_language_model]
67 | elif 'belle' in large_language_model.lower():
68 | self.llm.model_type = 'belle'
69 | self.llm.model_name_or_path = llm_model_dict['belle'][
70 | large_language_model]
71 | elif 'vicuna' in large_language_model.lower():
72 | self.llm.model_type = 'vicuna'
73 | self.llm.model_name_or_path = llm_model_dict['vicuna'][
74 | large_language_model]
75 | self.embeddings = HuggingFaceEmbeddings(
76 | model_name=embedding_model_dict[embedding_model], )
77 | self.embeddings.client = sentence_transformers.SentenceTransformer(
78 | self.embeddings.model_name, device=EMBEDDING_DEVICE)
79 | self.llm.load_llm(llm_device=LLM_DEVICE, num_gpus=num_gpus)
80 |
81 | def init_knowledge_vector_store(self,
82 | filepath: str or List[str],):
83 | loaded_files = []
84 | if isinstance(filepath, str):
85 | if not os.path.exists(filepath):
86 | return "路径不存在"
87 | elif os.path.isfile(filepath):
88 | file = os.path.split(filepath)[-1]
89 | try:
90 | docs = self.load_file(filepath)
91 | print(f"{file} 已成功加载")
92 | loaded_files.append(filepath)
93 | except Exception as e:
94 | print(e)
95 | print(f"{file} 未能成功加载")
96 | return f"{file} 未能成功加载"
97 | elif os.path.isdir(filepath):
98 | docs = []
99 | for file in os.listdir(filepath):
100 | fullfilepath = os.path.join(filepath, file)
101 | try:
102 | docs += self.load_file(fullfilepath)
103 | print(f"{file} 已成功加载")
104 | loaded_files.append(fullfilepath)
105 | except Exception as e:
106 | print(e)
107 | print(f"{file} 未能成功加载")
108 | else:
109 | docs = []
110 | for file in filepath:
111 | try:
112 | docs += self.load_file(file)
113 | print(f"{file} 已成功加载")
114 | loaded_files.append(file)
115 | except Exception as e:
116 | print(e)
117 | print(f"{file} 未能成功加载")
118 | if len(docs) > 0:
119 | if VECTOR_STORE_PATH and os.path.isdir(VECTOR_STORE_PATH):
120 | vector_store = Qdrant.from_documents(
121 | docs,
122 | self.embeddings,
123 | path=VECTOR_STORE_PATH,
124 | collection_name=COLLECTION_NAME,
125 | )
126 | vector_store.add_documents(docs)
127 | else:
128 | vector_store = Qdrant.from_documents(
129 | docs,
130 | self.embeddings,
131 | path=VECTOR_STORE_PATH,
132 | collection_name=COLLECTION_NAME,
133 | )
134 | return "文件均未成功加载,请检查依赖包或文件路径。", loaded_files
135 | else:
136 | print("文件均未成功加载,请检查依赖包或文件路径。")
137 | return "文件均未成功加载,请检查依赖包或文件路径。", loaded_files
138 |
139 | def get_knowledge_based_answer(self,
140 | query,
141 | web_content,
142 | top_k: int = 6,
143 | history_len: int = 3,
144 | temperature: float = 0.01,
145 | top_p: float = 0.1,
146 | history=[]):
147 | self.llm.temperature = temperature
148 | self.llm.top_p = top_p
149 | self.history_len = history_len
150 | self.top_k = top_k
151 | if web_content:
152 | prompt_template = f"""基于以下已知信息,简洁和专业的来回答用户的问题。
153 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息",不允许在答案中添加编造成分,答案请使用中文。
154 | 已知网络检索内容:{web_content}""" + """
155 | 已知内容:
156 | {context}
157 | 问题:
158 | {question}"""
159 | else:
160 | prompt_template = """基于以下已知信息,请简洁并专业地回答用户的问题。
161 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息"。不允许在答案中添加编造成分。另外,答案请使用中文。
162 |
163 | 已知内容:
164 | {context}
165 |
166 | 问题:
167 | {question}"""
168 | prompt = PromptTemplate(template=prompt_template,
169 | input_variables=["context", "question"])
170 | self.llm.history = history[
171 | -self.history_len:] if self.history_len > 0 else []
172 | client = qdrant_client.QdrantClient(path=VECTOR_STORE_PATH,
173 | prefer_grpc=True)
174 | qdrant = Qdrant(client=client,
175 | collection_name=COLLECTION_NAME,
176 | embedding_function=self.embeddings.embed_query)
177 | knowledge_chain = RetrievalQA.from_llm(
178 | llm=self.llm,
179 | retriever=qdrant.as_retriever(search_kwargs={"k": self.top_k}),
180 | prompt=prompt)
181 | knowledge_chain.combine_documents_chain.document_prompt = PromptTemplate(
182 | input_variables=["page_content"], template="{page_content}")
183 |
184 | knowledge_chain.return_source_documents = True
185 |
186 | result = knowledge_chain({"query": query})
187 | return result
188 |
189 | def load_file(self, filepath):
190 | if filepath.lower().endswith(".md"):
191 | loader = UnstructuredFileLoader(filepath, mode="elements")
192 | docs = loader.load()
193 | elif filepath.lower().endswith(".pdf"):
194 | loader = UnstructuredFileLoader(filepath)
195 | textsplitter = ChineseTextSplitter(pdf=True)
196 | docs = loader.load_and_split(textsplitter)
197 | else:
198 | loader = UnstructuredFileLoader(filepath, mode="elements")
199 | textsplitter = ChineseTextSplitter(pdf=False)
200 | docs = loader.load_and_split(text_splitter=textsplitter)
201 | return docs
202 |
203 |
204 | knowladge_based_chat_llm = KnowledgeBasedChatLLM()
205 |
206 |
207 | def init_model():
208 | try:
209 | knowladge_based_chat_llm.init_model_config()
210 | knowladge_based_chat_llm.llm._call("你好")
211 | return """初始模型已成功加载"""
212 | except Exception as e:
213 |
214 | return """模型未成功加载,请检查后重新尝试"""
215 |
216 |
217 | @serving
218 | def reinit_model(large_language_model: str, embedding_model: str):
219 | try:
220 | knowladge_based_chat_llm.init_model_config(
221 | large_language_model=large_language_model,
222 | embedding_model=embedding_model)
223 | model_status = """模型已成功重新加载"""
224 | except Exception as e:
225 | model_status = """模型未成功加载,请检查后重新尝试"""
226 | return model_status
227 |
228 |
229 | @serving
230 | def vector_store(file_path: str or List[str]):
231 |
232 | vector_store_state, loaded_files = knowladge_based_chat_llm.init_knowledge_vector_store(
233 | file_path)
234 | return vector_store_state
235 |
236 |
237 | @serving
238 | def predict(input: str,
239 | use_web: bool, top_k: int, history_len: int, temperature: float,
240 | top_p: float, history: list):
241 | if history == None:
242 | history = []
243 |
244 | if use_web == 'True':
245 | web_content = search_web(query=input)
246 | else:
247 | web_content = ''
248 |
249 | resp = knowladge_based_chat_llm.get_knowledge_based_answer(
250 | query=input,
251 | web_content=web_content,
252 | top_k=top_k,
253 | history_len=history_len,
254 | temperature=temperature,
255 | top_p=top_p,
256 | history=history)
257 | history.append((input, resp['result']))
258 | print(resp['result'])
259 | return resp['result']
260 |
261 | if __name__ == "__main__":
262 | reinit_model(large_language_model='ChatGLM-6B-int8',
263 | embedding_model='text2vec-base')
264 |
265 | vector_store(file_path='./README.md')
266 |
267 | predict('chatglm-6b的局限性在哪里?',
268 | use_web=False,
269 | top_k=6,
270 | history_len=3,
271 | temperature=0.01,
272 | top_p=0.1,
273 | history=[])
274 |
--------------------------------------------------------------------------------
/model_cache/OfflineDeploy.md:
--------------------------------------------------------------------------------
1 | This path is the model cache path.
2 | It could be setting via config.MODEL_CACHE_PATH variable in config.py scripts.
3 |
4 | You could run the app.py file as usural, and then all model download by hugging face migt be downloaded in this folder.
5 | When you try to transfer this project to offline environment, you could directly package all the file with
6 |
7 | ```bash
8 | tar -zcvf LangChain-ChatGLM-Webui.tar.gz /path/to/LangChain-ChatGLM-Webui
9 | ```
10 |
11 | Then transfer the tar file to the offline line environment and extend with
12 |
13 | ```bash
14 | mkdir -p /path/to/LangChain-ChatGLM-Webui
15 | tar -zcvf LangChain-ChatGLM-Webui.tar.gz -C /path/to/LangChain-ChatGLM-Webui
16 | cd /path/to/LangChain-ChatGLM-Webui
17 | ```
18 |
19 | Then run script as usural in offline environment.
--------------------------------------------------------------------------------
/modelscope/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/modelscope/README.md
--------------------------------------------------------------------------------
/modelscope/app.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import gradio as gr
4 | import nltk
5 | import torch
6 | from chatglm_llm import ChatGLM
7 | from duckduckgo_search import ddg
8 | from duckduckgo_search.utils import SESSION
9 | from langchain.chains import RetrievalQA
10 | from langchain.document_loaders import UnstructuredFileLoader
11 | from langchain.prompts import PromptTemplate
12 | from langchain.vectorstores import FAISS
13 | from modelscope_hub import ModelScopeEmbeddings
14 |
15 | nltk.data.path.append('../nltk_data')
16 |
17 | DEVICE = "cuda" if torch.cuda.is_available(
18 | ) else "mps" if torch.backends.mps.is_available() else "cpu"
19 |
20 | embedding_model_dict = {
21 | "corom-tiny": "damo/nlp_corom_sentence-embedding_chinese-tiny",
22 | "corom-tiny-ecom": "damo/nlp_corom_sentence-embedding_chinese-tiny-ecom",
23 | "corom-base-ecom": "damo/nlp_corom_sentence-embedding_chinese-base-ecom",
24 | "corom-base": "damo/nlp_corom_sentence-embedding_chinese-base",
25 | }
26 |
27 | llm_dict = {
28 | 'ChatGLM-6B': {
29 | 'model_name': 'ZhipuAI/ChatGLM-6B',
30 | 'model_revision': 'v1.0.15',
31 | },
32 | 'ChatGLM-6B-int8': {
33 | 'model_name': 'thomas/ChatGLM-6B-Int8',
34 | 'model_revision': 'v1.0.3',
35 | },
36 | 'ChatGLM-6B-int4': {
37 | 'model_name': 'ZhipuAI/ChatGLM-6B-Int4',
38 | 'model_revision': 'v1.0.3',
39 | }
40 | }
41 |
42 |
43 | def search_web(query):
44 |
45 | SESSION.proxies = {
46 | "http": f"socks5h://localhost:7890",
47 | "https": f"socks5h://localhost:7890"
48 | }
49 | results = ddg(query)
50 | web_content = ''
51 | if results:
52 | for result in results:
53 | web_content += result['body']
54 | return web_content
55 |
56 |
57 | def init_knowledge_vector_store(embedding_model, filepath):
58 |
59 | embeddings = ModelScopeEmbeddings(
60 | model_name=embedding_model_dict[embedding_model], )
61 |
62 | loader = UnstructuredFileLoader(filepath, mode="elements")
63 | docs = loader.load()
64 |
65 | vector_store = FAISS.from_documents(docs, embeddings)
66 | return vector_store
67 |
68 |
69 | def get_knowledge_based_answer(
70 | query,
71 | large_language_model,
72 | vector_store,
73 | VECTOR_SEARCH_TOP_K,
74 | web_content,
75 | chat_history=[],
76 | history_len=3,
77 | temperature=0.01,
78 | top_p=0.9,
79 | ):
80 | if web_content:
81 | prompt_template = f"""基于以下已知信息,简洁和专业的来回答用户的问题。
82 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息",不允许在答案中添加编造成分,答案请使用中文。
83 | 已知网络检索内容:{web_content}""" + """
84 | 已知内容:
85 | {context}
86 | 问题:
87 | {question}"""
88 | else:
89 | prompt_template = """基于以下已知信息,请简洁并专业地回答用户的问题。
90 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息"。不允许在答案中添加编造成分。另外,答案请使用中文。
91 |
92 | 已知内容:
93 | {context}
94 |
95 | 问题:
96 | {question}"""
97 | prompt = PromptTemplate(template=prompt_template,
98 | input_variables=["context", "question"])
99 |
100 | chatLLM = ChatGLM()
101 | chatLLM.model_name = llm_dict[large_language_model]['model_name']
102 | chatLLM.model_revision = llm_dict[large_language_model]['model_revision']
103 |
104 | chatLLM.history = chat_history[-history_len:] if history_len > 0 else []
105 | chatLLM.temperature = temperature
106 | chatLLM.top_p = top_p
107 |
108 | knowledge_chain = RetrievalQA.from_llm(
109 | llm=chatLLM,
110 | retriever=vector_store.as_retriever(
111 | search_kwargs={"k": VECTOR_SEARCH_TOP_K}),
112 | prompt=prompt)
113 | knowledge_chain.combine_documents_chain.document_prompt = PromptTemplate(
114 | input_variables=["page_content"], template="{page_content}")
115 |
116 | knowledge_chain.return_source_documents = True
117 | result = knowledge_chain({"query": query})
118 |
119 | return result['result']
120 |
121 |
122 | def clear_session():
123 | return '', None
124 |
125 |
126 | def predict(input,
127 | large_language_model,
128 | embedding_model,
129 | file_obj,
130 | VECTOR_SEARCH_TOP_K,
131 | history_len,
132 | temperature,
133 | top_p,
134 | use_web,
135 | history=None):
136 | if history == None:
137 | history = []
138 | print(file_obj.name)
139 | if use_web == 'True':
140 | web_content = search_web(query=input)
141 | else:
142 | web_content = ''
143 | vector_store = init_knowledge_vector_store(embedding_model, file_obj.name)
144 |
145 | resp = get_knowledge_based_answer(
146 | query=input,
147 | large_language_model=large_language_model,
148 | vector_store=vector_store,
149 | VECTOR_SEARCH_TOP_K=VECTOR_SEARCH_TOP_K,
150 | web_content=web_content,
151 | chat_history=history,
152 | history_len=history_len,
153 | temperature=temperature,
154 | top_p=top_p,
155 | )
156 | print(resp)
157 | history.append((input, resp))
158 | return '', history, history
159 |
160 |
161 | if __name__ == "__main__":
162 | block = gr.Blocks()
163 | with block as demo:
164 | gr.Markdown("""LangChain-ChatLLM-Webui
165 |
166 | 本项目基于LangChain和大型语言模型系列模型, 提供基于本地知识的自动问答应用.
167 | 目前项目提供基于ChatGLM-6B 的LLM和包括nlp_corom_sentence-embedding系列的多个Embedding模型, 支持上传 txt、docx、md 等文本格式文件.
168 | 后续将提供更加多样化的LLM、Embedding和参数选项供用户尝试, 欢迎关注Github地址.
169 |
170 | """)
171 | with gr.Row():
172 | with gr.Column(scale=1):
173 | model_choose = gr.Accordion("模型选择")
174 | with model_choose:
175 | large_language_model = gr.Dropdown(
176 | ["ChatGLM-6B", "ChatGLM-6B-int4", 'ChatGLM-6B-int8'],
177 | label="large language model",
178 | value="ChatGLM-6B-int8")
179 |
180 | embedding_model = gr.Dropdown(list(
181 | embedding_model_dict.keys()),
182 | label="Embedding model",
183 | value="corom-tiny")
184 |
185 | file = gr.File(label='请上传知识库文件',
186 | file_types=['.txt', '.md', '.docx'])
187 | use_web = gr.Radio(["True", "False"],
188 | label="Web Search",
189 | value="False")
190 | model_argument = gr.Accordion("模型参数配置")
191 |
192 | with model_argument:
193 |
194 | VECTOR_SEARCH_TOP_K = gr.Slider(
195 | 1,
196 | 10,
197 | value=6,
198 | step=1,
199 | label="vector search top k",
200 | interactive=True)
201 |
202 | HISTORY_LEN = gr.Slider(0,
203 | 3,
204 | value=0,
205 | step=1,
206 | label="history len",
207 | interactive=True)
208 |
209 | temperature = gr.Slider(0,
210 | 1,
211 | value=0.01,
212 | step=0.01,
213 | label="temperature",
214 | interactive=True)
215 | top_p = gr.Slider(0,
216 | 1,
217 | value=0.9,
218 | step=0.1,
219 | label="top_p",
220 | interactive=True)
221 |
222 | with gr.Column(scale=4):
223 | chatbot = gr.Chatbot(label='ChatLLM').style(height=400)
224 | message = gr.Textbox(label='请输入问题')
225 | state = gr.State()
226 |
227 | with gr.Row():
228 | clear_history = gr.Button("🧹 清除历史对话")
229 | send = gr.Button("🚀 发送")
230 |
231 | send.click(predict,
232 | inputs=[
233 | message, large_language_model,
234 | embedding_model, file, VECTOR_SEARCH_TOP_K,
235 | HISTORY_LEN, temperature, top_p, use_web,
236 | state
237 | ],
238 | outputs=[message, chatbot, state])
239 | clear_history.click(fn=clear_session,
240 | inputs=[],
241 | outputs=[chatbot, state],
242 | queue=False)
243 |
244 | message.submit(predict,
245 | inputs=[
246 | message, large_language_model,
247 | embedding_model, file,
248 | VECTOR_SEARCH_TOP_K, HISTORY_LEN,
249 | temperature, top_p, use_web, state
250 | ],
251 | outputs=[message, chatbot, state])
252 | gr.Markdown("""提醒:
253 | 1. 更改LLM模型前请先刷新页面,否则将返回error(后续将完善此部分).
254 | 2. 使用时请先上传自己的知识文件,并且文件中不含某些特殊字符,否则将返回error.
255 | 3. 请勿上传或输入敏感内容,否则输出内容将被平台拦截返回error.
256 | 4. 有任何使用问题,请通过[问题交流区](https://modelscope.cn/studios/thomas/ChatYuan-test/comment)或[Github Issue区](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/issues)进行反馈.
257 | """)
258 | demo.queue().launch(share=False)
--------------------------------------------------------------------------------
/modelscope/chatglm_llm.py:
--------------------------------------------------------------------------------
1 | import os
2 | from typing import List, Optional
3 |
4 | import torch
5 | from langchain.llms.base import LLM
6 | from langchain.llms.utils import enforce_stop_tokens
7 |
8 | from modelscope.pipelines import pipeline
9 | from modelscope.utils.constant import Tasks
10 |
11 | os.environ["TOKENIZERS_PARALLELISM"] = "false"
12 |
13 | DEVICE = "cuda"
14 | DEVICE_ID = "0"
15 | CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE
16 |
17 |
18 | def torch_gc():
19 | if torch.cuda.is_available():
20 | with torch.cuda.device(CUDA_DEVICE):
21 | torch.cuda.empty_cache()
22 | torch.cuda.ipc_collect()
23 |
24 |
25 | class ChatGLM(LLM):
26 | history = []
27 | max_length = 10000
28 | temperature: float = 0.01
29 | top_p = 0.9
30 | model_name = 'ZhipuAI/ChatGLM-6B'
31 | model_revision = 'v1.0.13'
32 |
33 | def __init__(self):
34 | super().__init__()
35 |
36 | @property
37 | def _llm_type(self) -> str:
38 | return "ChatGLM"
39 |
40 | def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
41 |
42 | inputs = {
43 | 'text': prompt,
44 | 'history': self.history,
45 | 'max_length': self.max_length,
46 | 'temperature': self.temperature,
47 | 'top_p': self.top_p
48 | }
49 | pipe = self.pipe()
50 | result = pipe(inputs)
51 | response = result['response']
52 | updated_history = result['history']
53 | torch_gc()
54 | if stop is not None:
55 | response = enforce_stop_tokens(response, stop)
56 | self.history = updated_history
57 | return response
58 |
59 | def pipe(self):
60 | pipe = pipeline(task=Tasks.chat,
61 | model=self.model_name,
62 | model_revision=self.model_revision)
63 | return pipe
64 |
--------------------------------------------------------------------------------
/modelscope/modelscope_hub.py:
--------------------------------------------------------------------------------
1 | """Wrapper around ModelScopeHub embedding models."""
2 | from typing import Any, List
3 |
4 | from langchain.embeddings.base import Embeddings
5 | from pydantic import BaseModel, Extra
6 |
7 |
8 | class ModelScopeEmbeddings(BaseModel, Embeddings):
9 | """Wrapper around modelscope_hub embedding models.
10 |
11 | To use, you should have the ``modelscope`` python package installed.
12 |
13 | Example:
14 | .. code-block:: python
15 |
16 | from langchain.embeddings import ModelScopeEmbeddingsEmbeddings
17 | model_id = "damo/nlp_corom_sentence-embedding_english-base"
18 | embed = ModelScopeEmbeddingsEmbeddings(model_id=model_id)
19 | """
20 |
21 | embed: Any
22 | model_id: str ="damo/nlp_corom_sentence-embedding_english-base"
23 | """Model name to use."""
24 |
25 | def __init__(self, **kwargs: Any):
26 | """Initialize the modelscope"""
27 | super().__init__(**kwargs)
28 | try:
29 | from modelscope.models import Model
30 | from modelscope.pipelines import pipeline
31 | from modelscope.utils.constant import Tasks
32 | self.embed = pipeline(Tasks.sentence_embedding,
33 | model=self.model_id)
34 |
35 | except ImportError as e:
36 | raise ValueError(
37 | "Could not import some python packages." "Please install it with `pip install modelscope`."
38 | ) from e
39 |
40 | class Config:
41 | """Configuration for this pydantic object."""
42 |
43 | extra = Extra.forbid
44 |
45 | def embed_documents(self, texts: List[str]) -> List[List[float]]:
46 | """Compute doc embeddings using a modelscope embedding model.
47 |
48 | Args:
49 | texts: The list of texts to embed.
50 |
51 | Returns:
52 | List of embeddings, one for each text.
53 | """
54 | texts = list(map(lambda x: x.replace("\n", " "), texts))
55 | inputs = {"source_sentence": texts}
56 | embeddings = self.embed(input=inputs)['text_embedding']
57 | return embeddings
58 |
59 | def embed_query(self, text: str) -> List[float]:
60 | """Compute query embeddings using a modelscope embedding model.
61 |
62 | Args:
63 | text: The text to embed.
64 |
65 | Returns:
66 | Embeddings for the text.
67 | """
68 | text = text.replace("\n", " ")
69 | inputs = {"source_sentence": [text]}
70 | embedding = self.embed(input=inputs)['text_embedding'][0]
71 | return embedding
--------------------------------------------------------------------------------
/modelscope/requirements.txt:
--------------------------------------------------------------------------------
1 | modelscope
--------------------------------------------------------------------------------
/nltk_data/taggers/averaged_perceptron_tagger/averaged_perceptron_tagger.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/taggers/averaged_perceptron_tagger/averaged_perceptron_tagger.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/.DS_Store
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/README:
--------------------------------------------------------------------------------
1 | Pretrained Punkt Models -- Jan Strunk (New version trained after issues 313 and 514 had been corrected)
2 |
3 | Most models were prepared using the test corpora from Kiss and Strunk (2006). Additional models have
4 | been contributed by various people using NLTK for sentence boundary detection.
5 |
6 | For information about how to use these models, please confer the tokenization HOWTO:
7 | http://nltk.googlecode.com/svn/trunk/doc/howto/tokenize.html
8 | and chapter 3.8 of the NLTK book:
9 | http://nltk.googlecode.com/svn/trunk/doc/book/ch03.html#sec-segmentation
10 |
11 | There are pretrained tokenizers for the following languages:
12 |
13 | File Language Source Contents Size of training corpus(in tokens) Model contributed by
14 | =======================================================================================================================================================================
15 | czech.pickle Czech Multilingual Corpus 1 (ECI) Lidove Noviny ~345,000 Jan Strunk / Tibor Kiss
16 | Literarni Noviny
17 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
18 | danish.pickle Danish Avisdata CD-Rom Ver. 1.1. 1995 Berlingske Tidende ~550,000 Jan Strunk / Tibor Kiss
19 | (Berlingske Avisdata, Copenhagen) Weekend Avisen
20 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
21 | dutch.pickle Dutch Multilingual Corpus 1 (ECI) De Limburger ~340,000 Jan Strunk / Tibor Kiss
22 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
23 | english.pickle English Penn Treebank (LDC) Wall Street Journal ~469,000 Jan Strunk / Tibor Kiss
24 | (American)
25 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
26 | estonian.pickle Estonian University of Tartu, Estonia Eesti Ekspress ~359,000 Jan Strunk / Tibor Kiss
27 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
28 | finnish.pickle Finnish Finnish Parole Corpus, Finnish Books and major national ~364,000 Jan Strunk / Tibor Kiss
29 | Text Bank (Suomen Kielen newspapers
30 | Tekstipankki)
31 | Finnish Center for IT Science
32 | (CSC)
33 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
34 | french.pickle French Multilingual Corpus 1 (ECI) Le Monde ~370,000 Jan Strunk / Tibor Kiss
35 | (European)
36 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
37 | german.pickle German Neue Zürcher Zeitung AG Neue Zürcher Zeitung ~847,000 Jan Strunk / Tibor Kiss
38 | (Switzerland) CD-ROM
39 | (Uses "ss"
40 | instead of "ß")
41 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
42 | greek.pickle Greek Efstathios Stamatatos To Vima (TO BHMA) ~227,000 Jan Strunk / Tibor Kiss
43 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
44 | italian.pickle Italian Multilingual Corpus 1 (ECI) La Stampa, Il Mattino ~312,000 Jan Strunk / Tibor Kiss
45 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
46 | norwegian.pickle Norwegian Centre for Humanities Bergens Tidende ~479,000 Jan Strunk / Tibor Kiss
47 | (Bokmål and Information Technologies,
48 | Nynorsk) Bergen
49 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
50 | polish.pickle Polish Polish National Corpus Literature, newspapers, etc. ~1,000,000 Krzysztof Langner
51 | (http://www.nkjp.pl/)
52 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
53 | portuguese.pickle Portuguese CETENFolha Corpus Folha de São Paulo ~321,000 Jan Strunk / Tibor Kiss
54 | (Brazilian) (Linguateca)
55 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
56 | slovene.pickle Slovene TRACTOR Delo ~354,000 Jan Strunk / Tibor Kiss
57 | Slovene Academy for Arts
58 | and Sciences
59 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
60 | spanish.pickle Spanish Multilingual Corpus 1 (ECI) Sur ~353,000 Jan Strunk / Tibor Kiss
61 | (European)
62 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
63 | swedish.pickle Swedish Multilingual Corpus 1 (ECI) Dagens Nyheter ~339,000 Jan Strunk / Tibor Kiss
64 | (and some other texts)
65 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
66 | turkish.pickle Turkish METU Turkish Corpus Milliyet ~333,000 Jan Strunk / Tibor Kiss
67 | (Türkçe Derlem Projesi)
68 | University of Ankara
69 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
70 |
71 | The corpora contained about 400,000 tokens on average and mostly consisted of newspaper text converted to
72 | Unicode using the codecs module.
73 |
74 | Kiss, Tibor and Strunk, Jan (2006): Unsupervised Multilingual Sentence Boundary Detection.
75 | Computational Linguistics 32: 485-525.
76 |
77 | ---- Training Code ----
78 |
79 | # import punkt
80 | import nltk.tokenize.punkt
81 |
82 | # Make a new Tokenizer
83 | tokenizer = nltk.tokenize.punkt.PunktSentenceTokenizer()
84 |
85 | # Read in training corpus (one example: Slovene)
86 | import codecs
87 | text = codecs.open("slovene.plain","Ur","iso-8859-2").read()
88 |
89 | # Train tokenizer
90 | tokenizer.train(text)
91 |
92 | # Dump pickled tokenizer
93 | import pickle
94 | out = open("slovene.pickle","wb")
95 | pickle.dump(tokenizer, out)
96 | out.close()
97 |
98 | ---------
99 |
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/czech.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/czech.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/danish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/danish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/dutch.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/dutch.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/english.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/english.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/estonian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/estonian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/finnish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/finnish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/french.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/french.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/german.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/german.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/greek.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/greek.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/italian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/italian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/malayalam.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/malayalam.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/norwegian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/norwegian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/polish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/polish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/portuguese.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/portuguese.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/russian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/russian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/slovene.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/slovene.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/spanish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/spanish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/swedish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/swedish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/PY3/turkish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/PY3/turkish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/README:
--------------------------------------------------------------------------------
1 | Pretrained Punkt Models -- Jan Strunk (New version trained after issues 313 and 514 had been corrected)
2 |
3 | Most models were prepared using the test corpora from Kiss and Strunk (2006). Additional models have
4 | been contributed by various people using NLTK for sentence boundary detection.
5 |
6 | For information about how to use these models, please confer the tokenization HOWTO:
7 | http://nltk.googlecode.com/svn/trunk/doc/howto/tokenize.html
8 | and chapter 3.8 of the NLTK book:
9 | http://nltk.googlecode.com/svn/trunk/doc/book/ch03.html#sec-segmentation
10 |
11 | There are pretrained tokenizers for the following languages:
12 |
13 | File Language Source Contents Size of training corpus(in tokens) Model contributed by
14 | =======================================================================================================================================================================
15 | czech.pickle Czech Multilingual Corpus 1 (ECI) Lidove Noviny ~345,000 Jan Strunk / Tibor Kiss
16 | Literarni Noviny
17 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
18 | danish.pickle Danish Avisdata CD-Rom Ver. 1.1. 1995 Berlingske Tidende ~550,000 Jan Strunk / Tibor Kiss
19 | (Berlingske Avisdata, Copenhagen) Weekend Avisen
20 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
21 | dutch.pickle Dutch Multilingual Corpus 1 (ECI) De Limburger ~340,000 Jan Strunk / Tibor Kiss
22 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
23 | english.pickle English Penn Treebank (LDC) Wall Street Journal ~469,000 Jan Strunk / Tibor Kiss
24 | (American)
25 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
26 | estonian.pickle Estonian University of Tartu, Estonia Eesti Ekspress ~359,000 Jan Strunk / Tibor Kiss
27 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
28 | finnish.pickle Finnish Finnish Parole Corpus, Finnish Books and major national ~364,000 Jan Strunk / Tibor Kiss
29 | Text Bank (Suomen Kielen newspapers
30 | Tekstipankki)
31 | Finnish Center for IT Science
32 | (CSC)
33 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
34 | french.pickle French Multilingual Corpus 1 (ECI) Le Monde ~370,000 Jan Strunk / Tibor Kiss
35 | (European)
36 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
37 | german.pickle German Neue Zürcher Zeitung AG Neue Zürcher Zeitung ~847,000 Jan Strunk / Tibor Kiss
38 | (Switzerland) CD-ROM
39 | (Uses "ss"
40 | instead of "ß")
41 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
42 | greek.pickle Greek Efstathios Stamatatos To Vima (TO BHMA) ~227,000 Jan Strunk / Tibor Kiss
43 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
44 | italian.pickle Italian Multilingual Corpus 1 (ECI) La Stampa, Il Mattino ~312,000 Jan Strunk / Tibor Kiss
45 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
46 | norwegian.pickle Norwegian Centre for Humanities Bergens Tidende ~479,000 Jan Strunk / Tibor Kiss
47 | (Bokmål and Information Technologies,
48 | Nynorsk) Bergen
49 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
50 | polish.pickle Polish Polish National Corpus Literature, newspapers, etc. ~1,000,000 Krzysztof Langner
51 | (http://www.nkjp.pl/)
52 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
53 | portuguese.pickle Portuguese CETENFolha Corpus Folha de São Paulo ~321,000 Jan Strunk / Tibor Kiss
54 | (Brazilian) (Linguateca)
55 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
56 | slovene.pickle Slovene TRACTOR Delo ~354,000 Jan Strunk / Tibor Kiss
57 | Slovene Academy for Arts
58 | and Sciences
59 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
60 | spanish.pickle Spanish Multilingual Corpus 1 (ECI) Sur ~353,000 Jan Strunk / Tibor Kiss
61 | (European)
62 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
63 | swedish.pickle Swedish Multilingual Corpus 1 (ECI) Dagens Nyheter ~339,000 Jan Strunk / Tibor Kiss
64 | (and some other texts)
65 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
66 | turkish.pickle Turkish METU Turkish Corpus Milliyet ~333,000 Jan Strunk / Tibor Kiss
67 | (Türkçe Derlem Projesi)
68 | University of Ankara
69 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
70 |
71 | The corpora contained about 400,000 tokens on average and mostly consisted of newspaper text converted to
72 | Unicode using the codecs module.
73 |
74 | Kiss, Tibor and Strunk, Jan (2006): Unsupervised Multilingual Sentence Boundary Detection.
75 | Computational Linguistics 32: 485-525.
76 |
77 | ---- Training Code ----
78 |
79 | # import punkt
80 | import nltk.tokenize.punkt
81 |
82 | # Make a new Tokenizer
83 | tokenizer = nltk.tokenize.punkt.PunktSentenceTokenizer()
84 |
85 | # Read in training corpus (one example: Slovene)
86 | import codecs
87 | text = codecs.open("slovene.plain","Ur","iso-8859-2").read()
88 |
89 | # Train tokenizer
90 | tokenizer.train(text)
91 |
92 | # Dump pickled tokenizer
93 | import pickle
94 | out = open("slovene.pickle","wb")
95 | pickle.dump(tokenizer, out)
96 | out.close()
97 |
98 | ---------
99 |
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/czech.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/czech.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/danish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/danish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/dutch.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/dutch.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/estonian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/estonian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/finnish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/finnish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/french.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/french.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/german.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/german.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/italian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/italian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/malayalam.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/malayalam.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/norwegian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/norwegian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/polish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/polish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/portuguese.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/portuguese.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/russian.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/russian.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/slovene.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/slovene.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/spanish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/spanish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/swedish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/swedish.pickle
--------------------------------------------------------------------------------
/nltk_data/tokenizers/punkt/turkish.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/X-D-Lab/LangChain-ChatGLM-Webui/7996cd5f621dfc7a51a6de871b38bae87f41bb71/nltk_data/tokenizers/punkt/turkish.pickle
--------------------------------------------------------------------------------
/paddlepaddle/README.md:
--------------------------------------------------------------------------------
1 | # LangChain-ChatGLM-Paddle
2 |
3 | LangChain-ChatGLM的Paddle版本依赖 `PaddlePaddle` 和 `PaddleNLP` 的develop版本
4 |
5 | 在AIStudio上可以一键运行:[链接](https://aistudio.baidu.com/aistudio/projectdetail/6195067)
6 |
--------------------------------------------------------------------------------
/paddlepaddle/app.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import gradio as gr
4 | import nltk
5 | from langchain.chains import RetrievalQA
6 | from langchain.document_loaders import UnstructuredFileLoader
7 | from langchain.prompts import PromptTemplate
8 | from langchain.prompts.prompt import PromptTemplate
9 | from langchain.vectorstores import FAISS
10 | from paddle_embedding import PaddleNLPEmbeddings
11 |
12 | from chatllm import ChatLLM
13 |
14 | nltk.data.path.append('../nltk_data')
15 | llm_model_dict = {
16 | 'ChatGLM-6B': 'THUDM/chatglm-6b'
17 | }
18 |
19 | embedding_model_dict = {
20 | "rocketqa-zh-base-query": "rocketqa-zh-base-query-encoder",
21 | "rocketqa-zh-dureader": "rocketqa-zh-dureader-query-encoder",
22 | "rocketqa-zh-dureader-query": "rocketqa-zh-dureader-query-encoder",
23 | "rocketqa-zh-medium-query": "rocketqa-zh-medium-query-encoder",
24 | "rocketqa-zh-medium-para": "rocketqa-zh-medium-para-encoder"
25 |
26 | }
27 |
28 |
29 | def init_knowledge_vector_store(embedding_model, filepath):
30 |
31 | embeddings = PaddleNLPEmbeddings(
32 | model = embedding_model_dict[embedding_model])
33 |
34 |
35 | loader = UnstructuredFileLoader(filepath, mode="elements")
36 | docs = loader.load()
37 |
38 | vector_store = FAISS.from_documents(docs, embeddings)
39 |
40 | return vector_store
41 |
42 |
43 | def get_knowledge_based_answer(query,
44 | large_language_model,
45 | vector_store,
46 | VECTOR_SEARCH_TOP_K,
47 | chat_history=[]):
48 |
49 |
50 | prompt_template = """基于以下已知信息,请简洁并专业地回答用户的问题。
51 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息"。不允许在答案中添加编造成分。另外,答案请使用中文。
52 |
53 | 已知内容:
54 | {context}
55 |
56 | 问题:
57 | {question}"""
58 | prompt = PromptTemplate(template=prompt_template,
59 | input_variables=["context", "question"])
60 | chatLLM = ChatLLM()
61 |
62 | knowledge_chain = RetrievalQA.from_llm(
63 | llm=chatLLM,
64 | retriever=vector_store.as_retriever(
65 | search_kwargs={"k": VECTOR_SEARCH_TOP_K}),
66 | prompt=prompt)
67 | knowledge_chain.combine_documents_chain.document_prompt = PromptTemplate(
68 | input_variables=["page_content"], template="{page_content}")
69 |
70 | knowledge_chain.return_source_documents = True
71 |
72 | result = knowledge_chain({"query": query})
73 | print('result')
74 | print(result)
75 | return result
76 |
77 |
78 | def clear_session():
79 | return '', None
80 |
81 |
82 | def predict(input: str,
83 | large_language_model: str,
84 | embedding_model: str,
85 | file_obj,
86 | VECTOR_SEARCH_TOP_K: int,
87 | history=None):
88 | if history == None:
89 | history = []
90 | print(file_obj.name)
91 | vector_store = init_knowledge_vector_store(embedding_model, file_obj.name)
92 |
93 | resp = get_knowledge_based_answer(
94 | query=input,
95 | large_language_model=large_language_model,
96 | vector_store=vector_store,
97 | VECTOR_SEARCH_TOP_K=VECTOR_SEARCH_TOP_K,
98 | chat_history=history,
99 | )
100 | print(resp['result'])
101 | history.append((input, resp['result']))
102 | return '', history, history
103 |
104 |
105 | if __name__ == "__main__":
106 | block = gr.Blocks()
107 | with block as demo:
108 | gr.Markdown("""LangChain-ChatLLM-Webui
109 |
110 | 本项目基于LangChain和大型语言模型系列模型, 提供基于本地知识的自动问答应用.
111 | 目前项目提供基于ChatGLM-6B 的LLM和包括rocketqa-zh系列的多个Embedding模型, 支持上传 txt、docx、md等文本格式文件.
112 | 后续将提供更加多样化的LLM、Embedding和参数选项供用户尝试, 欢迎关注Github地址.
113 |
114 | """)
115 | with gr.Row():
116 | with gr.Column(scale=1):
117 | model_choose = gr.Accordion("模型选择")
118 | with model_choose:
119 | large_language_model = gr.Dropdown(
120 | list(llm_model_dict.keys()),
121 | label="large language model",
122 | value="ChatGLM-6B")
123 | embedding_model = gr.Dropdown(list(
124 | embedding_model_dict.keys()),
125 | label="Embedding model",
126 | value="rocketqa-zh-dureader-query")
127 |
128 | VECTOR_SEARCH_TOP_K = gr.Slider(
129 | 1,
130 | 10,
131 | value=6,
132 | step=1,
133 | label="vector search top k",
134 | interactive=True)
135 | file = gr.File(label='请上传知识库文件, 目前支持txt、docx、md格式',
136 | file_types=['.txt', '.md', '.docx'])
137 |
138 | with gr.Column(scale=4):
139 | chatbot = gr.Chatbot(label='ChatLLM')
140 | message = gr.Textbox(label='请输入问题')
141 | state = gr.State()
142 |
143 | with gr.Row():
144 | clear_history = gr.Button("🧹 清除历史对话")
145 | send = gr.Button("🚀 发送")
146 |
147 | send.click(predict,
148 | inputs=[
149 | message, large_language_model,
150 | embedding_model, file, VECTOR_SEARCH_TOP_K,
151 | state
152 | ],
153 | outputs=[message, chatbot, state])
154 | clear_history.click(fn=clear_session,
155 | inputs=[],
156 | outputs=[chatbot, state],
157 | queue=False)
158 |
159 | message.submit(predict,
160 | inputs=[
161 | message, large_language_model,
162 | embedding_model, file,
163 | VECTOR_SEARCH_TOP_K, state
164 | ],
165 | outputs=[message, chatbot, state])
166 | gr.Markdown("""提醒:
167 | 1. 使用时请先上传自己的知识文件,并且文件中不含某些特殊字符,否则将返回error.
168 | 2. 有任何使用问题,请通过[问题交流区](https://huggingface.co/spaces/thomas-yanxin/LangChain-ChatLLM/discussions)或[Github Issue区](https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui/issues)进行反馈.
169 | """)
170 | demo.queue().launch(server_name='0.0.0.0', share=True)
171 |
--------------------------------------------------------------------------------
/paddlepaddle/chatllm.py:
--------------------------------------------------------------------------------
1 |
2 | import os
3 | from typing import Dict, List, Optional, Tuple, Union
4 |
5 | from langchain.llms.base import LLM
6 | from langchain.llms.utils import enforce_stop_tokens
7 | from paddlenlp import Taskflow
8 |
9 | chatbot = Taskflow("text2text_generation", batch_size=2)
10 |
11 |
12 | class ChatLLM(LLM):
13 | max_token: int = 10000
14 | temperature: float = 0.1
15 | top_p = 0.9
16 | history = []
17 | tokenizer: object = None
18 | model: object = None
19 |
20 | def __init__(self):
21 | super().__init__()
22 |
23 | @property
24 | def _llm_type(self) -> str:
25 | return "ChatLLM"
26 |
27 | def _call(self,
28 | prompt: str,
29 | stop: Optional[List[str]] = None) -> str:
30 | prompt_list = []
31 | prompt_list.append(prompt)
32 | results = chatbot(prompt_list)
33 | response = results['result'][0]
34 | if stop is not None:
35 | response = enforce_stop_tokens(response, stop)
36 | return response
--------------------------------------------------------------------------------
/paddlepaddle/cli.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import gradio as gr
4 | import nltk
5 | from langchain.chains import RetrievalQA
6 | from langchain.document_loaders import UnstructuredFileLoader
7 | from langchain.prompts import PromptTemplate
8 | from langchain.prompts.prompt import PromptTemplate
9 | from langchain.vectorstores import FAISS
10 | from paddle_embedding import PaddleNLPEmbeddings
11 |
12 | from chatllm import ChatLLM
13 |
14 | nltk.data.path.append('../nltk_data')
15 | llm_model_dict = {'ChatGLM-6B': 'THUDM/chatglm-6b'}
16 |
17 | embedding_model_dict = {
18 | "rocketqa-zh-base-query": "rocketqa-zh-base-query-encoder",
19 | "rocketqa-zh-dureader": "rocketqa-zh-dureader-query-encoder",
20 | "rocketqa-zh-dureader-query": "rocketqa-zh-dureader-query-encoder",
21 | "rocketqa-zh-medium-query": "rocketqa-zh-medium-query-encoder",
22 | "rocketqa-zh-medium-para": "rocketqa-zh-medium-para-encoder"
23 | }
24 |
25 |
26 | def init_knowledge_vector_store(embedding_model, filepath):
27 |
28 | embeddings = PaddleNLPEmbeddings(
29 | model=embedding_model_dict[embedding_model])
30 |
31 | loader = UnstructuredFileLoader(filepath, mode="elements")
32 | docs = loader.load()
33 |
34 | vector_store = FAISS.from_documents(docs, embeddings)
35 |
36 | return vector_store
37 |
38 |
39 | def get_knowledge_based_answer(query,
40 | large_language_model,
41 | vector_store,
42 | VECTOR_SEARCH_TOP_K,
43 | chat_history=[]):
44 |
45 | prompt_template = """基于以下已知信息,请简洁并专业地回答用户的问题。
46 | 如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息"。不允许在答案中添加编造成分。另外,答案请使用中文。
47 |
48 | 已知内容:
49 | {context}
50 |
51 | 问题:
52 | {question}"""
53 | prompt = PromptTemplate(template=prompt_template,
54 | input_variables=["context", "question"])
55 | chatLLM = ChatLLM()
56 |
57 | knowledge_chain = RetrievalQA.from_llm(
58 | llm=chatLLM,
59 | retriever=vector_store.as_retriever(
60 | search_kwargs={"k": VECTOR_SEARCH_TOP_K}),
61 | prompt=prompt)
62 | knowledge_chain.combine_documents_chain.document_prompt = PromptTemplate(
63 | input_variables=["page_content"], template="{page_content}")
64 |
65 | knowledge_chain.return_source_documents = True
66 |
67 | result = knowledge_chain({"query": query})
68 |
69 | return result['result']
70 |
71 |
72 | def clear_session():
73 | return '', None
74 |
75 |
76 | def predict(input: str,
77 | large_language_model: str,
78 | embedding_model: str,
79 | file_obj,
80 | VECTOR_SEARCH_TOP_K: int,
81 | history=None):
82 | if history == None:
83 | history = []
84 |
85 | vector_store = init_knowledge_vector_store(embedding_model, file_obj.name)
86 |
87 | resp = get_knowledge_based_answer(
88 | query=input,
89 | large_language_model=large_language_model,
90 | vector_store=vector_store,
91 | VECTOR_SEARCH_TOP_K=VECTOR_SEARCH_TOP_K,
92 | chat_history=history,
93 | )
94 |
95 | history.append((input, resp['result']))
96 | return '', history, history
97 |
98 |
99 | if __name__ == "__main__":
100 |
101 | vector_store = init_knowledge_vector_store(
102 | 'rocketqa-zh-dureader', '/home/aistudio/docs/README-ChatGLM.md')
103 |
104 | # for i, (old_query, response) in enumerate(history):
105 | # prompt += "[Round {}]\n问:{}\n答:{}\n".format(i, old_query, response)
106 | # prompt += "[Round {}]\n问:{}\n答:".format(len(history), query)
107 |
108 | while True:
109 | query = input('提问: ')
110 | resp = get_knowledge_based_answer(query=query,
111 | large_language_model='ChatGLM-6B',
112 | vector_store=vector_store,
113 | VECTOR_SEARCH_TOP_K=10,
114 | chat_history=[])
115 |
116 | print("回答: " + resp)
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/paddlepaddle/paddle_embedding.py:
--------------------------------------------------------------------------------
1 | """Wrapper around PaddleNLP embedding models."""
2 | from typing import Any, List
3 |
4 | from langchain.embeddings.base import Embeddings
5 | from pydantic import BaseModel, Extra
6 |
7 |
8 | class PaddleNLPEmbeddings(BaseModel, Embeddings):
9 | """Wrapper around paddlenlp embedding models.
10 |
11 | To use, you should have the ``modelscope`` python package installed.
12 |
13 | Example:
14 | .. code-block:: python
15 |
16 | from langchain.embeddings import PaddleNLPEmbeddings
17 | model = "rocketqa-zh-base-query-encoder"
18 | embed = PaddleNLPEmbeddings(model=model)
19 | """
20 |
21 | text_encoder: Any
22 | model: str ='rocketqa-zh-base-query-encoder'
23 |
24 | """Model name to use."""
25 |
26 | def __init__(self, **kwargs: Any):
27 | """Initialize the modelscope"""
28 | super().__init__(**kwargs)
29 | try:
30 | import paddle.nn.functional as F
31 | from paddlenlp import Taskflow
32 |
33 | self.text_encoder = Taskflow("feature_extraction", model=self.model)
34 |
35 |
36 | except ImportError as e:
37 | raise ValueError(
38 | "Could not import some python packages." "Please install it with `pip install modelscope`."
39 | ) from e
40 |
41 | class Config:
42 | """Configuration for this pydantic object."""
43 |
44 | extra = Extra.forbid
45 |
46 | def embed_documents(self, texts: List[str]) -> List[List[float]]:
47 | """Compute doc embeddings using a modelscope embedding model.
48 |
49 | Args:
50 | texts: The list of texts to embed.
51 |
52 | Returns:
53 | List of embeddings, one for each text.
54 | """
55 | texts = list(map(lambda x: x.replace("\n", " "), texts))
56 | text_embeds = self.text_encoder(texts)
57 | embeddings = text_embeds["features"].numpy()
58 |
59 | return embeddings.tolist()
60 |
61 | def embed_query(self, text: str) -> List[float]:
62 | """Compute query embeddings using a modelscope embedding model.
63 |
64 | Args:
65 | text: The text to embed.
66 |
67 | Returns:
68 | Embeddings for the text.
69 | """
70 | text = text.replace("\n", " ")
71 | text_embeds = self.text_encoder(text)
72 | embedding = text_embeds["features"].numpy()[0]
73 |
74 | return embedding.tolist()
--------------------------------------------------------------------------------
/paddlepaddle/requirements.txt:
--------------------------------------------------------------------------------
1 | langchain==0.0.147
2 | unstructured[local-inference]
3 | layoutparser[layoutmodels,tesseract]
4 | nltk
5 | beautifulsoup4
6 | icetk
7 | cpm_kernels
8 | faiss-cpu
9 | protobuf==3.19.0
10 |
--------------------------------------------------------------------------------
/poetry.toml:
--------------------------------------------------------------------------------
1 | [virtualenvs]
2 | in-project = true
3 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "langchain-chatglm-webui"
3 | version = "0.1.0"
4 | description = "基于LangChain和ChatGLM-6B等系列LLM的针对本地知识库的自动问答"
5 | authors = ["thomas-yanxin "]
6 | license = "Apache-2.0"
7 | readme = "README.md"
8 | repository = "https://github.com/thomas-yanxin/LangChain-ChatGLM-Webui"
9 |
10 | [tool.poetry.dependencies]
11 | python = ">=3.9,<4.0"
12 | langchain = "0.0.147"
13 | fschat = "0.2.3"
14 | accelerate = "*"
15 | qdrant-client = "*"
16 | duckduckgo_search = "*"
17 | transformers = ">=4.28.0"
18 | tokenizers = "*"
19 | nltk = "*"
20 | sentence-transformers = "*"
21 | beautifulsoup4 = "*"
22 | icetk = "*"
23 | cpm_kernels = "*"
24 | faiss-cpu = "*"
25 | # TODO: uncomment next line when detectron2 support PEP517 and poetry.
26 | # detectron2 = { git = "https://github.com/facebookresearch/detectron2.git", tag = "v0.6" }
27 | wandb = "0.13.0"
28 | jina = ">=3.15.2"
29 | langchain-serve = ">=0.0.24"
30 | protobuf = "3.19.0"
31 |
32 | [tool.poetry.extras]
33 | unstructured = ["local-inference"]
34 | layoutparser = ["layoutmodels", "tesseract"]
35 |
36 |
37 | [build-system]
38 | requires = ["poetry-core"]
39 | build-backend = "poetry.core.masonry.api"
40 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | langchain==0.1.0
2 | fschat==0.2.3
3 | accelerate
4 | qdrant-client # API版本需要
5 | duckduckgo_search==2.9.5
6 | transformers>=4.32.0
7 | tokenizers
8 | unstructured[local-inference]
9 | layoutparser[layoutmodels,tesseract]
10 | nltk
11 | sentence-transformers==2.3.1
12 | beautifulsoup4
13 | icetk
14 | cpm_kernels
15 | faiss-cpu
16 | detectron2@git+https://github.com/facebookresearch/detectron2.git@v0.6#egg=detectron2 # PDF需要
17 | wandb==0.16.2
18 | jina # API版本需要
19 | langchain-serve # API版本需要
20 | protobuf==4.25.2
21 | langchain-community
22 | einops
23 |
--------------------------------------------------------------------------------