chatGLM-6B 部署记录 Windows
Windwos 下 chatGLM-6B 部署记录

准备环境
当前电脑配置:i5-6200u、8g内存、AMD M370(A卡难受)
用的cpu运行的,但配置实在不够,跑是能跑,慢死了。。。

安装 python
https://www.python.org/downloads/windows/
之前访问还很流畅,这段时间也学会抽风了
网页中搜索 Download Windows installer ,就能找到 windows 安装包的下载链接,按需下载。
这里安装的是 3.10.11 64位。安装时勾选加入环境变量(已经安装了其他版本的话要注意一下)
> python -V
Python 3.10.11
升级pip
> pip install --upgrade pip
pip换源(清华源,遇到过不好用的情况,可以换阿里源)
> pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
> pip config set install.trusted-host https://pypi.tuna.tsinghua.edu.cn

安装 gcc
chatGLM 加载模型时会自动编译两个c文件并加载:quantization_kernels_parallel.c 和 quantization_kernels.c
这两个文件是以base64存在模型文件夹的 quantization.py 中的,加载模型时会解码写出文件。
这里 quantization_kernels_parallel.c 的编译结果 quantization_kernels_parallel.so 在加载时报错了:
FileNotFoundError: Could not find module '[略]\quantization_kernels_parallel.so' (or one of its dependencies). Try using the full path with constructor syntax.
不明白这个错误,网上找的资料也看不懂怎么处理。
但是好像又没有影响,让它继续运行,后面就成功启动了,能行。
踩坑
之前 python 安装的64位,gcc 安装的 mingw ,不是mingw64,而是只支持32位的老家伙。
然后就总报 "%1不是有效的Win32应用程序",挠头。
期间把 python 换成了32位的,但因为还会报别的错误懒得搞,最后就直接用wsl走起了,简单粗暴。
这次才知道是因为要动态编译和加载c代码,然后 python 和 gcc 的位数对不上才报错的。
安装 mingw64 ,32位、64位都能编译
其官网好像没有下载地址,托管在 sourceforge:https://sourceforge.net/projects/mingw-w64/files/
在线安装的不好使,总连不上服务器:
MinGW-W64 Online Installer
|- MinGW-W64-install.exe (exe,但不下载)
下面8.1.0版本里 选这两个中的一个:
MinGW-W64 GCC-8.1.0
|- x86_64-win32-sjlj (用的这个,另一个没试,都是压缩包)
|- x86_64-win32-seh
找个地方解压进去,然后把 bin 目录配置到 环境变量里去:
bin 目录的例子: X:\[略]\mingw64\bin
> gcc -v
...一大堆东西
gcc version 8.1.0 (x86_64-win32-sjlj-rev0, Built by MinGW-W64 project)
tdm-gcc
还有说安装 tdm-gcc 也行,但没去尝试,这就给个地址吧:
https://jmeubank.github.io/tdm-gcc/

git
https://git-scm.com/download
可以不用装,直接从网站下载项目压缩包就行。

部署 chatGLM2-6B
chatGLM-6B 已经有一段时间没有更新了,建议直接部署 chatGLM2-6B,而且二代速度确实快了一丢丢。
现在2023-07-08,昨天 chatGLM2-6B 还有更新,应该还会更新下去吧。
智谱AI上看到 部署 chatGLM2-6B 的本地私有化定价 30W/年 。
下面都是以 chatGLM2-6B 部署的,但 chatGLM-6B 也能启动。

直接下载 chatGLM2-6B
下载项目
https://github.com/THUDM/ChatGLM2-6B
页面上有个 [<>Code] 按钮,点击后再点击 [download zip] 下载压缩包,解压出来就行了
这里把 ChatGLM2-6B-main 中的文件都解压到 F:\_AI\ChatGLM2-6B 目录了
下载模型
https://huggingface.co/THUDM/chatglm2-6b-int4/tree/main
这里的文件都下载下来,放到同一个文件夹里,抱脸不像github可以打包下载,只能一个一个下载了
这里都下载到 F:\_AI\ChatGLM2-6B\THUDM\chatglm2-6b-int4 目录了
对于 chatGLM-6B 就是把地址改成 chatGLM-6B 的地址就行。
因为两个项目的地址没什么差异,直接把上面地址中的 chatGLM2-6B 改成 chatGLM-6B 就可以了。

git 获取chatGLM2-6B
> cd /D F:\_AI
> git clone https://github.com/THUDM/ChatGLM2-6B.git
... 略
> mkdir F:\_AI\ChatGLM2-6B\THUDM
> cd F:\_AI\ChatGLM2-6B\THUDM
> git clone https://huggingface.co/THUDM/chatglm2-6b-int4
... 略
同样, chatGLM-6B 就是 chatGLM2-6B 改成 chatGLM-6B 就可以了。

安装依赖
> cd /D F:\_AI\ChatGLM2-6B
> pip install -r requirements.txt
... 略

修改模型路径
之前用的相对路径出过一些问题,但不记得是什么情况了,这里先保留组织模型绝对路径的处理。
# 在启动的py文件里添加一段组织模型路径的代码
# 模型位置使用绝对路径并输出一下,可以检查一下对不对
current_path = os.path.abspath(__file__) # 当前脚本文件绝对路径
current_dir = os.path.dirname(current_path) # 当前脚本所在文件夹绝对路径
model_path = os.path.join(current_dir, "THUDM", "chatglm2-6b-int4") # 拼接路径
print("模型路径:", model_path)
# 修改 AutoTokenizer.from_pretrained 和 AutoModel.from_pretrained 的第一个参数为前面的 model_path
# AutoModel.from_pretrained(...).cuda() 改为 .float() 使用cpu运行。
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModel.from_pretrained(model_path, trust_remote_code=True).float()

启动 cli_demo.py
python cli_demo.py
上来就报错缺少 readline
ModuleNotFoundError: No module named 'readline'
pip install readline 安装不上,网上说安装 pyreadline
pip install pyreadline 确实能安装,但启动 cli_demo.py 又报错
AttributeError: module 'collections' has no attribute 'Callable'
Python 3.10 版本 collections 将一些属性放到了 collections.abc 子模块下,Callable 也是其中之一。(为什么是abc。。)
所以会出现 collections 没有 xx 属性的错误。
按错误信息找到报错位置,[略]\site-packages\pyreadline\py3k_compat.py
搜索 collections.Callable 改为 collections.abc.Callable (其实错误信息中已经给出在第8行了)
再次启动 cli_demo.py,成功。

启动 web_demo.py
python web_demo.py
也许是上面都处理过了,直接就启动了

启动 api.py
python api.py
也成功了。使用 PostMan 试了一下,可以运行。
POST http://127.0.0.1:8000
{
"prompt": "你好",
"history": [],
"max_length": 2048,
"top_p": 0.8,
"temperature": 0.95
}
参数的值的类型不能给错,如果数字带引号",程序里使用的时候不会自动转换成数字,于是就报错了。
api 就没法用打字机的效果了,机器慢等半天,还以为卡死了。

chatglm.cpp
cmake
此项目需要 cmake 进行编译,下载地址:https://cmake.org/download/
下载的 Windows x64 ZIP ,压缩包的版本,解压出来,把里面的 bin 目录配置到环境变量里。
bin 目录的例子: X:\[略]\cmake-3.27.0-rc4-windows-x86_64\bin
> cmake --version
cmake version 3.27.0-rc4
git 获取chatglm.cpp
> cd /D F:\_AI
> git clone --recursive https://github.com/li-plus/chatglm.cpp.git
... 略
> cd F:\_AI\chatglm.cpp
> git submodule update --init --recursive
模型转换
此项目需要把 chatGLM2-6B 的模型转换成 gglm 的,并提供了转换的代码 convert.py 。
先安装 convert.py 所需要的依赖
> pip install tabulate
这里用 chatGLM2-6B 的模型进行转换,chatGLM2-6B 用上面的步骤部署过了。
因为装过 chatGLM2-6B 的依赖了,所以这里也不知道单独部署 chatglm.cpp 是否需要安装 chatGLM2-6B 的依赖,大概是要的吧。
然后运行转换,把 F:\_AI\ChatGLM2-6B\THUDM\chatglm2-6b-int4 转换为 chatglm2-ggml.bin 文件
> python convert.py -i F:\_AI\ChatGLM2-6B\THUDM\chatglm2-6b-int4 -t q4_0 -o chatglm2-ggml.bin
使用 CMake 编译项目:
> cmake -B build
... 似乎成功了,又有点不像,但文件都生成好了
> cmake --build build -j
... 报的错误滚动了半天,人傻了
网上找了一个设置用 mingw64 的,先设置,再cmake还那样
> Set CC=[mingw64目录]\bin\gcc.exe
> Set CXX=[mingw64目录]\bin\g++.exe
不想搞了,先这样吧,反正 wsl 能跑起来。