o
    ;ήcKJ                     @   sr   d dl Z 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m	Z	m
Z
 d dlmZ eeZG dd deZdS )    N)deque)
ModelProtoTensorProto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__ U/tmp/pip-target-vg8gfxp4/lib/python/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rD|jnd  qntd|d urU|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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: {})r0   r   MatMulr   	Transposer1   )Nr   r   r   r   r   zFailed to match qkv nodeszMatched qkv nodes)r2   r   r0   r   r1   )r   r   r   r   r   zFailed to match v path)Softmaxr   r1   r   r   r   )r   r2   r   r0   r   r1   )r   Nr   r   r   r   )r3   r0   r   r1   )r   r   r   N)r3   r0   Divr1   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.zRoot node not matched.zFused Attention count:)input_name_to_nodesr(   get_nodes_by_op_type
get_parentr   r"   r#   formatr   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   r7   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)   
mask_index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   |   }|  }g }d}d}| d}|D ]}| |d}|d ur2|jdkr2|jd |jd< |d7 }q|dkrAtd|  d S d S )Nr   r   r   zSkip consequent Reshape count: )r7   r(   r8   r9   r   r   r"   rE   )	r   r7   r(   rF   rG   countr)   reshape_noder'   r   r   r   rm      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|j
 |j}	ntd|j|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|j
dd   d}ndtd|
j|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|j
 |
j}ntd|
j|j
 dS | |d|}|d u s'|j dkr.td dS | |jd }|d u rBtd dS t|}t	|j
d
kr^td|j|j
 |j}ntd|j|j
 dS td | ||	|| dS )NLayerNormalizationz-start fusing embedding from node with output=r   z...)r0   r0   Gatherr4   zfailed to match word_embed_pathFzfailed to get word initializer   z'Found word embedding. name:{}, shape:{}z0Failed to find word embedding. name:{}, shape:{}r      position_embeddingz+Found position embedding. name:{}, shape:{}z4Failed to find position embedding. name:{}, shape:{}rr   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:{}, shape:{}z3Failed to find segment embedding. name:{}, shape:{}zCreate Embedding nodeT)r   r"   r#   r    r   get_initializerr   r   to_arraylenshaperE   r:   name
from_arrayreshapeadd_initializerr9   create_embedding_subgraph)r   noder(   word_embed_path	skip_noder@   gather_nodeword_initializertempword_embeddingpos_initializertensorru   pos_embed_path
pos_gather	pos_slicegathersegment_initializersegment_embeddingr   r   r   fuse_embedding   s   




"








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...rq   N)r"   rE   r(   nodesr   r   )r   r(   r   r   r   r   rk   I  s   

z$BertOnnxModelKeras.process_embeddingc                 C   sn  g }|   D ]}|jdkr| |dr| |g dg d}|d u r#q|\}}}}| j }|jd |krAtd|j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 {} is not mask input {}r   mask_fuse_unsqueeze1_outputMask_UnSqueeze_1r   )inputsoutputsrz   axesmask_fuse_unsqueeze2_outputMask_UnSqueeze_2rs   r   mask_fuse_cast_output)r   r   toz
Fused maskzFailed to fuse mask)r   r   r;   r   r<   get_first_maskr   printr:   onnxhelper	make_node	attributerA   make_attributerB   r@   rC   rx   prune_graphr"   rE   )r   rF   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   rl   U  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   )	r0   r   r1   r   Gelur0   r   r1   r.   )	r   r   r   r   r   r   r   r   r   rt   r8   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_reshape  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   )
r0   r   r1   r   r   r0   r   r1   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"   rE   r   )r   r   r   r   r   postprocess  s   zBertOnnxModelKeras.postprocess)__name__
__module____qualname__r
   r   r-   rj   rn   rm   r   rk   rl   r   r   r   __classcell__r   r   r   r   r      s     "R4+4r   )argparseloggingsyscollectionsr   numpynpr   r   r   r   onnx_model_bert_tfr   	getLoggerr   r"   r   r   r   r   r   <module>   s   
