o
    ̳iw!                     @   s   d dl Z d dlmZ d dlmZ d dlmZ d dlZd dlmZ d dl	m
Z
mZ d dlm  mZ d dlmZ d dlmZ d d	lmZmZmZmZmZ d d
lmZ dd Zdd Zdd Zdd ZG dd de
ZG dd de
Z dS )    N)log2)partial)List)nn)Module
ModuleList)autocast)FSQ)	rearrangerepeatreducepackunpack)get_atc                 C   s   | d uS N )valr   r   X/home/ubuntu/.local/lib/python3.10/site-packages/vector_quantize_pytorch/residual_fsq.pyexists      r   c                 C   s   | d S )Nr   r   )lr   r   r   first   r   r   c                 C   s   t | r| S |S r   )r   )r   dr   r   r   default      r   c                 C   s   t | | | S r   )ceil)nummultr   r   r   round_up_multiple   r   r   c                       s^   e Zd ZdZdddddee f fddZed	d
 Zdd Z	dd Z
		dddZ  ZS )ResidualFSQz> Follows Algorithm 1. in https://arxiv.org/pdf/2107.03312.pdf Fr      )quantize_dropoutquantize_dropout_cutoff_indexquantize_dropout_multiple_oflevelsc                   s"  t    t|}||k}	|	rt||nt | _|	r"t||nt | _|	| _|| _	|| _
tg | _t|}
g }t|D ]}||
d |   td	||d|}| j| qAtdd | jD sjJ | jd j| _| jdt|dd |o|dk| _|dksJ || _|| _d S )
Nr    )r$   dimc                 S   s   g | ]}|j  qS r   )has_projections).0fsqr   r   r   
<listcomp>M   s    z(ResidualFSQ.__init__.<locals>.<listcomp>r   scalesF)
persistentr   )super__init__lenr   LinearIdentity
project_inproject_outr&   num_quantizersr$   r   layerstorchTensorrangeappendr	   allcodebook_sizeregister_bufferstackr!   r"   r#   )selfr%   r$   r3   r!   r"   r#   kwargscodebook_dimrequires_projectionlevels_tensorr*   indr(   	__class__r   r   r-   &   s6   


zResidualFSQ.__init__c                 C   s"   dd | j D }tj|dd}|S )Nc                 S   s   g | ]}|j qS r   )implicit_codebook)r'   layerr   r   r   r)   \   s    z)ResidualFSQ.codebooks.<locals>.<listcomp>r   r%   )r4   r5   r<   )r=   	codebooksr   r   r   rH   Z   s   zResidualFSQ.codebooksc                 C   s   |j d |j d }}t|gd\}}|| jk r.| jdks!J dtj|d| j| fdd}|dk}||d}td| j|}|t	|dd}t	| j
d	}|| }t||d
\}|S )Nr   zb * q        zmquantize dropout must be greater than 0 if you wish to reconstruct from a signal with less fine quantizations)valuezq [c] d, b n q -> q b n dzb n q -> q b n 1zq d -> q 1 1 dzq b * d)shaper   r3   r!   Fpadmasked_fillr   rH   r
   r*   r   )r=   indicesbatchquantize_dimpsmask	all_codesr*   r   r   r   get_codes_from_indices`   s   
z"ResidualFSQ.get_codes_from_indicesc                 C   s    |  |}t|dd}| |S )Nzq ... -> ...sum)rV   r   r2   )r=   rP   codescodes_summedr   r   r   get_output_from_indices   s   

z#ResidualFSQ.get_output_from_indicesNc                 C   s~  | j | j|j}}}| |}d}t| j|}g }	| jo!| j}
|
rRt	|r-t
|nt
}|| j|}|dkrCt|d |d }tj|jd d d|tjd}tddd? tt| j| jD ]-\}\}}|
rt||krt|	| qb||| \}}|| }||  }|| }|	| qbW d    n1 sw   Y  | |}tj|	d	d
}	||	f}|s|S | |	}g ||R S )NrJ   r       g      )devicedtypecudaF)enabledrI   rG   )r3   r#   r\   r1   r   r4   boundtrainingr!   r   randomRandom	randranger"   r   r5   fullrL   longr   	enumeratezipr*   r8   detachr2   r<   rV   )r=   xreturn_all_codes rand_quantize_dropout_fixed_seed	num_quantquant_dropout_multiple_ofr\   quantized_outresidualall_indicesshould_quantize_dropoutrandrand_quantize_dropout_indexnull_indicesquantizer_indexrF   scale	quantizedrP   retrU   r   r   r   forward   s>   



zResidualFSQ.forward)FN)__name__
__module____qualname____doc__r   intr-   propertyrH   rV   rZ   rz   __classcell__r   r   rC   r   r   #   s    4
%r   c                       sX   e Zd Zddd fdd
Zedd Zedd	 Zd
d Zdd Z	dddZ	  Z
S )GroupedResidualFSQr    F)groupsaccept_image_fmapc                   sz   t    || _|| _|| dksJ || }|| _tg | _t|D ]}| j	t
dd|i| q$| jd j| _d S )Nr   r%   r   )r,   r-   r%   r   r   r   r   rvqsr7   r8   r   r:   )r=   r%   r   r   r>   dim_per_group_rC   r   r   r-      s   

zGroupedResidualFSQ.__init__c                 C   s   t tdd | jD S )Nc                 s   s    | ]}|j V  qd S r   )rH   )r'   rvqr   r   r   	<genexpr>   s    z/GroupedResidualFSQ.codebooks.<locals>.<genexpr>)r5   r<   tupler   r=   r   r   r   rH      s   zGroupedResidualFSQ.codebooksc                 C   s   | j rdS dS )Nr    rI   )r   r   r   r   r   	split_dim   s   zGroupedResidualFSQ.split_dimc                 C   s$   t dd t| j|D }t|S )Nc                 s       | ]
\}}| |V  qd S r   )rV   r'   r   chunk_indicesr   r   r   r          z<GroupedResidualFSQ.get_codes_from_indices.<locals>.<genexpr>)r   rh   r   r5   r<   )r=   rP   rX   r   r   r   rV      s   
z)GroupedResidualFSQ.get_codes_from_indicesc                 C   s*   t dd t| j|D }tj|| jdS )Nc                 s   r   r   )rZ   r   r   r   r   r      r   z=GroupedResidualFSQ.get_output_from_indices.<locals>.<genexpr>rG   )r   rh   r   r5   catr   )r=   rP   outputsr   r   r   rZ      s   z*GroupedResidualFSQ.get_output_from_indicesc           
         s   |j | j}}|| | jksJ |j| j|d}t|tdtdd t	 fddt
| j|D }t	t
| }|^}}}tj||d}t|}||g|R }	|	S )NrG   r   g    cA)rk   rl   c                 3   s$    | ]\}}||fi  V  qd S r   r   )r'   r   chunkforward_kwargsr   r   r     s   " z-GroupedResidualFSQ.forward.<locals>.<genexpr>)rL   r   r%   r   r   dictrb   randintr   r   rh   r   r5   r   r<   )
r=   rj   rk   rL   r   outrx   rq   maybe_all_codesry   r   r   r   rz      s   

zGroupedResidualFSQ.forward)F)r{   r|   r}   r-   r   rH   r   rV   rZ   rz   r   r   r   rC   r   r      s    

r   )!rb   mathr   	functoolsr   typingr   r5   r   torch.nnr   r   torch.nn.functional
functionalrM   	torch.ampr   2vector_quantize_pytorch.finite_scalar_quantizationr	   einopsr
   r   r   r   r   einxr   r   r   r   r   r   r   r   r   r   r   <module>   s&     .