ó
    <Ð˜j¬,  ã                  ó    • S r SSKJr  SSKJrJr  SSKrSSKJs  J	r
  SSKJrJrJr  SSKJrJrJr  SSKJr  SSKJr  S	 rS
 r " S S\5      rg)zŸ
Disentanglement via Latent Quantization
 - https://arxiv.org/abs/2305.18378
Code adapted from Jax version in https://github.com/kylehkhsu/latent_quantization
é    )Úannotations)ÚCallableÚListN)ÚpackÚ	rearrangeÚunpack)ÚTensorÚint32Únn)ÚModule)Ú	Optimizerc                ó   • [        U /U5      $ ©N)r   )ÚtÚpatterns     Ú¹C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\vector_quantize_pytorch/latent_quantization.pyÚpack_oner      s   € Ü���WÓÐó    c                ó    • [        XU5      S   $ )Nr   )r   )r   Úpsr   s      r   Ú
unpack_oner      s   € Ü�!˜Ó! !Ñ$Ð$r   c                  óÆ   ^ • \ rS rSr       S                 SU 4S jjjrSSS jjrSSS jjrSS jrSS jrSS jr	SS jr
SSS	 jjrSS
 jrSS jrSrU =r$ )ÚLatentQuantizeé   c
           	     óþ  >• [         TU ]  5         X l        X�l        [        R
                  " U[        S9n
[        U[        5      (       a   U
R                  U5      n
U R                  S[        R
                  " U[        R                  S9SS9  U R                  S[        R
                  " U[        R                  S9SS9  U R                  SU
SS9  [        R                  " [        R                  " [        R
                  " S/[        S9U
SS	 /S
S9S
S9nU R                  SUSS9  US
:”  a  UO
[        U
5      U l        U R                   U-  nXPl        XÐl        U(       a  UOUS:„  nUS:”  a	  U(       d   eXpl        U R                  U:g  nU(       a!  [(        R*                  " U R                  U5      O[(        R,                  " 5       U l        U(       a   [(        R*                  " XÐR                  5      O[(        R,                  " 5       U l        Xàl        U R4                  R7                  5       R9                  5       U l        [=        [        R>                  " U R:                  5      S5      nXðR@                  -  U R4                  -  nU RC                  U5      nU R                  SUSS9  U
 Vs/ s H@  nUS-  S:X  a  [        RD                  " SSU5      O[        R>                  " U5      U-  S-
  PMB     nnU(       a\  [(        RF                  " U Vs/ s H  n[(        RH                  " U5      PM     sn5      U l%        U	b  U	" U RJ                  5      U l        ggUU l%        g! [         a  nUeSnAff = fs  snf s  snf )aB  
Initializes the LatentQuantization module.

Args:
    levels (List[int]|init): The number of levels per codebook.
        If an int is provided, it is used for all codebooks.
    dim (int): The dimensionality of the input tensor.
        The input tensor is expected to be of shape [B D ...]
    num_codebooks (int): The number of codebooks to use.
        (default is 1)
    codebook_dim (int): the dimension of the codebook.
        If levels is a list, codebook_dim is the length of the list.
        (default to -1)
    keep_num_codebooks_dim (Optional[bool]): Whether to keep the number of codebooks dimension in the output tensor. If not provided, it is set to True if num_codebooks > 1, otherwise False.
    optimize_values (Optional[bool]): Whether to optimize the values of the codebook. If not provided, it is set to True.
)ÚdtypeNÚcommitment_loss_weightF)Ú
persistentÚquantization_loss_weightÚ_levelsé   éÿÿÿÿr   ©ÚdimÚ_basisú... -> ... 1Úimplicit_codebooké   g      à¿g      à?)&ÚsuperÚ__init__r$   Úin_place_codebook_optimizerÚtorchÚtensorr
   Ú
isinstanceÚintÚrepeatÚRuntimeErrorÚregister_bufferÚfloat32ÚcumprodÚconcatÚlenÚcodebook_dimÚnum_codebooksÚeffective_codebook_dimÚkeep_num_codebooks_dimr   ÚLinearÚIdentityÚ
project_inÚproject_outÚhas_projectionsr    ÚprodÚitemÚcodebook_sizer   Úaranger%   Ú_scale_and_shift_inverseÚlinspaceÚParameterListÚ	ParameterÚvalues_per_latent)ÚselfÚlevelsr$   r   r   r8   r7   r:   Úoptimize_valuesr+   r    Úer%   r9   r?   Úall_indicesÚcodes_non_centeredr'   ÚlevelrH   ÚvaluesÚ	__class__s                        €r   r*   ÚLatentQuantize.__init__   s3  ø€ ô< 	‰ÑÔàŒØ+FÔ(Ü—,’,˜v¬UÑ3ˆô �fœc×"Ñ"ðØ!Ÿ.™.¨Ó6�ð 	×ÑØ$Ü�LŠLÐ/´u·}±}ÑEØð 	ñ 	
ð
 	×ÑØ&Ü�LŠLÐ1¼¿¹ÑGØð 	ñ 	
ð
 	×Ñ˜Y¨¸EÐÑBä—’Ü�LŠLœ%Ÿ,š,¨ s´%Ñ8¸'À#À2¸,ÐGÈQÑOÐUVñ
ˆð 	×Ñ˜X v¸%ÐÑ@à,8¸1Ó,<™LÄ#ÀgÃ,ˆÔà!%×!2Ñ!2°]Ñ!BÐØ*ÔØ&<Ô#ö '=Ñ"À-ÐRSÑBSð 	ð " AÓ%Ö.DÐEÐEØ&<Ô#àŸ(™(Ð&<Ñ<ˆö ô �IŠI�d—h‘hÐ 6Ô7ä—’“ð 	Œö ô �IŠIÐ,¯h©hÔ7ä—’“ð 	Ôð
  /Ôà!Ÿ\™\×.Ñ.Ó0×5Ñ5Ó7ˆÔô  ¤§¢¨T×-?Ñ-?Ó @À.ÓQˆØ)¯[©[Ñ8¸D¿L¹LÑHÐØ ×9Ñ9Ð:LÓMÐØ×ÑÐ0Ð2CÐPUÐÑVñ !ó	
ò !�ð �q‰y˜A‹~ô �NŠN˜4  eÔ,ä—’˜eÓ$ uÑ,¨sÑ2ò3ñ !ð	 	ð 
ö Ü%'×%5Ò%5Ù4EÓFÒ4E¨&”—’˜fÖ%Ñ4EÑFó&ˆDÔ"ð +Ñ6Ù3NØ×*Ñ*ó4�Õ0ð 7ð
 &7ˆDÕ"øôK  ó Ø�ûðüòh
ùò Gs%   ÁM! Ê-AM5Ì M:Í!
M2Í+M-Í-M2c                óH   • [         R                  " UR                  5       XS9$ )zComputes the quantization loss.©Ú	reduction©ÚFÚmse_lossÚdetach©rI   ÚzÚzhatÚreduces       r   Úquantization_lossÚ LatentQuantize.quantization_lossŒ   s   € ä�zŠz˜$Ÿ+™+›-¨Ñ=Ð=r   c                óH   • [         R                  " UR                  5       X#S9$ )zComputes the commitment loss.rT   rV   rZ   s       r   Úcommitment_lossÚLatentQuantize.commitment_loss�   s   € ä�zŠz˜!Ÿ(™(›* dÑ=Ð=r   c                ó²  • S n[         R                  " [        U R                  5       Vs/ s H2  n[         R                  " U" USUS4   U R
                  U   5      SS9PM4     snSS9n[         R                  " [        U R                  5       Vs/ s H  nU R
                  U   USU4      PM     snSS9nXU-
  R                  5       -   nU$ s  snf s  snf )zßQuantizes z, returns quantized zhat, same shape as z.
The quantization is done by measuring the distance between the input and the codebook values per latent dimension
and returning the index of the closest codebook value.
c                ó2   • [         R                  " X-
  5      $ r   )r,   Úabs)ÚxÚys     r   ÚdistanceÚ)LatentQuantize.quantize.<locals>.distanceš   s   € Ü—9’9˜Q™UÓ#Ð#r   .Nr"   r#   )r,   ÚstackÚranger7   ÚargminrH   rY   )rI   r[   rh   ÚiÚindexÚquantizes         r   ro   ÚLatentQuantize.quantize”   sí   € ò	$ô —’ô
 ˜t×0Ñ0Ô1ó	ò 2�Aô —’Ù˜Q˜s A t˜|™_¨d×.DÑ.DÀQÑ.GÓHÈbôñ 2ñ	ð ñ
ˆô —;’;ô ˜t×0Ñ0Ô1óâ1�Að ×&Ñ& qÑ)¨%°°Q°©-Ô8Ù1ñð ñ
ˆð  1™×,Ñ,Ó.Ñ.ˆàˆùò%ùòs   «9CÂ!Cc                ó6   • U R                   S-  nUS-  U-  U-   $ )z;scale and shift zhat from [-0.5, 0.5] to [0, level_per_dim]r(   ©r    )rI   Úzhat_normalizedÚ
half_widths      r   Ú_scale_and_shiftÚLatentQuantize._scale_and_shift²   s%   € à—\‘\ QÑ&ˆ
Ø !Ñ# jÑ0°JÑ>Ð>r   c                ó4   • U R                   S-  nX-
  U-  S-  $ )znormalize zhat to [-0.5, 0.5]r(   rr   )rI   r\   rt   s      r   rD   Ú'LatentQuantize._scale_and_shift_inverse·   s#   € à—\‘\ QÑ&ˆ
ØÑ! ZÑ/°!Ñ3Ð3r   c                ó¾   • UR                   S   U R                  :X  d   eU R                  U5      nXR                  -  R	                  SS9R                  [        5      $ )zSConverts a `code` which contains the number per latent to an index in the codebook.r"   r#   )Úshaper7   ru   r%   ÚsumÚtor
   )rI   r\   s     r   Úcodes_to_indicesÚLatentQuantize.codes_to_indices¼   sT   € à�z‰z˜"‰~ ×!2Ñ!2Ó2Ð2Ð2Ø×$Ñ$ TÓ*ˆØ—{‘{Ñ"×'Ñ'¨BÐ'Ð/×2Ñ2´5Ó9Ð9r   c                óø   • [        US5      nXR                  -  U R                  -  nU R                  U5      nU R                  (       a  [        US5      nU(       a  U R                  U5      n[        US5      nU$ )zInverse of `codes_to_indices`.r&   z... c d -> ... (c d)úb ... d -> b d ...)r   r%   r    rD   r:   r>   )rI   Úindicesr>   rN   Úcodess        r   Úindices_to_codesÚLatentQuantize.indices_to_codesÂ   sr   € ô ˜G ^Ó4ˆØ%¯©Ñ4¸¿¹ÑDÐØ×-Ñ-Ð.@ÓAˆà×&×&Ü˜eÐ%;Ó<ˆEæØ×$Ñ$ UÓ+ˆEä˜%Ð!5Ó6ˆàˆr   c                ó
  • U R                  U5      nU R                  U5      n[        US5      nU R                  U5      n[	        XcS5      n[        US5      n[	        XSS5      nU R
                  (       d  [        US5      nXFU4$ )Núb n c d -> b n (c d)úb * dr€   úb * cú... 1 -> ...)ro   r}   r   r>   r   r:   )rI   r[   Úis_img_or_videor   r‚   r�   Úouts          r   Úquantize_and_projectÚ#LatentQuantize.quantize_and_projectÓ   s‚   € Ø—‘˜aÓ ˆØ×'Ñ'¨Ó.ˆä˜%Ð!7Ó8ˆà×Ñ˜uÓ%ˆÜ˜ 'Ó*ˆÜ˜Ð1Ó2ˆä˜W¨'Ó2ˆà×*×*Ü ¨Ó8ˆGØ˜7Ð"Ð"r   c                óL  • UnU R                   SLn[        US5      n[        US5      u  pUR                  S   U R                  :X  d$   SU R                   SUR                  S    35       eU R                  U5      n[        USU R                  S9nU R                  U5      nU R                  U5      n[        US	5      nU R                  U5      n[        XtS5      n[        US
5      n[        XdS5      nU R                  (       d  [        US5      nU(       GaY  U R                  (       GaG  U R                  (       Gd5  U R                  S:w  a  U R                  X5      O[         R"                  " S5      nUU R$                  S:w  a  U R'                  X5      O[         R"                  " S5      -  nUR)                  5         U R                   R+                  5         U R                   R-                  5         U R                  U5      nU R                  U5      n[        US	5      nU R                  U5      n[        XtS5      n[        US
5      n[        XdS5      nU R                  (       d  [        US5      nU R                  (       a!  U R                  S:w  a  U R                  X'5      O[         R"                  " S5      n	U R                  (       a!  U R$                  S:w  a  U R'                  X'5      O[         R"                  " S5      n
U R                  U	-  U R$                  U
-  -   nXvU4$ )z}
einstein notation
b - batch
n - sequence (or flattened spatial dimensions)
d - feature dimension
c - number of codebook dim
Nzb d ... -> b ... dr‡   r"   zexpected dimension of z but found dimension of zb n (c d) -> b n c d)Úcr†   r€   rˆ   r‰   r   g        )r+   r   r   rz   r$   r=   r8   ro   r}   r>   r   r:   ÚtrainingrK   r   ra   r,   r-   r   r^   ÚbackwardÚstepÚ	zero_grad)rI   r[   Úoriginal_inputÚshould_inplace_optimizer   r‚   r�   r‹   Úlossra   r^   s              r   ÚforwardÚLatentQuantize.forwardã   s×  € ð ˆØ"&×"BÑ"BÈ$Ð"NÐä�aÐ-Ó.ˆÜ˜˜GÓ$‰ˆð �G‰G�B‰K˜4Ÿ8™8Ó#ð	Tà# D§H¡H :Ð-EÀaÇgÁgÈbÁkÀ]ÐSó	TØ#ð �O‰O˜AÓˆÜ�aÐ/°4×3EÑ3EÑFˆà—‘˜aÓ ˆØ×'Ñ'¨Ó.ˆä˜%Ð!7Ó8ˆà×Ñ˜uÓ%ˆÜ˜ 'Ó*ˆÜ˜Ð1Ó2ˆä˜W¨'Ó2ˆà×*×*Ü ¨Ó8ˆGç" t§}§} }¸T×=Q×=QÐ=Qð ×.Ñ.°!Ó3ð ×$Ñ$ QÔ,ä—\’\ #Ó&ð ð
 à×0Ñ0°AÓ5ð ×&Ñ& qÔ.ä—\’\ #Ó&ñˆDð
 �M‰MŒOØ×,Ñ,×1Ñ1Ô3Ø×,Ñ,×6Ñ6Ô8à—M‘M !Ó$ˆEØ×+Ñ+¨EÓ2ˆGÜ˜eÐ%;Ó<ˆEØ×"Ñ" 5Ó)ˆCä˜S gÓ.ˆCÜ˜CÐ!5Ó6ˆCä  ¨gÓ6ˆGà×.×.Ü# G¨^Ó<�ð
 �}�} ×!<Ñ!<ÀÓ!Að × Ñ  Ô5ä—’˜cÓ"ð 	ð �}�} ×!>Ñ!>À!Ó!Cð ×"Ñ" >Ô7ä—’˜cÓ"ð 	ð ×'Ñ'¨/Ñ9Ø×+Ñ+Ð.?Ñ?ñ@ð 	ð
 ˜TÐ!Ð!r   )r7   rB   r$   r9   r?   r+   r:   r8   r=   r>   rH   )çš™™™™™¹?r™   r!   r"   NTN)rJ   zList[int] | intr$   r/   r   úfloat | Noner   rš   r8   r/   r7   r/   r:   úbool | NonerK   r›   r+   zCallable[..., Optimizer])Úmean)r[   r	   r\   r	   Úreturnr	   )r[   r	   r�   r	   )rs   r	   r�   r	   )r\   r	   r�   r	   )T)r�   r	   r�   r	   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r*   r^   ra   ro   ru   rD   r}   rƒ   rŒ   r—   Ú__static_attributes__Ú__classcell__)rQ   s   @r   r   r      s¾   ø† ð
 03Ø14ØØØ.2Ø'+ð ðm7àðm7ð ðm7ð !-ð	m7ð
 #/ðm7ð ðm7ð ðm7ð !,ðm7ð %ðm7ð&
÷m7ð m7ö^>ö>ôô<?ô
4ô
:öô"#÷ S"ò S"r   r   )Ú__doc__Ú
__future__r   Útypingr   r   r,   Útorch.nn.functionalr   Ú
functionalrW   Úeinopsr   r   r   r	   r
   Útorch.nnr   Útorch.optimr   r   r   r   © r   r   Ú<module>r­      sE   ðñõ #ß !ã ß Ð ß *Ñ *ß #Ñ #Ý Ý !ò
ò%ôZ"�Võ Z"r   