o
    i3                     @   s    d dl Z d dlmZ dd ZdS )    Nc                    s   dkr| S t | tjtjtjfsJ | jjdks*| jd  dks)J dn%| jdkr;| j	  dks:J dn| jd | jd  }|  dksOJ d fdd	}| 
| | S )
aN  
    Wraps modules and applies quantization noise to the weights for
    subsequent quantization with Iterative Product Quantization as
    described in "Training with Quantization Noise for Extreme Model Compression"

    Args:
        - module: nn.Module
        - p: amount of Quantization Noise
        - block_size: size of the blocks for subsequent quantization with iPQ

    Remarks:
        - Module weights must have the right sizes wrt the block size
        - Only Linear, Embedding and Conv2d modules are supported for the moment
        - For more detail on how to quantize by blocks with convolutional weights,
          see "And the Bit Goes Down: Revisiting the Quantization of Neural Networks"
        - We implement the simplest form of noise here as stated in the paper
          which consists in randomly dropping blocks
    r         z0Input features must be a multiple of block sizesr   r   z0Input channels must be a multiple of block sizesz,Kernel size must be a multiple of block sizec           	         s8  | j rs.| j}|d}|d}tj|  | |jd}| | dd|}nT| j}| j	}| j
}| jdkrZtjt|  | |jd}| | dd|}n(tj|d|d|jd}| |dddd| jd | jd }|tj}dd  }|||d | j_d S d S )Nr   r   )devicer         )trainingweightsizetorchzerosr   
bernoulli_repeat_interleaveviewin_channelsout_channelskernel_sizeint	unsqueezerepeattoboolmasked_filldata)	modinputr
   in_featuresout_featuresmaskr   r   s
block_sizeis_convp V/home/ubuntu/.local/lib/python3.10/site-packages/funasr/models/data2vec/quant_noise.py_forward_pre_hook:   s8   





z&quant_noise.<locals>._forward_pre_hook)
isinstancennLinear	EmbeddingConv2dr
   ndimr   r   r   register_forward_pre_hook)moduler$   r"   kr'   r%   r!   r&   quant_noise
   s"   

*r1   )r   torch.nnr)   r1   r%   r%   r%   r&   <module>   s   