code: def dynamically_quantize_per_channel(
      x, quant_min, quant_max, target_dtype
  ):
      # assumes symmetric quantization
      # assumes axis == 0
      # assumes dense memory format
      # TODO(future): relax ^ as needed
  
      # default setup for affine quantization of activations
      eps = torch.finfo(torch.float32).eps
  
      # get min and max
      min_val, max_val = torch.aminmax(x, dim=1)
  
      # calculate scales and zero_points based on min and max
      # reference: https://fburl.com/code/srbiybme
      min_val_neg = torch.min(min_val, torch.zeros_like(min_val))
      max_val_pos = torch.max(max_val, torch.zeros_like(max_val))
      device = min_val_neg.device
  
      # reference: https://fburl.com/code/4wll53rk
      max_val_pos = torch.max(-min_val_neg, max_val_pos)
      scales = max_val_pos / (float(quant_max - quant_min) / 2)
      # ensure scales is the same dtype as the original tensor
      scales = torch.clamp(scales, min=eps).to(x.dtype)
      zero_points = torch.zeros(
          min_val_neg.size(), dtype=torch.int64, device=device
      )
  
      # quantize based on qmin/qmax/scales/zp
      # reference: https://www.internalfb.com/code/fbsource/[8edc275012b1]/fbcode/caffe2/torch/ao/quantization/fx/_decomposed.py?lines=63
      x_div = x / scales.unsqueeze(-1)
      x_round = torch.round(x_div)
      x_zp = x_round + zero_points.unsqueeze(-1)
      quant = torch.clamp(x_zp, quant_min, quant_max).to(target_dtype)
  
      return quant, scales, zero_points
  
imports: import time
  from pathlib import Path
  import torch
  import torch.nn
  import torch.nn.functional
  from sentencepiece import SentencePieceProcessor
  from model import Transformer
label_desc: Use image node_id 1 for calling a global function with example usage: dynamically_quantize_per_channel(x, quant_min, quant_max, target_dtype) and returns: quant,  scales,  zero_points