1.系统环境
硬件环境(Ascend/GPU/CPU): Ascend
MindSpore版本: mindspore=2.4.1
执行模式(动态图):GRAPH
Python版本: Python=3.9.20
操作系统平台: linux arrch64
2.报错信息
2.1问题描述
1.主要异常
问题出现在 AclLiteModel 类的 _init_resource 方法中。具体来看,调用acl.mdl.load_from_file 函数失败,并返回了错误代码 145001。
2.析构异常
在 AclLiteModel.del 方法中,销毁对象时试图访问 _is_destroyed属性,但该属性不存在。
2.2 报错脚本相关的全部代码
转.air格式所用脚本代码
# export_model.py
import mindspore
import numpy as np
from mindspore import Tensor
from src.deep_learning.networks import NestedUNet
net = NestedUNet(n_channels=3, n_classes=2, is_train=False)
params = mindspore.load_checkpoint('nested_unet_checkpoints/nested_unet_checkpoints.ckpt')
mindspore.load_param_into_net(net, params)
input_tensor = Tensor(np.ones([1, 3, 256, 256]).astype(np.float32))
mindspore.export(net, input_tensor, file_name='nested_unet', file_format='AIR')
转om格式所用命令
atc --framework=1 --model=./nested_unet.air --input_format=NCHW --output=nested_unet --log=error --soc_version=Ascend310B4
报错脚本
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import mindspore.dataset as ds
import acl
import acllite_utils as utils
from acllite_model import AclLiteModel
from acllite_resource import resource_list
class AclLiteResource:
"""
AclLiteResource
"""
def __init__(self, device_id=0):
self.device_id = device_id
self.context = None
self.stream = None
self.run_mode = None
def init(self):
"""
init resource
"""
print("init resource stage:")
ret = acl.init()
ret = acl.rt.set_device(self.device_id)
utils.check_ret("acl.rt.set_device", ret)
self.context, ret = acl.rt.create_context(self.device_id)
utils.check_ret("acl.rt.create_context", ret)
self.stream, ret = acl.rt.create_stream()
utils.check_ret("acl.rt.create_stream", ret)
self.run_mode, ret = acl.rt.get_run_mode()
utils.check_ret("acl.rt.get_run_mode", ret)
print("Init resource success")
def __del__(self):
print("acl resource release all resource")
resource_list.destroy()
if self.stream:
print("acl resource release stream")
acl.rt.destroy_stream(self.stream)
if self.context:
print("acl resource release context")
acl.rt.destroy_context(self.context)
print("Reset acl device ", self.device_id)
acl.rt.reset_device(self.device_id)
print("Release acl resource success")
image = cv2.imread('ultrasound_images_to_show/1.jpg')
image = cv2.resize(image, (256, 256))
image = np.expand_dims(image.astype(np.float32).transpose((2, 0, 1)) / 127.5 - 1, axis=0)
acl_resource = AclLiteResource()
acl_resource.init()
path = os.getcwd()
model_path = os.path.join(path, "nested_unet.om")
model = AclLiteModel(model_path)
result = model.execute([image, ]) # result是一个只装了一个numpy数组的列表
output_image = np.argmax(result[0][0], axis=0)
print(output_image.shape)
fig = plt.figure()
plt.imshow(output_image,cmap='gray')
fig.savefig('fig.jpg')
3.根因分析
使用昇腾硬件及om格式模型进行推理时会直接调用acl相关接口进行显存资源的分配,推理完毕后会调用__del__
方法将资源释放,若没有实现实例化AclLiteResource并使用init方法初始化资源管理对象,则会产生上述错误。
4.解决方案
在代码:
model = AclLiteModel(model_path)
result = model.execute([image, ]) # result是一个只装了一个numpy数组的列表
的前面补充这两句:
acl_resource = AclLiteResource()
acl_resource.init()
如此操作以后,报错消失,正常运行的控制台输出如下:
推理结果如下: 这正是理想的结果,说明这样操作是正确的。5.其他说明以及一些注意事项
因此报错相关的issue是本人之前在mindspore的gitee仓提的,故不论是脚本名还是路径名都与样图高度相似。我自己提出的问题我自己发现并解决了,也算一种圆满吧。代码存放的位置是我的gitee仓库,因为本仓库还有其他用途,暂时不能完全开源,因此附件仅包含复现本报错的必要代码。
5.1 注意事项一
使用香橙派的toolkit相关工具将.air模型转.om模型时必须把以下内容加到.bashrc中不然会报错:
# lib libraries that the run package depends on
export LD_LIBRARY_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/lib64:${LOCAL_ASCEND}/driver/lib64:${LOCAL_ASCEND}/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe/op_tiling:${LD_LIBRARY_PATH}
# Environment variables that must be configured
export TBE_IMPL_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe # TBE operator implementation tool path
export ASCEND_OPP_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp # OPP path
export PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/compiler/ccec_compiler/bin/:${PATH} # TBE operator compilation tool path
export PYTHONPATH=${TBE_IMPL_PATH}:${PYTHONPATH}
以上环境变量并没有内置在香橙派的镜像中,因此需要自己装格式的朋友请将上述内容加到.bashrc中
5.2 注意事项二
从.air转为香橙派可用的模型的转换命令为
atc --framework=1 --model=./nested_unet.air --input_format=NCHW --output=nested_unet --log=error --soc_version=Ascend310B4 # 把“nested_unet”换成待转文件名
注意一定要写Ascend310B4,写Ascend310可能会出问题。
找不到传附件功能,使用超链接下载时生成的下载链接不稳定,代码请命令行下载:
pip install openi后使用如下命令即可下载代码压缩包:
openi dataset download enter/nodule_segmentation shangjing_cell_classification阉割版.zip --cluster NPU --save_path .
压缩包内包含了复现使用的代码和图像数据。