更新时间:2024-11-12 GMT+08:00
分享

基于MindSpore Lite的模型转换

迁移推理业务的整体流程如下:

主要通过MindSpore Lite(简称MSLite)进行模型的转换,进一步通过MindSpore Runtime支持昇腾后端的能力来将推理业务运行到昇腾设备上。

模型准备

MindSpore Lite提供的模型convertor工具可以支持主流的模型格式到MindIR的格式转换,用户需要导出对应的模型文件,推荐导出为ONNX格式。

  1. 如何导出ONNX模型
    • PyTorch转ONNX,操作指导请见此处
    • PyTorch导出ONNX模型样例如下:
      import torch
      import torchvision
      model = torchvision.models.resnet50(pretrained=True)
      # 保存模型为ONNX格式
      torch.onnx.export(model, torch.randn(1, 3, 224, 224), "resnet50.onnx")
    • TensorFlow导出ONNX模型,操作指导请见此处
  2. 如何导出PTH模型

    PyTorch模型导出时需要包含模型的结构信息,需要利用jit.trace方式完成模型的导出与保存。

    # If you are instantiating the model with *from_pretrained* you can also easily set the TorchScript flag
    model = BertModel.from_pretrained("bert-base-uncased", torchscript=True)
    
    # Creating the trace
    traced_model = torch.jit.trace(model, [tokens_tensor, segments_tensors])
    torch.jit.save(traced_model, "traced_bert.pt")

转换关键参数准备

对应的模型转换成MindIR格式,通过后端绑定的编译形式来运行以达到更好的性能(类似静态图的运行模式),所以需要提前准备以下几个重点参数。

  1. 输入的inputShape,包含batch信息。

    MSLite涉及到编译优化的过程,不支持完全动态的权重模式,需要在转换时确定对应的inputShape,用于模型的格式的编译与转换,可以在netron官网进行查看,或者对于模型结构中的输入进行shape的打印,并明确输入的batch。

    一般来说,推理时指定的inputShape是和用户的业务及推理场景是紧密相关的,可以通过原始模型推理脚本或者网络模型进行判断。需要把Notebook中的模型下载到本地后,再放入netron官网中,查看其inputShape。

    如果netron中没有显示inputShape,可能由于使用了动态shape模型导致,请确保使用的是静态shape模型,静态shape模型文件导出方法请参考模型准备

    图1 netron中查看inputShape
  2. 精度选择。

    精度选择需要在模型转换阶段进行配置,执行converter_lite命令式通过--configFile参数指定配置文件路径,配置文件通过precision_mode参数指定精度模式。可选的参数有“enforce_fp32”,“preferred_fp32”,“enforce_fp16”,“enforce_origin”或者“preferred_optimal”,默认为“enforce_fp16”。

    [ascend_context]
    precision_mode= preferred_fp32

模型转换

在ModelArts开发环境中,通过对应的转换预置镜像,直接执行对应的转换过程,对应的转换和评估工具都已经预置了最新版本,详细介绍请见使用说明。inputShape查看方法请见转换关键参数准备

!converter_lite --modelFile=resnet50.onnx --fmk=ONNX --outputFile=resnet50 --saveType=MINDIR --inputShape="input.1:1,3,224,224" --device=Ascend

为了简化用户使用,ModelArts提供了Tailor工具便于用户进行模型转换,具体使用方式参考Tailor指导文档

推理应用适配

MindSpore Lite提供了JAVA/C++/Python API,进行推理业务的适配,并且在构建模型时,通过上下文的参数来确定运行时的具体配置,例如运行后端的配置等。下文以Python接口为例。

使用MindSpore Lite推理框架执行推理并使用昇腾后端主要包括以下步骤:

  • 创建运行上下文:创建Context,保存需要的一些基本配置参数,用于指导模型编译和模型执行,在昇腾迁移时需要特别指定target为“Ascend”,以及对应的device_id。
    context = mslite.Context()
    context.target = ["ascend"]
    context.ascend.device_id = 0
  • 模型加载与编译:执行推理之前,需要调用Modelbuild_from_file接口进行模型加载和模型编译。模型加载阶段将文件缓存解析成运行时的模型。模型编译阶段会耗费较多时间所以建议Model创建一次,编译一次,多次推理。
    model = mslite.Model()
    model.build_from_file("./resnet50.mindir", mslite.ModelType.MINDIR, context)
  • 输入数据:编译后的模型提供了predict接口用户执行模型推理任务,Inputs输入为List Tensor,这里的Tensor是MSLite的概念,具体的列表长度和tensor类型由转换时的InputShape来确定,由于后端指定了ascend,这些tensor都是在昇腾设备的显存中,用户需要在对应的tensor中填入数据,这些数据也会被搬移到显存中,进一步对于Inputs输入的内容进行处理。
    data = convert_img(input_image)
    in_data = [np.array(data)]
    inputs = model.get_inputs()
    for i, _input in enumerate(inputs):
    _input.set_data_from_numpy(in_data[i])
  • 执行推理:使用Modelpredict进行模型推理,返回值为Outputs,也是List Tensor类型,具体的长度和类别由模型定义,对应的Tensor数据由于指定了ascend后端,Output的内容在显存中,通过tensor的get_data_to_numpy方法来获取,并将数据读取到内存中使用。
    outputs = model.predict(inputs)
    outputs = [output.get_data_to_numpy() for output in outputs]

    更多Python接口的高级用法与示例,请参考Python API

相关文档