您的好友正在邀请您加入OpenI启智AI协作平台,畅享充沛的普惠算力资源(GPU/NPU/GCU/GPGPU/DCU/MLU)。
注册地址:https://openi.pcl.ac.cn/user/sign_up?sharedUser=Tlntin
推荐人:Tlntin
下载本项目
git clone https://github.com/Tlntin/qwen-ascend-llm.git
下载qwen1.5/qwen2的模型,选择chat模型或者instruct模型,将其放到download文件夹,仅支持huggingface下载的模型,网络不好的可以用镜像站:https://hf-mirror.com/Qwen
(可选)构建部署用的docker。需要先参考该教程登录并拉取镜像(建议跑通下面的所有步骤,得到.om文件后再编译docker)。
docker build . -t qwen_ascend_llm
(可选)构建开发用的docker。如果你想用docker来编译运行自定义芯片和自定义模型,可以运行下面的命令来构建镜像。同样的,需要先参考该教程登录并拉取镜像
docker build -f Dockerfile_dev . -t qwen_ascend_llm_dev
拉取编译好的镜像(仅适配昇腾310B1,例如香橙派AIPro 20T版)镜像内置了一个Qwen2-1.5B-Instruct模型以及对应的.om文件。
docker pull registry.cn-guangzhou.aliyuncs.com/tlntin/qwen_ascend_llm:v0.0.1_310B1_arm64
docker tag registry.cn-guangzhou.aliyuncs.com/tlntin/qwen_ascend_llm:v0.0.1_310B1_arm64 qwen_ascend_llm
启动部署用的容器(如果是开发用的容器,可以参考该脚本稍微修改,比如最底下的python api.py
命令可以换成sleep 8640000
让100天内不会关闭,然后加上-v 参数挂载一下download/output目录)。
./run_container.sh
查看容器日志,出现INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
则代表启动成功。
docker logs qwen_ascend_llm
调用容器提供的api接口。进入本项目的client目录,可以运行里面的文件请求服务端。
# openai_stream_client.py 流式请求,类似打字机效果,发送请求后立刻得到响应
# openai_normal_client.py 非流式请求,需要等模型推理完再返回
# openai_function_call.py 测试function_call,该功能启用时建议增加max_input_length和kv_cache_length的长度。
背诵《出师表》
python3 ./cli_chat.py \
--session_type="pytorch" \
--hf_model_dir="./download/Qwen2-1.5B-Instruct" \
--device_str="cpu" \
--dtype="float32" \
--torch_dtype="float32" \
--max_input_length=1024 \
--max_output_length=2048
除了上面说的CANN环境安装外,还需额外安装一些python模块(当然,你也可以使用docker构建开发环境,但是注意你的芯片和对应的得是310B系列,如果不是,需要参考官方镜像文档做一些修改)。
cd qwen-ascend-llm
pip install -r ./requirements.txt
导出onnx,当前我设置的kv-cache长度为2048,可以根据自己的内存、显存来设置更大参数,最大则不建议超过max_position_embeddings
这个数,可以去模型里面的config.json文件里面看,qwen2-1.5B-Instruct里面,这个数值为32768
python3 export/export_onnx.py \
--device_str=npu \
--dtype=float16 \
--hf_model_dir="./download/Qwen2-1.5B-Instruct" \
--onnx_model_path="./output/onnx/qwen2_1.5b_chat.onnx" \
--kv_cache_length=2048
验证onnx,返回项目根目录,运行cli_chat.py,测试一下onnx对话是否正常(注意:由于是cpu运行,所以速度较慢,请耐心等待)。
--max_input_length
为单次最大可以输入是数据量,该数值必须小于编译onnx的时候指定的--kv_cache_length
--max_output_length
则必须和之前转onnx的时候指定的--kv_cache_length
保持一致,否则onnx输出将会异常。max_output_length
-min(max_input_length, 实际输入的token数)--cpu_thread
根据你的cpu线程数设置,默认取4
python3 ./cli_chat.py \
--session_type=onnx \
--hf_model_dir="./download/Qwen2-1.5B-Instruct" \
--onnx_model_path="./output/onnx/qwen2_1.5b_chat.onnx" \
--dtype="float16" \
--cpu_thread=4 \
--max_input_length=1024 \
--max_output_length=2048
改变onnx结构,目前导出的Trilu算子有些问题,atc命令无法识别,需要改一下结构。
python3 export/change_node.py \
--input_model_path="./output/onnx/qwen2_1.5b_chat.onnx" \
--output_model_path="./output/onnx2/qwen2_1.5b_chat.onnx"
转onnx为om模型, 将修改后的onnx利用atc命令导出到onnx,注意此处的om_model_path不带.om
后缀。
success
就说明没啥问题。--max_prefill_length
为prefill阶段,单次能处理的最大长度,该数值越长则越能降低首字延迟,但是相应的onnx转om的时间也会变长。设置该数值时,一般为2的指数,例如2、4、8、16等等,推理时会利用递归自动匹配合适的prefill长度,例如输入12,会匹配[8, 4]。当前默认数值为4,如果设置为1,则不会开启动态shape推理功能。注意:开启动态shape后,模型体积会有50%-100%的增长,并且推理时占用的内存也会相应增长,如果对内存比较敏感,则建议关闭动态shape。--soc_version=xxxx
来指定,例如--soc_version=Ascend310B1
--kv_cache_length
的数值必须前面转onnx的时候指定的--kv_cache_length
保持一致,否则大概率会转换失败。--cpu_thread
为转onnx为om时,开启的cpu线程数,默认为1个线程并行编译,如果内存很多(每个线程单独占用一份内存,所以很费内存),可以调高一些。
python3 export/onnx2om.py \
--hf_model_dir="./download/Qwen2-1.5B-Instruct" \
--onnx_model_path="./output/onnx2/qwen2_1.5b_chat.onnx" \
--om_model_path="./output/model/qwen2_1.5b_chat" \
--kv_cache_length=2048 \
--cpu_thread=1 \
--max_prefill_length=4
使用下面的命令直接运行模型
--max_prefill_length
需要和上面编译om模型时使用的数值相同。--max_input_length
为单次最大可以输入是数据量,该数值必须小于编译onnx的时候指定的--kv_cache_length
--max_output_length
则必须和之前转onnx的时候指定的--kv_cache_length
保持一致,否则onnx输出将会异常。max_output_length
-min(max_input_length, 实际输入的token数)
python3 ./cli_chat.py \
--session_type="acl" \
--hf_model_dir="./download/Qwen2-1.5B-Instruct" \
--om_model_path="./output/model/qwen2_1.5b_chat.om" \
--max_input_length=1024 \
--max_output_length=2048 \
--max_prefill_length=4
demo展示1(演示模型,qwen1.5-0.5b-chat,未开启动态shape推理)
demo展示2(演示模型,qwen2-1.5b-instruct,开启动态shape推理, max_prefill_length=8)
demo展示3(演示模型,qwen2-1.5b-instruct,onnx cpu推理,CPU: i9-10900k 10核20线程)
使用下面的命令直接运行api,--max_prefill_length
需要和上面编译的时候使用的数值相同。
python3 ./api.py \
--hf_model_dir="./download/Qwen2-1.5B-Instruct" \
--om_model_path="./output/model/qwen2_1.5b_chat.om" \
--max_input_length=1024 \
--max_output_length=2048 \
--max_prefill_length=4
进入client目录,可以运行里面的文件请求服务端。
# openai_stream_client.py 流式请求,类似打字机效果,发送请求后立刻得到响应
# openai_normal_client.py 非流式请求,需要等模型推理完再返回
# openai_function_call.py 测试function_call,该功能启用时建议增加max_input_length和kv_cache_length的长度。
functional_call demo展示(使用qwen2-1.5b-instruct)
pip install msit
msit install compare
python3 export/compare.py \
--hf_model_dir="./download/Qwen2-0.5B-Instruct" \
--onnx_model_path="./output/onnx2/qwen2_0.5b_chat.onnx" \
--om_model_path="./output/model/qwen2_0.5b_chat.om" \
--kv_cache_length=2048 \
--cpu_thread=1 \
--dtype="float16" \
--max_prefill_length=1