ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia
- 初
- 环境与设备
- 环境准备
- 克隆模型
- 代码部署 ChatGLM-6B
- 完整代码
ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。 ChatGLM-6B 使用了和 ChatGPT 相似的技术,针对中文问答和对话进行了优化。经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答
本篇文章将介绍ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia GUP
初
希望能写一些简单的教程和案例分享给需要的人
环境与设备
系统:Ubuntu 22.04.2 LTS (ubuntu 就行)
设备:Nvidia GeForce RTX 4090 (英伟达 就行)
以下是一些推荐的消费级显卡:
-
Nvidia GeForce RTX 3080: RTX 3080 是一款性能出色的显卡,适用于高质量游戏和深度学习任务。它提供了强大的图形性能和 CUDA 核心,能够满足许多高性能计算需求。
-
AMD Radeon RX 6800 XT: 如果你对 AMD 的显卡感兴趣,RX 6800 XT 是一款强大的选择。它具有出色的游戏性能和计算能力,适用于多种应用场景。
-
Nvidia GeForce RTX 3070: RTX 3070 是一款性价比较高的显卡,它在性能和价格之间找到了很好的平衡。它适用于游戏、图形设计和一些中等规模的深度学习任务。
环境准备
在开始之前,确保 Ubuntu 系统已经安装了Python和必要的依赖项。
输入下面命令:判断PIP是否安装
pip --version
如果没安装,就安装 python3-pip
sudo apt update
sudo apt install python3-pip
安装完成后如下图:
克隆模型
全部都完成后,我们就可以去下载模型了
去下面这个网站,下载模型
https://huggingface.co/THUDM/chatglm2-6b-32k
点击克隆后,我们需要使用命令:
git lfs install
git clone https://huggingface.co/THUDM/chatglm2-6b-32k
这个时候,可能会遇到报错:需要安装 git ,还有 git-lfs
sudo apt install git
sudo apt install git-lfs
这两个都安装完成后,我们再克隆,我这边会到指定的路径克隆,大家自行选择。
克隆成功后,如下图:
代码部署 ChatGLM-6B
git clone https://github.com/THUDM/ChatGLM-6B.git
代码克隆下来后,就安装环境 pytorch
PyTorch 是一个开源的机器学习框架,它提供了丰富的工具和库,用于构建和训练各种深度学习模型。它由 Facebook 的人工智能研究院(Facebook AI Research,缩写为FAIR)开发并维护,旨在为研究人员和开发者提供一个灵活、动态的平台来实现各种机器学习任务。
PyTorch 提供了一种动态计算图的机制,这意味着您可以在运行时构建、修改和调整计算图,使其更加灵活和直观。这使得 PyTorch 在实验和原型开发阶段非常有用,因为它能够快速适应不同的数据和模型结构。此外,PyTorch 还具有广泛的神经网络库、优化算法以及用于数据加载和预处理的工具。它也支持 GPU 加速,可以在 NVIDIA CUDA 上利用 GPU 进行高效的计算,加速模型训练过程。总之,PyTorch 是一个受欢迎的机器学习框架,广泛用于深度学习研究、开发和应用。它以其动态计算图、灵活性和易用性而闻名。
直接进入下面网址
https://pytorch.org/
进入页面后,翻到下一页,我这里是ubuntu 所以我这边用预览版最新的 CUDA 12.1
关于CUDA的支持可以通过命令 nvidia-smi 来查看
我们执行命令
pip3 install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu121
等待安装结束
都按照完成后,进入项目,我这里项目路径是这个 /home/ai/dev/code
cd /home/ai/dev/code
cd /home/ai/dev/code/ChatGLM-6B
然后安装 环境
pip install -r requirements.txt
等待这些都安装完成后,
api.py 文件中的路径:
将原本的:THUDM/chatglm-6b
更换成:/home/ai/dev/model/chatglm2-6b-32k
/home/ai/dev/model/chatglm2-6b-32k
执行下面命令:
python3 api.py
测试一下:
curl -X POST "http://127.0.0.1:8000" \
-H 'Content-Type: application/json' \
-d '{"prompt": "你好", "history": []}'
上面是 API 的效果。如果选需要 ui 版本 web_demo.py 这个文件 修改模型路径后,执行:
python3 web_demo.py
修改截图如下:
方便外网请求的修改地方如下:
执行结果如下:
完整代码
api.py
from fastapi import FastAPI, Request
from transformers import AutoTokenizer, AutoModel
import uvicorn, json, datetime
import torch
DEVICE = "cuda"
DEVICE_ID = "0"
CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE
def torch_gc():
if torch.cuda.is_available():
with torch.cuda.device(CUDA_DEVICE):
torch.cuda.empty_cache()
torch.cuda.ipc_collect()
app = FastAPI()
@app.post("/")
async def create_item(request: Request):
global model, tokenizer
json_post_raw = await request.json()
json_post = json.dumps(json_post_raw)
json_post_list = json.loads(json_post)
prompt = json_post_list.get('prompt')
history = json_post_list.get('history')
max_length = json_post_list.get('max_length')
top_p = json_post_list.get('top_p')
temperature = json_post_list.get('temperature')
response, history = model.chat(tokenizer,
prompt,
history=history,
max_length=max_length if max_length else 2048,
top_p=top_p if top_p else 0.7,
temperature=temperature if temperature else 0.95)
now = datetime.datetime.now()
time = now.strftime("%Y-%m-%d %H:%M:%S")
answer = {
"response": response,
"history": history,
"status": 200,
"time": time
}
log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(response) + '"'
print(log)
torch_gc()
return answer
if __name__ == '__main__':
tokenizer = AutoTokenizer.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True)
model = AutoModel.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True).half().cuda()
model.eval()
uvicorn.run(app, host='0.0.0.0', port=8000, workers=1)
web_demo.py
from transformers import AutoModel, AutoTokenizer
import gradio as gr
import mdtex2html
tokenizer = AutoTokenizer.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True)
model = AutoModel.from_pretrained("/home/ai/dev/model/chatglm2-6b-32k", trust_remote_code=True).half().cuda()
model = model.eval()
"""Override Chatbot.postprocess"""
def postprocess(self, y):
if y is None:
return []
for i, (message, response) in enumerate(y):
y[i] = (
None if message is None else mdtex2html.convert((message)),
None if response is None else mdtex2html.convert(response),
)
return y
gr.Chatbot.postprocess = postprocess
def parse_text(text):
"""copy from https://github.com/GaiZhenbiao/ChuanhuChatGPT/"""
lines = text.split("\n")
lines = [line for line in lines if line != ""]
count = 0
for i, line in enumerate(lines):
if "```" in line:
count += 1
items = line.split('`')
if count % 2 == 1:
lines[i] = f'<pre><code class="language-{items[-1]}">'
else:
lines[i] = f'<br></code></pre>'
else:
if i > 0:
if count % 2 == 1:
line = line.replace("`", "\`")
line = line.replace("<", "<")
line = line.replace(">", ">")
line = line.replace(" ", " ")
line = line.replace("*", "*")
line = line.replace("_", "_")
line = line.replace("-", "-")
line = line.replace(".", ".")
line = line.replace("!", "!")
line = line.replace("(", "(")
line = line.replace(")", ")")
line = line.replace("$", "$")
lines[i] = "<br>"+line
text = "".join(lines)
return text
def predict(input, chatbot, max_length, top_p, temperature, history):
chatbot.append((parse_text(input), ""))
for response, history in model.stream_chat(tokenizer, input, history, max_length=max_length, top_p=top_p,
temperature=temperature):
chatbot[-1] = (parse_text(input), parse_text(response))
yield chatbot, history
def reset_user_input():
return gr.update(value='')
def reset_state():
return [], []
with gr.Blocks() as demo:
gr.HTML("""<h1 align="center">ChatGLM</h1>""")
chatbot = gr.Chatbot()
with gr.Row():
with gr.Column(scale=4):
with gr.Column(scale=12):
user_input = gr.Textbox(show_label=False, placeholder="Input...", lines=10).style(
container=False)
with gr.Column(min_width=32, scale=1):
submitBtn = gr.Button("Submit", variant="primary")
with gr.Column(scale=1):
emptyBtn = gr.Button("Clear History")
max_length = gr.Slider(0, 4096, value=2048, step=1.0, label="Maximum length", interactive=True)
top_p = gr.Slider(0, 1, value=0.7, step=0.01, label="Top P", interactive=True)
temperature = gr.Slider(0, 1, value=0.95, step=0.01, label="Temperature", interactive=True)
history = gr.State([])
submitBtn.click(predict, [user_input, chatbot, max_length, top_p, temperature, history], [chatbot, history],
show_progress=True)
submitBtn.click(reset_user_input, [], [user_input])
emptyBtn.click(reset_state, outputs=[chatbot, history], show_progress=True)
demo.queue().launch(server_name='0.0.0.0', share=False, inbrowser=True)