o
    g*$                     @   s   d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d d	lmZ d d
lmZm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ZdS )    N)Optional)FusionAttentionUnet)FusionBiasAdd)FusionBiasSplitGelu)FusionGroupNorm)FusionNhwcConv)FusionOptions)FusionSkipGroupNorm)FusionInsertTransposeFusionTranspose)is_installed)
ModelProto)	OnnxModel)BertOnnxModelc                       s   e Zd Zddededef fddZdd Zd	d
 Zdd Zdd Z	dd Z
ddee fddZdd Zddee fddZddee fddZdd Z  ZS ) UnetOnnxModelr   model	num_headshidden_sizec                    s>   |dkr|dks|dkr|| dksJ t  j|||d dS )aG  Initialize UNet ONNX Model.

        Args:
            model (ModelProto): the ONNX model
            num_heads (int, optional): number of attention heads. Defaults to 0 (detect the parameter automatically).
            hidden_size (int, optional): hidden dimension. Defaults to 0 (detect the parameter automatically).
        r   )r   r   N)super__init__)selfr   r   r   	__class__ _/var/www/visachat/venv/lib/python3.10/site-packages/onnxruntime/transformers/onnx_model_unet.pyr      s   (zUnetOnnxModel.__init__c                 C   s   |    d S N)remove_useless_divr   r   r   r   
preprocess&   s   zUnetOnnxModel.preprocessc                 C   s   |    |   d S r   )prune_graphremove_unused_constantr   r   r   r   postprocess)      zUnetOnnxModel.postprocessc                 C   s   dd |   D }g }|D ]}| |ddkr|| q|D ]}| |jd |jd  q|r?| | tdt	| dS dS )zRemove Div by 1c                 S   s   g | ]	}|j d kr|qS )Div)op_type).0noder   r   r   
<listcomp>/   s    z4UnetOnnxModel.remove_useless_div.<locals>.<listcomp>g      ?   r   zRemoved %d Div nodesN)
nodesfind_constant_inputappendreplace_input_of_all_nodesoutputinputremove_nodesloggerinfolen)r   	div_nodesnodes_to_removedivr&   r   r   r   r   -   s   

z UnetOnnxModel.remove_useless_divc                 C   s   t | dd}|  d S )NT)update_weight)r   apply)r   conv_to_nhwc_convr   r   r   convert_conv_to_nhwc=   s   z"UnetOnnxModel.convert_conv_to_nhwcc                 C   s   t | }|  d}| d}|D ]I}t|d}t|ts J |ttt|kr+q| 	|j
d sC| |jd sC| 	|jd rEJ | |j
d |jd  | | |d7 }qt|j| }|rltd| d S d S )Nr   	Transposepermr(   zRemoved %d Transpose nodes)r   r7   get_nodes_by_op_typer   get_node_attribute
isinstancelistranger2   find_graph_outputr-   find_graph_inputr.   r,   remove_noder4   r0   r1   )r   fusion_transposeremove_countr)   r&   permutationtotalr   r   r   merge_adjacent_transposeB   s,   


z&UnetOnnxModel.merge_adjacent_transposeNoptionsc                 C   s`   |d u p|j }t| | j| jd|dd}|  |d u p|j}t| | j| jdd|d}|  d S )NF)is_cross_attentionenable_packed_qkvenable_packed_kvT)rK   r   r   r   r7   rL   )r   rI   rK   self_attention_fusionrL   cross_attention_fusionr   r   r   fuse_multi_head_attention^   s(   z'UnetOnnxModel.fuse_multi_head_attentionc                 C   s   t | }|  d S r   )r   r7   )r   fusionr   r   r   fuse_bias_addw   r"   zUnetOnnxModel.fuse_bias_addc                 C   s   t dr6dd l}ddlm} |  d}|jt|ddd}| || W d    d S 1 s/w   Y  d S td | |d  d S )Ntqdmr   )logging_redirect_tqdm   rP   )initialdescz<tqdm is not installed. Run optimization without progress bar)r   rR   tqdm.contrib.loggingrS   r@   	_optimizer0   r1   )r   rI   rR   rS   stepsprogress_barr   r   r   optimize{   s   "
zUnetOnnxModel.optimizec                 C   s  |d ur|j s|   | j  |r|d | j  |r#|d |d u s*|jr.|   |r5|d |d u s<|jr@| 	  |rG|d | 
  |rR|d |   |r]|d |d u sd|jr||d u pj|j}t| |}|  t| }|  |r|d |d u s|jrt| }|  |r|d |d u s|jr| | |r|d |d u s|jr|   |r|d |   |r|d | j  |r|d |d u s|jrt| }|  |r|d |d u s|jr|   |r|d |d ur
|jr
|   |r|d |d u s|jr#|    | !  |r+|d |d ur8|j"r8| #  |r@|d | $  |rL|d t%&d| '   d S )Nr(   zopset version: )(enable_shape_inferencedisable_shape_inferenceutilsremove_identity_nodesupdateremove_useless_cast_nodesenable_layer_normfuse_layer_normenable_gelu	fuse_gelur   fuse_reshapeenable_group_normgroup_norm_channels_lastr   r7   r
   enable_bias_splitgelur   enable_attentionrO   enable_skip_layer_normfuse_skip_layer_norm
fuse_shaperemove_useless_reshape_nodesenable_skip_group_normr	   enable_bias_skip_layer_normfuse_add_bias_skip_layer_normenable_gelu_approximationgelu_approximationenable_nhwc_convr9   rH   enable_bias_addrQ   r!   r0   r1   get_opset_version)r   rI   rZ   channels_lastgroup_norm_fusioninsert_transpose_fusionbias_split_gelu_fusionskip_group_norm_fusionr   r   r   rX      s   






















zUnetOnnxModel._optimizec                 C   s@   i }g d}|D ]}|  |}t|||< qtd|  |S )z8
        Returns node count of fused operators.
        )		AttentionMultiHeadAttentionLayerNormalizationSkipLayerNormalizationBiasSplitGelu	GroupNormSkipGroupNormNhwcConvBiasAddzOptimized operators:)r<   r2   r0   r1   )r   op_countopsopr)   r   r   r   get_fused_operator_statistics   s   
z+UnetOnnxModel.get_fused_operator_statistics)r   r   r   )NN)__name__
__module____qualname__r   intr   r   r!   r   r9   rH   r   r   rO   rQ   r[   rX   r   __classcell__r   r   r   r   r      s    er   ) loggingtypingr   fusion_attention_unetr   fusion_bias_addr   fusion_biassplitgelur   fusion_group_normr   fusion_nhwc_convr   fusion_optionsr   fusion_skip_group_normr	   rD   r
   r   import_utilsr   onnxr   
onnx_modelr   onnx_model_bertr   	getLoggerr   r0   r   r   r   r   r   <module>   s    
