r"""Prepares a copy of the model for quantization calibration or quantization-aware training. Quantization configuration should be assigned preemptively to individual submodules in `.qconfig` attribute. The model will be attached with observer or fake quant modules, and qconfig wil
(model, inplace=False, allow_list=None,
observer_non_leaf_module_list=None,
prepare_custom_config_dict=None)
| 263 | return module |
| 264 | |
| 265 | def prepare(model, inplace=False, allow_list=None, |
| 266 | observer_non_leaf_module_list=None, |
| 267 | prepare_custom_config_dict=None): |
| 268 | r"""Prepares a copy of the model for quantization calibration or quantization-aware training. |
| 269 | |
| 270 | Quantization configuration should be assigned preemptively |
| 271 | to individual submodules in `.qconfig` attribute. |
| 272 | |
| 273 | The model will be attached with observer or fake quant modules, and qconfig |
| 274 | will be propagated. |
| 275 | |
| 276 | Args: |
| 277 | `model`: input model to be modified in-place |
| 278 | `inplace`: carry out model transformations in-place, the original module is mutated |
| 279 | `allow_list`: list of quantizable modules |
| 280 | `observer_non_leaf_module_list`: list of non-leaf modules we want to add observer |
| 281 | `prepare_custom_config_dict`: customization configuration dictionary for prepare function |
| 282 | |
| 283 | .. code-block:: python |
| 284 | |
| 285 | # Example of prepare_custom_config_dict: |
| 286 | prepare_custom_config_dict = { |
| 287 | # user will manually define the corresponding observed |
| 288 | # module class which has a from_float class method that converts |
| 289 | # float custom module to observed custom module |
| 290 | "float_to_observed_custom_module_class": { |
| 291 | CustomModule: ObservedCustomModule |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | """ |
| 296 | torch._C._log_api_usage_once("quantization_api.quantize.prepare") |
| 297 | if prepare_custom_config_dict is None: |
| 298 | prepare_custom_config_dict = get_default_custom_config_dict() |
| 299 | custom_module_class_mapping = prepare_custom_config_dict.get("float_to_observed_custom_module_class", {}) |
| 300 | |
| 301 | if not inplace: |
| 302 | model = copy.deepcopy(model) |
| 303 | |
| 304 | # TODO: remove allow_list |
| 305 | qconfig_propagation_list = allow_list |
| 306 | if allow_list is None: |
| 307 | qconfig_propagation_list = get_default_qconfig_propagation_list() |
| 308 | propagate_qconfig_(model, qconfig_dict=None) |
| 309 | |
| 310 | # sanity check common API misusage |
| 311 | if not any(hasattr(m, 'qconfig') and m.qconfig for m in model.modules()): |
| 312 | warnings.warn("None of the submodule got qconfig applied. Make sure you " |
| 313 | "passed correct configuration through `qconfig_dict` or " |
| 314 | "by assigning the `.qconfig` attribute directly on submodules") |
| 315 | |
| 316 | _add_observer_( |
| 317 | model, qconfig_propagation_list, observer_non_leaf_module_list, |
| 318 | custom_module_class_mapping=custom_module_class_mapping) |
| 319 | return model |
| 320 | |
| 321 | def _remove_activation_post_process(module): |
| 322 | # TODO: maybe we should change activation_post_process to _activation_post_process |
searching dependent graphs…