Export a caffe2-compatible Detectron2 model to caffe2 format via ONNX. Arg: model: a caffe2-compatible version of detectron2 model, defined in caffe2_modeling.py tensor_inputs: a list of tensors that caffe2 model takes as input.
(model: torch.nn.Module, tensor_inputs: List[torch.Tensor])
| 127 | |
| 128 | |
| 129 | def export_caffe2_detection_model(model: torch.nn.Module, tensor_inputs: List[torch.Tensor]): |
| 130 | """ |
| 131 | Export a caffe2-compatible Detectron2 model to caffe2 format via ONNX. |
| 132 | |
| 133 | Arg: |
| 134 | model: a caffe2-compatible version of detectron2 model, defined in caffe2_modeling.py |
| 135 | tensor_inputs: a list of tensors that caffe2 model takes as input. |
| 136 | """ |
| 137 | model = copy.deepcopy(model) |
| 138 | assert isinstance(model, torch.nn.Module) |
| 139 | assert hasattr(model, "encode_additional_info") |
| 140 | |
| 141 | # Export via ONNX |
| 142 | logger.info( |
| 143 | "Exporting a {} model via ONNX ...".format(type(model).__name__) |
| 144 | + " Some warnings from ONNX are expected and are usually not to worry about." |
| 145 | ) |
| 146 | onnx_model = export_onnx_model(model, (tensor_inputs,)) |
| 147 | # Convert ONNX model to Caffe2 protobuf |
| 148 | init_net, predict_net = Caffe2Backend.onnx_graph_to_caffe2_net(onnx_model) |
| 149 | ops_table = [[op.type, op.input, op.output] for op in predict_net.op] |
| 150 | table = tabulate(ops_table, headers=["type", "input", "output"], tablefmt="pipe") |
| 151 | logger.info( |
| 152 | "ONNX export Done. Exported predict_net (before optimizations):\n" + colored(table, "cyan") |
| 153 | ) |
| 154 | |
| 155 | # Apply protobuf optimization |
| 156 | fuse_alias_placeholder(predict_net, init_net) |
| 157 | if any(t.device.type != "cpu" for t in tensor_inputs): |
| 158 | fuse_copy_between_cpu_and_gpu(predict_net) |
| 159 | remove_dead_end_ops(init_net) |
| 160 | _assign_device_option(predict_net, init_net, tensor_inputs) |
| 161 | params, device_options = get_params_from_init_net(init_net) |
| 162 | predict_net, params = remove_reshape_for_fc(predict_net, params) |
| 163 | init_net = construct_init_net_from_params(params, device_options) |
| 164 | group_norm_replace_aten_with_caffe2(predict_net) |
| 165 | |
| 166 | # Record necessary information for running the pb model in Detectron2 system. |
| 167 | model.encode_additional_info(predict_net, init_net) |
| 168 | |
| 169 | logger.info("Operators used in predict_net: \n{}".format(_op_stats(predict_net))) |
| 170 | logger.info("Operators used in init_net: \n{}".format(_op_stats(init_net))) |
| 171 | |
| 172 | return predict_net, init_net |
| 173 | |
| 174 | |
| 175 | def run_and_save_graph(predict_net, init_net, tensor_inputs, graph_save_path): |
no test coverage detected