o
    ٷihH                     @   sF   d dl Z d dlZd dlmZ d dlmZ e eZG dd deZdS )    N)numpy_helper)BertOnnxModelTFc                       st   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Z  ZS )BertOnnxModelKerasc                    s   t  ||| d S N)super__init__)selfmodel	num_headshidden_size	__class__ b/home/ubuntu/.local/lib/python3.10/site-packages/onnxruntime/transformers/onnx_model_bert_keras.pyr      s   zBertOnnxModelKeras.__init__c                 C   s^   |  |g dg d}|d ur|S |  |g dg d}|d ur"|S |  |g dg d}|S )N)MulSubReshapeCast)   Nr   r   )r   r   r   Slice	Unsqueeze)r   r   r   r   r   )r   r   r   r   r   )r   Nr   r   r   )match_parent_path)r   add_or_sub_before_softmax
mask_nodesr   r   r   match_mask_path   s(   z"BertOnnxModelKeras.match_mask_pathc           
      C   s   g }|||fD ]8}|j d }|| }	|	|krq|	jdkr,|	j d |jd kr,||	 qtd| d|jd   dg f  S d|fS )Nr   r   zCheck attention input failed:z, FT)inputop_typeoutputappendloggerdebug)
r   matmul_qmatmul_kmatmul_vparentoutput_name_to_nodereshape_nodesx
root_input	root_noder   r   r   check_attention_input+   s   

z(BertOnnxModelKeras.check_attention_inputc           ,      C   s  |    |  }g }d}| d}|D ]}| |d}|d u s%|jdvrZ|jdkrJ| |d}|d u s9|jdvrItd|d urC|jnd   qntd|d urT|jnd   q	 | |g dg d}|d u rptd	 q|\}}	}
}}}td
 | |g dg d}|d u rtd q|\}}}}}| |g dg d}|d ur|\}}}| |g dg d}|d ur|\}}}}}}nA| |g dg d}|d u r| |g dg d}|d u rtd q|\}}} }| |g dg d}|d ur|\}}}}}|d u rtd q| |g dg d}!|!d u r'td q|!\}"}#}$}%}&| |d }'|'d u r@td q| 	|'d dsOtd q| 
||&|||\}(})|(r| j|'d jd }*td | jj|*||&|||$|| j| j|jd |jd d}+|+d u rq| |+ |d7 }||||g || || ||! || ||' ||) ||	 | ||	jd |
jd  qtd q| | |   td|  d S ) Nr   SkipLayerNormalization)r+   EmbedLayerNormalizationAddr   zFirst input for skiplayernorm: )r-   r   MatMulr   	Transposer.   )Nr   r   r   r   r   zFailed to match qkv nodeszMatched qkv nodes)r/   r   r-   r   r.   )r   r   r   r   r   zFailed to match v path)Softmaxr   r.   r   r   r   )r   r/   r   r-   r   r.   )r   Nr   r   r   r   )r0   r-   r   r.   )r   r   r   N)r0   r-   Divr.   zFailed to match qk path)r   r   r   r   r   zFailed to match q pathzFailed to match k pathzFailed to match mask pathz;Sub node expected to have an input with constant value 1.0.zCreate an Attention node.)
mask_indexq_matmulk_matmulv_matmulq_addk_addv_addr
   r   first_inputr   zRoot node not matched.zFused Attention count:)input_name_to_nodesr%   get_nodes_by_op_type
get_parentr   r   r    r   r   has_constant_inputr*   attention_maskprocess_maskr   attention_fusioncreate_attention_noder
   r   r   add_nodeextendr   replace_node_inputremove_nodesupdate_graphinfo),r   r%   nodes_to_removeattention_countskip_layer_norm_nodesnormalize_noder$   	qkv_nodesaddextra_reshape_0matmulreshape_qkvtranspose_qkv
matmul_qkvv_nodestranspose_v	reshape_vadd_vextra_reshape_1r#   qk_nodes
softmax_qksub_qk	matmul_qkq_nodesmul_qtranspose_q	reshape_qadd_qextra_reshape_2r!   add_qkmul_qkk_nodestranspose_k	reshape_kadd_kextra_reshape_3r"   r   is_same_rootr&   r4   attention_noder   r   r   fuse_attention;   s  




























z!BertOnnxModelKeras.fuse_attentionc                 C   s   |    |   |   d S r   )process_embedding	fuse_maskskip_reshape)r   r   r   r   
preprocess   s   zBertOnnxModelKeras.preprocessc                 C   s~   |    |   d}| d}|D ]}| |d}|d ur.|jdkr.|jd |jd< |d7 }q|dkr=td|  d S d S )Nr   r   r   zSkip consequent Reshape count: )r<   r%   r=   r>   r   r   r   rI   )r   countr&   reshape_noder$   r   r   r   rp      s   
zBertOnnxModelKeras.skip_reshapec                 C   s  |j dksJ td|jd  d | |g dg d|}|d u r*td dS |\}}}| |jd }|d u rBtd	 dS t|}t	|j
d
kr_td|j d|j
  |j}	ntd|j d|j
  dS | |jd }
|
d urt|
}t	|j
dkr|j
d dkrt||j
d |j
d
 fd}| | td|
j d|j
dd    d}njtd|
j d|j
  dS | |ddgddg|}|d u rtd dS |\}}| |jd }
|
d u rtd dS t|
}t	|j
d
krtd|
j d|j
  |
j}ntd|
j d|j
  dS | |d|}|d u s3|j dkr:td dS | |jd }|d u rNtd dS t|}t	|j
d
krltd|j d|j
  |j}ntd|j d|j
  dS td | ||	|| dS )NLayerNormalizationz-start fusing embedding from node with output=r   z...)r-   r-   Gatherr1   zfailed to match word_embed_pathFzfailed to get word initializer   zFound word embedding. name:z, shape:z$Failed to find word embedding. name:r      position_embeddingzFound position embedding. name:z(Failed to find position embedding. name:ru   r   zfailed to match pos_embed_pathzfailed to get pos initializerzfailed to get gatherz!failed to get segment initializerzFound segment embedding. name:z'Failed to find segment embedding. name:zCreate Embedding nodeT)r   r   r    r   r   get_initializerr   r   to_arraylenshaperI   name
from_arrayreshapeadd_initializerr>   create_embedding_subgraph)r   noder%   word_embed_path	skip_noderD   gather_nodeword_initializertempword_embeddingpos_initializertensorrx   pos_embed_path
pos_gather	pos_slicegathersegment_initializersegment_embeddingr   r   r   fuse_embedding   sv   




"
"







z!BertOnnxModelKeras.fuse_embeddingc                 C   sF   t d |  }|  D ]}|jdkr | ||r dS  dS qdS )zM
        Automatically detect word, segment and position embeddings.
        z#start processing embedding layer...rt   N)r   rI   r%   nodesr   r   )r   r%   r   r   r   r   rn   7  s   

z$BertOnnxModelKeras.process_embeddingc                 C   sr  g }|   D ]}|jdkr| |dr| |g dg d}|d u r#q|\}}}}| j }|jd |krCtd|jd  d|  qtj	j
d|gd	gd
dgd}	tj	j
dd	gdgddgd}
tj	j
ddgdgd}|jtj	ddg | ||jd d ||||g | |	 | |
 | | q| | t|dkr|   tt|dkrd d S d d S )Nr   i)r   r   r   r   )r   r   r   r   r   zCast input z is not mask input r   mask_fuse_unsqueeze1_outputMask_UnSqueeze_1r   )inputsoutputsr}   axesmask_fuse_unsqueeze2_outputMask_UnSqueeze_2rv   r   mask_fuse_cast_output)r   r   toz
Fused maskzFailed to fuse mask)r   r   r?   r   r@   get_first_maskr   printonnxhelper	make_node	attributerE   make_attributerF   rD   rG   r{   prune_graphr   rI   )r   rJ   r   	mask_pathsub_node	cast_node
slice_nodeunsqueeze_nodemask_input_nameunsqueeze_added_1unsqueeze_added_2cast_node_2r   r   r   ro   C  sR   
	



$zBertOnnxModelKeras.fuse_maskc              
   C   s   |  d}d}|D ]H}| |g dg d}|d u rq	|\	}}}}}	}
}}}|jd |
jd< | | |	jd |jd< | | |jd |jd< | | |d7 }q	|S )Nr+   r   )	r-   r   r.   r   Gelur-   r   r.   r+   )	r   r   r   r   r   r   r   r   r   rw   r=   r   r   r   remove_node)r   skiplayernorm_nodesreshape_removedskiplayernorm_nodepathadd_1	reshape_1matmul_1	reshape_2geluadd_2	reshape_3matmul_2skiplayernormr   r   r   remove_extra_reshapew  s:   




z'BertOnnxModelKeras.remove_extra_reshapec                 C   s   |  d}d}|D ]V}| |g dg d}|d u rq	|\
}}}}}	}
}}}}|jd |jd< | | |jd |
jd< | | |	jd |jd< | | |jd |jd< | | |d7 }q	|S )Nr+   r   )
r-   r   r.   r   r   r-   r   r.   r   r+   )
Nr   r   r   r   r   r   r   r   r      r   )r   r   r   r   r   r   r   r   r   r   r   r   r   	reshape_4r   r   r   r   remove_extra_reshape_2  s@   





z)BertOnnxModelKeras.remove_extra_reshape_2c                 C   s.   |   |   }td| d |   d S )NzRemove z Reshape nodes.)r   r   r   rI   r   )r   r   r   r   r   postprocess  s   zBertOnnxModelKeras.postprocess)__name__
__module____qualname__r   r   r*   rm   rq   rp   r   rn   ro   r   r   r   __classcell__r   r   r   r   r      s     L4+4r   )	loggingr   r   onnx_model_bert_tfr   	getLoggerr   r   r   r   r   r   r   <module>   s   
