class_docstr: Prepares the model for QAT by inserting weight and activation quantizers as
  specified in qconfig_mapping.
  
  Implements additional graph passes on a prepared module returned by prepare_qat_fx.
class_docstr_tok: ["Prepares","the","model","for","QAT","by","inserting","weight","and","activation","quantizers","as","specified","in","qconfig_mapping",".","Implements","additional","graph","passes","on","a","prepared","module","returned","by","prepare_qat_fx","."]
docstr: During evaluation, dropout is a no-op. During conversion,
  
  conv_1 -> activation_q_1 -> dropout -> activation_q_2 -> conv_2
  
  becomes
  
  conv_1 -> quant_1 -> dequant_1 -> quant_2 -> dequant_2 -> conv_2
  
  where quant_1,dequant_1 have different qparams from quant_2/dequant_2
  because dropout scales the output by 1/(1-p). This leads to inefficiency
  during inference. Since during inference, conv_2 sees quantized activations
  coming from conv_1, removing activation_q_2 doesn't lead to
  increased quantization error. Hence, this pass removes activation_q_2.
docstr_tok: ["During","evaluation",",","dropout","is","a","no-op",".","During","conversion",",","conv_1","-",">","activation_q_1","-",">","dropout","-",">","activation_q_2","-",">","conv_2","becomes","conv_1","-",">","quant_1","-",">","dequant_1","-",">","quant_2","-",">","dequant_2","-",">","conv_2","where","quant_1",",","dequant_1","have","different","qparams","from","quant_2\/dequant_2","because","dropout","scales","the","output","by","1\/","(","1-p",")",".","This","leads","to","inefficiency","during","inference",".","Since","during","inference",",","conv_2","sees","quantized","activations","coming","from","conv_1",",","removing","activation_q_2","does","n't","lead","to","increased","quantization","error",".","Hence",",","this","pass","removes","activation_q_2","."]
code: def _remove_activation_quantizer_after_dropout(
      model: _fx.GraphModule,
  ):
      """
      During evaluation, dropout is a no-op. During conversion,
  
      conv_1 -> activation_q_1 -> dropout -> activation_q_2 -> conv_2
  
      becomes
  
      conv_1 -> quant_1 -> dequant_1 -> quant_2 -> dequant_2 -> conv_2
  
      where quant_1,dequant_1 have different qparams from quant_2/dequant_2
      because dropout scales the output by 1/(1-p). This leads to inefficiency
      during inference. Since during inference, conv_2 sees quantized activations
      coming from conv_1, removing activation_q_2 doesn't lead to
      increased quantization error. Hence, this pass removes activation_q_2.
      """
      nodes_to_remove = set()
      for node in model.graph.nodes:
          if node.op == "call_module":
              layer = _find_module(model, node)
              if isinstance(layer, tuple(_scale_only_layers)):
                  prev_module = _find_module(model, node.prev)
                  next_module = _find_module(model, node.next)
                  if _is_activation_post_process(
                      next_module
                  ) and _is_activation_post_process(prev_module):
                      nodes_to_remove.add(node.next)
      for node in nodes_to_remove:
          node.replace_all_uses_with(node.prev)
          model.delete_submodule(node.target)
          model.graph.erase_node(node)
      model.recompile()
      return model
  
imports: from collections import defaultdict
  from typing import Any
  from typing import Optional
  import torch
  import torch.ao.quantization
  import torch.fx
  import torch.nn
  import torch.nn.intrinsic
  import torch.nn.intrinsic.qat
  from torch.ao.quantization.backend_config import BackendConfig
  from torch.ao.quantization.fx.custom_config import PrepareCustomConfig
  from torch.quantization.quantize_fx import prepare_qat_fx
  import coremltools.optimize.torch.quantization.modules.qat_modules
  from coremltools.optimize.torch._utils.torch_utils import get_parent_child_name
  from coremltools.optimize.torch.quantization._backend_config import _fixed_qparams_modules
  from coremltools.optimize.torch.quantization._utils import CombinationOpType
  from coremltools.optimize.torch.quantization._utils import combine_op_type
  from coremltools.optimize.torch.quantization._utils import find_module
  from coremltools.optimize.torch.quantization._utils import find_target
  from coremltools.optimize.torch.quantization._utils import get_share_qparams_ops
  from coremltools.optimize.torch.quantization._utils import group_activation_quantization_modules_by_id
  from coremltools.optimize.torch.quantization._utils import is_activation_post_process
  from coremltools.optimize.torch.quantization._utils import is_quantized
  from coremltools.optimize.torch.quantization.quantization_config import QuantizationScheme
label_desc: Use image node_id 5 for calling the QATConfigurationHandler obj's underlying member method code with example usage: obj._remove_activation_quantizer_after_dropout(model) and returns: model