Wanli
commited on
Commit
·
0e997e3
1
Parent(s):
41c69c8
update generate table script (#164)
Browse files- benchmark/README.md +0 -26
- benchmark/color_table.svg +0 -0
- benchmark/generate_table.py +208 -85
- benchmark/table_config.yaml +219 -0
benchmark/README.md
CHANGED
@@ -57,32 +57,6 @@ python benchmark.py --all --cfg_overwrite_backend_target 1
|
|
57 |
|
58 |
Benchmark is done with latest `opencv-python==4.7.0.72` and `opencv-contrib-python==4.7.0.72` on the following platforms. Some models are excluded because of support issues.
|
59 |
|
60 |
-
|
61 |
-
| Model | Task | Input Size | CPU-INTEL (ms) | CPU-RPI (ms) | CPU-RV1126 (ms) | CPU-KVE2 (ms) | CPU-HSX3 (ms) | CPU-AXP (ms) | GPU-JETSON (ms) | NPU-KV3 (ms) | NPU-Ascend310 (ms) | CPU-D1 (ms) |
|
62 |
-
| -------------------------------------------------------- | ----------------------------- | ---------- | -------------- | ------------ | --------------- | ------------- | ------------- | ------------ | --------------- | ------------ | ------------------ | ----------- |
|
63 |
-
| [YuNet](../models/face_detection_yunet) | Face Detection | 160x120 | 0.72 | 5.43 | 68.89 | 2.47 | 11.04 | 98.16 | 12.18 | 4.04 | 2.24 | 86.69 |
|
64 |
-
| [SFace](../models/face_recognition_sface) | Face Recognition | 112x112 | 6.04 | 78.83 | 1550.71 | 33.79 | 140.83 | 2093.12 | 24.88 | 46.25 | 2.66 | --- |
|
65 |
-
| [FER](../models/facial_expression_recognition/) | Facial Expression Recognition | 112x112 | 3.16 | 32.53 | 604.36 | 15.99 | 64.96 | 811.32 | 31.07 | 29.80 | 2.19 | --- |
|
66 |
-
| [LPD-YuNet](../models/license_plate_detection_yunet/) | License Plate Detection | 320x240 | 8.63 | 167.70 | 3222.92 | 57.57 | 283.75 | 4300.13 | 56.12 | 29.53 | 7.63 | --- |
|
67 |
-
| [YOLOX](../models/object_detection_yolox/) | Object Detection | 640x640 | 141.20 | 1805.87 | 38359.93 | 577.93 | 2749.22 | 49994.75 | 388.95 | 420.98 | 28.59 | --- |
|
68 |
-
| [NanoDet](../models/object_detection_nanodet/) | Object Detection | 416x416 | 66.03 | 225.10 | 2303.55 | 118.38 | 408.16 | 3360.20 | 64.94 | 116.64 | 20.62 | --- |
|
69 |
-
| [DB-IC15](../models/text_detection_db) (EN) | Text Detection | 640x480 | 71.03 | 1862.75 | 49065.03 | 394.77 | 1908.87 | 65681.91 | 208.41 | --- | 17.15 | --- |
|
70 |
-
| [DB-TD500](../models/text_detection_db) (EN&CN) | Text Detection | 640x480 | 72.31 | 1878.45 | 49052.24 | 392.52 | 1922.34 | 65630.56 | 210.51 | --- | 17.95 | --- |
|
71 |
-
| [CRNN-EN](../models/text_recognition_crnn) | Text Recognition | 100x32 | 20.16 | 278.11 | 2230.12 | 77.51 | 464.58 | 3277.07 | 196.15 | 125.30 | --- | --- |
|
72 |
-
| [CRNN-CN](../models/text_recognition_crnn) | Text Recognition | 100x32 | 23.07 | 297.48 | 2244.03 | 82.93 | 495.94 | 3330.69 | 239.76 | 166.79 | --- | --- |
|
73 |
-
| [PP-ResNet](../models/image_classification_ppresnet) | Image Classification | 224x224 | 34.71 | 463.93 | 11793.09 | 178.87 | 759.81 | 15753.56 | 98.64 | 75.45 | 6.99 | --- |
|
74 |
-
| [MobileNet-V1](../models/image_classification_mobilenet) | Image Classification | 224x224 | 5.90 | 72.33 | 1546.16 | 32.78 | 140.60 | 2091.13 | 33.18 | 145.66\* | 5.15 | --- |
|
75 |
-
| [MobileNet-V2](../models/image_classification_mobilenet) | Image Classification | 224x224 | 5.97 | 66.56 | 1166.56 | 28.38 | 122.53 | 1583.25 | 31.92 | 146.31\* | 5.41 | --- |
|
76 |
-
| [PP-HumanSeg](../models/human_segmentation_pphumanseg) | Human Segmentation | 192x192 | 8.81 | 73.13 | 1610.78 | 34.58 | 144.23 | 2157.86 | 67.97 | 74.77 | 6.94 | --- |
|
77 |
-
| [WeChatQRCode](../models/qrcode_wechatqrcode) | QR Code Detection and Parsing | 100x100 | 1.29 | 5.71 | --- | --- | --- | --- | --- | --- | --- | --- |
|
78 |
-
| [DaSiamRPN](../models/object_tracking_dasiamrpn) | Object Tracking | 1280x720 | 29.05 | 712.94 | 14738.64 | 152.78 | 929.63 | 19800.14 | 76.82 | --- | --- | --- |
|
79 |
-
| [YoutuReID](../models/person_reid_youtureid) | Person Re-Identification | 128x256 | 30.39 | 625.56 | 11117.07 | 195.67 | 898.23 | 14886.02 | 90.07 | 44.61 | 5.58 | --- |
|
80 |
-
| [MP-PalmDet](../models/palm_detection_mediapipe) | Palm Detection | 192x192 | 6.29 | 86.83 | 872.09 | 38.03 | 142.23 | 1191.81 | 83.20 | 33.81 | 5.17 | --- |
|
81 |
-
| [MP-HandPose](../models/handpose_estimation_mediapipe) | Hand Pose Estimation | 224x224 | 4.68 | 43.57 | 460.56 | 20.27 | 80.67 | 636.22 | 40.10 | 19.47 | 6.27 | --- |
|
82 |
-
| [MP-PersonDet](../models/person_detection_mediapipe) | Person Detection | 224x224 | 13.88 | 98.52 | 1326.56 | 46.07 | 191.41 | 1835.97 | 56.69 | --- | 16.45 | --- |
|
83 |
-
|
84 |
-
\*: Models are quantized in per-channel mode, which run slower than per-tensor quantized models on NPU.
|
85 |
-
|
86 |
### Intel 12700K
|
87 |
|
88 |
Specs: [details](https://www.intel.com/content/www/us/en/products/sku/134594/intel-core-i712700k-processor-25m-cache-up-to-5-00-ghz/specifications.html)
|
|
|
57 |
|
58 |
Benchmark is done with latest `opencv-python==4.7.0.72` and `opencv-contrib-python==4.7.0.72` on the following platforms. Some models are excluded because of support issues.
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
### Intel 12700K
|
61 |
|
62 |
Specs: [details](https://www.intel.com/content/www/us/en/products/sku/134594/intel-core-i712700k-processor-25m-cache-up-to-5-00-ghz/specifications.html)
|
benchmark/color_table.svg
CHANGED
|
|
benchmark/generate_table.py
CHANGED
@@ -2,94 +2,193 @@ import re
|
|
2 |
import matplotlib.pyplot as plt
|
3 |
import matplotlib as mpl
|
4 |
import numpy as np
|
|
|
5 |
|
6 |
-
mpl.use("svg")
|
7 |
|
8 |
# parse a '.md' file and find a table. return table information
|
9 |
-
def parse_table(filepath):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
with open(filepath, "r", encoding="utf-8") as f:
|
11 |
content = f.read()
|
12 |
lines = content.split("\n")
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
for
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
return header, body
|
36 |
|
37 |
|
38 |
-
#
|
39 |
-
def
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
d = float(data[i])
|
55 |
-
if d > max_data:
|
56 |
-
max_data = d
|
57 |
-
max_idx = i
|
58 |
-
if d < min_data:
|
59 |
-
min_data = d
|
60 |
-
min_idx = i
|
61 |
-
except:
|
62 |
-
pass
|
63 |
-
|
64 |
-
min_list.append(min_idx)
|
65 |
-
max_list.append(max_idx)
|
66 |
-
|
67 |
-
# calculate colors
|
68 |
-
color = []
|
69 |
-
for t in data:
|
70 |
-
try:
|
71 |
-
t = (float(t) - min_data) / (max_data - min_data)
|
72 |
-
color.append(cmap(t))
|
73 |
-
except:
|
74 |
-
color.append('white')
|
75 |
-
colors.append(color)
|
76 |
-
return colors, min_list, max_list
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
fig, axs = plt.subplots(nrows=3, figsize=(10, 0.8))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
gradient = np.linspace(0, 1, 256)
|
94 |
gradient = np.vstack((gradient, gradient))
|
95 |
axs[0].imshow(gradient, aspect='auto', cmap=cmap)
|
@@ -101,6 +200,24 @@ if __name__ == '__main__':
|
|
101 |
cellColours=table_colors,
|
102 |
cellLoc="left",
|
103 |
loc="upper left")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
# adjust table position
|
106 |
table_pos = axs[1].get_position()
|
@@ -122,24 +239,21 @@ if __name__ == '__main__':
|
|
122 |
cell = table.get_celld()[(i + 1, min_list[i])]
|
123 |
cell.set_text_props(weight='bold', color='white')
|
124 |
|
|
|
|
|
|
|
125 |
table_height = 0
|
126 |
table_width = 0
|
127 |
-
# calculate table height and width
|
128 |
for i in range(len(table_texts)):
|
129 |
cell = table.get_celld()[(i, 0)]
|
130 |
table_height += cell.get_height()
|
131 |
for i in range(len(table_texts[0])):
|
132 |
cell = table.get_celld()[(0, i)]
|
133 |
-
table_width += cell.get_width()
|
134 |
|
135 |
# add notes for table
|
136 |
-
axs[2].text(0, -table_height -
|
137 |
-
|
138 |
-
# turn off labels
|
139 |
-
for ax in axs:
|
140 |
-
ax.set_axis_off()
|
141 |
-
ax.set_xticks([])
|
142 |
-
ax.set_yticks([])
|
143 |
|
144 |
# adjust color map position to center
|
145 |
cm_pos = axs[0].get_position()
|
@@ -151,4 +265,13 @@ if __name__ == '__main__':
|
|
151 |
])
|
152 |
|
153 |
plt.rcParams['svg.fonttype'] = 'none'
|
154 |
-
plt.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import matplotlib.pyplot as plt
|
3 |
import matplotlib as mpl
|
4 |
import numpy as np
|
5 |
+
import yaml
|
6 |
|
|
|
7 |
|
8 |
# parse a '.md' file and find a table. return table information
|
9 |
+
def parse_table(filepath, cfg):
|
10 |
+
# parse benchmark data
|
11 |
+
def _parse_benchmark_data(lines):
|
12 |
+
raw_data = []
|
13 |
+
for l in lines:
|
14 |
+
l = l.strip()
|
15 |
+
# parse each line
|
16 |
+
m = re.match(r"(\d+\.?\d*)\s+(\d+\.?\d*)\s+(\d+\.?\d*)\s+\[([^]]*)]\s+(.*)", l)
|
17 |
+
if m:
|
18 |
+
raw_data.append(m.groups())
|
19 |
+
return raw_data
|
20 |
+
|
21 |
+
# find each cpu, gpu, npu block
|
22 |
+
def _find_all_platform_block(lines):
|
23 |
+
cur_start = None
|
24 |
+
cur_platform = None
|
25 |
+
platform_block = dict()
|
26 |
+
for i in range(len(lines)):
|
27 |
+
l = lines[i].strip()
|
28 |
+
# found start and end of a platform
|
29 |
+
if l.startswith("CPU") or l.startswith("GPU") or l.startswith("NPU"):
|
30 |
+
if cur_platform is not None:
|
31 |
+
platform_block[cur_platform] = (cur_start, i)
|
32 |
+
cur_platform = l[:-1]
|
33 |
+
cur_start = i + 1
|
34 |
+
continue
|
35 |
+
if cur_platform is not None and i == len(lines) - 1:
|
36 |
+
platform_block[cur_platform] = (cur_start, i)
|
37 |
+
for key in platform_block:
|
38 |
+
r = platform_block[key]
|
39 |
+
platform_block[key] = _parse_benchmark_data(lines[r[0]:r[1]])
|
40 |
+
|
41 |
+
return platform_block
|
42 |
+
|
43 |
+
# find device block
|
44 |
+
def _find_all_device_block(lines, level):
|
45 |
+
cur_start = None
|
46 |
+
cur_device_name = None
|
47 |
+
device_block = dict()
|
48 |
+
for i in range(len(lines)):
|
49 |
+
l = lines[i].strip()
|
50 |
+
m = re.match(r"^(#+)\s+(.*)", l)
|
51 |
+
# found start and end of a device
|
52 |
+
if m and len(m.group(1)) == level:
|
53 |
+
if cur_device_name is not None:
|
54 |
+
device_block[cur_device_name] = (cur_start, i)
|
55 |
+
cur_device_name = m.group(2)
|
56 |
+
cur_start = i + 1
|
57 |
+
continue
|
58 |
+
if cur_device_name is not None and i == len(lines) - 1:
|
59 |
+
device_block[cur_device_name] = (cur_start, i)
|
60 |
+
|
61 |
+
for key in device_block:
|
62 |
+
r = device_block[key]
|
63 |
+
device_block[key] = _find_all_platform_block(lines[r[0]:r[1]])
|
64 |
+
|
65 |
+
return device_block
|
66 |
+
|
67 |
+
# find detail block
|
68 |
+
def _find_detail_block(lines, title, level):
|
69 |
+
start = None
|
70 |
+
end = len(lines)
|
71 |
+
for i in range(len(lines)):
|
72 |
+
l = lines[i].strip()
|
73 |
+
m = re.match(r"^(#+)\s+(.*)", l)
|
74 |
+
# found start of detailed results block
|
75 |
+
if m and len(m.group(1)) == level and m.group(2) == title:
|
76 |
+
start = i + 1
|
77 |
+
continue
|
78 |
+
# found end of detailed results block
|
79 |
+
if start is not None and m and len(m.group(1)) <= level:
|
80 |
+
end = i
|
81 |
+
break
|
82 |
+
|
83 |
+
return _find_all_device_block(lines[start:end], level + 1)
|
84 |
+
|
85 |
with open(filepath, "r", encoding="utf-8") as f:
|
86 |
content = f.read()
|
87 |
lines = content.split("\n")
|
88 |
|
89 |
+
devices = cfg["Devices"]
|
90 |
+
models = cfg["Models"]
|
91 |
+
# display information of all devices
|
92 |
+
devices_display = [x['display_info'] for x in cfg["Devices"]]
|
93 |
+
header = ["Model", "Task", "Input Size"] + devices_display
|
94 |
+
body = [[x["name"], x["task"], x["input_size"]] + ["---"] * len(devices) for x in models]
|
95 |
+
table_raw_data = _find_detail_block(lines, title="Detailed Results", level=2)
|
96 |
+
|
97 |
+
device_name_header = [f"{x['name']}-{x['platform']}" for x in devices]
|
98 |
+
device_name_header = [""] * (len(header) - len(device_name_header)) + device_name_header
|
99 |
+
# device name map to model col idx
|
100 |
+
device_name_to_col_idx = {k: v for v, k in enumerate(device_name_header)}
|
101 |
+
# model name map to model row idx
|
102 |
+
model_name_to_row_idx = {k[0]: v for v, k in enumerate(body)}
|
103 |
+
# convert raw data to usage data
|
104 |
+
for device in devices:
|
105 |
+
raw_data = table_raw_data[device["name"]][device["platform"]]
|
106 |
+
col_idx = device_name_to_col_idx[f"{device['name']}-{device['platform']}"]
|
107 |
+
for model in models:
|
108 |
+
# find which row idx of this model
|
109 |
+
row_idx = model_name_to_row_idx[model["name"]]
|
110 |
+
model_idxs = [i for i in range(len(raw_data)) if model["keyword"] in raw_data[i][-1]]
|
111 |
+
if len(model_idxs) > 0:
|
112 |
+
# only choose the first one
|
113 |
+
model_idx = model_idxs[0]
|
114 |
+
# choose mean as value
|
115 |
+
body[row_idx][col_idx] = raw_data[model_idx][0]
|
116 |
+
# remove used data
|
117 |
+
for idx in sorted(model_idxs, reverse=True):
|
118 |
+
raw_data.pop(idx)
|
119 |
+
|
120 |
+
# handle suffix
|
121 |
+
for suffix in cfg["Suffixes"]:
|
122 |
+
row_idx = model_name_to_row_idx[suffix["model"]]
|
123 |
+
col_idx = device_name_to_col_idx[f"{suffix['device']}-{suffix['platform']}"]
|
124 |
+
body[row_idx][col_idx] += suffix["str"]
|
125 |
+
|
126 |
return header, body
|
127 |
|
128 |
|
129 |
+
# render table and save
|
130 |
+
def render_table(header, body, save_path, cfg, cmap_type):
|
131 |
+
# parse models information and return some data
|
132 |
+
def _parse_data(models_info, cmap, cfg):
|
133 |
+
min_list = []
|
134 |
+
max_list = []
|
135 |
+
colors = []
|
136 |
+
# model name map to idx
|
137 |
+
model_name_to_idx = {k["name"]: v for v, k in enumerate(cfg["Models"])}
|
138 |
+
for model in models_info:
|
139 |
+
# remove \*
|
140 |
+
data = [x.replace("\\*", "") for x in model]
|
141 |
+
# get max data
|
142 |
+
max_idx = -1
|
143 |
+
min_data = 9999999
|
144 |
+
min_idx = -1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
|
146 |
+
for i in range(len(data)):
|
147 |
+
try:
|
148 |
+
d = float(data[i])
|
149 |
+
if d < min_data:
|
150 |
+
min_data = d
|
151 |
+
min_idx = i
|
152 |
+
except:
|
153 |
+
pass
|
154 |
+
# set all bigger than acceptable time to red color
|
155 |
+
idx = model_name_to_idx[model[0]]
|
156 |
+
acc_time = cfg["Models"][idx]["acceptable_time"]
|
157 |
|
158 |
+
min_list.append(min_idx)
|
159 |
+
max_list.append(max_idx)
|
160 |
+
|
161 |
+
# calculate colors
|
162 |
+
color = []
|
163 |
+
for t in data:
|
164 |
+
try:
|
165 |
+
t = float(t)
|
166 |
+
if t > acc_time:
|
167 |
+
# all bigger time will be set to red
|
168 |
+
color.append(cmap(1.))
|
169 |
+
else:
|
170 |
+
# sqrt to make the result non-linear
|
171 |
+
t = np.sqrt((t - min_data) / (acc_time - min_data))
|
172 |
+
color.append(cmap(t))
|
173 |
+
except:
|
174 |
+
color.append('white')
|
175 |
+
colors.append(color)
|
176 |
+
return colors, min_list, max_list
|
177 |
+
|
178 |
+
cmap = mpl.colormaps.get_cmap(cmap_type)
|
179 |
+
table_colors, min_list, max_list = _parse_data(body, cmap, cfg)
|
180 |
+
table_texts = [header] + body
|
181 |
+
table_colors = [['white'] * len(header)] + table_colors
|
182 |
+
|
183 |
+
# create a figure, base width set to 1000, height set to 80
|
184 |
fig, axs = plt.subplots(nrows=3, figsize=(10, 0.8))
|
185 |
+
# turn off labels and axis
|
186 |
+
for ax in axs:
|
187 |
+
ax.set_axis_off()
|
188 |
+
ax.set_xticks([])
|
189 |
+
ax.set_yticks([])
|
190 |
+
|
191 |
+
# create and add a color map
|
192 |
gradient = np.linspace(0, 1, 256)
|
193 |
gradient = np.vstack((gradient, gradient))
|
194 |
axs[0].imshow(gradient, aspect='auto', cmap=cmap)
|
|
|
200 |
cellColours=table_colors,
|
201 |
cellLoc="left",
|
202 |
loc="upper left")
|
203 |
+
# set style of header, each url of hardware
|
204 |
+
ori_height = table[0, 0].get_height()
|
205 |
+
url_base = 'https://github.com/opencv/opencv_zoo/tree/master/benchmark#'
|
206 |
+
hw_urls = [f"{url_base}{x['name'].lower().replace(' ', '-')}" for x in cfg["Devices"]]
|
207 |
+
hw_urls = [""] * 3 + hw_urls
|
208 |
+
for col in range(len(header)):
|
209 |
+
cell = table[0, col]
|
210 |
+
cell.set_text_props(ha='center', weight='bold', linespacing=1.5, url=hw_urls[col])
|
211 |
+
cell.set_url(hw_urls[col])
|
212 |
+
cell.set_height(ori_height * 2.2)
|
213 |
+
|
214 |
+
url_base = 'https://github.com/opencv/opencv_zoo/tree/master/models/'
|
215 |
+
model_urls = [f"{url_base}{x['folder']}" for x in cfg["Models"]]
|
216 |
+
model_urls = [""] + model_urls
|
217 |
+
for row in range(len(body) + 1):
|
218 |
+
cell = table[row, 0]
|
219 |
+
cell.set_text_props(url=model_urls[row])
|
220 |
+
cell.set_url(model_urls[row])
|
221 |
|
222 |
# adjust table position
|
223 |
table_pos = axs[1].get_position()
|
|
|
239 |
cell = table.get_celld()[(i + 1, min_list[i])]
|
240 |
cell.set_text_props(weight='bold', color='white')
|
241 |
|
242 |
+
# draw table and trigger changing the column width value
|
243 |
+
fig.canvas.draw()
|
244 |
+
# calculate table height and width
|
245 |
table_height = 0
|
246 |
table_width = 0
|
|
|
247 |
for i in range(len(table_texts)):
|
248 |
cell = table.get_celld()[(i, 0)]
|
249 |
table_height += cell.get_height()
|
250 |
for i in range(len(table_texts[0])):
|
251 |
cell = table.get_celld()[(0, i)]
|
252 |
+
table_width += cell.get_width()
|
253 |
|
254 |
# add notes for table
|
255 |
+
axs[2].text(0, -table_height - 1, "Units: All data in milliseconds (ms).", va='bottom', ha='left', fontsize=11, transform=axs[1].transAxes)
|
256 |
+
axs[2].text(0, -table_height - 2, "\\*: Models are quantized in per-channel mode, which run slower than per-tensor quantized models on NPU.", va='bottom', ha='left', fontsize=11, transform=axs[1].transAxes)
|
|
|
|
|
|
|
|
|
|
|
257 |
|
258 |
# adjust color map position to center
|
259 |
cm_pos = axs[0].get_position()
|
|
|
265 |
])
|
266 |
|
267 |
plt.rcParams['svg.fonttype'] = 'none'
|
268 |
+
plt.rcParams['svg.hashsalt'] = '11' # fix hash salt for avoiding id change
|
269 |
+
plt.savefig(save_path, format='svg', bbox_inches="tight", pad_inches=0, metadata={'Date': None, 'Creator': None})
|
270 |
+
|
271 |
+
|
272 |
+
if __name__ == '__main__':
|
273 |
+
with open("table_config.yaml", 'r') as f:
|
274 |
+
cfg = yaml.safe_load(f)
|
275 |
+
|
276 |
+
hw_info, model_info = parse_table("README.md", cfg)
|
277 |
+
render_table(hw_info, model_info, "color_table.svg", cfg, "RdYlGn_r")
|
benchmark/table_config.yaml
ADDED
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# model information
|
2 |
+
# - name: model name, used for display
|
3 |
+
# task: model task, used for display
|
4 |
+
# input_size: input size, used for display
|
5 |
+
# folder: which folder the model located in, used for jumping to model detail
|
6 |
+
# acceptable_time: maximum acceptable inference time, large ones will be marked red
|
7 |
+
# keyword: used to specify this model from all benchmark results
|
8 |
+
#
|
9 |
+
# device information
|
10 |
+
# - name: full device name used to identify the device block, and jump to device detail
|
11 |
+
# display_info: device information for display
|
12 |
+
# platform: used to identify benchmark result of specific platform
|
13 |
+
#
|
14 |
+
# suffix information
|
15 |
+
# - model: which model
|
16 |
+
# device: which device
|
17 |
+
# suffix: this suffix will be appended to end of this text
|
18 |
+
|
19 |
+
Models:
|
20 |
+
- name: "YuNet"
|
21 |
+
task: "Face Detection"
|
22 |
+
input_size: "160x120"
|
23 |
+
folder: "face_detection_yunet"
|
24 |
+
acceptable_time: 50
|
25 |
+
keyword: "face_detection_yunet"
|
26 |
+
|
27 |
+
- name: "SFace"
|
28 |
+
task: "Face Recognition"
|
29 |
+
input_size: "112x112"
|
30 |
+
folder: "face_recognition_sface"
|
31 |
+
acceptable_time: 200
|
32 |
+
keyword: "face_recognition_sface"
|
33 |
+
|
34 |
+
- name: "FER"
|
35 |
+
task: "Face Expression Recognition"
|
36 |
+
input_size: "112x112"
|
37 |
+
folder: "facial_expression_recognition"
|
38 |
+
acceptable_time: 200
|
39 |
+
keyword: "facial_expression_recognition_mobilefacenet"
|
40 |
+
|
41 |
+
- name: "LPD_YuNet"
|
42 |
+
task: "License Plate Detection"
|
43 |
+
input_size: "320x240"
|
44 |
+
folder: "license_plate_detection_yunet"
|
45 |
+
acceptable_time: 700
|
46 |
+
keyword: "license_plate_detection_lpd_yunet"
|
47 |
+
|
48 |
+
- name: "YOLOX"
|
49 |
+
task: "Object Detection"
|
50 |
+
input_size: "640x640"
|
51 |
+
folder: "object_detection_yolox"
|
52 |
+
acceptable_time: 2800
|
53 |
+
keyword: "object_detection_yolox"
|
54 |
+
|
55 |
+
- name: "NanoDet"
|
56 |
+
task: "Object Detection"
|
57 |
+
input_size: "416x416"
|
58 |
+
folder: "object_detection_nanodet"
|
59 |
+
acceptable_time: 2000
|
60 |
+
keyword: "object_detection_nanodet"
|
61 |
+
|
62 |
+
- name: "DB-IC15 (EN)"
|
63 |
+
task: "Text Detection"
|
64 |
+
input_size: "640x480"
|
65 |
+
folder: "text_detection_db"
|
66 |
+
acceptable_time: 2000
|
67 |
+
keyword: "text_detection_DB_IC15_resnet18"
|
68 |
+
|
69 |
+
- name: "DB-TD500 (EN&CN)"
|
70 |
+
task: "Text Detection"
|
71 |
+
input_size: "640x480"
|
72 |
+
folder: "text_detection_db"
|
73 |
+
acceptable_time: 2000
|
74 |
+
keyword: "text_detection_DB_TD500_resnet18"
|
75 |
+
|
76 |
+
- name: "CRNN-EN"
|
77 |
+
task: "Text Recognition"
|
78 |
+
input_size: "100*32"
|
79 |
+
folder: "text_recognition_crnn"
|
80 |
+
acceptable_time: 2000
|
81 |
+
keyword: "text_recognition_CRNN_EN"
|
82 |
+
|
83 |
+
- name: "CRNN-CN"
|
84 |
+
task: "Text Recognition"
|
85 |
+
input_size: "100*32"
|
86 |
+
folder: "text_recognition_crnn"
|
87 |
+
acceptable_time: 2000
|
88 |
+
keyword: "text_recognition_CRNN_CN"
|
89 |
+
|
90 |
+
- name: "PP-ResNet"
|
91 |
+
task: "Image Classification"
|
92 |
+
input_size: "224x224"
|
93 |
+
folder: "image_classification_ppresnet"
|
94 |
+
acceptable_time: 1000
|
95 |
+
keyword: "image_classification_ppresnet50"
|
96 |
+
|
97 |
+
- name: "MobileNet-V1"
|
98 |
+
task: "Image Classification"
|
99 |
+
input_size: "224x224"
|
100 |
+
folder: "image_classification_mobilenet"
|
101 |
+
acceptable_time: 500
|
102 |
+
keyword: "image_classification_mobilenetv1"
|
103 |
+
|
104 |
+
- name: "MobileNet-V2"
|
105 |
+
task: "Image Classification"
|
106 |
+
input_size: "224x224"
|
107 |
+
folder: "image_classification_mobilenet"
|
108 |
+
acceptable_time: 500
|
109 |
+
keyword: "image_classification_mobilenetv2"
|
110 |
+
|
111 |
+
- name: "PP-HumanSeg"
|
112 |
+
task: "Human Segmentation"
|
113 |
+
input_size: "192x192"
|
114 |
+
folder: "human_segmentation_pphumanseg"
|
115 |
+
acceptable_time: 700
|
116 |
+
keyword: "human_segmentation_pphumanseg"
|
117 |
+
|
118 |
+
- name: "WeChatQRCode"
|
119 |
+
task: "QR Code Detection and Parsing"
|
120 |
+
input_size: "100x100"
|
121 |
+
folder: "qrcode_wechatqrcode"
|
122 |
+
acceptable_time: 100
|
123 |
+
keyword: "WeChatQRCode"
|
124 |
+
|
125 |
+
- name: "DaSiamRPN"
|
126 |
+
task: "Object Tracking"
|
127 |
+
input_size: "1280x720"
|
128 |
+
folder: "object_tracking_dasiamrpn"
|
129 |
+
acceptable_time: 3000
|
130 |
+
keyword: "object_tracking_dasiamrpn"
|
131 |
+
|
132 |
+
- name: "YoutuReID"
|
133 |
+
task: "Person Re-Identification"
|
134 |
+
input_size: "128x256"
|
135 |
+
folder: "person_reid_youtureid"
|
136 |
+
acceptable_time: 800
|
137 |
+
keyword: "person_reid_youtu"
|
138 |
+
|
139 |
+
- name: "MP-PalmDet"
|
140 |
+
task: "Palm Detection"
|
141 |
+
input_size: "192x192"
|
142 |
+
folder: "palm_detection_mediapipe"
|
143 |
+
acceptable_time: 500
|
144 |
+
keyword: "palm_detection_mediapipe"
|
145 |
+
|
146 |
+
- name: "MP-HandPose"
|
147 |
+
task: "Hand Pose Estimation"
|
148 |
+
input_size: "224x224"
|
149 |
+
folder: "handpose_estimation_mediapipe"
|
150 |
+
acceptable_time: 500
|
151 |
+
keyword: "handpose_estimation_mediapipe"
|
152 |
+
|
153 |
+
- name: "MP-PersonDet"
|
154 |
+
task: "Person Detection"
|
155 |
+
input_size: "224x224"
|
156 |
+
folder: "person_detection_mediapipe"
|
157 |
+
acceptable_time: 1300
|
158 |
+
keyword: "person_detection_mediapipe"
|
159 |
+
|
160 |
+
|
161 |
+
Devices:
|
162 |
+
- name: "Intel 12700K"
|
163 |
+
display_info: "Intel\n12700K\nCPU"
|
164 |
+
platform: "CPU"
|
165 |
+
|
166 |
+
- name: "Rasberry Pi 4B"
|
167 |
+
display_info: "Rasberry Pi 4B\nBCM2711\nCPU"
|
168 |
+
platform: "CPU"
|
169 |
+
|
170 |
+
- name: "Toybrick RV1126"
|
171 |
+
display_info: "Toybrick\nRV1126\nCPU"
|
172 |
+
platform: "CPU"
|
173 |
+
|
174 |
+
- name: "Khadas Edge2 (with RK3588)"
|
175 |
+
display_info: "Khadas Edge2\nRK3588S\nCPU"
|
176 |
+
platform: "CPU"
|
177 |
+
|
178 |
+
- name: "Horizon Sunrise X3 PI"
|
179 |
+
display_info: "Horizon Sunrise Pi\nX3\nCPU"
|
180 |
+
platform: "CPU"
|
181 |
+
|
182 |
+
- name: "MAIX-III AX-PI"
|
183 |
+
display_info: "MAIX-III AX-Pi\nAX620A\nCPU"
|
184 |
+
platform: "CPU"
|
185 |
+
|
186 |
+
- name: "Jetson Nano B01"
|
187 |
+
display_info: "Jetson Nano\nB01\nCPU"
|
188 |
+
platform: "CPU"
|
189 |
+
|
190 |
+
- name: "Khadas VIM3"
|
191 |
+
display_info: "Khadas VIM3\nA311D\nCPU"
|
192 |
+
platform: "CPU"
|
193 |
+
|
194 |
+
- name: "Atlas 200 DK"
|
195 |
+
display_info: "Atlas 200 DK\nAscend 310\nCPU"
|
196 |
+
platform: "CPU"
|
197 |
+
|
198 |
+
- name: "Jetson Nano B01"
|
199 |
+
display_info: "Jetson Nano\nB01\nGPU"
|
200 |
+
platform: "GPU (CUDA-FP32)"
|
201 |
+
|
202 |
+
- name: "Khadas VIM3"
|
203 |
+
display_info: "Khadas VIM3\nA311D\nNPU"
|
204 |
+
platform: "NPU (TIMVX)"
|
205 |
+
|
206 |
+
- name: "Atlas 200 DK"
|
207 |
+
display_info: "Atlas 200 DK\nAscend 310\nNPU"
|
208 |
+
platform: "NPU"
|
209 |
+
|
210 |
+
Suffixes:
|
211 |
+
- model: "MobileNet-V1"
|
212 |
+
device: "Khadas VIM3"
|
213 |
+
platform: "NPU (TIMVX)"
|
214 |
+
str: "\\*"
|
215 |
+
|
216 |
+
- model: "MobileNet-V2"
|
217 |
+
device: "Khadas VIM3"
|
218 |
+
platform: "NPU (TIMVX)"
|
219 |
+
str: "\\*"
|