我正在尝试使用新的torch.backends.prepare.convert_model_to_nnapi()函数为Android设备上的nnapi准备PyTorch CNN模型。我基本上是在学习教程。这是我的密码:
#Prepare the trained model for NNAPI on Android device
import sys
import os
import torch
import torch.utils.bundled_inputs
import torch.utils.mobile_optimizer
import torch.backends._nnapi.prepare
import torchvision.models.quantization.mobilenet
from pathlib import Path
#import a function from a different module that returns the model in eval mode, loading the state dict from a checkpoint file (pretrained)
from common.model import trace_model
# This script supports 3 modes of quantization:
# - "none": Fully floating-point model.
# - "core": Quantize the core of the model, but wrap it a
# quantizer/dequantizer pair, so the interface uses floating point.
# - "full": Quantize the model, and use quantized tensors
# for input and output.
#
# "none" maintains maximum accuracy
# "core" sacrifices some accuracy for performance,
# but maintains the same interface.
# "full" maximized performance (with the same accuracy as "core"),
# but requires the application to use quantized tensors.
#
# There is a fourth option, not supported by this script,
# where we include the quant/dequant steps as NNAPI operators.
def make_mymodel_nnapi(output_dir_path, quantize_mode):
quantize_core, quantize_iface = {
"none": (False, False),
"core": (True, False),
"full": (True, True),
}[quantize_mode]
#get the model. Ignore layers
model, layers = trace_model()
#Commented this section out because model I'm using doesn't have fuse_model() fxn.
# Fuse BatchNorm operators in the floating point model.
# (Quantized models already have this done.)
# Remove dropout for this inference-only use case.
#if not quantize_core:
# model.fuse_model()
#assert type(model.classifier[0]) == torch.nn.Dropout
#model.classifier[0] = torch.nn.Identity()
#create some input based on my CNN's shape
input_float = torch.zeros(2, 272, 17, 2)
input_tensor = input_float
# If we're doing a quantized model, we need to trace only the quantized core.
# So capture the quantizer and dequantizer, use them to prepare the input,
# and replace them with identity modules so we can trace without them.
if quantize_core:
quantizer = model.quant
dequantizer = model.dequant
model.quant = torch.nn.Identity()
model.dequant = torch.nn.Identity()
input_tensor = quantizer(input_float)
# Many NNAPI backends prefer NHWC tensors, so convert our input to channels_last,
# and set the "nnapi_nhwc" attribute for the converter.
input_tensor = input_tensor.contiguous(memory_format=torch.channels_last)
input_tensor.nnapi_nhwc = True
# Trace the model. NNAPI conversion only works with TorchScript models,
# and traced models are more likely to convert successfully than scripted.
with torch.no_grad():
traced = torch.jit.trace(model, input_tensor)
#ERROR IN THIS FUNCTION
#Prepare model for NNAPI
nnapi_model = torch.backends._nnapi.prepare.convert_model_to_nnapi(traced, input_tensor)
if __name__ == "__main__":
for quantize_mode in ["none", "core", "full"]:
make_mymodel_nnapi(Path(os.environ["HOME"]) / "mobilenetv2-nnapi", quantize_mode)
我得到的是convert_model_to_nnapi()函数中的一个错误:
Traceback (most recent call last):
File "trace_model_nnapi.py", line 131, in <module>
make_mymodel_nnapi(Path(os.environ["HOME"]) / "mobilenetv2-nnapi", quantize_mode)
File "trace_model_nnapi.py", line 89, in make_mymodel_nnapi
nnapi_model = torch.backends._nnapi.prepare.convert_model_to_nnapi(traced, input_tensor)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/prepare.py", line 169, in convert_model_to_nnapi
ser_model, used_weights, inp_mem_fmts, out_mem_fmts = serialize_model(model, inputs)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/serializer.py", line 1363, in serialize_model
return _NnapiSerializer(config).serialize_model(module, inputs)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/serializer.py", line 520, in serialize_model
self.add_node(node)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/serializer.py", line 641, in add_node
raise Exception("Unsupported node kind (%r) in node %r" % (node.kind(), node))
Exception: Unsupported node kind ('aten::contiguous') in node %x.2 : Tensor = aten::contiguous(%x.1, %39) # /home/nodog/docs/asp/mymodel/common/model.py:267:0
如果我注释掉代码中的“许多NNAPI后端更喜欢NHWC张量”部分:
Traceback (most recent call last):
File "trace_model_nnapi.py", line 131, in <module>
make_mymodel_nnapi(Path(os.environ["HOME"]) / "mobilenetv2-nnapi", quantize_mode)
File "trace_model_nnapi.py", line 89, in make_mymodel_nnapi
nnapi_model = torch.backends._nnapi.prepare.convert_model_to_nnapi(traced, input_tensor)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/prepare.py", line 169, in convert_model_to_nnapi
ser_model, used_weights, inp_mem_fmts, out_mem_fmts = serialize_model(model, inputs)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/serializer.py", line 1363, in serialize_model
return _NnapiSerializer(config).serialize_model(module, inputs)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/serializer.py", line 520, in serialize_model
self.add_node(node)
File "/home/nodog/.local/lib/python3.8/site-packages/torch/backends/_nnapi/serializer.py", line 641, in add_node
raise Exception("Unsupported node kind (%r) in node %r" % (node.kind(), node))
Exception: Unsupported node kind ('aten::size') in node %40 : int = aten::size(%x.1, %39) # /home/nodog/docs/asp/mymodel/common/model.py:269:0
似乎serializer.py中的ADDER_映射(看起来是节点类型列表)中不包括“aten::size”和“aten::Continental”。有没有人知道我是否做错了什么,或者某些功能还没有添加到NNAPI系统中? 顺便说一下,我使用的CNN模型有Conv1d、Batchnorm、Dropout和Relu层
谢谢
目前没有回答
相关问题 更多 >
编程相关推荐