Skip to content

Commit e225dab

Browse files
feat(mgeconvert): support relu inplace and remove flatten before linear for caffe
1 parent 35aed5a commit e225dab

6 files changed

Lines changed: 84 additions & 23 deletions

File tree

bin/convert

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ def init(subparsers):
123123
"tracedmodule_to_caffe": mgeconvert.tracedmodule_to_caffe,
124124
"mge_to_caffe": mgeconvert.mge_to_caffe,
125125
}
126+
convert_backend_map = {
127+
"caffe": 1,
128+
"1":1,
129+
"snpe": 2,
130+
"2":2,
131+
"trt": 3,
132+
"3":3,
133+
"nnie": 4,
134+
"4":4
135+
}
136+
assert args.convert_backend in convert_backend_map, "unsupported backend"
137+
convert_backend = convert_backend_map[args.convert_backend]
126138
if "tracedmodule" in target:
127139
converter_map[target](
128140
args.input,
@@ -137,15 +149,15 @@ def init(subparsers):
137149
split_conv_relu=args.split_conv_relu,
138150
fuse_bn=args.fuse_bn,
139151
quantize_file_path=args.quantize_file_path,
140-
convert_backend=args.convert_backend,
152+
convert_backend=convert_backend,
141153
)
142154
else:
143155
converter_map[target](
144156
args.input,
145157
prototxt=args.prototxt,
146158
caffemodel=args.caffemodel,
147159
outspec=outspec,
148-
convert_backend=args.convert_backend,
160+
convert_backend=convert_backend,
149161
)
150162

151163
def caffe_parser(subparsers):
@@ -240,9 +252,9 @@ def init(subparsers):
240252

241253
p.add_argument(
242254
"--convert_backend",
243-
default=1,
244-
type=int,
245-
help="backend 1 for caffe, 2 for snpe, 3 for trt",
255+
default='1',
256+
type=str,
257+
help="backend '1' or 'caffe' for caffe, '2' or 'snpe' for snpe, '3' or 'trt' for trt, '4' or 'nnie' for nnie",
246258
)
247259

248260
caffe_parser(subparsers)

mgeconvert/backend/ir_to_caffe/caffe_op.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class BackEnd(IntEnum):
7878
CAFFE = 1
7979
SNPE = 2
8080
TRT = 3
81+
NNIE = 4
8182

8283

8384
def isconst(x):
@@ -118,7 +119,10 @@ def _gen_layer(opr, etype, context, single_input=True, **kwargs):
118119
if single_input
119120
else list(map(context.get_blob_name, opr.inp_tensors))
120121
)
121-
top = [context.set_blob_name(opr.out_tensors[0], opr.out_tensors[0].name)]
122+
if etype == "ReLU" and context.convert_backend == BackEnd.NNIE:
123+
top = [context.set_blob_name(opr.out_tensors[0], opr.inp_tensors[0].name)]
124+
else:
125+
top = [context.set_blob_name(opr.out_tensors[0], opr.out_tensors[0].name)]
122126
return cp.LayerParameter(
123127
bottom=bottom, top=top, name=opr.out_tensors[0].name, type=etype, **kwargs
124128
)
@@ -949,11 +953,8 @@ def _reshape(opr, context):
949953
tmp_shape = out_shape + (1,) * d
950954
bottom = [context.get_blob_name(opr.inp_tensors[0])]
951955
top = [context.set_blob_name(opr.out_tensors[0], opr.out_tensors[0].name)]
952-
if context.convert_backend == BackEnd.CAFFE:
956+
if context.convert_backend == BackEnd.NNIE:
953957
if inp_shape != tmp_shape:
954-
logger.warning(
955-
"trt don't support flatten after reshape, but caffe support! please use BackEnd.TRT in tracedmodule_to_caffe by pass convert_backend:BackEnd=BackEnd.TRT"
956-
)
957958
param = cp.ReshapeParameter(shape=cp.BlobShape(dim=tmp_shape))
958959
tmp = [bottom[0] + "tmp"]
959960
context.add_layer(
@@ -976,18 +977,17 @@ def _reshape(opr, context):
976977
flatten_param=param,
977978
)
978979
)
979-
elif context.convert_backend == BackEnd.TRT:
980-
if inp_shape != tmp_shape:
981-
param = cp.ReshapeParameter(shape=cp.BlobShape(dim=tmp_shape))
982-
context.add_layer(
983-
cp.LayerParameter(
984-
bottom=bottom,
985-
top=top,
986-
name=opr.out_tensors[0].name,
987-
type="Reshape",
988-
reshape_param=param,
989-
)
980+
else:
981+
param = cp.ReshapeParameter(shape=cp.BlobShape(dim=out_shape))
982+
context.add_layer(
983+
cp.LayerParameter(
984+
bottom=bottom,
985+
top=top,
986+
name=opr.out_tensors[0].name,
987+
type="Reshape",
988+
reshape_param=param,
990989
)
990+
)
991991
else:
992992
logger.warning(
993993
"NNIE doesn't support this reshape Opr %s, inp_shape %s, out_shape %s, NNIE reshape only support C/H/W, not N!",

mgeconvert/converter_ir/ir_transform.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
IdentityOpr,
3333
LeakyReluOpr,
3434
LinearOpr,
35+
MatMulOpr,
3536
MulOpr,
3637
OpBase,
3738
PadOpr,
@@ -83,7 +84,8 @@ class TransformerRule(Enum):
8384
# for TFLite Converter
8485
SLICE_PARAMS_AS_INPUTS_AND_MAKE_SQUEEZE = 119
8586
RESIZE_PARAMS_AS_INPUT = 120
86-
REPLACE_FLATTEN_TO_RESHAPE = 120.1
87+
REMOVE_FLATTEN_BEFORE_LINEAR = 120.1
88+
REPLACE_FLATTEN_TO_RESHAPE = 120.2
8789

8890
# remove reshape
8991
REMOVE_RESHAPE_REALTED_OP = 121
@@ -1273,3 +1275,25 @@ def _expand_conv_relu(net: IRGraph):
12731275
t.owner_opr = relu_op
12741276

12751277
net.replace_op(opr, relu_op)
1278+
1279+
1280+
@_register_tranformation_rule(TransformerRule.REMOVE_FLATTEN_BEFORE_LINEAR)
1281+
def _remove_flatten(net: IRGraph):
1282+
for opr in net.all_oprs:
1283+
if not isinstance(opr, MatMulOpr):
1284+
continue
1285+
inp_oprs = net.find_inp_oprs(opr)
1286+
1287+
if (
1288+
isinstance(inp_oprs[0], OpBase)
1289+
and isinstance(inp_oprs[0], FlattenOpr)
1290+
and len(net.find_out_oprs(inp_oprs[0])) == 1
1291+
and net.find_out_oprs(inp_oprs[0])[0] == opr
1292+
):
1293+
assert opr.inp_tensors[0].np_data is None
1294+
flatten_opr = inp_oprs[0]
1295+
opr.inp_tensors[0] = flatten_opr.inp_tensors[0]
1296+
flatten_opr.inp_tensors[0].user_opr.remove(flatten_opr)
1297+
flatten_opr.inp_tensors[0].user_opr.append(opr)
1298+
idx = net.all_oprs.index(flatten_opr)
1299+
net.delete_ops(idx)

mgeconvert/converters/tm_to_caffe.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ def tracedmodule_to_caffe(
7575
TransformerRule.FUSE_CONV_BN,
7676
]
7777

78+
if convert_backend == BackEnd.NNIE:
79+
transformer_options.extend(
80+
[TransformerRule.REMOVE_FLATTEN_BEFORE_LINEAR,]
81+
)
82+
7883
if split_conv_relu:
7984
transformer_options += [TransformerRule.REMOVE_RELU]
8085
transformer = IRTransform(transformer_options)

test/traced_module/test_caffe.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def _test_convert_result(
5858
split_conv_relu=False,
5959
fuse_bn=False,
6060
input_name="x",
61+
convert_backend=1,
6162
):
6263
tracedmodule_to_caffe(
6364
trace_module,
@@ -70,6 +71,7 @@ def _test_convert_result(
7071
param_fake_quant=param_fake_quant,
7172
split_conv_relu=split_conv_relu,
7273
fuse_bn=fuse_bn,
74+
convert_backend=convert_backend,
7375
)
7476

7577
caffe_net = caffe.Net(tmp_file + ".txt", tmp_file + ".caffemodel", caffe.TEST)
@@ -134,6 +136,12 @@ def test_linear():
134136
_test_convert_result(net.data, tm_module, mge_result, max_error)
135137

136138

139+
def test_flatten_linear():
140+
net = LinearOpr("flatten")
141+
tm_module, mge_result = get_traced_module(net, mge.tensor(net.data1))
142+
_test_convert_result(net.data1, tm_module, mge_result, max_error, convert_backend=4)
143+
144+
137145
def test_linear_bn():
138146
net = LinearBnOpr()
139147
for _ in range(10):
@@ -249,6 +257,13 @@ def test_active(mode):
249257
_test_convert_result(net.data, tm_module, mge_result, max_error)
250258

251259

260+
@pytest.mark.parametrize("mode", ["relu",])
261+
def test_active_inplace(mode):
262+
net = ActiveOpr(mode)
263+
tm_module, mge_result = get_traced_module(net, mge.tensor(net.data))
264+
_test_convert_result(net.data, tm_module, mge_result, max_error, convert_backend=4)
265+
266+
252267
@pytest.mark.parametrize("mode", ["max", "sum", "mean"])
253268
def test_reduce(mode):
254269
net = ReduceOpr(mode)

test/utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,21 @@ def forward(self, x):
120120

121121

122122
class LinearOpr(M.Module):
123-
def __init__(self):
123+
def __init__(self, mode="normal"):
124124
super().__init__()
125125
self.data = np.random.random((10, 100)).astype(np.float32)
126+
self.data1 = np.random.random((10, 10, 10)).astype(np.float32)
126127
self.linear = M.Linear(100, 200, bias=False)
127128
self.linear_bias = M.Linear(200, 200, bias=True)
128129
self.linear_bias.bias = mge.Parameter(
129130
np.random.random(self.linear_bias.bias.shape).astype(np.float32)
130131
)
132+
self.mode = mode
131133

132134
def forward(self, x):
135+
if self.mode == "flatten":
136+
x = F.flatten(x, 1)
137+
133138
x = self.linear(x)
134139
x = self.linear_bias(x)
135140
return x

0 commit comments

Comments
 (0)