o
    @Ti                     @   s   d dl Z d dl mZ ddlmZ e Zde jde jfddZdd
e jdede jfddZG dd dej	Z
G dd dej	ZdS )    N)nn   )
get_loggerzreturnc                 C   s   |   }| ||    S )z&Round with straight through gradients.)rounddetach)r   zhat r
   H/home/ubuntu/.local/lib/python3.10/site-packages/linacodec/module/fsq.py	round_ste   s   r   绽|=probepsc                 C   s   t j| t | |  dd S )Ndim)torchsumlog)r   r   r
   r
   r   get_entropy   s   r   c                       s   e Zd Zdee f fddZddejdedejfdd	Z	dejdejfd
dZ
dejdejfddZdejdejfddZdejdejfddZdejdejfddZdejdejfddZdejdejfddZdejfddZ  ZS )FSQlevelsc                    st   t    || _t|| _tj|tjd}| jd|dd tj	tdg|d d  dtjd}| jd	|dd d S )
N)dtype_levelsF)
persistent   r   r   )r   r   _basis)
super__init__r   lenr   r   tensorlongregister_buffercumprod)selfr   r   r   	__class__r
   r   r      s   

&zFSQ.__init__MbP?r   r   r   c                 C   sN   | j d d|  d }t| j d dkdd}||  }||  | | S )z&Bound `z`, an array of shape (..., d).r   r   r   g      ?g        )r   r   wheretantanh)r%   r   r   half_loffsetshiftr
   r
   r   bound    s   z	FSQ.boundc                 C   s    t | |}| jd }|| S )z5Quantizes z, returns quantized zhat, same shape as z.r   )r   r/   r   )r%   r   	quantized
half_widthr
   r
   r   quantize'   s   
zFSQ.quantizezhat_normalizedc                 C   s   | j d }|| | S Nr   r   )r%   r3   r1   r
   r
   r   _scale_and_shift-      
zFSQ._scale_and_shiftr	   c                 C   s   | j d }|| | S r4   r5   )r%   r	   r1   r
   r
   r   _scale_and_shift_inverse1   r7   zFSQ._scale_and_shift_inversec                 C   sD   |j d t| jksJ | |}|| jtj tjj	ddS )z.Converts a `code` to an index in the codebook.r   r   )
shaper    r   r6   r   tor   float64r"   r   )r%   r	   r
   r
   r   codes_to_indices5   s   
"zFSQ.codes_to_indicesindicesc                 C   s$   | d}|| j | j }| |S )zInverse of `codes_to_indices`.r   )	unsqueezer   r   r8   )r%   r=   codes_non_centeredr
   r
   r   indices_to_codes<   s   

zFSQ.indices_to_codesc                 C      |  |}| |}||fS Nr2   r<   r%   r   z_qr=   r
   r
   r   encodeC      

z
FSQ.encodec                 C   s   |  |}|S rB   )r@   r%   r=   rE   r
   r
   r   decodeH   s   
z
FSQ.decodec                 C   rA   rB   rC   rD   r
   r
   r   forwardL   rG   zFSQ.forward)r(   )__name__
__module____qualname__listintr   r   Tensorfloatr/   r2   r6   r8   r<   r@   rF   rI   rJ   __classcell__r
   r
   r&   r   r      s    
r   c                	       s   e Zd Zdededee ddf fddZddd	Zedefd
dZedefddZ	de
jdee
jef fddZdde
jdedee
je
jf fddZde
jde
jfddZ  ZS )FiniteScalarQuantizer	input_dim
output_dimr   r   Nc              
      s   t    || _|| _t|| _td| d| d| d| j  t	||kr0t
|t	|nt
 | _t	||krFt
t	||| _d S t
 | _d S )Nz%Finite Scalar Quantizer with levels: z, input_dim: z, output_dim: z, codebook_size: )r   r   
input_dim_output_dim_r   fsqloggerdebugall_codebook_sizer    r   LinearIdentityproj_inproj_out)r%   rT   rU   r   r&   r
   r   r   S   s   

&0zFiniteScalarQuantizer.__init__c                 C   s   d S rB   r
   r%   r
   r
   r   build_codebook`   s   z$FiniteScalarQuantizer.build_codebookc                 C   s   | j S rB   )rW   r`   r
   r
   r   rU   c   s   z FiniteScalarQuantizer.output_dimc                 C   s   d}| j jD ]}||9 }q|S )Nr   )rX   r   )r%   sizelevelr
   r
   r   r[   g   s   
z'FiniteScalarQuantizer.all_codebook_sizer   c                 C   sv   |  |}| |\}}| |}|d}tj|dd\}}| |  }	t|	}
t	|
}||||d}||fS )Nr   T)return_counts)latentquantized_latentr=   
perplexity)
r^   rX   r_   viewr   uniquerQ   numelr   exp)r%   r   re   rf   r=   rE   flat_indicesunique_indicescountsused_indices_probsentropyrg   	info_dictr
   r
   r   rJ   n   s   



zFiniteScalarQuantizer.forwardF	skip_projc                 C   s0   |  |}| j|\}}|s| |}||fS rB   )r^   rX   rF   r_   )r%   r   rr   rE   r=   r
   r
   r   rF      s
   

zFiniteScalarQuantizer.encoder=   c                 C   s   | j |}| |}|S rB   )rX   rI   r_   rH   r
   r
   r   rI      s   
zFiniteScalarQuantizer.decode)r   N)F)rK   rL   rM   rO   rN   r   ra   propertyrU   r[   r   rP   tupledictrJ   boolrF   rI   rR   r
   r
   r&   r   rS   R   s    "
&rS   )r   )r   r   utilr   rY   rP   r   rQ   r   Moduler   rS   r
   r
   r
   r   <module>   s   =