§
    ‚Štj.%  ã                  óº   — d dl mZ d dlmZ ddlmZmZ ddlmZ ddl	m
Z
 ddlmZ  e¦   «         rd d	lZerdd
lmZ  ej        e¦  «        Z G d„ de
¦  «        Zd	S )é    )Úannotations)ÚTYPE_CHECKINGé   )Úis_torch_availableÚlogging)Ú
SinqConfigé   )ÚHfQuantizer)Úget_module_from_nameN)ÚPreTrainedModelc                  ó¤   ‡ — e Zd ZU dZdZded<   ded<   d ˆ fd„Zd!d	„Zed!d
„¦   «         Z	d„ Z
d"d„Zd#d„Zd$d„Zd%d„Zd„ Zd„ Z	 d&d'd„Zd(d„Zˆ xZS ))ÚSinqHfQuantizera¤  
    HF v5 quantizer for SINQ.

    Modes:
      - method="sinq" (default):
          * weight-only SINQ
          * param-level ConversionOps (`SinqQuantize`) during load for pure language models
            (each Linear.weight is turned into a SINQLinear module)
          * module-level quantization after load for multimodal models
      - method="asinq":
          * A-SINQ (activation-aware) SINQ quantization
    TÚboolÚ requires_parameters_quantizationr   Úquantization_configc                óX   •—  t          ¦   «         j        |fi |¤Ž d | _        d| _        d S )NF)ÚsuperÚ__init__Ú_normalized_device_strÚ_do_param_level_sinq)Úselfr   ÚkwargsÚ	__class__s      €úd/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/transformers/quantizers/quantizer_sinq.pyr   zSinqHfQuantizer.__init__2   s9   ø€ Ø�‰ŒÔÐ,Ð7Ð7°Ð7Ð7Ð7à26ˆÔ#Ø*/ˆÔ!Ð!Ð!ó    Úreturnc                ó   — dS ©NT© ©r   s    r   Úis_serializablezSinqHfQuantizer.is_serializable8   s   € Øˆtr   c                ó   — dS r   r   r    s    r   Úis_trainablezSinqHfQuantizer.is_trainable;   s   € àˆtr   c                óÌ   — |€at           j                             ¦   «         r!dt           j                             ¦   «         i}nddi}t                               d|› d�¦  «         |S )NÚ Úcpuz:The device_map was not initialized. Setting device_map to zJ. If you want to use the model for inference, please set device_map='auto')ÚtorchÚcudaÚis_availableÚcurrent_deviceÚloggerÚinfo)r   Ú
device_maps     r   Úupdate_device_mapz!SinqHfQuantizer.update_device_map?   sz   € ØÐÝŒz×&Ò&Ñ(Ô(ð )Ø ¥%¤*×";Ò";Ñ"=Ô"=Ð>�
�
à  %˜[�
Ý�KŠKð[Ø)3ð[ð [ð [ñô ð ð
 Ðr   Údtypeútorch.dtypec                ó0   — |€t           j        }|| _        |S ©N)r'   Úbfloat16r/   )r   r/   s     r   Úupdate_dtypezSinqHfQuantizer.update_dtypeL   s   € Øˆ=Ý”NˆEØˆŒ
Øˆr   ÚNonec                ó   — ddl m}  |¦   «         st          d¦  «        ‚t          j                             ¦   «         st                               d¦  «         |                     d¦  «        }t          |t          ¦  «        rTt          |                     ¦   «         ¦  «        }t          |¦  «        dk    r t          dt          |¦  «        › d�¦  «        ‚| j        j        d	k    r| j        st'          d
¦  «        ‚d S d S )Nr   )Úis_sinq_availablezMThe 'sinq' package is not installed. Please install it with: pip install sinqz¯No CUDA device is available. Quantization and inference will run on the CPU. Please note that this will significantly slow down inference speed and increase quantization time.r-   r	   zkSinqHfQuantizer: multi-GPU device_map detected, but SINQ currently supports only a single CUDA device. Got z. Please use device_map=None.ÚasinqzßYou are using `method='asinq'` in the quantization config. Right now the calibrated version of SINQ is not supported in Hugging Face, please refer and use the official SINQ repository `to quantize a model with this method. )Úutilsr7   ÚImportErrorr'   r(   r)   r+   ÚwarningÚgetÚ
isinstanceÚdictÚsetÚvaluesÚlenÚRuntimeErrorÚsortedr   ÚmethodÚpre_quantizedÚ
ValueError)r   Úargsr   r7   r-   Údevice_map_valuess         r   Úvalidate_environmentz$SinqHfQuantizer.validate_environmentR   s0  € Ø-Ð-Ð-Ð-Ð-Ð-à Ð Ñ"Ô"ð 	oÝÐmÑnÔnÐnåŒz×&Ò&Ñ(Ô(ð 	Ý�NŠNð Bñô ð ð —Z’Z Ñ-Ô-ˆ
å�j¥$Ñ'Ô'ð 	Ý # J×$5Ò$5Ñ$7Ô$7Ñ 8Ô 8ÐÝÐ$Ñ%Ô%¨Ò)Ð)Ý"ð\Ý#)Ð*;Ñ#<Ô#<ð\ð \ð \ñô ð ð
 Ô#Ô*¨gÒ5Ð5¸dÔ>PÐ5Ýð:ñô ð ð 6Ð5Ð5Ð5r   Úcfgr>   c                óÀ   — ddl m} |j        } |t          |j        ¦  «        |j        �t          |j        ¦  «        ndddddt          |j        ¦  «        |¬¦  «        S )zI
        Build the dict that SINQLinear expects as quant_config.
        r   )Úsinq_base_quant_configNFr	   )ÚnbitsÚ
group_sizeÚ
quant_zeroÚquant_scaleÚview_as_floatÚaxisÚtiling_moderD   )Úsinq.sinqlinear_hfrL   rD   ÚintrM   rN   ÚstrrS   )r   rJ   Úsinq_base_quant_config_fnrD   s       r   Ú_build_sinq_quant_dictz&SinqHfQuantizer._build_sinq_quant_dictn   sx   € ð 	[ÐZÐZÐZÐZÐZà”ˆØ(Ð(Ý�c”i‘.”.Ø.1¬nÐ.H•s˜3œ>Ñ*Ô*Ð*ÈdØØØØÝ˜CœOÑ,Ô,Øð	
ñ 	
ô 	
ð 		
r   Úmodelr   Ú
param_namerV   c                óÜ   — ddl m} | j        rdS | j        j        dk    rdS | j        sdS t          ||¦  «        \  }}|dk    rdS t          ||¦  «        }t          |dd¦  «        }|o| }	|	S )a-  
        Called per-parameter to decide whether to run `SinqQuantize` on it.

        - If `self.pre_quantized`, we do *not* quantize again (handled by SinqDeserialize instead).
        - For method="asinq": return False (ASINQ is not supported in Hugging Face).
        - For method="sinq": True only for SINQLinear.weight not in modules_to_not_convert.

        Note: After _process_model_before_weight_loading(), the modules are already SINQLinear,
        not nn.Linear. We check for SINQLinear modules that are not yet quantized (ready=False).
        r   )Ú
SINQLinearFr8   ÚweightÚreadyT)	rT   r\   rE   r   rD   r   r   r=   Úgetattr)
r   rY   rZ   r   r\   ÚmoduleÚtensor_nameÚis_sinqÚis_readyÚresults
             r   Úparam_needs_quantizationz(SinqHfQuantizer.param_needs_quantization€   s¥   € ð 	2Ð1Ð1Ð1Ð1Ð1àÔð 	Ø�5àÔ#Ô*¨gÒ5Ð5Ø�5ð Ô(ð 	Ø�5å2°5¸*ÑEÔEÑˆ�à˜(Ò"Ð"Ø�5õ ˜V ZÑ0Ô0ˆÝ˜6 7¨DÑ1Ô1ˆØÐ) ˜\ˆØˆr   c                ó$   — ddl m}  || ¦  «        S )z›
        Return the ConversionOps used for param-level quantization (Sinq).
        The actual SINQLinear construction is in integrations/sinq.py.
        r   )ÚSinqQuantize)Úintegrations.sinqrg   )r   rg   s     r   Úget_quantize_opsz SinqHfQuantizer.get_quantize_ops¢   s&   € ð
 	5Ð4Ð4Ð4Ð4Ð4àˆ|˜DÑ!Ô!Ð!r   c                ód   — ddl m} | j        r"ddlm}  |g d¢dg || ¦  «        g¬¦  «        gS g S )a4  
        If `pre_quantized=True`, interpret a checkpoint produced by SINQLinear.state_dict:

            <prefix>.W_q
            <prefix>.bias
            <prefix>.meta

        via a WeightConverter + SinqDeserialize so that we reconstruct a SINQLinear
        module instead of a plain nn.Linear.
        r   )ÚWeightConverter)ÚSinqDeserialize)z.W_qz.metaz.biasz.weight)Úsource_patternsÚtarget_patternsÚ
operations)Úcore_model_loadingrk   rE   rh   rl   )r   rk   rl   s      r   Úget_weight_conversionsz&SinqHfQuantizer.get_weight_conversions«   s€   € ð 	9Ð8Ð8Ð8Ð8Ð8àÔð 	Ø;Ð;Ð;Ð;Ð;Ð;ð  �ð%ð %ð %ð
 &/ KØ / °Ñ 5Ô 5Ð6ðñ ô ð
ð 
ð ˆ	r   NÚkeep_in_fp32_modulesúlist[str] | Nonec                óD  — ddl m} |                      || j        j        pg |¦  «        | _        | j        j        dk    o| j         | _        | j        rdn|                      | j        ¦  «        }t          |t          ¦  «        rZt          t          |                     ¦   «         ¦  «        d¦  «        }t          |t          ¦  «        rd|› �}n2t          |¦  «        }n"t           j                             ¦   «         rdnd} ||| j        || j        || j        ¬	¦  «        }dS )
a  
        Called on meta-initialized model, before loading any weights.

        For SINQ, we replace nn.Linear modules with empty SINQLinear modules here.
        The actual quantization happens later in SinqQuantize.convert() when weights are loaded.
        r   )Úreplace_with_sinq_linearÚsinqNr   zcuda:zcuda:0r&   )Úmodules_to_not_convertÚquant_configÚcompute_dtypeÚdevicerE   )rh   ru   Úget_modules_to_not_convertr   rw   rD   rE   r   rX   r=   r>   ÚnextÚiterr@   rU   rV   r'   r(   r)   r/   )	r   rY   r-   rr   r   ru   Úsinq_quant_dictÚfirst_deviceÚ
device_strs	            r   Ú$_process_model_before_weight_loadingz4SinqHfQuantizer._process_model_before_weight_loadingÈ   s?  € ð 	AÐ@Ð@Ð@Ð@Ð@à&*×&EÒ&EØ�DÔ,ÔCÐIÀrÐL`ñ'
ô '
ˆÔ#ð
 %)Ô$<Ô$CÀvÒ$MÐ$hÐVZÔVhÐRhˆÔ!à"&Ô"4Ðo˜$˜$¸$×:UÒ:UÐVZÔVnÑ:oÔ:oˆõ �j¥$Ñ'Ô'ð 	JÝ¥ Z×%6Ò%6Ñ%8Ô%8Ñ 9Ô 9¸1Ñ=Ô=ˆLÝ˜,­Ñ,Ô,ð /Ø3 \Ð3Ð3�
�
å  Ñ.Ô.�
�
å%*¤Z×%<Ò%<Ñ%>Ô%>ÐI˜˜ÀEˆJà(Ð(ØØ#'Ô#>Ø(Øœ*ØØÔ,ð
ñ 
ô 
ˆˆˆr   c                ó&   — ddl m}  |¦   «          |S )aq  
        Called after *all* weights have been loaded.

        For SINQ:
        1. Move non-SINQLinear modules to GPU (embeddings, norms, lm_head, etc.)
           - SINQLinear modules already have GemLite buffers on GPU
           - We skip moving SINQLinear's W_q/meta to avoid memory duplication
        2. Patch HF save/load methods for SINQ serialization
        r   )Úpatch_hf_pretrained_io)Ú
sinq.hf_iorƒ   )r   rY   r   rƒ   s       r   Ú#_process_model_after_weight_loadingz3SinqHfQuantizer._process_model_after_weight_loadingó   s,   € ð 	6Ð5Ð5Ð5Ð5Ð5ð 	ÐÑ Ô Ð àˆr   )r   r   )r   r   )r/   r0   r   r0   )r   r5   )rJ   r   r   r>   )rY   r   rZ   rV   r   r   r2   )rY   r   rr   rs   )rY   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__r   r!   Úpropertyr#   r.   r4   rI   rX   re   ri   rq   r�   r…   Ú__classcell__)r   s   @r   r   r   !   sO  ø€ € € € € € ðð ð .2Ð$Ð1Ð1Ð1Ñ1Ø#Ð#Ð#Ñ#ð0ð 0ð 0ð 0ð 0ð 0ðð ð ð ð ðð ð ñ „Xððð ð ðð ð ð ðð ð ð ð8
ð 
ð 
ð 
ð$ ð  ð  ð  ðD"ð "ð "ðð ð ðB 26ð	)
ð )
ð )
ð )
ð )
ðVð ð ð ð ð ð ð r   r   )Ú
__future__r   Útypingr   r9   r   r   Úutils.quantization_configr   Úbaser
   Úquantizers_utilsr   r'   Úmodeling_utilsr   Ú
get_loggerr†   r+   r   r   r   r   ú<module>r”      sÿ   ðð #Ð "Ð "Ð "Ð "Ð "à  Ð  Ð  Ð  Ð  Ð  à /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø Ð Ð Ð Ð Ð Ø 2Ð 2Ð 2Ð 2Ð 2Ð 2ð ÐÑÔð Ø€L€L€Làð 1Ø0Ð0Ð0Ð0Ð0Ð0à	ˆÔ	˜HÑ	%Ô	%€ðeð eð eð eð e�kñ eô eð eð eð er   