ChatGLM3
本项目实现BM1684X部署语言大模型ChatGLM3-6B。通过TPU-MLIR编译器将模型转换成bmodel,并采用c++代码将其部署到BM1684X的PCIE环境,或者SoC环境。
在知乎上写了关于ChatGLM
的解读,方便大家理解源码:
开发环境
- 下载docker,启动容器,如下:
docker pull sophgo/tpuc_dev:latest
# myname1234 is just an example, you can set your own name
docker run --privileged --name myname1234 -v $PWD:/workspace -it sophgo/tpuc_dev:latest
后文假定环境都在docker的/workspace
目录。
- 从Huggingface下载
ChatGLM3-6B
,比较大,会花较长时间
git lfs install
git clone git@hf.co:THUDM/chatglm3-6b
并对该工程做三点修改(也可以直接使用files/chatglm3-6b
下的config.json
和modeling_chatglm.py
替换原模型的对应文件):
将
config.json
文件中seq_length
配置为512;将
modeling_chatglm.py
文件中的如下代码:
if attention_mask is not None:
attention_scores = attention_scores.masked_fill(attention_mask, float("-inf"))
修改为:
if attention_mask is not None:
attention_scores = attention_scores + (attention_mask * -10000.0)
这样修改可以提升效率,使用masked_fill
效率低下;另一方面masked_fill
转ONNX存在些bug。
- 将
modeling_chatglm.py
文件中的如下代码:
pytorch_major_version = int(torch.__version__.split('.')[0])
if pytorch_major_version >= 2:
修改为:
pytorch_major_version = int(torch.__version__.split('.')[0])
if False:
这是因为ONNX无法支持torch.nn.functional.scaled_dot_product_attention
算子的转换。
- 下载
TPU-MLIR
代码并编译,(也可以直接下载编译好的release包解压)
git clone git@github.com:sophgo/tpu-mlir.git
cd tpu-mlir
source ./envsetup.sh
./build.sh
编译模型
- 指定
ChatGLM3-6B
的python路径
export PYTHONPATH=your_chatglm3-6b_path:$PYTHONPATH
- 导出所有onnx模型,如果过程中提示缺少某些组件,直接
pip3 install 组件
即可;seq_length需与config.json中的设置相同,device默认为cpu。
cd compile
python3 export_onnx.py --model_path your_chatglm3-6b_path --seq_length 512 --device cpu
此时有大量onnx模型被导出到tmp目录。
- 对onnx模型进行编译
目前TPU-MLIR支持对ChatGLM3进行F16、INT8和INT4量化,且支持多芯分布式推理,默认情况下会进行F16量化和单芯推理,最终生成chatglm3-6b_f16_1devv.bmodel
文件
./compile.sh --name chatglm3-6b
若想进行INT8或INT4量化,则执行以下命令,最终生成chatglm3-6b_int8_1dev.bmodel
或chatglm3-6b_int4_1dev.bmodel
文件,如下命令:
./compile.sh --mode int8 --name chatglm3-6b # or int4
若想进行2芯推理,则执行以下命令,最终生成chatglm3-6b_f16_2dev.bmodel
文件,4芯8芯同理(python_demo目前仅支持单芯):
./compile.sh --num_device 2 --name chatglm3-6b
编译程序(python_demo版本)
执行如下编译,(PCIE版本与SoC版本相同):
cd python_demo
mkdir build
cd build
cmake ..
make
mv chat.cpython-310-x86_64-linux-gnu.so ..
cd ..
运行pipeline.py
:
source ../../../envsetup.sh
python3 pipeline.py --model_path $PATH_TO_BMODEL --tokenizer_path ../support/token_config/ --devid 0 --generation_mode greedy
编译程序(C++版本)
执行如下编译,(PCIE版本与SoC版本相同):
cd demo
mkdir build
cd build
cmake ..
make
编译生成chatglm可执行程序,将chatglm
放到demo目录下,同时按照下列方式指定芯片数量和bmodel路径。
运行chatglm
,默认单芯运行chatglm3-6b_f16_1dev.bmodel
:
./chatglm --model chatglm3-6b_f16_1dev.bmodel --tokenizer ../support/tokenizer.model
如果是要运行INT8或INT4模型,则命令如下:
./chatglm --model chatglm3-6b_int8_1dev.bmodel --tokenizer ../support/tokenizer.model # same with int4
如果是2芯分布式推理,使用如下命令(比如指定在2号和3号芯片上运行, 用source /etc/profiel
后使用bm-smi
查询芯片id号):
./chatglm --model chatglm3-6b_f16_2dev.bmodel --devid 2,3 --tokenizer ../support/tokenizer.model
编译程序(Python Web版本)
pip install gradio==3.39.0
cd web_demo
mkdir build
cd build
cmake ..
make -j
编译成功会生成libtpuchat.so*
, 在web_demo.py中指定bmodel_path token_path device_id, lib_path(编译生产的.so文件), 以及dev_id。
python web_demo.py --dev 0 --bmodel_path your_bmodel_path
即可成功运行web的demo。
如果是SoC环境,参考C++版本
PS:尽量下载gradio==3.39.0版本,不然会出现各种问题!!
运行效果
以下为单芯片下INT8量化模式的运行效果:
常见问题
sentencepiece是怎么来的
工程中已经有编译好的,所以不需要编译,如果好奇的话,参考如下步骤。
下载sentencepiece,并编译得到libsentencepiece.a
git clone git@github.com:google/sentencepiece.git
cd sentencepiece
mkdir build
cd build
cmake ..
make -j
如果要编译SoC环境,则参考demo的编译方式,在makefile中指定交叉编译器
demo程序无法正常运行
如果demo程序拷贝到运行环境提示无法运行,比如接口找不到等等错误。
原因是运行环境的库有所不同,将demo中的./support/lib_pcie
(PCIE)或者 ./support/lib_soc
(SoC)里面的so文件拷贝到运行环境,链接到里面的so即可。
工具调用
参考:工具调用