bge-m3 推理适配昇腾
【摘要】 BGE-M3是首个集多语言(Multi-Linguality)、多粒度(Multi-Granularity)、多功能(Multi-Functionality)三大技术特征于一体的语义向量模型, 本文介绍了如何使用昇腾推理该模型的方法
/**************************如有任何问题和疑问,请评论区留言*********************************/
0.前提条件
0.1 登录机器
机器已开通,密码已获取,能通过ssh登录
0.2 检查NPU设备
NPU设备检查:运行npu-smi info命令,返回npu设备信息。
0.3 docker安装
#检查docker是否安装:docker -v,如如尚未安装,运行以下命令进行docker安装
yum install -y docker-engine.aarch64 docker-engine-selinux.noarch docker-runc.aarch64
#配置IP转发,用于容器内的网络访问:
sed -i 's/net\.ipv4\.ip_forward=0/net\.ipv4\.ip_forward=1/g' /etc/sysctl.conf
sysctl -p | grep net.ipv4.ip_forward
0.4 获取镜像
docker pull swr.cn-southwest-2.myhuaweicloud.com/atelier/pytorch_2_3_ascend:pytorch_2.3.1-cann_8.0.rc3-py_3.10-hce_2.0.2409-aarch64-snt9b-20241114095658-d7e26d8
0.5 启动镜像
启动容器镜像。启动前请先按照参数说明修改${}中的参数。
docker run -it --net=host \
--device=/dev/davinci0 \
--device=/dev/davinci1 \
--device=/dev/davinci2 \
--device=/dev/davinci3 \
--device=/dev/davinci4 \
--device=/dev/davinci5 \
--device=/dev/davinci6 \
--device=/dev/davinci7 \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
--shm-size=32g \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /var/log/npu/:/usr/slog \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v ${work_dir}:${container_work_dir} \
--name ${container_name} \
${image_id} \
/bin/bash
参数说明:
device=/dev/davinci0,..., --device=/dev/davinci7:挂载NPU设备,示例中挂载了8张卡davinci0~davinci7,可根据需要选择挂载卡数。
${work_dir}:${container_work_dir} 代表需要在容器中挂载宿主机的目录。宿主机和容器使用不同的文件系统,work_dir为宿主机中工作目录,目录下存放着训练所需代码、数据等文件。container_dir为要挂载到的容器中的目录。为方便两个地址可以相同。
shm-size:共享内存大小。
${container_name}:容器名称,进入容器时会用到,此处可以自己定义一个容器名称。
${image_id}:镜像ID,通过docker images查看刚拉取的镜像ID。
注意
容器不能挂载到/home/ma-user目录,此目录为ma-user用户家目录。如果容器挂载到/home/ma-user下,拉起容器时会与基础镜像冲突,导致基础镜像不可用。
driver及npu-smi需同时挂载至容器。
不要将多个容器绑到同一个NPU上,会导致后续的容器无法正常使用NPU功能。
1. 推理验证
在容器工作目录container_work_dir下执行以下操作
1.1 下载模型文件
下载链接: https://modelscope.cn/models/BAAI/bge-m3
1.2 安装 sentence_transformers和optimum
pip install sentence_transformers optimum==1.17.0
1.3 下载转换脚本
wget https://huggingface.co/aapot/bge-m3-onnx/resolve/main/export_onnx.py
wget https://huggingface.co/aapot/bge-m3-onnx/resolve/main/bgem3_model.py
修改bgem3_model.py
1.4 模型转换
1) pytorch -> onnx
python export_onnx.py --output . --opset 17 --device cpu --optimize O1
执行后在当前路径生成model.onnx以及model.onnx.data
2) onnx -> mindir
1)创建convert.ini文件, 其内容如下:
[acl_build_options] `
input_format="ND"
input_shape="input_ids:1,-1;attention_mask:1,-1"
2)执行转换命令
converter_lite --fmk=ONNX --modelFile=model.onnx --outputFile=model --saveType=MINDIR --optimize=ascend_oriented --configFile=convert.ini
转换后生成model_graph.mindir
说明:
该镜像已安装转换工具converter_lite
关于converter_lite工具详细使用参考https://www.mindspore.cn/lite/docs/zh-CN/r2.4.0/converter/converter_tool.html
3)benchmark 测试
benchmark --modelFile=model_graph.mindir --device=Ascend --inputShapes=1,31:1,31 --loopCount=100
测试结果:
说明:
该镜像已安装benchmark工具
关于benchmark工具详细使用参考https://www.mindspore.cn/lite/docs/zh-CN/r2.4.0/mindir/benchmark_tool.html
1.5 推理验证
基于mslite推理demo代码如下:
import torch
import torch_npu
from torch_npu.contrib import transfer_to_npu
from transformers import AutoTokenizer
from sentence_transformers import SentenceTransformer
import mindspore_lite as mslite
def mslite_init_model(model_path):
context = mslite.Context()
context.target = ["ascend"]
context.ascend.device_id = 0
context.cpu.thread_num = 1
context.cpu.thread_affinity_mode=2
# build model from file
model = mslite.Model()
model.build_from_file(model_path, mslite.ModelType.MINDIR, context)
return model
def mslite_infer(model, input_data):
ms_inp = list(input_data.values())
inputs = model.get_inputs()
shapes = [ms_inp[0].shape, ms_inp[1].shape]
model.resize(inputs, shapes)
for i, _input in enumerate(inputs):
_input.set_data_from_numpy(ms_inp[i])
outputs = model.predict(inputs)
return outputs[0].get_data_to_numpy()
def main():
device = torch.device('npu:0')
sentences_1 = ["BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction."]
tokenizer = AutoTokenizer.from_pretrained("pytorch模型所在路径")
encoded_input = tokenizer(sentences_1[0], padding="longest", return_tensors="np")
#mslite infer
input_ids = encoded_input['input_ids'].astype("int32")
attention_mask = encoded_input['attention_mask'].astype("int32")
mslite_input_data = {"input_ids": input_ids,"attention_mask":attention_mask}
mslite_model = mslite_init_model("model_graph.mindir所在路径")
mslite_output = mslite_infer(mslite_model, mslite_input_data)
print("mslite_output shape:", mslite_output.shape)
#torch infer
sentence_transformer_model = SentenceTransformer(' pytorch模型所在路径',
model_kwargs={"attn_implementation": "sdpa"})
sentence_transformer_model.to(device)
embeddings = sentence_transformer_model.encode(sentences_1, batch_size=32, show_progress_bar=True)
print("torch infer shape:", embeddings.shape)
if __name__ == "__main__":
torch_npu.npu.config.allow_internal_format = False
torch.npu.set_compile_mode(jit_compile=False)
main()
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)