U
    h                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlZd dlZd dl	Z	d dl
mZ d dlmZ d dlmZ d dlmZ e eZG dd	 d	e	jjZG d
d dZG dd dZdS )    N)Path)List)	OnnxModel)torch_onnx_export)WhisperConfig)InferenceSessionc                       s.   e Zd ZdZed fddZdd Z  ZS )WhisperEncoderz2Whisper encoder outputs only the last hidden state)configc                    s   t    || _|| _d S N)super__init__encoderr	   )selfr   r	   	__class__ [/tmp/pip-unpacked-wheel-socb9apf/onnxruntime/transformers/models/whisper/whisper_encoder.pyr      s    
zWhisperEncoder.__init__c                 C   s   | j j |d S )Nr   )r   modelr   input_featuresr   r   r   forward!   s    zWhisperEncoder.forward)__name__
__module____qualname____doc__r   r   r   __classcell__r   r   r   r   r      s   r   c                   @   s>   e Zd Zdd ZeeeeejedddZ	e
dddZd	S )
WhisperEncoderInputsc                 C   s
   || _ d S r
   )	input_idsr   r   r   r   r   &   s    zWhisperEncoderInputs.__init__)
batch_sizesequence_lengthfeature_sizedeviceuse_int32_inputsc                 C   s   t j| ||f|d}t|S )ah  Create dummy inputs for Whisper encoder.

        Args:
            batch_size (int): batch size
            sequence_length (int): sequence length
            feature_size (int): feature size for spectrogram input
            device (torch.device): device of output tensors

        Returns:
            WhisperEncoderInputs: dummy inputs for encoder
        )sizer!   )torchZrandnr   )r   r   r    r!   r"   r   r   r   r   create_dummy)   s
    z!WhisperEncoderInputs.create_dummy)returnc                 C   s   | j d krg S | j gS r
   )r   )r   r   r   r   to_list?   s    
zWhisperEncoderInputs.to_listN)r   r   r   r   staticmethodintr$   r!   boolr%   r   r'   r   r   r   r   r   %   s       r   c                   @   sV   e Zd ZedejeeedddZee	dddZ
edeeejed	d
dZdS )WhisperEncoderHelperTF)r!   onnx_model_pathverboseuse_external_data_formatc           
      C   s   | j }tjdd|j|d}t|jjddd t }t	j
|d}t|jjddd t| t| |rp|n|ddgdgd	d
ddd	ddddd||d |rtj|dd}	tj|	|ddd W 5 Q R X dS )a  Export encoder to ONNX

        Args:
            encoder (WhisperEncoder): encoder object
            device (torch.device): device of encoder object
            onnx_model_path (str): onnx path
            verbose (bool, optional): print verbose information. Defaults to True.
            use_external_data_format (bool, optional): use external data format or not. Defaults to False.
           i  )r   r   r    r!   T)parentsexist_okzencoder.onnxr   hidden_statesr   r    r   )r      r/   )r   r3   )r   r2      )
argsfZexport_paramsZinput_namesZoutput_namesZdynamic_axesZopset_versionZdo_constant_foldingr.   r-   )Zload_external_data)Zsave_as_external_dataZall_tensors_to_one_fileN)r	   r   r%   Znum_mel_binsr   parentmkdirtempfileTemporaryDirectoryospathjoinr   tupler'   onnxZ
load_modelr   save)
r   r!   r,   r-   r.   r	   Zencoder_inputsZtmp_dir_nameZtemp_onnx_model_pathr   r   r   r   export_onnxF   sD    



z WhisperEncoderHelper.export_onnx)inputsc                 C   s$   dt |j   i}| d|S )zRun inference of ONNX model.r   N)numpyZascontiguousarrayr   cpurun)ort_sessionrB   Z
ort_inputsr   r   r   onnxruntime_inference~   s     z*WhisperEncoderHelper.onnxruntime_inference)r   rF   r!   r"   c           	      C   sb   t jdd||d}| }| | }t||}tt|  |d  }t	
d|  |S )zQCompare the result from PyTorch and OnnxRuntime to verify the ONNX model is good.      )r   r   r!   r"   r   z	max_diff=)r   r%   r'   r+   rG   rC   ZamaxabsrD   loggerinfo)	r   rF   r!   r"   rB   Z
input_listZtorch_outputsZort_outputsZmax_diffr   r   r   verify_onnx   s     z WhisperEncoderHelper.verify_onnxN)TF)F)r   r   r   r(   r$   r!   strr*   rA   r   rG   r   r   rM   r   r   r   r   r+   E   s&     7    r+   )loggingr;   r9   pathlibr   typingr   rC   r?   r$   Z
onnx_modelr   Ztorch_onnx_export_helperr   Ztransformersr   Zonnxruntimer   	getLoggerr   rK   nnModuler   r   r+   r   r   r   r   <module>   s   
 