赞
踩
1、准备阶段
glibc版本不能太低,需要大于2.27,我的是2.29
查看glibc版本
ldd -version
python版本不能太旧,我的是conda安装的python3.10
验证python版本
python -V
下载qwen.cpp的工程
git clone --recursive https://github.com/QwenLM/qwen.cpp
如果下载不成功,就手动下载工程的zip文件,下载完上传到linux服务器解压
注意手动下载需要手动安装第三方库(编译main所需,可以选择不安装)
到工程的third_party目录,查看第三方库是否安装成功,如果都是空的,需要手动下载第三方库,存放在third_party目录。
在这里找到第三方库链接:
https://github.com/QwenLM/qwen.cpp/tree/master/third_party
2、下载qwen1.8b的chat模型到本地
从魔塔社区下载:
创建一个python文件,命名为download.py。输入以下代码,需安装modelscope库
下载qwen1.8b模型,使用魔塔社区提供的链接,cache_dir为储存在本地目录,根据情况自己设置
- from modelscope import snapshot_download
- model_dir = snapshot_download("Qwen/Qwen-1_8B-Chat", revision = "v1.0.0", cache_dir='model')
输入完执行download.py,会自动把模型文件下载到当前目录的model目录下面。
或者从Hugging Face下载:
https://huggingface.co/Qwen/Qwen-1_8B-Chat
通过魔法进入,手动下载
或者使用以下命令:
git lfs clone https://huggingface.co/Qwen/Qwen-1_8B-Chat
检验模型是否下载完成
cd到模型文件存放目录,使用ls命令查看
3、模型格式转换
回到下载的qwen.cpp工程所在目录,然后执行命令
python3 qwen_cpp/convert.py -i Qwen/Qwen-1.8B-Chat -t q4_0 -o qwen1.8b-ggml.bin
注意:
-i后面跟的是模型文件所在目录,需要输入自己下载好的文件所在目录
-t表示量化程度
原文档说明:
转换完成后会在当前目录生成一个qwen1.8b-ggml.bin的文件,大概只有900多MB大小。
将qwen1.8b-ggml.bin和qwen_1.8chat模型所在目录的qwen.tiktoken文件复制到同一个目录。
4、下载加载qwen.cpp对应的python库
cpu版
pip install -U qwen-cpp
或者从源安装
- # 从GitHub安装
- pip install git+https://github.com/QwenLM/qwen.cpp.git@master
- # 从当前工程安装,需要在qwen.cpp工程目录下
- pip install .
测试是否安装成功:
- python
-
- import qwen_cpp
无报错说明安装成功。
我安装0.1.3版会存在一些问题,所以安装的是0.1.2版。
5、api代码
将qwen模型加载,并提供为openai格式的api
qwen没有提供直接的方式,需要自己想办法。
访问chatglm.cpp项目,复制openai_api.py里面的内容到本地进行修改,两者加载方式区别不大,只需要改很少内容。
https://github.com/li-plus/chatglm.cpp/tree/main/chatglm_cpp
第6行:
import chatglm_cpp
修改为:
import qwen_cpp
第16-18行:
- class Settings(BaseSettings):
- model: str = "chatglm-ggml.bin"
- num_threads: int = 0
修改为:
- class Settings(BaseSettings):
- model: str = "/home/big_model_http/model/qwen1.8b-ggml.bin"
- tiktoken_path : str = "/home/big_model_http/model/qwen.tiktoken"
- num_threads: int = 8
注意修改为自己的路径,num_threads为线程数,cpu上使用多少线程开启,我自己的8线程最优。
第150行注释掉:
#messages = [chatglm_cpp.ChatMessage(role=msg.role, content=msg.content) for msg in body.messages]
修改为:
messages = [msg.content for msg in body.messages if msg.role in ["user", "assistant"]]
第157-164行:
- output = pipeline.chat(
- messages=messages,
- max_length=body.max_tokens,
- max_context_length=max_context_length,
- do_sample=body.temperature > 0,
- top_p=body.top_p,
- temperature=body.temperature,
- )
将messages=messages修改为history=messages
- output = pipeline.chat(
- history=messages,
- max_length=body.max_tokens,
- max_context_length=max_context_length,
- do_sample=body.temperature > 0,
- top_p=body.top_p,
- num_threads=settings.num_threads,
- temperature=body.temperature,
- )
第166-167行计算token修改:
- prompt_tokens = len(pipeline.tokenizer.encode_messages(messages, max_context_length))
- completion_tokens = len(pipeline.tokenizer.encode(output.content, body.max_tokens))
修改为以下:
- prompt_tokens = len(pipeline.tokenizer.encode_history(messages, max_context_length))
- completion_tokens = len(pipeline.tokenizer.encode(output, body.max_tokens))
代码最后添加个启动主程序:
- if __name__ == "__main__":
- import uvicorn
- uvicorn.run(app, host="0.0.0.0", port=8000)
然后直接执行:
python openai_api.py
修改之后可以直接复用chatglm.cpp的openai格式代码,但是没有system角色,使用system角色可能需要改qwen.cpp的源码,我不会改,或者使用llama.cpp库,和这个相似的操作。
测试是否成功:
建一个测试文件test.sh
- curl -X POST http://127.0.0.1:8000/v1/chat/completions \
- -H "Content-Type: application/json" \
- -d '{
- "max_tokens": 2200,
- "temperature": 0.01,
- "max_content_length": 2048,
- "messages": [
- {
- "role": "system",
- "content": "你是一个乐于助人的助手"
- },
- {
- "role": "user",
- "content": "你好?"
- }
- ]
- }'
给文件赋予权限
chmod +x test.sh
执行:
./test.sh
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。