
    ёiQI                         S SK r S SKrS SKrS SKrS SKrS SKJr  SSKJ	r	  SSK
JrJrJrJr  SSKJrJrJrJrJr  SSKJr  S	rS
r\	" \\R4                  SS9r " S S5      rg)    N)quant_layers   )
get_logger)_get_input_name_index_get_op_input_var_names_get_op_output_var_names_get_output_name_index   )
fuse_utils
ptq_config	ptq_hooksptq_quantizerutils)PTQRegistry.pdmodelz
.pdiparamsz&%(asctime)s-%(levelname)s: %(message)s)fmtc                      ^  \ rS rSrSr\R                  4U 4S jjrSS jrSS jr	S r
S rS rS	 rS
 rS rS r\S 5       r\S 5       rSrU =r$ )ImperativePTQ*   z$
Static post training quantization.
c                 p   > [         TU ]  5         [        U[        R                  5      (       d   eXl        g)a  
Constructor.

Args:
    quant_config(PTQConfig): the config of post training quantization.
        The config has weight_quantizer and activation_quantizer.
        In default, the weight_quantizer is PerChannelAbsmaxQuantizer
        and the activation_quantizer is KLQuantizer.
N)super__init__
isinstancer   	PTQConfig_quant_config)selfquant_config	__class__s     b/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/quantization/imperative/ptq.pyr   ImperativePTQ.__init__/   s/     	,
(<(<====)    c                    [        U[        R                  R                  5      (       d   S5       eU(       d  [        R
                  " U5      nU(       a&  UR                  5         [        R                  " X5      nUR                  5        H  u  pV[        R                  " U5      (       d  M"  [        R                  " U5      (       d  M?  U R                  U5      (       a  MW  [        R
                  " U R                  5      n[        R                   " U5      (       a  SUl        Xvl        [$        R&                  nUR)                  U5      n	Xl        UR,                  R/                  U	R0                  SS9  M     U$ )aQ  
Add quant config and hook to the target layer.

Args:
    model(paddle.nn.Layer): The model to be quantized.
    inplace(bool): Whether apply quantization to the input model.
                   Default: False.
    fuse(bool): Whether to fuse layers.
                Default: False.
    fuse_list(list): The layers' names to be fused. For example,
        "fuse_list = [["conv1", "bn1"], ["conv2", "bn2"]]".
        A TypeError would be raised if "fuse" was set as
        True but "fuse_list" was None.
        Default: None.
Return
    quantized_model(paddle.nn.Layer): The quantized model.
2The model must be the instance of paddle.nn.Layer.TF)last)r   paddlennLayercopydeepcopyevalr   fuse_layersnamed_sublayersr   is_supported_layerr   is_leaf_layer_is_skip_layerr   is_simulated_quant_layerenable_in_act_quantizerr   quant_forward_post_hookregister_forward_post_hookquant_hook_handle_forward_post_hooksmove_to_end_hook_id)
r   modelinplacefuse	fuse_listnamelayerr   hookr4   s
             r   quantizeImperativePTQ.quantize?   s$   $ %11 	
@	
1 MM%(EJJL**5<E 002KD..u55''..++E22  $}}T-?-?@77>>;?L8&2# !88$)$D$DT$J!1B.))55%..U 6 ! 3( r!   c                    [        U[        R                  R                  5      (       d   S5       eU R	                  U5        [        R
                  R                  " SXUS.UD6  Sn[        R                  " 5       (       a  Sn[        R                  " 5         [        R                  " 5       n[        R                  R                  5       n[        R                  R                  U5      n[        R                  R                  U5      n	[        R                  R!                  U5      n
U
["        -   nU
[$        -   n[        R                  R'                  U	UUUS9u  nnnU R)                  U5        U R+                  X5        U R-                  U5        SnUc  SnO.UR/                  S5      (       a  UR1                  S	S
5      S   nOUn[        R                  R3                  U	U5      nU Vs/ s H"  nUR5                  5       R7                  U5      PM$     nn[        R                  R9                  UUUUUR;                  5       S9  U(       a  [        R<                  " 5         ggs  snf )a  
1. Convert the quantized model
2. Call jit.save to save the inference model
3. Post process the inference model.

Args:
    model (Layer): The model to be saved.
    path (str): The path prefix to save model. The format is
        ``dirname/file_prefix`` or ``file_prefix``.
    input_spec (list[InputSpec|Tensor], optional): Describes the input
        of the saved model's forward method, which can be described by
        InputSpec or example Tensor. If None, all input variables of
        the original Layer's forward method would be the inputs of
        the saved model. Default None.
    **config (dict, optional): Other save configuration options for
        compatibility. We do not recommend using these configurations,
        they may be removed in the future. If not necessary, DO NOT use
        them. Default None.
        The following options are currently supported:
        (1) output_spec (list[Tensor]): Selects the output targets of
        the saved model. By default, all return variables of original
        Layer's forward method are kept as the output of the saved model.
        If the provided ``output_spec`` list is not all output variables,
        the saved model will be pruned according to the given
        ``output_spec`` list.

Returns:
    None
r#   )r=   path
input_specFT)path_prefixexecutormodel_filenameparams_filenameNr8   r   .r
   r   )rE   program )r   r%   r&   r'   _convertjitsavein_dynamic_modeenable_staticCPUPlacestaticglobal_scopeExecutorosrB   dirnamebasenameINFER_MODEL_SUFFIXINFER_PARAMS_SUFFIXload_inference_model	_clean_up_gather_input_thresholds_remove_scale_opendswithrsplitjoinglobal_blockvarsave_inference_modelclonedisable_static)r   r8   rB   rC   configis_dynamic_modeplacescopeexerU   rV   rF   rG   infer_programfeed_target_namesfetch_targets
model_namerD   r<   	feed_varss                       r   save_quantized_model"ImperativePTQ.save_quantized_modelo   s   > %11 	
@	
1
 	e

Pe:PP  !!##"O  "!**,mm$$U+''//$'77##D)!$66"%88 MM..)+	 / 
		
 	}%%%m;m, 
! J$$Z00'..sA6q9J'Jggll7J7?P
?PtM&&(,,T2?P 	 
 	**!'') 	+ 	
 !!# 
s   +)I#c                    UR                  5        HA  u  p#U R                  U5      (       d  M  UR                  R                  R	                  5         MC     U R                  U5        UR                  5        H8  u  p#U R                  U5      (       d  M  U R                  X3R                  5        M:     U R                  U5        g)z
Convert the quantized model.

Args:
    model(paddle.nn.Layer): The quantized model.
    inplace(bool): Whether apply conversion to the input model.
                   Default: False.
Returns:
    None
N)r,   _is_quant_layerr   r4   remove_cal_thresholds_save_output_thresholds_wrap_simulated_layers)r   r8   r<   	sub_layers       r   rK   ImperativePTQ._convert   s      %446OD##I..''99@@B  7 	U#$446OD##I..,,Y8O8OP  7 	##E*r!   c                    [        U[        R                  R                  5      (       d   S5       eSnSnUR	                  5        H"  u  pEU R                  U5      (       d  M  US-  nM$     UR	                  5        H  u  pEU R                  U5      (       d  M  US-  nUS-  S:X  a  [        R                  SU SU S35        UR                  nUR                  (       a  UR                  R                  5         UR                  R                  5         [        R                  " U5      (       d  M  UR                  4nUR                   R#                  XW5        UR                   R                  5         M     g)	z{
Calculate the thresholds of inputs and outputs.

Args:
    model(paddle.nn.Layer): The quantized model.
Returns:
    None
8The input model must be the instance of paddle.nn.Layer.r   r
      zProcess the z / z layerN)r   r%   r&   r'   r,   rr   _loggerinfor   r1   in_act_quantizercal_thresholdsout_act_quantizerr   r0   weightwt_quantizersample_data)r   r8   	total_numcur_numr<   rw   r   weightss           r   rt   ImperativePTQ._cal_thresholds   s9    %11 	
F	
1 	$446OD##I..Q	  7  %446OD##I..1Q;!#LL<yI;f!MN(6677 11@@B..==?77	BB(//1G --99)M --<<>  7r!   c                    [        U[        R                  R                  5      (       d   S5       e[        R
                  " U5      nUR                  nUR                  R                  n[        U5      S:X  d   e[        U5      S:X  a@  US   [        S5      -   S-   nUR                  XeS   05        UR                  SUS   05        g[        R                  SUS    S[        U5       35        g)	z
Save the output thresholds to the layer.

Args:
    sub_layer(paddle.nn.Layer): The quantized layer.
    quant_config(PTQConfig): the quant config for the layer.
Returns:
    None
rz   r
   r   
_thresholdout_thresholdzoutput_thresholds shape of z need to be 1, but received N)r   r%   r&   r'   r   
layer_infooutput_namesr   
thresholdslenstr_set_op_attrsr|   warning)r   rw   r   r   r   output_thresholds	save_names          r   ru   %ImperativePTQ._save_output_thresholds	  s     )VYY__55 	
F	
5 !++I6
!..(::EE< A%%% !Q&$Q#a&0<?I##Y!0D$EF##_6G6J$KLOO-l1o->>Z[^_p[qZrsr!   c                    [        U[        R                  R                  5      (       d   S5       eUR	                  5        GH  u  p#U R                  U5      (       d  M  [        R                  " U5      (       d  M;  UR                  nUR                  SL d   eUR                  nUR                  nSn[        R                  R                  5        H  u  p[        X95      (       d  M  SU-   n  O   Uc   e[        U[        R                   5      (       a  Sn
OSn
U
SUR"                  UR"                  S.n[$        R&                  U   " U40 UD6n[)        US	5      (       d   e[)        UR*                  S
5      (       d   e[-        UR.                  5      S:X  aV  [0        R2                  " UR.                  S   /[0        R4                  S9nUR*                  R6                  R9                  U5        [)        US5      (       d   e[)        UR:                  S
5      (       d   e[-        UR.                  5      S:X  d   eUR.                  S   n[        U[<        5      (       a$  [0        R2                  " U[0        R4                  S9nO$[0        R2                  " U/[0        R4                  S9nUR:                  R6                  R9                  U5        U R?                  X5        [        R@                  " X5      u  nn[C        UUU5        GM     g)z
Replace conv2d and linear with the quantized layers, and save
thresholds into the fake layers.
Args:
    model(paddle.nn.Layer): The model to be quantized.
Returns:
    None
rz   TN	Quantizedabs_maxchannel_wise_abs_maxmoving_average_abs_max)weight_quantize_typeactivation_quantize_typeweight_bitsactivation_bits_fake_quant_input_scaler
   r   )dtype_fake_quant_weight)"r   r%   r&   r'   r,   rr   r   r0   r   r1   r   r~   r   layer_name_mapitemsr   AbsmaxQuantizer
quant_bitsr   __dict__hasattrr   r   r   nparrayfloat32r   	set_valuer   listru   find_parent_layer_and_sub_namesetattr)r   r8   r<   rw   r   r   r~   quant_layer_namekeyvaluer   kwargsquant_layerinput_thresholdweight_thresholdparent_layersub_names                    r   rv   $ImperativePTQ._wrap_simulated_layers%  s    %11 	
F	
1  %446OD## 66yAA(66#;;tCCC+88#/#@#@  $( "'"6"6"<"<">JC!)33+6+<( #? (333lM,I,IJJ+4(+A(,@0H#/#:#:'7'B'B	 +334DE!'
 {,?@@@@{<<hGGGG'223q8&(hh)44Q78

'O  1188BB' {,@AAAA{==xHHHH<223q888#/#:#:1#= .55')xx(

($ (*xx)*"**($ ..55??$
 ,,[G */)M)M*&h h<E  7r!   c                 <   [         R                  " U5       GH  n[        U5       GHm  n[         R                  " UR                  U5      nUc  M*  SUR
                  ;   d  UR
                  S:X  a  UR                  S5      S   n[         R                  " X&5      n[         R                  " U5      n[        X45      u  pUR                  U[        U	5      -   S-   U5        UR                  SS5        M  [        U5       H  n
X:w  a  M
  [        XZ5      u  pU[        U	5      -   S-   nUR                  U5      (       d  M@  UR                  U5      n[        X45      u  pU[        U	5      -   S-   nUR                  Xk5        UR                  SS5        M     GMp     GM     g)	z
Get and save input thresholds from the front ops.

Args:
    program(Program): the input infer program.
    scope(Scope): the corresponding scope for the program.
Returns:
    None
Nquantize_dequantizemoving_average_abs_max_scaleOutScaler   r   with_quant_attrT)r   program_all_opsr   find_previous_opblocktypeoutputload_variable_datafp_numpy_to_naiver   	_set_attrr   r   r	   has_attrattr)r   rI   rh   opin_var_nameprevious_op	attr_namein_thresholdargnameindexout_var_name	thresholds               r   r[   &ImperativePTQ._gather_input_thresholdsv  sr    ''0B6r:#44RXX{K& *[-=-=="''+II + 2 2: >q AI#(#;#;E#ML#(#:#:<#HL%:2%KNGLL#e*,|;\ LL!2D9(@(M'6$)?'* %,c%j$8<$G	*33I>>$$/$4$4Y$?	)>r)O$+c%j$8<$G	Y:%6= )N%  ; 1r!   c                    S n[         R                  " U5       GH'  nSUR                  ;   a.  UR                   H  nSU;   d  M  UR	                  U5        M     MB  UR                  S;   d  MT  UR                  S:X  a  SOSnUR                  U5      S   n[         R                  " UR                  U5      n[        U5      S	:  d  US   R                  S
:w  a  M  US   n[        X65      u  pU	[        U
5      -   S-   n[        XR                  S5      S   5      u  pU	[        U
5      -   S-   nU" X8X5        U" X8SS5        GM*     g)z
Remove useless thresholds which are added in jit.save.

Args:
    program(Program): the input infer program.
Returns:
    None
c                 V   U R                  U5      (       a  UR                  U5      (       a|  U R                  U5      UR                  U5      :X  aW  U R                  U5      nU R                  U5        UR                  U5        UR                  X45        UR                  SS5        g g g g )Nr   T)r   r   _remove_attrr   )r   next_opold_attr_namenew_attr_namer   s        r   _helper(ImperativePTQ._clean_up.<locals>._helper  s    M**$$]33GGM*gll=.IIGGM2	.$$]3!!-;!!"3T: J 4 +r!   r   r   )conv2dmatmulr   OutputOutr   r
   elementwise_addr   N)r   r   r   
attr_namesr   r   find_next_opsr   r   r	   r   )r   rI   r   r   r   arg_namer   next_opsr   r   r   r   r   s                r   rZ   ImperativePTQ._clean_up  s'   
	; ''0B$/!#I#y0	2 "/ 00')ww(':8!yy215 ..rxxFx=1$(8(8<M(M"1+!7!I '#e* 4| C!7^^E215" !(#e* 4| C]B_oF1 1r!   c                 (   [         R                  " U5       Hx  nUR                  S:X  d  M  UR                  S5      S   nUR	                  S5      S   n[         R
                  " UR                  U5      nU H  nUR                  XC5        M     Mz     g)z-
Remove the moving_average_abs_max_scale op.
r   Xr   r   N)r   r   r   inputr   r   r   _rename_input)r   rI   r   r   r   r   r   s          r   r\   ImperativePTQ._remove_scale_op  sy     ''0Bww88 hhsmA.!yy/2 ..rxxF'G)),D  ( 1r!   c                 D    [        U S5      =(       a    U R                  SL $ )N
skip_quantT)r   r   r=   s    r   r/   ImperativePTQ._is_skip_layer  s    ul+H0@0@D0HHr!   c                     [        U S5      $ )Nr   )r   r   s    r   rr   ImperativePTQ._is_quant_layer  s    uo..r!   )r   )FFN)N)__name__
__module____qualname____firstlineno____doc__r   default_ptq_configr   r?   ro   rK   rt   ru   rv   r[   rZ   r\   staticmethodr/   rr   __static_attributes____classcell__)r   s   @r   r   r   *   sy     %/$A$A * .`\$|+0"?H8O=b+>Z.G`
E I I / /r!   r   )r(   loggingrT   numpyr   r%   paddle.nn.quantr   static.log_helperr   static.quantization.utilsr   r   r   r	    r   r   r   r   r   ptq_registryr   rW   rX   r   INFOr|   r   rJ   r!   r   <module>r      s`      	   ( +  F E % " 
gll H
{/ {/r!   