ó
    qyüi.%  ã                  óÄ   • S SK Jr  S SKJr  SSKJrJr  SSKJr  SSK	J
r
  SSKJr  \" 5       (       a  S S	Kr\(       a  SS
KJr  \R                   " \5      r " S S\
5      rg	)é    )Úannotations)ÚTYPE_CHECKINGé   )Úis_torch_availableÚlogging)Ú
SinqConfigé   )ÚHfQuantizer)Úget_module_from_nameN)ÚPreTrainedModelc                  óÆ   ^ • \ rS rSr% SrSrS\S'   S\S'   SU 4S jjrSS	 jr\	SS
 j5       r
S rSS jrSS jrSS jrSS jrS rS r S   SS jjr  SS jrSrU =r$ )ÚSinqHfQuantizeré!   a|  
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                óD   >• [         TU ]  " U40 UD6  S U l        SU l        g )NF)ÚsuperÚ__init__Ú_normalized_device_strÚ_do_param_level_sinq)Úselfr   ÚkwargsÚ	__class__s      €Úc/home/mande/repo/quber/.venv/lib/python3.13/site-packages/transformers/quantizers/quantizer_sinq.pyr   ÚSinqHfQuantizer.__init__2   s&   ø€ Ü‰ÒÐ,Ñ7°Ò7à26ˆÔ#Ø*/ˆÕ!ó    c                ó   • g©NT© ©r   s    r   Úis_serializableÚSinqHfQuantizer.is_serializable8   s   € Ør   c                ó   • gr   r    r!   s    r   Úis_trainableÚSinqHfQuantizer.is_trainable;   s   € àr   c                óÎ   • Uca  [         R                  R                  5       (       a!  S[         R                  R                  5       0nOSS0n[        R                  SU S35        U$ )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_mapÚ!SinqHfQuantizer.update_device_map?   se   € ØÑÜ�z‰z×&Ñ&×(Ñ(Ø ¤%§*¡*×";Ñ";Ó"=Ð>‘
à  %˜[�
Ü�K‰Kð)Ø)3¨ð 5[ð[ôð
 Ðr   c                ó8   • Uc  [         R                  nXl        U$ ©N)r*   Úbfloat16Údtype)r   r6   s     r   Úupdate_dtypeÚSinqHfQuantizer.update_dtypeL   s   € Ø‰=Ü—N‘NˆEØŒ
Øˆr   c                óè  • SSK Jn  U" 5       (       d  [        S5      e[        R                  R                  5       (       d  [        R                  S5        UR                  S5      n[        U[        5      (       a@  [        UR                  5       5      n[        U5      S:”  a  [        S[        U5       S35      eU R                   R"                  S	:X  a  U R$                  (       d  ['        S
5      eg g )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.r0   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. )Úutilsr:   ÚImportErrorr*   r+   r,   r.   ÚwarningÚgetÚ
isinstanceÚdictÚsetÚvaluesÚlenÚRuntimeErrorÚsortedr   ÚmethodÚpre_quantizedÚ
ValueError)r   Úargsr   r:   r0   Údevice_map_valuess         r   Úvalidate_environmentÚ$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                óÐ   • SSK Jn  UR                  nU" [        UR                  5      UR
                  b  [        UR
                  5      OSSSSS[        UR                  5      US9$ )z9
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_moderG   )Úsinq.sinqlinear_hfrO   rG   ÚintrP   rQ   ÚstrrV   )r   ÚcfgÚsinq_base_quant_config_fnrG   s       r   Ú_build_sinq_quant_dictÚ&SinqHfQuantizer._build_sinq_quant_dictn   s[   € õ 	[à—‘ˆÙ(Ü�c—i‘i“.Ø.1¯n©nÑ.H”s˜3Ÿ>™>Ô*ÈdØØØØÜ˜CŸO™OÓ,Øñ	
ð 		
r   c                ó  • SSK Jn  U R                  (       a  gU R                  R                  S:X  a  gU R
                  (       d  g[        X5      u  pVUS:w  a  g[        XT5      n[        USS5      nU=(       a    U(       + n	U	$ )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   )Ú
SINQLinearFr;   ÚweightÚreadyT)	rW   r_   rH   r   rG   r   r   r@   Úgetattr)
r   ÚmodelÚ
param_namer   r_   ÚmoduleÚtensor_nameÚis_sinqÚis_readyÚresults
             r   Úparam_needs_quantizationÚ(SinqHfQuantizer.param_needs_quantization€   s{   € õ 	2à××Øà×#Ñ#×*Ñ*¨gÓ5Øð ×(×(Øä2°5ÓEÑˆà˜(Ó"Øô ˜VÓ0ˆÜ˜6 7¨DÓ1ˆØ×) œ\ˆØˆr   c                ó   • SSK Jn  U" U 5      $ )zƒ
Return the ConversionOps used for param-level quantization (Sinq).
The actual SINQLinear construction is in integrations/sinq.py.
r   )ÚSinqQuantize)Úintegrations.sinqrm   )r   rm   s     r   Úget_quantize_opsÚ SinqHfQuantizer.get_quantize_ops¢   s   € õ
 	5á˜DÓ!Ð!r   c                óf   • SSK Jn  U R                  (       a  SSKJn  U" / SQS/U" U 5      /S9/$ / $ )zü
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_loadingrr   rH   rn   rs   )r   rr   rs   s      r   Úget_weight_conversionsÚ&SinqHfQuantizer.get_weight_conversions«   sE   € õ 	9à××Ý;ñ  ò%ð
 &/ KÙ /°Ó 5Ð6ñð
ð 
ð ˆ	r   c           	     óž  • SSK Jn  U R                  XR                  R                  =(       d    / U5      U l        U R                  R
                  S:H  =(       a    U R                  (       + U l        U R                  (       a  SOU R                  U R                  5      n[        U[        5      (       aJ  [        [        UR                  5       5      S5      n[        U[        5      (       a  SU 3nO3[        U5      nO'[         R"                  R%                  5       (       a  SOSnU" UU R                  UU R&                  UU R                  S	9ng)
zä
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ÚdevicerH   )rn   r{   Úget_modules_to_not_convertr   r}   rG   rH   r   r\   r@   rA   ÚnextÚiterrC   rX   rY   r*   r+   r,   r6   )	r   rc   r0   Úkeep_in_fp32_modulesr   r{   Úsinq_quant_dictÚfirst_deviceÚ
device_strs	            r   Ú$_process_model_before_weight_loadingÚ4SinqHfQuantizer._process_model_before_weight_loadingÈ   s  € õ 	Aà&*×&EÑ&EØ×,Ñ,×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                ó    • SSK Jn  U" 5         U$ )a9  
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   rc   r   r‹   s       r   Ú#_process_model_after_weight_loadingÚ3SinqHfQuantizer._process_model_after_weight_loadingó   s   € õ 	6ñ 	Ô àˆr   )r   r   r6   r}   )r   r   )Úreturnr   )r6   útorch.dtyper�   r�   )r�   ÚNone)rZ   r   r�   rA   )rc   r   rd   rY   r�   r   r4   )rc   r   r„   zlist[str] | None)rc   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   Ú__annotations__r   r"   Úpropertyr%   r1   r7   rL   r\   rj   ro   rx   rˆ   r�   Ú__static_attributes__Ú__classcell__)r   s   @r   r   r   !   s�   ø‡ ñð .2Ð$ dÓ1Ø#Ó#÷0ôð óó ðòôôô8
ô$ òD"òðB 26ð	)
àð)
ð /õ	)
ðVà÷ò r   r   )Ú
__future__r   Útypingr   r<   r   r   Úutils.quantization_configr   Úbaser
   Úquantizers_utilsr   r*   Úmodeling_utilsr   Ú
get_loggerr’   r.   r   r    r   r   Ú<module>r¢      sK   ðõ #å  ç /Ý 2Ý Ý 2ñ ×ÑÛæÝ0à	×	Ò	˜HÓ	%€ôe�kõ er   