Merge branch 'main' into main
This commit is contained in:
commit
f1f7e4bbf8
15
FAQ.md
Normal file
15
FAQ.md
Normal file
@ -0,0 +1,15 @@
|
||||
## Q1
|
||||
|
||||
**Mac直接加载量化后的模型出现提示 `clang: error: unsupported option '-fopenmp'**
|
||||
|
||||
这是由于Mac由于本身缺乏omp导致的,此时可运行但是单核。需要单独安装 openmp 依赖,即可在Mac下使用OMP:
|
||||
|
||||
```bash
|
||||
# 参考`https://mac.r-project.org/openmp/`
|
||||
## 假设: gcc(clang)是14.x版本,其他版本见R-Project提供的表格
|
||||
curl -O https://mac.r-project.org/openmp/openmp-14.0.6-darwin20-Release.tar.gz
|
||||
sudo tar fvxz openmp-14.0.6-darwin20-Release.tar.gz -C /
|
||||
```
|
||||
此时会安装下面几个文件:`/usr/local/lib/libomp.dylib`, `/usr/local/include/ompt.h`, `/usr/local/include/omp.h`, `/usr/local/include/omp-tools.h`。
|
||||
|
||||
> 注意:如果你之前运行`ChatGLM`项目失败过,最好清一下Huggingface的缓存,i.e. 默认下是 `rm -rf ${HOME}/.cache/huggingface/modules/transformers_modules/chatglm-6b-int4`。由于使用了`rm`命令,请明确知道自己在删除什么。
|
42
README.md
42
README.md
@ -123,17 +123,14 @@ Multi-Query Attention 同时也降低了生成过程中 KV Cache 的显存占用
|
||||
|
||||
## 使用方式
|
||||
### 环境安装
|
||||
|
||||
使用 pip 安装依赖:`pip install -r requirements.txt`,其中 `transformers` 库版本推荐为 `4.27.1`,`torch` 推荐使用 2.0 以上的版本,以获得最佳的推理性能。
|
||||
|
||||
|
||||
我们提供了一个网页版 Demo 和一个命令行 Demo。使用时首先需要下载本仓库:
|
||||
|
||||
首先需要下载本仓库:
|
||||
```shell
|
||||
git clone https://github.com/THUDM/ChatGLM2-6B
|
||||
cd ChatGLM2-6B
|
||||
```
|
||||
|
||||
然后使用 pip 安装依赖:`pip install -r requirements.txt`,其中 `transformers` 库版本推荐为 `4.30.2`,`torch` 推荐使用 2.0 以上的版本,以获得最佳的推理性能。
|
||||
|
||||
### 代码调用
|
||||
|
||||
可以通过如下代码调用 ChatGLM2-6B 模型来生成对话:
|
||||
@ -183,7 +180,18 @@ python web_demo.py
|
||||
```
|
||||
|
||||
程序会运行一个 Web Server,并输出地址。在浏览器中打开输出的地址即可使用。
|
||||
> 由于国内 Gradio 的网络访问较为缓慢,启用 `demo.queue().launch(share=True, inbrowser=True)` 时所有网络会经过 Gradio 服务器转发,导致打字机体验大幅下降,现在默认启动方式已经改为 `share=False`,如有需要公网访问的需求,可以重新修改为 `share=True` 启动。
|
||||
> 默认使用了 `share=False` 启动,不会生成公网链接。如有需要公网访问的需求,可以修改为 `share=True` 启动。
|
||||
>
|
||||
|
||||
感谢 [@AdamBear](https://github.com/AdamBear) 实现了基于 Streamlit 的网页版 Demo `web_demo2.py`。使用时首先需要额外安装以下依赖:
|
||||
```shell
|
||||
pip install streamlit streamlit-chat
|
||||
```
|
||||
然后通过以下命令运行:
|
||||
```shell
|
||||
streamlit run web_demo2.py
|
||||
```
|
||||
经测试,如果输入的 prompt 较长的话,使用基于 Streamlit 的网页版 Demo 会更流畅。
|
||||
|
||||
### 命令行 Demo
|
||||
|
||||
@ -232,7 +240,6 @@ model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).q
|
||||
|
||||
如果你的内存不足,可以直接加载量化后的模型:
|
||||
```python
|
||||
# INT8 量化的模型将"THUDM/chatglm-6b-int4"改为"THUDM/chatglm-6b-int8"
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b-int4",trust_remote_code=True).cuda()
|
||||
```
|
||||
|
||||
@ -244,14 +251,15 @@ model = AutoModel.from_pretrained("THUDM/chatglm2-6b-int4",trust_remote_code=Tru
|
||||
```python
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).float()
|
||||
```
|
||||
|
||||
<!--
|
||||
|
||||
如果遇到了报错 `Could not find module 'nvcuda.dll'` 或者 `RuntimeError: Unknown platform: darwin` (MacOS) ,请[从本地加载模型](README.md#从本地加载模型) -->
|
||||
如果你的内存不足的话,也可以使用量化后的模型
|
||||
```python
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b-int4",trust_remote_code=True).float()
|
||||
```
|
||||
在 cpu 上运行量化后的模型需要安装 `gcc` 与 `openmp`。多数 Linux 发行版默认已安装。对于 Windows ,可在安装 [TDM-GCC](https://jmeubank.github.io/tdm-gcc/) 时勾选 `openmp`。 Windows 测试环境 `gcc` 版本为 `TDM-GCC 10.3.0`, Linux 为 `gcc 11.3.0`。在 MacOS 上请参考 [Q1](FAQ.md#q1)。
|
||||
|
||||
### Mac 部署
|
||||
|
||||
对于搭载了 Apple Silicon 或者 AMD GPU 的 Mac,可以使用 MPS 后端来在 GPU 上运行 ChatGLM2-6B。需要参考 Apple 的 [官方说明](https://developer.apple.com/metal/pytorch) 安装 PyTorch-Nightly(正确的版本号应该是2.1.0.dev2023xxxx,而不是 2.0.0)。
|
||||
对于搭载了 Apple Silicon 或者 AMD GPU 的 Mac,可以使用 MPS 后端来在 GPU 上运行 ChatGLM2-6B。需要参考 Apple 的 [官方说明](https://developer.apple.com/metal/pytorch) 安装 PyTorch-Nightly(正确的版本号应该是2.x.x.dev2023xxxx,而不是 2.x.x)。
|
||||
|
||||
目前在 MacOS 上只支持[从本地加载模型](README.md#从本地加载模型)。将代码中的模型加载改为从本地加载,并使用 mps 后端:
|
||||
```python
|
||||
@ -259,12 +267,8 @@ model = AutoModel.from_pretrained("your local path", trust_remote_code=True).to(
|
||||
```
|
||||
|
||||
加载半精度的 ChatGLM2-6B 模型需要大概 13GB 内存。内存较小的机器(比如 16GB 内存的 MacBook Pro),在空余内存不足的情况下会使用硬盘上的虚拟内存,导致推理速度严重变慢。
|
||||
<!-- 此时可以使用量化后的模型如 chatglm-6b-int4。因为 GPU 上量化的 kernel 是使用 CUDA 编写的,因此无法在 MacOS 上使用,只能使用 CPU 进行推理。
|
||||
```python
|
||||
# INT8 量化的模型将"THUDM/chatglm-6b-int4"改为"THUDM/chatglm-6b-int8"
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm-6b-int4",trust_remote_code=True).float()
|
||||
```
|
||||
为了充分使用 CPU 并行,还需要[单独安装 OpenMP](FAQ.md#q1)。 -->
|
||||
此时可以使用量化后的模型 chatglm2-6b-int4。因为 GPU 上量化的 kernel 是使用 CUDA 编写的,因此无法在 MacOS 上使用,只能使用 CPU 进行推理。
|
||||
为了充分使用 CPU 并行,还需要[单独安装 OpenMP](FAQ.md#q1)。
|
||||
|
||||
## 协议
|
||||
|
||||
|
2
api.py
2
api.py
@ -51,6 +51,6 @@ async def create_item(request: Request):
|
||||
|
||||
if __name__ == '__main__':
|
||||
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True)
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True, device='cuda')
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).cuda()
|
||||
model.eval()
|
||||
uvicorn.run(app, host='0.0.0.0', port=8000, workers=1)
|
||||
|
@ -6,7 +6,7 @@ import readline
|
||||
from utils import load_model_on_gpus
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True)
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True, device='cuda')
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).cuda()
|
||||
# 多显卡支持,使用下面三行代替上面两行,将num_gpus改为你实际的显卡数量
|
||||
# model_path = "THUDM/chatglm2-6b"
|
||||
# tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
|
||||
|
@ -1,5 +1,5 @@
|
||||
protobuf
|
||||
transformers==4.27.1
|
||||
transformers==4.30.2
|
||||
cpm_kernels
|
||||
torch>=2.0
|
||||
gradio
|
||||
|
@ -1,9 +1,10 @@
|
||||
from transformers import AutoModel, AutoTokenizer
|
||||
import gradio as gr
|
||||
import mdtex2html
|
||||
from utils import load_model_on_gpus
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True)
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True, device='cuda')
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).cuda()
|
||||
# 多显卡支持,使用下面三行代替上面两行,将num_gpus改为你实际的显卡数量
|
||||
# model_path = "THUDM/chatglm2-6b"
|
||||
# tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
|
||||
|
72
web_demo2.py
Normal file
72
web_demo2.py
Normal file
@ -0,0 +1,72 @@
|
||||
from transformers import AutoModel, AutoTokenizer
|
||||
import streamlit as st
|
||||
from streamlit_chat import message
|
||||
|
||||
|
||||
st.set_page_config(
|
||||
page_title="ChatGLM2-6b 演示",
|
||||
page_icon=":robot:",
|
||||
layout='wide'
|
||||
)
|
||||
|
||||
|
||||
@st.cache_resource
|
||||
def get_model():
|
||||
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True)
|
||||
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).cuda()
|
||||
model = model.eval()
|
||||
return tokenizer, model
|
||||
|
||||
|
||||
MAX_TURNS = 20
|
||||
MAX_BOXES = MAX_TURNS * 2
|
||||
|
||||
|
||||
def predict(input, max_length, top_p, temperature, history=None):
|
||||
tokenizer, model = get_model()
|
||||
if history is None:
|
||||
history = []
|
||||
|
||||
with container:
|
||||
if len(history) > 0:
|
||||
if len(history)>MAX_BOXES:
|
||||
history = history[-MAX_TURNS:]
|
||||
for i, (query, response) in enumerate(history):
|
||||
message(query, avatar_style="big-smile", key=str(i) + "_user")
|
||||
message(response, avatar_style="bottts", key=str(i))
|
||||
|
||||
message(input, avatar_style="big-smile", key=str(len(history)) + "_user")
|
||||
st.write("AI正在回复:")
|
||||
with st.empty():
|
||||
for response, history in model.stream_chat(tokenizer, input, history, max_length=max_length, top_p=top_p,
|
||||
temperature=temperature):
|
||||
query, response = history[-1]
|
||||
st.write(response)
|
||||
|
||||
return history
|
||||
|
||||
|
||||
container = st.container()
|
||||
|
||||
# create a prompt text for the text generation
|
||||
prompt_text = st.text_area(label="用户命令输入",
|
||||
height = 100,
|
||||
placeholder="请在这儿输入您的命令")
|
||||
|
||||
max_length = st.sidebar.slider(
|
||||
'max_length', 0, 32768, 8192, step=1
|
||||
)
|
||||
top_p = st.sidebar.slider(
|
||||
'top_p', 0.0, 1.0, 0.8, step=0.01
|
||||
)
|
||||
temperature = st.sidebar.slider(
|
||||
'temperature', 0.0, 1.0, 0.95, step=0.01
|
||||
)
|
||||
|
||||
if 'state' not in st.session_state:
|
||||
st.session_state['state'] = []
|
||||
|
||||
if st.button("发送", key="predict"):
|
||||
with st.spinner("AI正在思考,请稍等........"):
|
||||
# text generation
|
||||
st.session_state["state"] = predict(prompt_text, max_length, top_p, temperature, st.session_state["state"])
|
Loading…
Reference in New Issue
Block a user