Ë
    Hêñi.%  ã                  ó°   — 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y	)é    )Ú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                óB   •— t        ‰| �  |fi |¤Ž d | _        d| _        y )NF)ÚsuperÚ__init__Ú_normalized_device_strÚ_do_param_level_sinq)Úselfr   ÚkwargsÚ	__class__s      €úh/var/www/pod-logistic/pod-ai/venv/lib/python3.12/site-packages/transformers/quantizers/quantizer_sinq.pyr   zSinqHfQuantizer.__init__2   s&   ø€ Ü‰ÑÐ,Ñ7°Ò7à26ˆÔ#Ø*/ˆÕ!ó    c                 ó   — y©NT© ©r   s    r   Úis_serializablezSinqHfQuantizer.is_serializable8   s   € Ør   c                 ó   — yr   r   r   s    r   Úis_trainablezSinqHfQuantizer.is_trainable;   s   € àr   c                óÂ   — |€\t         j                  j                  «       r!dt         j                  j                  «       i}nddi}t        j                  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?   sb   € ØÐÜ�z‰z×&Ñ&Ô(Ø ¤%§*¡*×";Ñ";Ó"=Ð>‘
à  %˜[�
Ü�K‰Kð)Ø)3¨ð 5[ð[ôð
 Ðr   c                ó8   — |€t         j                  }|| _        |S ©N)r&   Úbfloat16Údtype)r   r1   s     r   Úupdate_dtypezSinqHfQuantizer.update_dtypeL   s   € Øˆ=Ü—N‘NˆEØˆŒ
Øˆr   c                ó¼  — ddl m}  |«       st        d«      ‚t        j                  j                  «       st        j                  d«       |j                  d«      }t        |t        «      r?t        |j                  «       «      }t        |«      dkD  rt        dt        |«      › d�«      ‚| j                   j"                  d	k(  r| j$                  st'        d
«      ‚y y )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. )Úutilsr4   ÚImportErrorr&   r'   r(   r*   ÚwarningÚgetÚ
isinstanceÚdictÚsetÚvaluesÚlenÚRuntimeErrorÚsortedr   ÚmethodÚpre_quantizedÚ
ValueError)r   Úargsr   r4   r,   Údevice_map_valuess         r   Úvalidate_environmentz$SinqHfQuantizer.validate_environmentR   sÕ   € Ý-á Ô"ÜÐmÓnÐnä�z‰z×&Ñ&Ô(Ü�N‰Nð Bôð —Z‘Z Ó-ˆ
ä�j¤$Ô'Ü # J×$5Ñ$5Ó$7Ó 8ÐÜÐ$Ó%¨Ò)Ü"ð#Ü#)Ð*;Ó#<Ð"=Ð=Zð\óð ð
 ×#Ñ#×*Ñ*¨gÒ5¸d×>PÒ>PÜð:óð ð ?QÐ5r   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_moderA   )Úsinq.sinqlinear_hfrH   rA   ÚintrI   rJ   ÚstrrO   )r   ÚcfgÚsinq_base_quant_config_fnrA   s       r   Ú_build_sinq_quant_dictz&SinqHfQuantizer._build_sinq_quant_dictn   s[   € õ 	[à—‘ˆÙ(Ü�c—i‘i“.Ø.1¯n©nÐ.H”s˜3Ÿ>™>Ô*ÈdØØØØÜ˜CŸO™OÓ,Øô	
ð 		
r   c                óä   — ddl m} | j                  ry| j                  j                  dk(  ry| j
                  syt        ||«      \  }}|dk7  ryt        ||«      }t        |dd«      }|xr | }	|	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   )Ú
SINQLinearFr5   ÚweightÚreadyT)	rP   rW   rB   r   rA   r   r   r:   Úgetattr)
r   ÚmodelÚ
param_namer   rW   ÚmoduleÚtensor_nameÚis_sinqÚis_readyÚresults
             r   Úparam_needs_quantizationz(SinqHfQuantizer.param_needs_quantization€   s�   € õ 	2à×ÒØà×#Ñ#×*Ñ*¨gÒ5Øð ×(Ò(Øä2°5¸*ÓEÑˆ�à˜(Ò"Øô ˜V ZÓ0ˆÜ˜6 7¨DÓ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.sinqrd   )r   rd   s     r   Úget_quantize_opsz SinqHfQuantizer.get_quantize_ops¢   s   € õ
 	5á˜DÓ!Ð!r   c                ób   — 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_loadingrh   rB   re   ri   )r   rh   ri   s      r   Úget_weight_conversionsz&SinqHfQuantizer.get_weight_conversions«   sE   € õ 	9à×ÒÝ;ñ  ò%ð
 &/ KÙ /°Ó 5Ð6ôð
ð 
ð ˆ	r   c                ób  — ddl m} | j                  || j                  j                  xs g |«      | _        | j                  j
                  dk(  xr | j                   | _        | j                  rdn| j                  | j                  «      }t        |t        «      rEt        t        |j                  «       «      d«      }t        |t        «      rd|› �}n.t        |«      }n"t         j"                  j%                  «       rdnd} ||| j                  || j&                  || j                  ¬	«      }y)
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ÚdevicerB   )re   rp   Úget_modules_to_not_convertr   rr   rA   rB   r   rU   r:   r;   ÚnextÚiterr=   rQ   rR   r&   r'   r(   r1   )	r   r[   r,   Úkeep_in_fp32_modulesr   rp   Úsinq_quant_dictÚfirst_deviceÚ
device_strs	            r   Ú$_process_model_before_weight_loadingz4SinqHfQuantizer._process_model_before_weight_loadingÈ   s  € õ 	Aà&*×&EÑ&EØ�D×,Ñ,×CÑCÒIÀrÐL`ó'
ˆÔ#ð
 %)×$<Ñ$<×$CÑ$CÀvÑ$MÒ$hÐVZ×VhÑVhÐRhˆÔ!à"&×"4Ò"4™$¸$×:UÑ:UÐVZ×VnÑVnÓ:oˆô �j¤$Ô'Ü¤ Z×%6Ñ%6Ó%8Ó 9¸1Ó=ˆLÜ˜,¬Ô,Ø$ \ NÐ3‘
ä  Ó.‘
ä%*§Z¡Z×%<Ñ%<Ô%>™À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   r[   r   r   s       r   Ú#_process_model_after_weight_loadingz3SinqHfQuantizer._process_model_after_weight_loadingó   s   € õ 	6ñ 	Ô àˆr   )r   r   )Úreturnr   )r1   útorch.dtyper‚   rƒ   )r‚   ÚNone)rS   r   r‚   r;   )r[   r   r\   rR   r‚   r   r/   )r[   r   ry   zlist[str] | None)r[   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__r   r    Úpropertyr"   r-   r2   rF   rU   rb   rf   rn   r}   r�   Ú__classcell__)r   s   @r   r   r   !   sˆ   ø… ñð .2Ð$ dÓ1Ø#Ó#õ0óð òó ðòóóó8
ó$ òD"òðB 26ð	)
àð)
ð /ó	)
ðVà÷r   r   )Ú
__future__r   Útypingr   r6   r   r   Úutils.quantization_configr   Úbaser
   Úquantizers_utilsr   r&   Úmodeling_utilsr   Ú
get_loggerr…   r*   r   r   r   r   ú<module>r“      sJ   ðõ #å  ç /Ý 2Ý Ý 2ñ ÔÛáÝ0à	ˆ×	Ñ	˜HÓ	%€ôe�kõ er   