



'''simple docstring'''





import logging
import re

import pytorch_quantization
import pytorch_quantization.nn as quant_nn
import torch
from pytorch_quantization import calib
from pytorch_quantization.tensor_quant import QuantDescriptor


A__    :   List[Any]           =					logging.getLogger(__name__)

A__    :   Tuple           =					5_0  # max width of layer names
A__    :   int           =					7_0  # max width of quantizer names





def   a_   (		_UpperCAmelCase    :      Optional[int]				)    ->  str:
      __snake_case :   int													=    parser.add_argument_group('quant_trainer arguments'				)
      group.add_argument('--wprec' ,type=_UpperCAmelCase ,default=8 ,help='weight precision'				)
      group.add_argument('--aprec' ,type=_UpperCAmelCase ,default=8 ,help='activation precision'				)
      group.add_argument('--quant-per-tensor' ,action='store_true' ,help='per tensor weight scaling'				)
      group.add_argument('--quant-disable' ,action='store_true' ,help='disable all quantizers'				)
      group.add_argument('--quant-disable-embeddings' ,action='store_true' ,help='disable all embeddings quantizers'				)
      group.add_argument('--quant-disable-keyword' ,type=_UpperCAmelCase ,nargs='+' ,help='disable quantizers by keyword'				)
      group.add_argument('--quant-disable-layer-module' ,type=_UpperCAmelCase ,help='disable quantizers by keyword under layer.'				)
      group.add_argument('--quant-enable-layer-module' ,type=_UpperCAmelCase ,help='enable quantizers by keyword under layer'				)
      group.add_argument('--calibrator' ,default='max' ,help='which quantization range calibrator to use'				)
      group.add_argument('--percentile' ,default=_UpperCAmelCase ,type=_UpperCAmelCase ,help='percentile for PercentileCalibrator'				)
      group.add_argument('--fuse-qkv' ,action='store_true' ,help='use the same scale factor for qkv'				)
      group.add_argument('--clip-gelu' ,metavar='N' ,type=_UpperCAmelCase ,help='clip gelu output maximum value to N'				)
      group.add_argument(
          '--recalibrate-weights' ,action='store_true' ,help=(
              'recalibrate weight amaxes by taking the max of the weights.'
              ' amaxes will be computed with the current quantization granularity (axis).'
          ) ,)





def   a_   (		_UpperCAmelCase    :      Union[str, Any]				)    ->  List[Any]:

      if args.calibrator == "max":
            __snake_case :   str													=    'max'
      elif args.calibrator == "percentile":
            if args.percentile is None:
                  raise ValueError('Specify --percentile when using percentile calibrator'				)
            __snake_case :   str													=    'histogram'
      elif args.calibrator == "mse":
            __snake_case :   Union[str, Any]													=    'histogram'
      else:
            raise ValueError(f'''Invalid calibrator {args.calibrator}'''				)

      __snake_case :   Any													=    QuantDescriptor(num_bits=args.aprec ,calib_method=_UpperCAmelCase				)
      __snake_case :   List[str]													=    QuantDescriptor(num_bits=args.wprec ,axis=(None if args.quant_per_tensor else (0,))				)
      quant_nn.QuantLinear.set_default_quant_desc_input(_UpperCAmelCase				)
      quant_nn.QuantLinear.set_default_quant_desc_weight(_UpperCAmelCase				)





def   a_   (		_UpperCAmelCase    :      List[Any] ,_UpperCAmelCase    :      Union[str, Any] ,_UpperCAmelCase    :      Union[str, Any]=False ,_UpperCAmelCase    :      Optional[Any]=False				)    ->  List[str]:
      logger.info('Configuring Model for Quantization'				)
      logger.info(f'''using quantization package {pytorch_quantization.__file__}'''				)

      if not calib:
            if args.quant_disable_embeddings:
                  set_quantizer_by_name(_UpperCAmelCase ,['embeddings'] ,which='weight' ,_disabled=_UpperCAmelCase				)

            if args.quant_disable:
                  set_quantizer_by_name(_UpperCAmelCase ,[''] ,_disabled=_UpperCAmelCase				)

            if args.quant_disable_keyword:
                  set_quantizer_by_name(_UpperCAmelCase ,args.quant_disable_keyword ,_disabled=_UpperCAmelCase				)

            if args.quant_disable_layer_module:
                  set_quantizer_by_name(_UpperCAmelCase ,[r'layer.\d+.' + args.quant_disable_layer_module] ,_disabled=_UpperCAmelCase				)

            if args.quant_enable_layer_module:
                  set_quantizer_by_name(_UpperCAmelCase ,[r'layer.\d+.' + args.quant_enable_layer_module] ,_disabled=_UpperCAmelCase				)

            if args.recalibrate_weights:
                  recalibrate_weights(_UpperCAmelCase				)

            if args.fuse_qkv:
                  fuse_qkv(_UpperCAmelCase ,_UpperCAmelCase				)

      if args.clip_gelu:
            clip_gelu(_UpperCAmelCase ,args.clip_gelu				)

      # if args.local_rank in [-1, 0] and not calib:
      print_quant_summary(_UpperCAmelCase				)





def   a_   (		_UpperCAmelCase    :      Optional[Any]				)    ->  Union[str, Any]:
      logger.info('Enabling Calibration'				)
      for name, module in model.named_modules():
            if name.endswith('_quantizer'				):
                  if module._calibrator is not None:
                        module.disable_quant()
                        module.enable_calib()
                  else:
                        module.disable()
                  logger.info(f'''{name:80}: {module}'''				)





def   a_   (		_UpperCAmelCase    :      List[str] ,_UpperCAmelCase    :      Any				)    ->  List[Any]:
      logger.info('Loading calibrated amax'				)
      for name, module in model.named_modules():
            if name.endswith('_quantizer'				):
                  if module._calibrator is not None:
                        if isinstance(module._calibrator ,calib.MaxCalibrator				):
                              module.load_calib_amax()
                        else:
                              module.load_calib_amax('percentile' ,percentile=args.percentile				)
                        module.enable_quant()
                        module.disable_calib()
                  else:
                        module.enable()
      model.cuda()
      print_quant_summary(_UpperCAmelCase				)





def   a_   (		_UpperCAmelCase    :      List[Any] ,_UpperCAmelCase    :      List[str]				)    ->  List[str]:

      def fusea(_UpperCAmelCase    :      Optional[int] ,_UpperCAmelCase    :      List[Any] ,_UpperCAmelCase    :      List[str]				):
            for mod in [qq, qk, qv]:
                  if not hasattr(_UpperCAmelCase ,'_amax'				):
                        print('          WARNING: NO AMAX BUFFER'				)
                        return
            __snake_case :   Union[str, Any]													=    qq._amax.detach().item()
            __snake_case :   Any													=    qk._amax.detach().item()
            __snake_case :   Optional[int]													=    qv._amax.detach().item()

            __snake_case :   Dict													=    max(_UpperCAmelCase ,_UpperCAmelCase ,_UpperCAmelCase				)
            qq._amax.fill_(_UpperCAmelCase				)
            qk._amax.fill_(_UpperCAmelCase				)
            qv._amax.fill_(_UpperCAmelCase				)
            logger.info(f'''          q={q:5.2f} k={k:5.2f} v={v:5.2f} -> {amax:5.2f}'''				)

      for name, mod in model.named_modules():
            if name.endswith('.attention.self'				):
                  logger.info(f'''FUSE_QKV: {name:{name_width}}'''				)
                  fusea(mod.matmul_q_input_quantizer ,mod.matmul_k_input_quantizer ,mod.matmul_v_input_quantizer				)
                  if args.quant_per_tensor:
                        fusea(mod.query._weight_quantizer ,mod.key._weight_quantizer ,mod.value._weight_quantizer				)





def   a_   (		_UpperCAmelCase    :      Union[str, Any] ,_UpperCAmelCase    :      Dict				)    ->  Optional[int]:

      for name, mod in model.named_modules():
            if name.endswith('.output.dense'				) and not name.endswith('attention.output.dense'				):
                  __snake_case :   Union[str, Any]													=    mod._input_quantizer._amax.data.detach().item()
                  mod._input_quantizer._amax.data.detach().clamp_(max=_UpperCAmelCase				)
                  __snake_case :   int													=    mod._input_quantizer._amax.data.detach().item()
                  logger.info(f'''CLIP_GELU: {name:{name_width}} amax: {amax_init:5.2f} -> {amax:5.2f}'''				)





def   a_   (		_UpperCAmelCase    :      str				)    ->  Union[str, Any]:

      for name, mod in model.named_modules():
            if hasattr(_UpperCAmelCase ,'_weight_quantizer'				) and mod._weight_quantizer.axis is not None:
                  __snake_case :   Union[str, Any]													=    mod.weight.shape[0]
                  __snake_case :   int													=    mod._weight_quantizer._amax.detach()
                  __snake_case :   Dict													=    torch.ones(_UpperCAmelCase ,dtype=amax.dtype ,device=amax.device				) * amax
                  print(f'''expanding {name} {amax} -> {mod._weight_quantizer._amax}'''				)





def   a_   (		_UpperCAmelCase    :      Any				)    ->  str:

      for name, mod in model.named_modules():
            if hasattr(_UpperCAmelCase ,'_weight_quantizer'				):
                  if not hasattr(mod.weight_quantizer ,'_amax'				):
                        print('RECALIB: {name:{name_width}} WARNING: NO AMAX BUFFER'				)
                        continue

                  # determine which axes to reduce across
                  # e.g. a 4D tensor quantized per axis 0 should reduce over (1,2,3)
                  __snake_case :   Optional[Any]													=    set() if mod._weight_quantizer.axis is None else set(mod._weight_quantizer.axis				)
                  __snake_case :   Tuple													=    set(range(len(mod.weight.size()				)				)				) - axis_set
                  __snake_case :   Optional[Any]													=    pytorch_quantization.utils.reduce_amax(mod.weight ,axis=_UpperCAmelCase ,keepdims=_UpperCAmelCase				).detach()
                  logger.info(f'''RECALIB: {name:{name_width}} {mod._weight_quantizer._amax.flatten()} -> {amax.flatten()}'''				)
                  __snake_case :   str													=    amax





def   a_   (		_UpperCAmelCase    :      List[Any] ,_UpperCAmelCase    :      Any=25 ,_UpperCAmelCase    :      List[str]=1_80 ,_UpperCAmelCase    :      Dict=None				)    ->  List[Any]:

      if ignore is None:
            __snake_case :   Union[str, Any]													=    []
      elif not isinstance(_UpperCAmelCase ,_UpperCAmelCase				):
            __snake_case :   Optional[Any]													=    [ignore]

      __snake_case :   Any													=    0
      for name, mod in model.named_modules():
            if not hasattr(_UpperCAmelCase ,'weight'				):
                  continue
            __snake_case :   int													=    max(_UpperCAmelCase ,len(_UpperCAmelCase				)				)

      for name, mod in model.named_modules():
            __snake_case :   Optional[Any]													=    getattr(_UpperCAmelCase ,'_input_quantizer' ,_UpperCAmelCase				)
            __snake_case :   Optional[Any]													=    getattr(_UpperCAmelCase ,'_weight_quantizer' ,_UpperCAmelCase				)
            if not hasattr(_UpperCAmelCase ,'weight'				):
                  continue
            if type(_UpperCAmelCase				) in ignore:
                  continue
            if [True for s in ignore if type(_UpperCAmelCase				) is str and s in name]:
                  continue
            __snake_case :   Optional[Any]													=    f'''Act:{input_q.extra_repr()}'''
            __snake_case :   int													=    f'''Wgt:{weight_q.extra_repr()}'''
            __snake_case :   Optional[Any]													=    f'''{name:{name_width}} {act_str} {wgt_str}'''
            if len(_UpperCAmelCase				) <= line_width:
                  logger.info(_UpperCAmelCase				)
            else:
                  logger.info(f'''{name:{name_width}} {act_str}'''				)
                  logger.info(f'''{"  ":{name_width}} {wgt_str}'''				)





def   a_   (		_UpperCAmelCase    :      int				)    ->  str:
      __snake_case :   List[Any]													=    0
      for name, mod in model.named_modules():
            if isinstance(_UpperCAmelCase ,pytorch_quantization.nn.TensorQuantizer				):
                  print(f'''{name:80} {mod}'''				)
                  count += 1
      print(f'''{count} TensorQuantizers found in model'''				)





def   a_   (		_UpperCAmelCase    :      List[str] ,_UpperCAmelCase    :      str ,_UpperCAmelCase    :      Optional[Any] ,_UpperCAmelCase    :      Optional[Any] ,_UpperCAmelCase    :      Tuple				)    ->  Tuple:
      __snake_case :   int													=    getattr(_UpperCAmelCase ,_UpperCAmelCase ,_UpperCAmelCase				)
      if quantizer_mod is not None:
            assert hasattr(_UpperCAmelCase ,_UpperCAmelCase				)
            setattr(_UpperCAmelCase ,_UpperCAmelCase ,_UpperCAmelCase				)
      else:
            logger.warning(f'''{name} has no {quantizer}'''				)





def   a_   (		_UpperCAmelCase    :      Optional[Any] ,_UpperCAmelCase    :      Optional[Any] ,_UpperCAmelCase    :      Tuple="both" ,**_UpperCAmelCase    :      Optional[int]				)    ->  str:
      __snake_case :   str													=    f'''Warning: changing {which} quantizers of {name:{qname_width}}'''
      for k, v in kwargs.items():
            s += f''' {k}={v}'''
            if which in ["input", "both"]:
                  set_quantizer(_UpperCAmelCase ,_UpperCAmelCase ,'_input_quantizer' ,_UpperCAmelCase ,_UpperCAmelCase				)
            if which in ["weight", "both"]:
                  set_quantizer(_UpperCAmelCase ,_UpperCAmelCase ,'_weight_quantizer' ,_UpperCAmelCase ,_UpperCAmelCase				)
      logger.info(_UpperCAmelCase				)





def   a_   (		_UpperCAmelCase    :      List[str] ,_UpperCAmelCase    :      Tuple ,**_UpperCAmelCase    :      Optional[int]				)    ->  Optional[int]:

      for name, mod in model.named_modules():
            if hasattr(_UpperCAmelCase ,'_input_quantizer'				) or hasattr(_UpperCAmelCase ,'_weight_quantizer'				):
                  for n in names:
                        if re.search(_UpperCAmelCase ,_UpperCAmelCase				):
                              set_quantizers(_UpperCAmelCase ,_UpperCAmelCase ,**_UpperCAmelCase				)
            elif name.endswith('_quantizer'				):
                  for n in names:
                        if re.search(_UpperCAmelCase ,_UpperCAmelCase				):
                              __snake_case :   Optional[int]													=    f'''Warning: changing {name:{name_width}}'''
                              for k, v in kwargs.items():
                                    s += f''' {k}={v}'''
                                    setattr(_UpperCAmelCase ,_UpperCAmelCase ,_UpperCAmelCase				)
                              logger.info(_UpperCAmelCase				)








'''simple docstring'''





from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available


A__    :   List[Any]           =					{
    '''configuration_luke''': ['''LUKE_PRETRAINED_CONFIG_ARCHIVE_MAP''', '''LukeConfig'''],
    '''tokenization_luke''': ['''LukeTokenizer'''],
}

try:
    if not is_torch_available():
        raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
    pass
else:
    A__    :   Union[str, Any]           =					[
        '''LUKE_PRETRAINED_MODEL_ARCHIVE_LIST''',
        '''LukeForEntityClassification''',
        '''LukeForEntityPairClassification''',
        '''LukeForEntitySpanClassification''',
        '''LukeForMultipleChoice''',
        '''LukeForQuestionAnswering''',
        '''LukeForSequenceClassification''',
        '''LukeForTokenClassification''',
        '''LukeForMaskedLM''',
        '''LukeModel''',
        '''LukePreTrainedModel''',
    ]


if TYPE_CHECKING:
    from .configuration_luke import LUKE_PRETRAINED_CONFIG_ARCHIVE_MAP, LukeConfig
    from .tokenization_luke import LukeTokenizer

    try:
        if not is_torch_available():
            raise OptionalDependencyNotAvailable()
    except OptionalDependencyNotAvailable:
        pass
    else:
        from .modeling_luke import (
            LUKE_PRETRAINED_MODEL_ARCHIVE_LIST,
            LukeForEntityClassification,
            LukeForEntityPairClassification,
            LukeForEntitySpanClassification,
            LukeForMaskedLM,
            LukeForMultipleChoice,
            LukeForQuestionAnswering,
            LukeForSequenceClassification,
            LukeForTokenClassification,
            LukeModel,
            LukePreTrainedModel,
        )

else:
    import sys

    A__    :   List[str]           =					_LazyModule(__name__, globals()['''__file__'''], _import_structure, module_spec=__spec__)



