code: def update_scale_zp(
      self, wrapper: ModuleWrapper, target_name: str, target: Tensor
  ):
      if (
          not wrapper.training
          or self.current_step < self.quant_start_step
          or not self.check_target(wrapper, target_name)
      ):
          return
      if target_name in wrapper.quantization_target_spaces:
          target_space = wrapper.quantization_target_spaces[target_name]
          if (
              target_space.tracked_max is None
              or target_space.tracked_min is None
          ):
              return
          # Comments copied from the old version:
          # Extend the [min, max] interval to ensure that it contains 0.
          # Otherwise, we would not meet the requirement that 0 be an exactly representable value.
          # I think this is for activations that need to be pad in the training.
          # However this is a default behavior in PyTorch quantization observer.
          # So we also make it a default behavior.
          tracked_min = torch.min(
              target_space.tracked_min,
              torch.zeros_like(target_space.tracked_min),
          )
          tracked_max = torch.max(
              target_space.tracked_max,
              torch.zeros_like(target_space.tracked_max),
          )
          zero_point = torch.zeros_like(tracked_min)
          qmin, qmax = target_space.qmin, target_space.qmax
          assert isinstance(qmin, int) and isinstance(qmax, int)
          if target_space.quant_scheme in ["symmetric", None]:
              abs_max = torch.max(
                  torch.abs(tracked_min), torch.abs(tracked_max)
              )
              scale = abs_max / (float(qmax - qmin) / 2)
              scale = torch.max(
                  scale,
                  torch.full_like(
                      scale, torch.finfo(torch.float32).eps
                  ),
              )
              # NOTE: here need to check, +1 because in pytorch, symmetric qint8 zp is 0, quint8 zp is 128.
              zero_point_val = (qmax + qmin + 1) // 2
              zero_point = torch.full_like(zero_point, zero_point_val)
          elif target_space.quant_scheme == "affine":
              scale = (tracked_max - tracked_min) / float(qmax - qmin)
              scale = torch.max(
                  scale,
                  torch.full_like(
                      scale, torch.finfo(torch.float32).eps
                  ),
              )
              zero_point = qmin - torch.round(tracked_min / scale)
          else:
              raise RuntimeError(
                  f"Unknown quant_scheme {target_space.quant_scheme}"
              )
          zero_point = torch.clamp(zero_point, qmin, qmax)
          target_space.scale, target_space.zero_point = (
              scale,
              zero_point,
          )
  
imports: from __future__ import annotations
  from typing import Dict, List, overload
  import torch
  from torch import Tensor
  from ..base.compressor import Compressor, Quantizer
  from ..base.wrapper import ModuleWrapper
  from ..utils import Evaluator, _EVALUATOR_DOCSTRING
label_desc: Use image node_id 8 for calling the QATQuantizer obj's underlying member method code with example usage: obj.update_scale_zp(wrapper, target_name, target) without return types