MCPcopy
hub / github.com/OpenPPL/ppq / export

Method export

ppq/parser/caffe_exporter.py:249–400  ·  view source on GitHub ↗
(self, file_path: str, graph: BaseGraph, config_path: str = None,
               input_shapes: List[List[int]] = [[1, 3, 224, 224]], write_weight=False)

Source from the content-addressed store, hash-verified

247
248class PPLDSPCaffeExporter(CaffeExporter):
249 def export(self, file_path: str, graph: BaseGraph, config_path: str = None,
250 input_shapes: List[List[int]] = [[1, 3, 224, 224]], write_weight=False):
251 # PPL3 DSP do not need a json config file, all quantization configuration will be merged into protobuf
252 caffe_model, caffe_proto = self.prepare_model(graph, input_shapes)
253 for idx in range(len(caffe_proto.layer)):
254 layer = caffe_proto.layer[idx]
255 layer_name = layer.name
256
257 assert isinstance(layer, ppl_caffe_pb2.LayerParameter)
258 assert isinstance(layer_name, str)
259 # layer is a caffe data structure, corresponding to operation in ppq.
260 # following code write ppq quantization configuration to caffe layer.
261
262 # step - 1, find corresponding op
263 if layer_name not in graph.operations:
264 # PATCH FOR Slice
265 if layer.type == 'Slice':
266 # slice0 --> (ppq parse, export, combine) --> slice0_0_0, everything else
267 # is the same with original model
268 # layer_name is slice0_0_0, obtain original_name slice0
269 original_name = ''.join(layer_name.split('_')[:-2])
270 for bottom in layer.bottom:
271 var = graph.variables.get(bottom, None)
272 if var is not None and isinstance(var, QuantableVariable) and not var.is_parameter:
273 cfg = None
274 for dest_op, dest_cfg in zip(var.dest_ops, var.dest_op_configs):
275 # dest_op.name is slice0_0
276 if ''.join(dest_op.name.split('_')[:-1]) == original_name:
277 cfg = dest_cfg
278 break
279 assert cfg is not None
280 qt_min = convert_value(cfg.scale * (cfg.quant_min - cfg.offset), True, DataType.FP32)
281 qt_max = convert_value(cfg.scale * (cfg.quant_max - cfg.offset), True, DataType.FP32)
282 layer.quantize_param.add(type='bottom', range_min=qt_min, range_max=qt_max)
283
284 for top in layer.top:
285 var = graph.variables.get(top, None)
286 if var is not None and isinstance(var, QuantableVariable) and not var.is_parameter:
287 cfg = var.source_op_config
288 assert cfg is not None
289 qt_min = convert_value(cfg.scale * (cfg.quant_min - cfg.offset), True, DataType.FP32)
290 qt_max = convert_value(cfg.scale * (cfg.quant_max - cfg.offset), True, DataType.FP32)
291 layer.quantize_param.add(type='top', range_min=qt_min, range_max=qt_max)
292 continue
293 else:
294 raise KeyError(f'Can not find operation {layer_name} with current graph.')
295
296 op = graph.operations[layer_name]
297 if not isinstance(op, QuantableOperation): continue
298
299 # step - 2, dump parameter quantization config
300 if layer.type in {'Convolution', 'Deconvolution'}:
301 for cfg, var in op.config_with_variable:
302 if not var.is_parameter: continue
303 if cfg.num_of_bits > 8: continue # skip bias
304
305 if cfg.policy.has_property(QuantizationProperty.PER_CHANNEL):
306 qt_min = convert_value(cfg.scale * (cfg.quant_min - cfg.offset), False, DataType.FP32)

Callers

nothing calls this directly

Calls 5

prepare_modelMethod · 0.80
addMethod · 0.80
has_propertyMethod · 0.80
dump_to_fileMethod · 0.80
convert_valueFunction · 0.70

Tested by

no test coverage detected