o
    ̳i]                     @   sh   d dl mZ d dlZd dlZd dlmZ d dlm  mZ	 d dl
mZ d dlmZ G dd dejZdS )    )UnionN)	rearrange)weight_normc                       sZ   e Zd Z fddZedd Zdd Zddd	Zd
d Zdd Z	dd Z
dd Z  ZS )FactorizedVectorQuantizec                    sx   t    || _|| _|| _|| jkr(tt|| j| _tt| j|| _	n
t
 | _t
 | _	t|| j| _d S N)super__init__codebook_sizecodebook_dim
commitmentr   nnLinearin_projout_projIdentity	Embedding	_codebook)selfdimr	   r
   r   kwargs	__class__ Y/home/ubuntu/.local/lib/python3.10/site-packages/xcodec2/vq/factorized_vector_quantize.pyr      s   



z!FactorizedVectorQuantize.__init__c                 C   s   | j S r   )r   r   r   r   r   codebook   s   z!FactorizedVectorQuantize.codebookc                 C   s   t |d}| |}t |d}| |\}}| jr?tj|| ddddg| j }tj|| ddddg}|| }nt	j
|jd |jd}|||   }t |d}| |}t |d}|||fS )	a  Quantized the input tensor using a fixed codebook and returns
        the corresponding codebook vectors

        Parameters
        ----------
        z : Tensor[B x D x T]

        Returns
        -------
        Tensor[B x D x T]
            Quantized continuous representation of input
        Tensor[1]
            Commitment loss to train encoder to predict vectors closer to codebook
            entries
        Tensor[1]
            Codebook loss to update the codebook
        Tensor[B x T]
            Codebook indices (quantized discrete representation of input)
        Tensor[B x D x T]
            Projected latents (continuous representation of input before quantization)
        zb d t -> b t dzb t d -> b d tnone)	reduction      r   )device)r   r   decode_latentstrainingFmse_lossdetachmeanr   torchzerosshaper    r   )r   zz_ez_qindicescommitment_losscodebook_losscommit_lossr   r   r   forward   s   


$




z FactorizedVectorQuantize.forwardTc                 C   s   |  |}|r| |}|S r   )
embed_coder   )r   vqprojembr   r   r   vq2embN   s   

zFactorizedVectorQuantize.vq2embc                 C   s   | j jS r   )r   weightr   r   r   r   get_embT   s   z FactorizedVectorQuantize.get_embc                 C   s   t || jjS r   )r#   	embeddingr   r7   r   embed_idr   r   r   r2   W   s   z#FactorizedVectorQuantize.embed_codec                 C   s   |  |ddS )Nr   r   )r2   	transposer:   r   r   r   decode_codeZ   s   z$FactorizedVectorQuantize.decode_codec                 C   s   t |d}| jj}t|}t|}|djdddd| |   |djddd  }t | dd d|	dd}| 
|}||fS )	Nzb d t -> (b t) dr   r   T)keepdimz(b t) -> b tr   )b)r   r   r7   r#   	normalizepowsumtmaxsizer=   )r   latents	encodingsr   distr-   r,   r   r   r   r!   ]   s   


 
z'FactorizedVectorQuantize.decode_latents)T)__name__
__module____qualname__r   propertyr   r1   r6   r8   r2   r=   r!   __classcell__r   r   r   r   r   
   s    

1r   )typingr   numpynpr'   torch.nnr   torch.nn.functional
functionalr#   einopsr   torch.nn.utilsr   Moduler   r   r   r   r   <module>   s    