Skip to content

Commit 702b671

Browse files
committed
Build OpenVINO network in runtime
1 parent 1fedd0f commit 702b671

File tree

8 files changed

+112
-138
lines changed

8 files changed

+112
-138
lines changed

README.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,6 @@ $ source venv3/bin/activate
7979

8080
To optimize inference on CPU with Intel OpenVINO:
8181

82-
1. Convert model to OpenVINO IR (optional if you already have `.xml` and `.bin` files)
83-
```bash
84-
(venv3) $ git clone -b releases/2021/1 --depth 1 https://github.com/openvinotoolkit/openvino
85-
(venv3) $ export PYTHONPATH=openvino/model-optimizer/:$PYTHONPATH
86-
(venv3) $ pip install -r openvino/model-optimizer/requirements_onnx.txt
87-
(venv3) $ python bonito/openvino/convert.py dna_r9.4.1
88-
```
89-
90-
2. Run evaluation
9182
```bash
9283
(venv3) $ export LD_LIBRARY_PATH=$(pwd)/venv3/lib:$LD_LIBRARY_PATH
9384
(venv3) $ bonito evaluate dna_r9.4.1 --use_openvino --device=cpu

bonito/model.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ def forward(self, x):
5050
return SwishAutoFn.apply(x)
5151

5252

53+
class Sum(Module):
54+
def forward(self, x, y):
55+
return x + y
56+
57+
5358
activations = {
5459
"relu": ReLU,
5560
"swish": Swish,
@@ -166,6 +171,7 @@ def __init__(self, in_channels, out_channels, activation, repeat=5, kernel_size=
166171

167172
self.use_res = residual
168173
self.conv = ModuleList()
174+
self.sum = Sum()
169175

170176
_in_channels = in_channels
171177
padding = self.get_padding(kernel_size[0], stride[0], dilation[0])
@@ -223,7 +229,7 @@ def forward(self, x):
223229
for layer in self.conv:
224230
_x = layer(_x)
225231
if self.use_res:
226-
_x += self.residual(x)
232+
_x = self.sum(_x, self.residual(x))
227233
return self.activation(_x)
228234

229235

bonito/openvino/convert.py

Lines changed: 0 additions & 43 deletions
This file was deleted.

bonito/openvino/loader.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# This script provides a method which builds OpenVINO network in runtime
2+
import numpy as np
3+
from openvino.inference_engine import IECore, IENetwork
4+
5+
import ngraph.opset4 as ng
6+
from ngraph.impl.op import Parameter
7+
from ngraph.impl import Function, Shape, Type
8+
9+
import torch
10+
from torch.autograd import Variable
11+
12+
13+
nodes = {}
14+
out = None
15+
16+
def forward_hook(self, inputs, output):
17+
global out
18+
layer_type = self.__class__.__name__
19+
20+
params = [value.numpy() for value in self.state_dict().values()]
21+
22+
inp = nodes[inputs[0].data_ptr()]
23+
if layer_type == 'Conv1d':
24+
weights = np.expand_dims(params[0], axis=2)
25+
if self.groups == 1:
26+
out = ng.convolution(inp, weights,
27+
[1, self.stride[0]],
28+
[0, self.padding[0]],
29+
[0, self.padding[0]],
30+
[1, self.dilation[0]])
31+
32+
else:
33+
weights = weights.reshape(self.groups, weights.shape[0] // self.groups, weights.shape[1], weights.shape[2], weights.shape[3])
34+
out = ng.group_convolution(inp, weights,
35+
[1, self.stride[0]],
36+
[0, self.padding[0]],
37+
[0, self.padding[0]],
38+
[1, self.dilation[0]])
39+
if len(params) > 1:
40+
assert(len(params) == 2)
41+
bias = params[1].reshape(1, params[1].shape[0], 1, 1)
42+
out = ng.add(out, bias)
43+
44+
elif layer_type == 'BatchNorm1d':
45+
out = ng.batch_norm_inference(inp, params[0], params[1], params[2], params[3], self.eps)
46+
elif layer_type == 'Swish':
47+
out = ng.swish(inp)
48+
elif layer_type == 'Sum':
49+
out = ng.add(inp, nodes[inputs[1].data_ptr()])
50+
elif layer_type == 'Dropout':
51+
return
52+
else:
53+
raise Exception('Unknown layer type: ' + layer_type)
54+
55+
nodes[output.data_ptr()] = out
56+
57+
58+
def sanity_check(net, inp, ref):
59+
ie = IECore()
60+
exec_net = ie.load_network(net, 'CPU')
61+
ie_out = exec_net.infer({'input': inp.numpy()})
62+
ie_out = next(iter(ie_out.values()))
63+
64+
ref = ref.numpy().reshape(ie_out.shape)
65+
diff = np.max(np.abs(ie_out - ref))
66+
print('PyTorch / OpenVINO diff:', diff)
67+
print('Reference values range: [{}, {}]'.format(np.min(ref), np.max(ref)))
68+
if diff > 1.1e-4:
69+
raise Exception('Sanity check failed with diff', diff)
70+
71+
72+
def torch2openvino(model):
73+
with torch.no_grad():
74+
model.eval()
75+
for module in model.modules():
76+
if len([m for m in module.modules()]) != 1:
77+
continue
78+
module.register_forward_hook(forward_hook)
79+
80+
# Just a dummy input to make forward pass
81+
inp = Variable(torch.randn([1, 1, 1000]))
82+
83+
param = Parameter(Type.f32, Shape([1, 1, 1, 1000]))
84+
nodes[inp.data_ptr()] = param
85+
ref = model(inp)
86+
87+
out_node = ng.transpose(out, [0, 3, 2, 1])
88+
out_node = ng.log(ng.softmax(out_node, axis=3))
89+
90+
param.set_friendly_name('input')
91+
out_node.set_friendly_name('output')
92+
func = Function([out_node], [param], '')
93+
94+
caps = Function.to_capsule(func)
95+
net = IENetwork(caps)
96+
97+
# Uncomment to perform conversion check
98+
# sanity_check(net, inp, ref)
99+
100+
return net

bonito/openvino/mo_extension/front/onnx/conv2d.py

Lines changed: 0 additions & 31 deletions
This file was deleted.

bonito/openvino/mo_extension/front/onnx/swish.py

Lines changed: 0 additions & 37 deletions
This file was deleted.

bonito/openvino/mo_extension/front/onnx/transpose.py

Lines changed: 0 additions & 16 deletions
This file was deleted.

bonito/openvino/model.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
try:
66
from openvino.inference_engine import IECore, StatusCode
7+
from .loader import torch2openvino
78
except ImportError:
89
pass
910

@@ -16,7 +17,10 @@ def __init__(self, model, half, dirname):
1617
model_name = model.config['model'] + ('_fp16' if half else '')
1718
xml_path, bin_path = [os.path.join(dirname, model_name) + ext for ext in ['.xml', '.bin']]
1819
self.ie = IECore()
19-
self.net = self.ie.read_network(xml_path, bin_path)
20+
if os.path.exists(xml_path) and os.path.exists(bin_path):
21+
self.net = self.ie.read_network(xml_path, bin_path)
22+
else:
23+
self.net = torch2openvino(model)
2024
self.exec_net = None
2125

2226

0 commit comments

Comments
 (0)