U
    T?h!H  ã                   @   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__© ú`/var/www/html/venv/lib/python3.8/site-packages/onnxruntime/transformers/onnx_model_bert_keras.pyr      s    zBertOnnxModelKeras.__init__c              	   C   s~   |   |ddddgdd ddg¡}|d k	r*|S |   |dddddgdddddg¡}|d k	rX|S |   |dddddgdd dddg¡}|S )	NÚMulÚSubÚReshapeÚCasté   r   ÚSliceÚ	Unsqueeze)Úmatch_parent_path)r   Zadd_or_sub_before_softmaxÚ
mask_nodesr   r   r   Úmatch_mask_path   s(    

ýýýz"BertOnnxModelKeras.match_mask_pathc           
      C   sˆ   g }|||fD ]p}|j d }|| }	|	|kr.q|	jdkrX|	j d |jd krX| |	¡ 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ÚxZ
root_inputZ	root_noder   r   r   Úcheck_attention_input+   s    

z(BertOnnxModelKeras.check_attention_inputc           ,      C   s2  |   ¡  |  ¡ }g }d}|  d¡}|D ]â}|  |d¡}|d ksJ|jdkr¶|jdkr”|  |d¡}|d ksr|jdkr´t d|d k	r†|jnd › ¡ q&q¶t d|d k	r¨|jnd › ¡ q&n |  |ddddd	dgd dddddg¡}|d krðt d
¡ q&|\}}	}
}}}t d¡ |  |d	ddddgdddddg¡}|d krBt d¡ q&|\}}}}}|  |dddgdddg¡}|d k	rÀ|\}}}|  |dd	ddddgdd ddddg¡}|d k	rb|\}}}}}}n¢|  |ddddgdddd g¡}|d kr|  |ddddgdddd g¡}|d krt d¡ q&|\}}} }|  |d	ddddgdddddg¡}|d k	rb|\}}}}}|d krxt d¡ q&|  |d	ddddgdddddg¡}!|!d kr°t d¡ q&|!\}"}#}$}%}&|  |d ¡}'|'d krât d¡ q&|  	|'d d¡s t d¡ q&|  
||&|||¡\}(})|(rþ| j |'d jd ¡}*t d¡ | j |*||&|||$|| j| j|jd |jd d ¡}+|+d krzq&|  |+¡ |d7 }| |||g¡ | |¡ | |¡ | |!¡ | |¡ | |'¡ | |)¡ | |	¡ |  ||	jd |
jd ¡ q&t d¡ q&q&|  |¡ |  ¡  t d|› ¡ d S )Nr   ÚSkipLayerNormalization)r(   ZEmbedLayerNormalizationÚAddr   zFirst input for skiplayernorm: r   ÚMatMulZ	TransposezFailed to match qkv nodeszMatched qkv nodeszFailed to match v pathZSoftmaxr   r   ÚDivzFailed to match qk pathz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.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_maskZprocess_maskr   Zattention_fusionZcreate_attention_noder
   r   r   Úadd_nodeÚextendr   Úreplace_node_inputÚremove_nodesZupdate_graphÚinfo),r   r$   Únodes_to_removeZattention_countZskip_layer_norm_nodesZnormalize_noder#   Z	qkv_nodesÚaddZextra_reshape_0ÚmatmulZreshape_qkvZtranspose_qkvZ
matmul_qkvZv_nodesZtranspose_vZ	reshape_vZadd_vZextra_reshape_1r"   Zqk_nodesZ
softmax_qkZsub_qkZ	matmul_qkZq_nodesZmul_qZtranspose_qZ	reshape_qZadd_qZextra_reshape_2r    Zadd_qkZmul_qkZk_nodesZtranspose_kZ	reshape_kZadd_kZextra_reshape_3r!   r   Zis_same_rootr%   Z
mask_indexZ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   sz   |   ¡  |  ¡  d}|  d¡}|D ]:}|  |d¡}|d k	r"|jdkr"|jd |jd< |d7 }q"|dkrvt d|› ¡ d S )Nr   r   r   zSkip consequent Reshape count: )r-   r$   r.   r/   r   r   r   r6   )r   Úcountr%   Zreshape_noder#   r   r   r   r=   Ý   s    

zBertOnnxModelKeras.skip_reshapec                 C   s$  |j dkst‚t d|jd › d¡ |  |dddgdddg|¡}|d krXt d¡ dS |\}}}|  |jd ¡}|d krˆt 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 k	r˜t 	|
¡}t
|jƒdkrx|jd dkrxt | |jd |jd
 f¡d¡}|  |¡ t d|
j› d|jdd … › ¡ d}nt d|
j› d|j› ¡ dS nº|  |ddgddg|¡}|d krÈt d¡ dS |\}}|  |jd ¡}
|
d krøt d¡ dS t 	|
¡}t
|jƒd
kr4t d|
j› d|j› ¡ |
j}nt d|
j› d|j› ¡ dS |  |d|¡}|d ksv|j dkr„t d¡ dS |  |jd ¡}|d kr¬t d¡ dS t 	|¡}t
|jƒd
krèt 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)   ZGatherz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: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   ÚAssertionErrorr   r   r   r   Zget_initializerr   r   Zto_arrayÚlenÚshaper6   ÚnameZ
from_arrayZreshapeZadd_initializerr/   Zcreate_embedding_subgraph)r   Únoder$   Zword_embed_pathZ	skip_noder2   Zgather_nodeZword_initializerÚtempZword_embeddingZpos_initializerZtensorrC   Zpos_embed_pathZ
pos_gatherZ	pos_sliceZgatherZsegment_initializerZsegment_embeddingr   r   r   Úfuse_embeddingì   sv    





 "
"









z!BertOnnxModelKeras.fuse_embeddingc                 C   sD   t  d¡ |  ¡ }|  ¡ D ]$}|jdkr|  ||¡r: dS  q@qdS )zM
        Automatically detect word, segment and position embeddings.
        z#start processing embedding layer...r@   N)r   r6   r$   Únodesr   rJ   )r   r$   rH   r   r   r   r;   8  s    

z$BertOnnxModelKeras.process_embeddingc              	   C   sz  g }|   ¡ D ]*}|jdkr|  |d¡r|  |ddddgddddg¡}|d krPq|\}}}}| j ¡ }|jd |krt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rZ|  ¡  t t|ƒdkrpdnd¡ d S )Nr   iðØÿÿr   r   r   r   r   r   zCast input z is not mask input Zmask_fuse_unsqueeze1_outputZMask_UnSqueeze_1)ÚinputsÚoutputsrG   ZaxesZmask_fuse_unsqueeze2_outputZMask_UnSqueeze_2rA   Zmask_fuse_cast_output)rL   rM   Útoz
Fused maskzFailed to fuse mask)rK   r   r0   r   r1   Zget_first_maskr   ÚprintÚonnxÚhelperZ	make_nodeÚ	attributer3   Zmake_attributer4   r2   r5   rE   Úprune_graphr   r6   )r   r7   rH   Z	mask_pathZsub_nodeZ	cast_nodeZ
slice_nodeZunsqueeze_nodeZmask_input_nameZunsqueeze_added_1Zunsqueeze_added_2Zcast_node_2r   r   r   r<   D  sP    
ûû	ý


zBertOnnxModelKeras.fuse_maskc                 C   sÄ   |   d¡}d}|D ]¬}|  |dddddddddg	dddddddddg	¡}|d krRq|\	}}}}}	}
}}}|jd |
jd< |  |¡ |	jd |jd< |  |¡ |jd |jd< |  |¡ |d7 }q|S )Nr(   r   r)   r   r*   ÚGelurB   ©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_reshapex  sL    
÷óö



z'BertOnnxModelKeras.remove_extra_reshapec                 C   sä   |   d¡}d}|D ]Ì}|  |ddddddddddg
d dddddddddg
¡}|d krVq|\
}}}}}	}
}}}}|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*   rT   é   rU   )r   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   Z	reshape_4rc   r   r   r   Úremove_extra_reshape_2£  sT    
öòõ




z)BertOnnxModelKeras.remove_extra_reshape_2c                 C   s.   |   ¡ |  ¡  }t d|› d¡ |  ¡  d S )NzRemove z Reshape nodes.)rd   rf   r   r6   rS   )r   rX   r   r   r   Úpostprocess×  s    zBertOnnxModelKeras.postprocess)Ú__name__Ú
__module__Ú__qualname__r   r   r'   r:   r>   r=   rJ   r;   r<   rd   rf   rg   Ú__classcell__r   r   r   r   r      s    L4+4r   )	ÚloggingrP   r   Zonnx_model_bert_tfr   Ú	getLoggerrh   r   r   r   r   r   r   Ú<module>   s
   
