U
    T?h_                  	   @   s  d dl Z d dlZd dlmZ d dlZd dlZd dlmZ d dlm	Z	m
Z
mZ d dl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mZmZ d
ejd< e eZdej iZ!d:ddZ"dd Z#dd Z$ej%fddZ&dd Z'dd Z(dd Z)dd Z*d;ddZ+e,e,e-e.e.e
e.e.dd d!Z/e,e,e,d"d#d$Z0d%d& Z1d<d'd(Z2d)d* Z3d=d,d-Z4d.d/ Z5d0d1 Z6d2d3 Z7d4d5 Z8d6d7 Z9d8d9 Z:dS )>    N)Path)AffinitySetting)OptimizerInfo	Precisioncreate_onnxruntime_session)MODEL_CLASSES)QuantizeHelper)torch_onnx_export)
AutoConfigAutoFeatureExtractorAutoTokenizerLxmertConfigTransfoXLConfig)PRETRAINED_GPT2_MODELSGPT2ModelNoPastStateTFGPT2ModelNoPastState2ZTF_CPP_MIN_LOG_LEVELtriuc                 C   s   |d kst t| jdkr.| d| dks2t td }|tjdtjd|}|d | dd | df }t|	 | t
| S )N   r      r   )   r   dtype)AssertionErrorlenshapesize
torch_functorchonesuint8whereboolZ
zeros_like)xZdiagonaloutZ
torch_triutemplatemask r'   X/var/www/html/venv/lib/python3.8/site-packages/onnxruntime/transformers/onnx_exporter.py	triu_onnx#   s    & r)   c                   C   s
   t t_d S N)r)   r   r   r'   r'   r'   r(   replace_torch_functions-   s    r+   c                   C   s   t d t_d S )Nr   )r   r   r   r'   r'   r'   r(   restore_torch_functions1   s    r,   c           
      C   s  |j dkr4tj|d|j|jtj}d|i}|S tjjd| d ||f|d}d|i}d|krztj||g|d	}||d< d
|krtj	||g|d	}	|	|d
< |j
r||d< t|trtjdd|jtj|d< tjdd|jtj|d< t|trtj	|jgtjd	|d< |S )NZvitswin   pixel_valuesr   r   lowhighr   r   	input_idsattention_maskr   Ztoken_type_idsdecoder_input_idsvisual_feats
visual_posz@tf_transfo_xl_model/transformer/pos_emb/einsum/Einsum/inputs_1:0)
model_typenumpyrandomZrand
image_sizeZastypeZfloat32randintr   Zzerosis_encoder_decoder
isinstancer   Zrandnvisual_feat_dimvisual_pos_dimr   hidden_size)

vocab_size
batch_sizesequence_lengthinput_namesconfigZ	data_typer4   inputsr5   Zsegment_idsr'   r'   r(   create_onnxruntime_input5   s.    

 
rI   c                 C   s&   i }|D ]}|| kr| | ||< q|S r*   r'   )rH   rF   Zremaining_model_inputsZ
input_namer'   r'   r(   filter_inputsS   s
    rJ   c                 C   s"   t | ttfrdd | D n| gS )Nc                 S   s   g | ]}t |qS r'   )flatten.0ir'   r'   r(   
<listcomp>\   s     zflatten.<locals>.<listcomp>)r?   listtuple)rH   r'   r'   r(   rK   [   s    rK   c                 C   s0   | D ]&}t |ttfs ||nt|| q|S r*   )r?   rP   rQ   appendupdate_flatten_list)rH   Zres_listrN   r'   r'   r(   rS   _   s    $rS   c           
      C   s   | d j d }dd | D }dd tt|D }t|D ]J\}}ddi||< || j }t|D ]"\}}	|	|kr`|| |d	i q`q:||fS )
Nr4   c                 S   s   i | ]}|d ddqS )rD   seq_len)r   r   r'   rM   keyr'   r'   r(   
<dictcomp>h   s      z&build_dynamic_axes.<locals>.<dictcomp>c                 S   s   g | ]}d t |d  qS )Zoutput_r   )strrL   r'   r'   r(   rO   j   s     z&build_dynamic_axes.<locals>.<listcomp>r   rD   rU   )r   ranger   	enumerateupdate)
example_inputsZoutputs_flattenrE   dynamic_axesoutput_namesrN   Zoutput_namedimsjdimr'   r'   r(   build_dynamic_axese   s    
rc   c              	   C   sN  t | |dd}|d kr*t|  d dS t|  d dd | D }|||}t|t|krtdt| dt|  dS tt|D ]}	t	t
||	 ||	    }
|
d	krtd
|
 d|	  |rdnd	}|rdnd	}tj||	 ||	   ||dstd|	 d| d|   dS qtd|   dS )NF)Zenable_all_optimizationz is an invalid ONNX modelz is a valid ONNX modelc                 S   s   i | ]\}}||  qS r'   )r:   )rM   ktr'   r'   r(   rX      s      z'validate_onnx_model.<locals>.<dictcomp>z"Number of output tensors expected z, got g-C6?zMax absolute diff=z for output tensor g?g?)rtolatolzOutput tensor z is not close: rtol=z, atol=z0inference result of onnxruntime is validated on T)r   loggererrorinfoitemsrunr   rZ   r:   ZamaxabscpuZallclose)onnx_model_pathr]   example_outputs_flattenuse_gpuZfp16r_   Ztest_sessionZexample_ort_inputsZexample_ort_outputsrN   Zabs_diffrf   rg   r'   r'   r(   validate_onnx_modelt   s8    $rr   )onnx_dir
model_nameinput_countoptimized_by_scriptrq   	precisionoptimized_by_onnxruntimeuse_external_datac                 C   s   ddl m} |dd|}	|s,|	 d| }
n&|r4dnd}|	 d| d| d| }
|r^|
d7 }
| }|r|stj| |
}tj|st| tj||
 dS )	Nr   )subz[^a-zA-Z0-9_]_Zgpurn   _ortz.onnx)rerz   ospathjoinexistsmakedirs)rs   rt   ru   rv   rq   rw   rx   ry   rz   Znormalized_model_namefilenameZdevice	directoryr'   r'   r(   get_onnx_file_path   s    

r   )	file_pathsuffixreturnc                 C   s&   t | }t|j|j| |jS )a  
    Append a suffix at the filename (before the extension).
    Args:
        path: pathlib.Path The actual path object we would like to add a suffix
        suffix: The suffix to add
    Returns: path with suffix appended at the end of the filename and before extension
    )r   rY   parentjoinpathstemwith_suffixr   )r   r   r   r'   r'   r(   add_filename_suffix   s    r   c                 C   sf   |st j|sRt|jjddd ddlm}m} || ||dd}||||< nt	
d|  d S )NTparentsexist_okr   )get_fusion_statisticsoptimize_by_onnxruntimec   )rq   optimized_model_path	opt_level'Skip optimization since model existed: )r~   r   r   r   r   mkdir	optimizerr   r   rh   rj   )ro   ort_model_pathrq   	overwritemodel_fusion_statisticsr   r   r{   r'   r'   r(   optimize_onnx_model_by_ort   s    r   c              
   C   s   |st j|st|jjddd ddlm} ddlm	} |d krL||}|
| |tjkrfd|_|tjkrvd|_|dkrd}d}|| |||d||dd}|d	ks|d
kr|  | |	|< |tjkr|jdd |||
 ntd|  d S )NTr   r   )FusionOptions)optimize_modelFr.   )Z	num_headsrB   r   optimization_optionsrq   Zonly_onnxruntimeZ
bert_kerasZbert_tf)Zkeep_io_typesr   )r~   r   r   r   r   r   fusion_optionsr   r   r   use_raw_attention_maskr   FLOAT16Zenable_gelu_approximationINT8Zenable_embed_layer_normZuse_dynamic_axesZget_fused_operator_statisticsZconvert_float_to_float16Zsave_model_to_filerh   rj   )ro   r   r9   num_attention_headsrB   rq   rw   r   r   r   use_external_data_formatr   r   r   Z	opt_modelr'   r'   r(   optimize_onnx_model   s>    




r   c                 C   sz   |d k	r&|t kr|S tddt  | tkr2dS dd l}|d| d k	rNdS |d| d k	rbdS |d	| d k	rvd
S dS )NzValid model class:  r   r   z-squad$ZAutoModelForQuestionAnsweringz-mprc$Z"AutoModelForSequenceClassificationZgpt2ZAutoModelWithLMHeadZ	AutoModel)r   	Exceptionr   r   r}   search)rt   custom_model_classr}   r'   r'   r(   modelclass_dispatcher  s    r   Fc                 C   sz   t | |}|dkr6|r&tj| ||dS tj| ||dS |rBd| }td|gd}td|  t||}|j| ||dS )Nr   )rG   	cache_dirZTFtransformers)fromlistzModel class name: )r   r   from_pretrainedr   
__import__rh   rj   getattr)rt   rG   r   r   is_tf_modelZmodel_class_nameZtransformers_modulemodel_classr'   r'   r(   load_pretrained_model/  s    

r   c                 C   s@   t j| |d}t|drd|_|| t| |||d}||fS )Nr   return_dictF)rG   r   r   )r
   r   hasattrr   modifyr   )rt   r   r   config_modifierrG   modelr'   r'   r(   load_pt_modelB  s    

r   c                 C   sH   t j| |d}|| t }|  t| |||dd}|  ||fS )Nr   T)rG   r   r   r   )r
   r   r   r   Zget_affinityr   Zset_affinity)rt   r   r   r   rG   Zaffinity_settingr   r'   r'   r(   load_tf_modelN  s    
r   c                 C   s    ddl m} || \}}||fS )Nr   )tf2pt_pipeline)Zconvert_tf_models_to_pytorchr   )rt   r   rG   r   r'   r'   r(   load_pt_model_from_tfc  s    r   c                 C   s*  d}|rt ||||d|}|tjkr0|||jfS |tjksN|tjksN|tjkrt|| t	|d||d|}t
||||j|j|||	|
||| |}|rt |||||tjk|}|tjkrtd|  t||| td|  |tjkr|rt|d}t||||
| |||dkr"|jn|jfS )NTFzQuantizing model: zFinished quantizing model: r|   r-   )rr   r   ZNOOPTrC   ZBYSCRIPTr   r   r   r   r   r   r   rB   rh   rj   r   Zquantize_onnx_modelZBYORTr   r   Z
num_labels)rt   r   r9   rs   rF   rq   rw   Zoptimize_infovalidate_onnxr   r   rG   r   ro   r]   rp   r_   r   is_valid_onnx_modelr   r   r'   r'   r(   validate_and_optimize_onnxm  s    

	

	r   c                  C   s  t | |||\}}|  d }d }|dkrvtj| |d}tjjdd|j|j d tjd	|j|jd}||dd}n*t
j| |d}|j| d	}|jd
dd}t||}|f |}t|ttfstdt| t|}t|g }t|| t|d|	|
d|}|stj|std|  t|jjddd d }d }|dkrbdd |D dg }}nt ||\}}t!  t"|t|# |t|$ ||d||d	 t%  ntd|  t&| |||||	|
|||||||||d |\}}}||||fS )Nr-   r   r      r/   r1   pt)return_tensorsr   This is a sample inputz%type of output is not list or tuple: FExporting ONNX model to Tr   c                 S   s   i | ]}|d diqS )r   r0   r'   rV   r'   r'   r(   rX     s      z-export_onnx_model_from_pt.<locals>.<dictcomp>Zlogits)	r   argsfrF   r_   r^   Zdo_constant_foldingopset_versionr   !Skip export since model existed: )'r   rn   r   r   r:   r;   r=   r<   r    Zreshaper   max_model_input_sizesgetencode_plusrJ   r?   rP   rQ   r   typerK   rS   r   r   r~   r   r   rh   rj   r   r   r   rc   r+   r	   valueskeysr,   r   ) rt   r   r   r9   r   r   r   rs   rF   rq   rw   optimizer_infor   r   r   r   r   rG   r   r]   max_input_sizeZimage_processordata	tokenizerexample_outputsrp   ro   r^   r_   Zonnx_model_filer   rC   r'   r'   r(   export_onnx_model_from_pt  s         

 




r   c           (      C   s   dd l }|jg d tj| |d}|jd kr<|ddi |j| d}t	| |||\}}|
t| |jdd|d	d
d}t||}|jr|jdd|d	d
dj|d< | dkr|jdd|jg|d< |jdd|jg|d< z|jrd|_W n tk
r   Y nX ||dd}d }| dks,| dkr:dg}|d }ddlm} ||}t|| t|d|	|
d|}|r||d d n|}|stj|std|  |st|j j!d
d
d dd l"}dd l#}|j$%|j$j& g }|' D ]6\} }!d gt|!j( }"|)|j*t+|"|!j,| d q|j-j.|t+||||d\}#}#|r|/|d}$|$0tj1| W 5 Q R X tj2tj1|d}tj|rt3| t4|| ntd|  |d }t5| |||||	|
|||||||||||\}%}&}'|%|&|'|fS ) Nr   ZGPUr   	pad_tokenz[PAD]r   r   tf
max_lengthT)r   r   paddingZ
truncationr6   zunc-nlp/lxmert-base-uncasedr   r7   r8   F)Ztrainingzxlnet-base-casedzxlnet-large-casedZlast_hidden_state)nestr   r   )name)Zinput_signatureZopsetZlarge_modelZoutput_pathrz__MODEL_PROTO.onnxr   Z_tf)6Z
tensorflowrG   Zset_visible_devicesr   r   r   Zadd_special_tokensr   r   r   Zresize_token_embeddingsr   r   rJ   r>   r4   r;   normalr@   rA   Z	use_cacher   Ztensorflow.python.utilr   rK   r   r~   r   r   rh   rj   r   r   r   zipfiletf2onnxloggingZ	set_levelERRORrk   r   rR   Z
TensorSpecrQ   r   convertZ
from_kerasZipFile
extractalldirnamer   removerenamer   )(rt   r   r   r9   r   r   r   rs   rF   rq   rw   r   r   r   r   r   r   r   r   r   rG   r   r]   r   r_   r   rp   ro   Ztf_internal_model_pathr   r   specsr   valuer`   r{   zZoptimized_onnx_pathr   rC   r'   r'   r(   export_onnx_model_from_tf;  s    




 


r   )r   N)N)N)F);r   r~   pathlibr   r:   r   Zaffinity_helperr   Zbenchmark_helperr   r   r   Zhuggingface_modelsr   Zquantize_helperr   Ztorch_onnx_export_helperr	   r   r
   r   r   r   r   Z0onnxruntime.transformers.models.gpt2.gpt2_helperr   r   r   environ	getLogger__name__rh   r   r   r)   r+   r,   Zint64rI   rJ   rK   rS   rc   rr   rY   intr"   r   r   r   r   r   r   r   r   r   r   r   r   r'   r'   r'   r(   <module>   sZ   




 
-! 
;

_o