o
    pi0                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlmZ ddlmZ ddl	m
Z
mZmZmZmZmZmZmZ eee jddZd	Zd
Zdd Zdd ZG dd dZG dd dZ				dddZdS )    N)static   )
get_logger   )_channelwise_quant_axis1_opsbias_correction_wcalculate_quant_cos_errordequant_tensorload_variable_dataquant_tensorset_variable_datastable_sigmoidz&%(asctime)s-%(levelname)s: %(message)s)fmtgg?c                 C   s&   t jt jj| tt  t dddS )Nr   r   )minmax)paddleclipnn
functionalZsigmoidZETAGAMMAalpha_v r   j/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/paddle/static/quantization/adaround.pycompute_soft_rounding,   s
   r   c                 C   s    t jt| tt  t dddS )Nr   r   )Za_minZa_max)npr   r   r   r   r   r   r   r   compute_soft_rounding_np4   s   r   c                   @   s.   e Zd ZdddZdd Zdd Zd	d
 ZdS )AdaRoundLoss{Gz?   r   c                 C   s   || _ || _d S N)default_reg_paramdefault_beta_range)selfZ	reg_paramr$   r   r   r   __init__;   s   
zAdaRoundLoss.__init__c                 C   s(   t jj||}t t j|dd}|S )N)Zaxis)r   r   r   Zsquare_error_costmeansum)r%   Zada_quantized_outputZorig_outputZsquare_cost
recon_lossr   r   r   compute_recon_loss?   s
   zAdaRoundLoss.compute_recon_lossc                    s(    fdd}t j|dd |}|S )Nc                     s<   t  } tttd|  d  d }j| }|S )Nr   r   )r   r   r)   powabsr#   )Zh_vZreg_term
round_lossr   betar%   r   r   round_loss_fnG   s   
z6AdaRoundLoss.compute_round_loss.<locals>.round_loss_fnc                   S   s   t jdgdddS )Nr   float32        )shapedtypeZ
fill_value)r   fullr   r   r   r   <lambda>X       z1AdaRoundLoss.compute_round_loss.<locals>.<lambda>)r   r   Zcond)r%   r   
warm_startr0   r1   r.   r   r/   r   compute_round_lossF   s   zAdaRoundLoss.compute_round_lossc           	      C   sJ   | j \}}|| }|| ||  }|d||  dt|tj    }|S )Ng      ?r   )r$   r   cospi)	r%   Zmax_iterZcur_iterr9   Z
start_betaZend_betaZwarm_start_end_iterZrel_iterr0   r   r   r   compute_beta^   s   
zAdaRoundLoss.compute_betaN)r   r    )__name__
__module____qualname__r&   r+   r:   r=   r   r   r   r   r   :   s
    
r   c                   @   sX   e Zd Z					dddZdd Zdd	 Zd
d Zdd Zdd Zdd Z	dd Z
dS )AdaRoundNT  c                 C   sr   || _ || _d| _d| _d| _t | _|| _|| _|| _	d| _
|tv r&d| _
|| _|d | _| | || d S )Ng?   r3   r   r   .alpha)is_trainnum_iterationsr9   weight_bitsoffsetr   adaround_lossori_weight_tensorscalescope
quant_axisr   weight_var_name
alpha_nameinitialize_alphacopy)r%   rK   weight_tensorrL   rN   weight_op_typerE   rF   r   r   r   r&   q   s   

zAdaRound.__init__c                 C   sf   t ||| jd}t|}|| }ttt |t  d  }tj|j	d|d tj
j|d| _dS )zN
        Initializes alpha parameter, same shape as the weight tensor
        rM   r   r2   rD   )r4   r5   nameZdefault_initializerN)r   rM   r   floorlogr   r   r   Zcreate_parameterr4   r   ZinitializerAssignr   )r%   ZtensorrK   var_nametensor_scaleZtensor_flooralphar   r   r   rP      s   
zAdaRound.initialize_alphac                 C   s.   t | j|| j| |j|||gd| jd}|S )NTprogramfeed
fetch_listreturn_numpyrL   )r   rL   rN   run)r%   r]   placeexedatafp32_fetch_listweight_tensor_dequantadaround_out_tensorr   r   r   )_calculate_output_with_adarounded_weights   s   z2AdaRound._calculate_output_with_adarounded_weightsc                 C   sH   t | j| j}t|}t| j | j| jd}t	
|}t	||}|S NrT   )r
   rL   rO   r   r   rJ   rQ   rK   rM   r   rV   add)r%   Znp_alphaZh_alpharZ   rR   weight_tensor_quantr   r   r   _calculate_quant_weight   s   
z AdaRound._calculate_quant_weightc                 C   s$   |   }t|| j | j| jd}|S ri   )rl   r	   rH   rK   rM   )r%   rk   rf   r   r   r   _calculate_adarounded_weights   s   z&AdaRound._calculate_adarounded_weightsc                 C   s   |   }|S r"   )rl   )r%   rk   r   r   r   update_final_weights   s   zAdaRound.update_final_weightsc           	      C   s8   | j | j||}| j ||}|| }|||d}|S )N)lossr.   r*   )rI   r:   r   r+   )	r%   r0   r9   rg   orig_out_tensorr.   r*   ro   Zlossesr   r   r   get_loss   s   zAdaRound.get_lossc                 C   s,   || j | j k }| j| j || j}||fS r"   )rF   r9   rI   r=   )r%   Zcur_iterationr9   r0   r   r   r   update_beta_warm   s
   
zAdaRound.update_beta_warm)NNNTrB   )r>   r?   r@   r&   rP   rh   rl   rm   rn   rq   rr   r   r   r   r   rA   p   s    
rA   rB   MbP?FTc           ,      C   s:  |d j }i }| D ]}\}}td|  || }t||}|| }d }| jD ]}|jdkrB||| | 	|}|}q,t
 }t
 }t
||n tjj X t||||||	d}t
jddg|jR dd}t
jd	dg|jR dd}t
jd
ddgdd}t
jdddgdd}|||||}tjj|
d}|d }|| W d    n1 sw   Y  W d    n1 sw   Y  || t } | }!t|  D ]\}"}#| }!t } |j||#|gd|d}$| }%|||||#||%}&t|$d |&d }'|r|'dkrtd  n^||"\}(})|$d |&d |(|)d}*|j||*dd | D dd}+td|"dd|
ddt !|+d ddt !|+d ddt !|+d dd | |! dd! t"j#$  |"|	kro nq|% ||< |rt&||| ||j'|j(d"||< ~q|) D ]}t*|||||  qd S )#Nr   zStart adaround op: fetch)rL   rN   rS   rF   rp   r'   r2   )rU   r4   r5   rg   r0   r   r9   bool)Zlearning_ratero   Tr\   gGz?z)The cosine error is small, skip training.)rp   rg   r0   r9   c                 S   s   g | ]}|j qS r   )rU   ).0vr   r   r   
<listcomp>Z  r8   z run_adaround.<locals>.<listcomp>)r^   r_   r`   zIter dz, lr z.5fz, loss z, loss_round z, loss_recon r   z, time s)rG   )+rU   items_loggerinfor
   Zglobal_blockopstypeZ_rename_inputvarr   ZProgramZprogram_guardr   utilsZunique_nameguardrA   rd   r4   rq   	optimizerZAdamZminimizera   time	enumeraterm   rh   r   rr   valuesr   r(   sysstdoutflushrn   r   rM   rG   keysr   ),Zdata_loaderZfp32_programr_   rc   rL   rb   Zquantized_op_pairsZweight_op_pairsZ
scale_dictrF   lrZbias_correctionZ	fast_modeZfetch_op_nameZfinal_weight_tensor_quant_dictrN   Zquant_op_out_namerS   Zweight_var_tensorrK   re   Z_opZstartup_programZtrain_programZadaroundrp   rg   Zbeta_tensorZwarm_start_tensorZtrain_fetches_lossr   ro   
start_timeZprev_start_timeird   Znp_orig_out_tensorZadaround_weight_tensor_dequantZnp_adaround_out_tensorZ	cos_errorr0   r9   Z	feed_dictoutr   r   r   run_adaround   s   






 
'	
V


r   )rB   rs   FT)loggingr   r   numpyr   r   r   Z
log_helperr   r   r   r   r   r	   r
   r   r   r   r>   INFOr|   r   r   r   r   r   rA   r   r   r   r   r   <module>   s,   (6{