
    `i8H                         S SK rS SKJr  S SKJr  S SKJrJr  S SK	J
r
JrJrJr  S SKJr  S SKJr  S SKJr  \" \5      r " S	 S
5      r " S S5      r " S S\5      rg)    N)	getLogger)Enum)TupleUnion)helpernumpy_helperTensorProto	NodeProto)	OnnxModel)Fusion)FusionUtilsc                   $    \ rS rSrSrSrSrSrSrg)AttentionMaskFormat   r             N)	__name__
__module____qualname____firstlineno__MaskIndexEndMaskIndexEndAndStartAttentionMaskNoMask__static_attributes__r       n/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/onnxruntime_tools/transformers/fusion_attention.pyr   r      s    LMFr   r   c                   R    \ rS rSrSrS\4S jrS\4S jrS r	S r
S	\S
\4S jrSrg)r      2
Fuse Attention subgraph into one Attention node.
modelc                 v    Xl         0 U l        0 U l        [        U5      U l        [
        R                  U l        g N)r#   mask_indicemask_castedr   utilsr   r   mask_format)selfr#   s     r   __init__AttentionMask.__init__   s1    
 '
.;;r   r)   c                     Xl         g r%   )r)   )r*   r)   s     r   set_mask_formatAttentionMask.set_mask_format%   s    &r   c                 f    XR                   ;   a  X R                   U   :X  d   eX R                   U'   g r%   )r&   )r*   mask
mask_indexs      r   set_mask_indiceAttentionMask.set_mask_indice(   s3    ###!1!1$!7777!+r   c                 t    [        U R                  5      S:  d   e[        [        U R                  5      5      $ )Nr   )lenr&   nextiter)r*   s    r   get_first_maskAttentionMask.get_first_mask-   s1    4##$q(((D))*++r   inputreturnc           	      >   U R                   [        R                  :X  a  g XR                  ;   a  U R                  U   $ U R                  R                  U5      (       a  U R                  R                  U5      u  p#OU R                  R                  U5      u  p4SnU(       a  X0R                  U'   U R                   [        R                  :X  a  X0R                  U'   U$ U R                  R                  S5      n[        R                  " SU/U/U R                  R                  SS5      S9nUR                  R                  [        R                   " SS/5      [        R                   " SS	5      /5        U R                  R#                  U5        XPR                  U'   U$ )
NTr2   	ReduceSumMaskReduceSuminputsoutputsnameaxesr   keepdimsr   )r)   r   r   r&   r#   find_graph_inputr(   cast_graph_input_to_int32cast_input_to_int32r'   r   create_node_namer   	make_node	attributeextendmake_attributeadd_node)r*   r;   casted
input_name	cast_nodeoutput_namemask_index_nodes          r   process_maskAttentionMask.process_mask1   sf   2999$$$##E** ::&&u--!%!E!Ee!LFJ$(JJ$B$B5$I!JF&0U# 2@@@&0U# jj11,? **;3=,4?=04

0K0KKYh0ik 	!!((&*?*?*LfNcNcdnpqNr)st

O,"-r   )r'   r)   r&   r#   r(   N)r   r   r   r   __doc__r   r+   r   r.   r3   r9   strrT   r   r   r   r   r   r      s=    <i <'+> ',
, #  #  r   r   c                      ^  \ rS rSrSrS\S\S\S\4U 4S jjrS\	S	\
\\4   4S
 jrS\S\	S\	S\	S\	S\	S\	S\S\S\S\S	\\	S4   4S jrS rSrU =r$ )FusionAttentionT   r"   r#   hidden_size	num_headsattention_maskc                 P   > [         TU ]  USSS/5        X l        X0l        X@l        g )N	AttentionSkipLayerNormalizationLayerNormalization)superr+   r[   r\   r]   )r*   r#   r[   r\   r]   	__class__s        r   r+   FusionAttention.__init__X   s,    .FH\-]^&",r   	reshape_qr<   c                    U R                   R                  UR                  S   5      nUc=  [        R	                  UR                  S    S35        U R
                  U R                  4$ [        R                  " U5      n[        U5      S:w  d  US   S::  d	  US   S::  a1  [        R	                  SU S35        U R
                  U R                  4$ US   nUS   nXE-  nU R
                  S:  a$  X@R
                  :w  a  [        R                  S	5        U R                  S:  a$  X`R                  :w  a  [        R                  S
5        XF4$ )zDetect num_heads and hidden_size from a reshape node.

Args:
    reshape_q (NodeProto): reshape node for Q

Returns:
    Tuple[int, int]: num_heads and hidden_size
r   z is not initializer.   r   r   r   zq_shape_value=z7. Expected value are like [0, 0, num_heads, head_size].zU--num_heads is {self.num_heads}. Detected value is {num_heads}. Using detected value.z[--hidden_size is {self.hidden_size}. Detected value is {hidden_size}. Using detected value.)r#   get_initializerr;   loggerdebugr\   r[   r   to_arrayr6   warn)r*   re   q_shapeq_shape_valuer\   	head_sizer[   s          r   get_num_heads_and_hidden_size-FusionAttention.get_num_heads_and_hidden_size^   s'    **,,Y__Q-?@?LLIOOA.//CDE>>4#3#333$--g6}"}Q'71'<a@PTU@ULL>-8opq>>4#3#333!!$	!!$	+>>A)~~"=KKopaK3C3C$CKKuv%%r   r2   q_matmulk_matmulv_matmulq_addk_addv_addr;   outputNc                 
   US:  d  U	S:  d
  X-  S:X  d   eU R                   R                  UR                  S   5      nU R                   R                  UR                  S   5      nU R                   R                  UR                  S   5      nU R                   R                  UR                  S   5      nU R                   R                  UR                  S   5      nU R                   R                  UR                  S   5      nUc  [        UR                  S    S35        gU(       a  U(       a  U(       a  U(       d  g[        R
                  " U5      n[        R
                  " U5      n[        R
                  " U5      nUR                  UR                  s=:X  a  UR                  :X  d   e   eUR                  S   n[        R                  " UR                  SS 5      n[        R                  " UUU4SS9n[        R
                  " U5      n[        R
                  " U5      n[        R
                  " U5      nUR                  UR                  s=:X  a  UR                  :X  d   e   e[        R                  " UR                  5      U:X  d   eUU	:w  a  [        R                  SUU4 SU	 35        g[        R                  " UUU4SS9nU R                   R                  S5      n[        R                  " US	-   [        R                   US
U-  /UR#                  5       R%                  5       S9nUR&                  S:X  aa  UR)                  [        R*                  " [        R
                  " U5      R-                  [        R.                  5      UR0                  5      5        U R                   R3                  U5        [        R                  " US-   [        R                   S
U-  /UR#                  5       R%                  5       S9nUR&                  S:X  aa  UR)                  [        R*                  " [        R
                  " U5      R-                  [        R.                  5      UR0                  5      5        U R                   R3                  U5        U
US	-   US-   /nUb  UR5                  U5        [        R6                  " SUU/US9n SU l        U R:                  R=                  [        R>                  " SU5      /5        U $ )a  Create an Attention node.

Args:
    mask_index (str): mask input
    q_matmul (NodeProto): MatMul node in fully connection for Q
    k_matmul (NodeProto): MatMul node in fully connection for  K
    v_matmul (NodeProto): MatMul node in fully connection for  V
    q_add (NodeProto): Add bias node in fully connection for Q
    k_add (NodeProto): Add bias node in fully connection for K
    v_add (NodeProto): Add bias node in fully connection for V
    num_heads (int): number of attention heads. If a model is pruned, it is the number of heads after pruning.
    hidden_size (int): hidden dimension. If a model is pruned, it is the hidden dimension after pruning.
    input (str): input name
    output (str): output name

Returns:
    Union[NodeProto, None]: the node created or None if failed.
r   r   NzM is not initializer. Please set do_constant_folding=True in torch.onnx.export)axiszShape for weights of Q is z#, which does not match hidden_size=r_   _qkv_weightr   )rC   	data_typedimsvals
   	_qkv_biasr@   zcom.microsoftr\   ) r#   rh   r;   printr   rk   shapenpprodstackri   rj   rI   r   make_tensorr	   FLOATflattentolistr|   CopyFrom
from_arrayastypefloat16rC   add_initializerappendrJ   domainrK   rL   rM   )!r*   r2   rr   rs   rt   ru   rv   rw   r\   r[   r;   rx   q_weightk_weightv_weightq_biask_biasv_biasqwkwvwin_sizeout_size
qkv_weightqbkbvbqkv_biasattention_node_nameweightbiasattention_inputsattention_nodes!                                    r   create_attention_node%FusionAttention.create_attention_node   s   * 1}aK4KPQ3QQQ::--hnnQ.?@::--hnnQ.?@::--hnnQ.?@++EKKN;++EKKN;++EKKN;X^^A&''tuvX&V""8,""8,""8, xx288/rxx///// ((1+77288AB<(XXr2rl3
""6*""6*""6* xx288/rxx/////wwrxx H,,,{"LL,Wh->,??bcnbopr88RRLq1"jj99+F##)<})L.9.?.?*11x<)@)3););)=)D)D)FH #OOL33L4I4I&4Q4X4XY[YcYc4dflfqfqrs

""6*!!':['H,7,=,=()H~'/'7'7'9'@'@'BD r!MM,11,2G2G2M2T2TUWU_U_2`bfbkbklm

""4(!#6#FH[^iHij!##J/))+1A39(/BD !0  '')>)>{I)V(WXr   c                    UnUR                   S:X  a$  U R                  R                  USS5      nUb  UnOg U R                  R                  U/ SQ/ SQ5      nS nUb  Uu  ppn	O+U R                  R                  U/ SQ/ SQ5      nUb  Uu  ppOg / n[	        UR
                  5       H4  u  pX;  a  M  XS   R                  S   :X  a  M#  UR                  U5        M6     [        U5      S:w  a  g US   n U R                  R                  US	S5      nUbm  UUR                  S      nUb5  [        U5      S
:X  a&  US   nUR                   S:X  a  UR                  S   nO$g Ub  [        U5      S:X  a  UR                  S   nOg X/   nU Vs/ s H  nUR                   PM     nnUR                  S5      S:w  a  g U R                  R                  U	/ SQ/ SQ5      nUc  [        R                  S5        g Uu    nnnSnU R                  R                  U	/ SQ/ SQ5      nUc`  U R                  R                  U	/ SQ/ SQ5      nUc<  U R                  R                  U	/ SQ/ SQ5      nSnUc  [        R                  S5        g S nS nS nU(       a  Uu  nnnnOUu  nnnnU R                  R                  U/ SQ/ SQ5      nUc:  U R                  R                  U/ SQ/ SQ5      nUc  [        R                  S5        g US   nUS   n US   n!U R                  R                  U/ SQ/ SQ5      n"U"c:  U R                  R                  U/ SQ/ SQ5      n"U"c  [        R                  S 5        g U"S   n#U"S   n$S n%U(       a0  U R                  R                  U/ S!Q/ S"Q4/ S#Q/ SQ4/U5      u  nn%nO/U R                  R                  U/ S$Q/ S%Q4/ S&Q/ S'Q4/U5      u  nn%nU%c  [        R                  S(5        g UR
                  S   U:X  Ga_  U!R
                  S   U:X  GaJ  UR
                  S   U:X  Ga5  U R                  R                  U%S   R
                  S   5      n&Uc  W
OUn'U R                  U5      u  n(n)U(S::  d  U)S::  d	  U)U(-  S:w  a  [        R                  S)5        g U R!                  U&U!U$UU U#UU(U)UU'R                  S   5      n*U*c  g U R"                  R                  U*5        Ub  UR
                  S   n+S*U+-   n,[$        R&                  " S+U+-   [(        R*                  S,/[,        R.                  " SSU([1        U)U(-  5      /5      R3                  5       SS-9n-U R                  R5                  U-5        U R                  R7                  [$        R8                  " S.U'R                  S   U-R:                  /U,/S/U+-   5      5        U,UR
                  S'   U R<                  R?                  U'X/5        U R<                  R?                  U5        U R<                  R?                  U5        U R<                  R?                  U"5        U R<                  R?                  U5        SU l         g g g g s  snf )0Nra   Addr   )r   MatMulReshape	Transposer   )Nr   r   r   r   )r   Einsumr   r   )r   r   r   r   r   Mulr      r   r   )r   r   r   r   z&fuse_attention: failed to match v pathF)Softmaxr   Divr   )r   r   r   r   )r   r   r   r   )r   Wherer   r   )r   r   r   r   Tz'fuse_attention: failed to match qk path)r   r   r   r   r   )r   r   r   r   r   z&fuse_attention: failed to match q path)r   r   r   r   r   )r   r   r   r   r   z&fuse_attention: failed to match k path)Expandr   Equal)r   r   r   )Castr   r   r   )r   Subr   	Unsqueezer   )r   r   r   r   r   )r   r   r   r   )r   r   r   r   z)fuse_attention: failed to match mask pathz9fuse_attention: failed to detect num_heads or hidden_sizeedge_modified_shape_modified_tensorrg   )rC   r|   r}   r~   rawr   reshape_modified_)!op_typer#   match_parentmatch_parent_path	enumerater;   rx   r   r6   countri   rj   match_parent_pathsr]   rT   rp   r   nodes_to_addr   r   r	   INT64r   int64inttobytesr   rN   rJ   rC   nodes_to_removerL   prune_graph).r*   normalize_nodeinput_name_to_nodesoutput_name_to_node
start_nodeadd_before_layernorm	qkv_nodeseinsum_node_
matmul_qkvreshape_qkvtranspose_qkvother_inputsir;   
root_inputmul_before_layernormmul_childrenlayernorm_nodechildrenchildchildren_typesv_nodesadd_vmatmul_v
is_distillqk_nodesadd_qk	matmul_qkwhere_qkq_nodesre   add_qmatmul_qk_nodesadd_kmatmul_k
mask_nodesr2   attention_last_noder\   r[   new_nodeunique_indexnew_edgeshape_tensors.                                                 r   fuseFusionAttention.fuse   s    $
!!%99#'::#:#:>5RS#T #/1
 JJ00=p1CE	 FOCQK
 

44ZAikwxI$>G;
!*"2"23HA/!++A..& 4 |!!!_
	  $zz66z5!L+./C/J/J1/MNL'C,=,B!-a!))-AA!/!6!6q!9J)c,.?1.D188;
&25=>XE%--X>)Q.**..z;dfrs?LLAB")Auh
:://
<_amnzz33J@ceqrH::77
Dikwx!
#LL!JK	*2'Q)Q(0%Q9**..y:ceqr?jj229>n3BDGEFBK	2;**..y:ceqr?jj229>t3BDGEF2; 
#zz<<X?]_h>i?egs>t>v=P RAz1
  $zz<<JO\BLQSTg iAz1 LLDE>>!
*x~~a/@J/NS[SaSabcSdhrSr,,99*R.:N:Nq:QRJ1<1D+-%)%G%G	%R"I{A~!1kI6MRS5SXY11*hRZ\achjo2;[*ViVpVpqrVsuH$$X.&*003+l:%117NQ]7]<G<M<M89s79xxAyAD[S\E\A]A_ 8``g`g`i6: < 

**<8

##$$Y1D1K1KA1NP\PaPa0bemdn%8<%GIJ (0!!!$  '')<m(XY  ''1  ''0  ''0  ''0  $DQ Ts/N*C ?s   	Y$)r]   r[   r\   r   )r   r   r   r   rV   r   r   r   r+   r
   r   rp   rW   r   r   r   r   __classcell__)rc   s   @r   rY   rY   T   s    -i -c -c -[h -&y &U3PS8_ &B^ ^y ^T] ^ir ^%.^7@^IR^_b^qt^%(^25^:?	4:P^@e$ e$r   rY   )numpyr   loggingr   enumr   typingr   r   onnxr   r   r	   r
   
onnx_modelr   fusion_baser   fusion_utilsr   r   ri   r   r   rY   r   r   r   <module>r      sO   
     = =    $	8	 9 9xp$f p$r   