Ë
    �…j&Q  ã                   óv   — d dl mZ d dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZ d dlmZ  ee«      Z G d„ de«      Zy)	é    )Ú	getLoggerN)ÚFusion)ÚNumpyHelper)Ú	NodeProtoÚhelperÚnumpy_helper)Ú	OnnxModelc                   óî   ‡ — e Zd ZdZdededefˆ fd„Zdedefd„Zd	edefd
„Z	d„ Z
	 ddedededeeef   fd„Zdededededededededededz  fd„Zd„ Zd„ Zdefd„Zd d„Zdededededef
d„Zˆ xZS )!ÚFusionMultiHeadAttentionSam2zI
    Fuse MultiHeadAttention subgraph of Segment Anything v2 (SAM2).
    ÚmodelÚhidden_sizeÚ	num_headsc                 ób   •— t         ‰| �  |ddg«       || _        || _        d| _        d| _        y )NÚMultiHeadAttentionÚLayerNormalizationT)ÚsuperÚ__init__r   r   Únum_heads_warningÚhidden_size_warning)Úselfr   r   r   Ú	__class__s       €úo/root/aria/tools/markitdown-venv/lib/python3.12/site-packages/onnxruntime/transformers/fusion_attention_sam2.pyr   z%FusionMultiHeadAttentionSam2.__init__   s<   ø€ ô 	‰Ñ˜Ð 4Ð7KÐ6LÔMØ&ˆÔØ"ˆŒð "&ˆÔØ#'ˆÕ ó    Ú	reshape_qÚreturnc                 ó  — d}| j                   j                  |j                  d   «      }|�At        |t        j
                  «      r't        |j                  «      dgk(  rt        |d   «      }t        |t        «      r|dkD  r|S y)ú²Detect num_heads from a reshape node.

        Args:
            reshape_q (NodeProto): reshape node for Q
        Returns:
            int: num_heads, or 0 if not found
        r   é   é   é   )	r   Úget_constant_valueÚinputÚ
isinstanceÚnpÚndarrayÚlistÚshapeÚint)r   r   r   Úshape_values       r   Úget_decoder_num_headsz2FusionMultiHeadAttentionSam2.get_decoder_num_heads#   sy   € ð ˆ	ð —j‘j×3Ñ3°I·O±OÀAÑ4FÓGˆØÐ"Ü˜+¤r§z¡zÔ2´t¸K×<MÑ<MÓ7NÐSTÐRUÒ7UÜ ¨A¡Ó/�	ä�i¤Ô%¨)°aª-ØÐàr   Ú
reshape_inc                 óR  — d}| j                   j                  |j                  d   «      }|�Bt        |t        j
                  «      rÊt        |j                  «      dgk(  r±t        |d   «      }n¢| j                   j                  |dd«      }|�ƒt        |j                  «      dk(  rk| j                   j                  |j                  d   «      }|�At        |t        j
                  «      r't        |j                  «      dgk(  rt        |d   «      }t        |t        «      r|dkD  r|S y)r   r   r   é   é   ÚConcat)r   r!   r"   r#   r$   r%   r&   r'   r(   Úmatch_parentÚlen)r   r+   r   r)   Úconcat_shapes        r   Úget_encoder_num_headsz2FusionMultiHeadAttentionSam2.get_encoder_num_heads8   s   € ð ˆ	à—j‘j×3Ñ3°J×4DÑ4DÀQÑ4GÓHˆØÐ"Ü˜+¤r§z¡zÔ2´t¸K×<MÑ<MÓ7NÐSTÐRUÒ7UÜ ¨A¡Ó/‘	àŸ:™:×2Ñ2°:¸xÈÓKˆLØÐ'¬C°×0BÑ0BÓ,CÀqÒ,Hà"Ÿj™j×;Ñ;¸L×<NÑ<NÈqÑ<QÓR�ØÐ*Ü! +¬r¯z©zÔ:¼tÀK×DUÑDUÓ?VÐ[\ÐZ]Ò?]Ü$'¨°A©Ó$7˜	ä�i¤Ô%¨)°aª-ØÐàr   c                 óœ   — | j                   j                  |j                  d   «      }|r"t        j                  |«      j
                  d   S y)zÚDetect hidden_size from LayerNormalization node.
        Args:
            layernorm_node (NodeProto): LayerNormalization node before Q, K and V
        Returns:
            int: hidden_size, or 0 if not found
        r    r   )r   Úget_initializerr"   r   Úto_arrayr'   )r   Úlayernorm_nodeÚlayernorm_biass      r   Úget_hidden_sizez,FusionMultiHeadAttentionSam2.get_hidden_sizeT   sE   € ð Ÿ™×3Ñ3°N×4HÑ4HÈÑ4KÓLˆÙÜ×'Ñ'¨Ó7×=Ñ=¸aÑ@Ð@àr   r7   Ú
is_encoderc                 ó  — |r| j                  |«      }n| j                  |«      }|dk  r| j                  }| j                  dkD  rH|| j                  k7  r9| j                  r-t        j                  d| j                  › d|› d�«       d| _        | j                  |«      }|dk  r| j                  }| j                  dkD  rH|| j                  k7  r9| j                  r-t        j                  d| j                  › d|› d�«       d| _        ||fS )a  Detect num_heads and hidden_size.

        Args:
            reshape_q (NodeProto): reshape node for Q
            layernorm_node (NodeProto): LayerNormalization node before Q, K, V
        Returns:
            Tuple[int, int]: num_heads and hidden_size
        r   z--num_heads is z. Detected value is z. Using detected value.Fz--hidden_size is )	r3   r*   r   r   ÚloggerÚwarningr9   r   r   )r   r   r7   r:   r   r   s         r   Úget_num_heads_and_hidden_sizez:FusionMultiHeadAttentionSam2.get_num_heads_and_hidden_sizea   s  € ñ Ø×2Ñ2°9Ó=‰Ià×2Ñ2°9Ó=ˆIØ˜Š>ØŸ™ˆIà�>‰>˜AÒ )¨t¯~©~Ò"=Ø×%Ò%Ü—‘ °·±Ð0@Ð@TÐU^ÐT_Ð_vÐwÔxØ).�Ô&à×*Ñ*¨>Ó:ˆØ˜!ÒØ×*Ñ*ˆKà×Ñ˜aÒ K°4×3CÑ3CÒ$CØ×'Ò'Ü—‘Ø'¨×(8Ñ(8Ð'9Ð9MÈkÈ]ÐZqÐrôð ,1�Ô(à˜+Ð%Ð%r   Úq_matmulÚq_addÚk_matmulÚk_addÚv_matmulÚv_addÚoutputNc
           
      óÆ  — |dkD  r$||z  dk7  rt         j                  d|› d|› �«       y| j                  j                  |j                  d   «      }
| j                  j                  |j                  d   «      }| j                  j                  |j                  d   «      }|
r|r|syt        j                  |
«      }t        j                  |«      }t        j                  |«      }t         j                  d|j                  › d|j                  › d|j                  › d	|› �«       | j                  j                  d
«      }|j                  d   |j                  d   |j                  d   g}t        j                  d
||	g|¬«      }d|_        |j                  j                  t        j                  d|«      g«       dj!                  d«      }| j#                  |«       |S )aF  Create an Attention node.

        Args:
            q_matmul (NodeProto): MatMul node in fully connection for Q
            q_add (NodeProto): Add bias node in fully connection for Q
            k_matmul (NodeProto): MatMul node in fully connection for K
            k_add (NodeProto): Add bias node in fully connection for K
            v_matmul (NodeProto): MatMul node in fully connection for V
            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.
            output (str): output name

        Returns:
            Union[NodeProto, None]: the node created or None if failed.
        r   zinput hidden size z# is not a multiple of num of heads Nr   zqw=z kw=z vw=z hidden_size=r   ©ÚinputsÚoutputsÚnameúcom.microsoftr   úMultiHeadAttention ({})zcross attention)r<   Údebugr   r5   r"   r   r6   r'   Úcreate_node_namerE   r   Ú	make_nodeÚdomainÚ	attributeÚextendÚmake_attributeÚformatÚincrease_counter)r   r?   r@   rA   rB   rC   rD   r   r   rE   Úq_weightÚk_weightÚv_weightÚqwÚkwÚvwÚattention_node_nameÚattention_inputsÚattention_nodeÚcounter_names                       r   Úcreate_attention_nodez2FusionMultiHeadAttentionSam2.create_attention_node…   s­  € ð8 ˜Š? ¨iÑ 7¸AÒ=Ü�L‰LÐ-¨k¨]Ð:]Ð^gÐ]hÐiÔjØà—:‘:×-Ñ-¨h¯n©n¸QÑ.?Ó@ˆØ—:‘:×-Ñ-¨h¯n©n¸QÑ.?Ó@ˆØ—:‘:×-Ñ-¨h¯n©n¸QÑ.?Ó@ˆÙ™X©(Øä×!Ñ! (Ó+ˆÜ×!Ñ! (Ó+ˆÜ×!Ñ! (Ó+ˆÜ�‰�s˜2Ÿ8™8˜* D¨¯©¨
°$°r·x±x°jÀÈkÈ]Ð[Ô\à"Ÿj™j×9Ñ9Ð:NÓOÐð �L‰L˜‰OØ�L‰L˜‰OØ�L‰L˜‰Oð
Ðô  ×)Ñ)Ø Ø#Ø�HØ$ô	
ˆð !0ˆÔØ× Ñ ×'Ñ'¬×)>Ñ)>¸{ÈIÓ)VÐ(WÔXà0×7Ñ7Ð8IÓJˆØ×Ñ˜lÔ+ØÐr   c                 óx  — | j                  |||«      ry | j                  |«      }|€H|j                  d   |vry ||j                  d      }|j                  dk7  ry | j                  |«      }|€y |\	  }}}}	}
}}}}|}| j	                  ||d«      \  }}|dk  rt
        j                  d«       y | j                  |	|
|||||||j                  d   ¬«	      }|€y | j                  j                  |«       | j                  | j                  |j                  <   | j                  j                  ||g«       d| _        y )Nr   ÚAddFú*fuse_attention: failed to detect num_heads)rE   T)Úfuse_sam_encoder_patternÚmatch_attention_subgraphr"   Úop_typer>   r<   rM   r`   rE   Únodes_to_addÚappendÚthis_graph_nameÚnode_name_to_graph_namerJ   Únodes_to_removerR   Úprune_graph)r   Únormalize_nodeÚinput_name_to_nodesÚoutput_name_to_nodeÚ	match_qkvÚskip_addÚreshape_qkvÚtranspose_qkvr   Úmatmul_qÚadd_qÚmatmul_kÚadd_kÚmatmul_vÚadd_vÚattention_last_nodeÚq_num_headsÚq_hidden_sizeÚnew_nodes                      r   Úfusez!FusionMultiHeadAttentionSam2.fuseÅ   sr  € Ø×(Ñ(¨Ð9LÐNaÔbØà×1Ñ1°.ÓAˆ	ØÐØ×#Ñ# AÑ&Ð.AÑAØà*¨>×+?Ñ+?ÀÑ+BÑCˆHØ×Ñ 5Ò(Øà×5Ñ5°hÓ?ˆIàÐ ØàclÑ`ˆ�] I¨x¸ÀÈ%ÐQYÐ[`à)Ðà%)×%GÑ%GÈ	ÐSaÐchÓ%iÑ"ˆ�]Ø˜!ÒÜ�L‰LÐEÔFØð ×-Ñ-ØØØØØØØØØ&×-Ñ-¨aÑ0ð .ó 

ˆð ÐØà×Ñ× Ñ  Ô*Ø6:×6JÑ6Jˆ×$Ñ$ X§]¡]Ñ3à×Ñ×#Ñ#Ð%8¸-Ð$HÔIð  ˆÕr   c           	      óô  — | j                   j                  |g d¢g d¢«      }|€y|\  }}}}}| j                   j                  |g d¢g d¢«      }|€t        j                  d«       y|\  }}}}	| j                   j                  |ddgd	d	g«      }
|
�|
\  }}nt        j                  d
«       y| j                   j                  |g d¢g d¢«      }|€t        j                  d«       y|\  }}}}}| j                   j                  |g d¢g d¢«      }|€t        j                  d«       y|\  }}}}}| j                   j                  |g d¢g d¢«      }|�|d   |k7  rt        j                  d«       y||||||||	|f	S )z.Match Q, K and V paths exported by PyTorch 2.*©rb   ÚMatMulÚReshapeÚ	Transposer�   )NNNr   r   N)rƒ   r‚   rb   r�   )r   r   r   Nz&fuse_attention: failed to match v pathÚSoftmaxr�   r   z'fuse_attention: failed to match qk path)ÚMulrƒ   r‚   rb   r�   )r   Nr   r   Nz&fuse_attention: failed to match q path)r   Nr   r   Nz&fuse_attention: failed to match k path)ÚSqrtÚDivr†   ÚCastÚSliceÚShaperƒ   r‚   )Nr   r   r   r   r   r   r   éÿÿÿÿz*fuse_attention: failed to match mul_q path©r   Úmatch_parent_pathr<   rM   )r   Únode_after_output_projectionÚ	qkv_nodesÚ_rr   rs   Ú
matmul_qkvÚv_nodesry   rx   Úqk_nodesÚ_softmax_qkÚ	matmul_qkÚq_nodesÚmul_qÚ_transpose_qr   ru   rt   Úk_nodesÚ_mul_krw   rv   Úmul_q_nodess                           r   re   z5FusionMultiHeadAttentionSam2.match_attention_subgraph÷   s¡  € à—J‘J×0Ñ0Ø(Ú?Ú$ó
ˆ	ð ÐØà9BÑ6ˆˆAˆ{˜M¨:à—*‘*×.Ñ.¨zÒ;dÒfuÓvˆØˆ?Ü�L‰LÐAÔBØØ")ÑˆˆAˆu�hà—:‘:×/Ñ/°
¸YÈÐ<QÐTUÐWXÐSYÓZˆØÐØ'/Ñ$ˆ[™)ä�L‰LÐBÔCØà—*‘*×.Ñ.ØÒGÒI^ó
ˆð ˆ?Ü�L‰LÐAÔBØØ<CÑ9ˆ�˜i¨°à—*‘*×.Ñ.ØÒGÒI^ó
ˆð ˆ?Ü�L‰LÐAÔBØà*1Ñ'ˆ��A�u˜hð —j‘j×2Ñ2ØÚUÚ'ó
ˆð
 Ð +¨b¡/°YÒ">Ü�L‰LÐEÔFØà˜M¨9°hÀÀxÐQVÐX`ÐbgÐgÐgr   c                 ó<  — | j                   j                  |g d¢g d¢«      }|€!| j                   j                  |g d¢g d¢«      }|€| j                   j                  |dgdg«      }|€y|d   }| j                  |t        |«      d	k(  rd	nd ¬
«      }|€y|\  }}}	}
}}t	        j
                  |
d«      }t        |t        «      r|g d¢k7  ryt	        j
                  |d«      }t        |t        «      r|g d¢k7  ryt	        j
                  |d«      }t        |t        «      r|g d¢k7  ry| j                   j                  |	g d¢g d¢«      }|€y|\  }}}| j                  ||d«      \  }}|dk  rt        j                  d«       yd}| j                   j                  |«      }|€Tt        j                  t        j                  g d¢d¬«      |¬«      }| j                   j!                  || j"                  «       | j                   j%                  d«      }t'        j(                  d|
j*                  d   |g|
j*                  d   dz   g|¬«      }| j,                  j/                  |«       | j"                  | j0                  |j2                  <   |
}|j*                  d   |j*                  d<   |j*                  d   dz   |j4                  d<   t        j                  d|›d|›�«       | j7                  ||||«      }|€yt        | j                   j9                  ||«      «      d	k(  sJ ‚|j4                  d   |j*                  d<   | j,                  j/                  |«       | j"                  | j0                  |j2                  <   | j:                  j=                  |g«       d| _        y)N)rb   r‚   rƒ   r‚   ©r   Nr   r   )rb   r‰   r‰   r‚   rƒ   r‚   )r   Nr   r   r   r   rb   r   Fr‹   r   )Úinput_indexÚperm)r   r    r   r.   )r   r    r.   r   )r‚   rb   r�   )r   r   NTrc   Úbsnh_to_bsd_reshape_dims)r   r   r‹   Úint64)Údtype)rJ   r‚   Ú_BSDrG   Ú_BNSHzFound MHA: q_num_heads=z q_hidden_size=) r   r�   Ú$match_sam_encoder_attention_subgraphr1   r	   Úget_node_attributer#   r&   r>   r<   rM   r5   r   Ú
from_arrayr$   ÚarrayÚadd_initializerri   rN   r   rO   r"   rg   rh   rj   rJ   rE   Úcreate_mha_nodeÚget_childrenrk   rR   rl   )r   rm   rn   ro   ÚnodesrŽ   Úmatched_sdpaÚreshape_outÚtranspose_outÚ	split_qkvÚtranspose_qÚtranspose_kÚtranspose_vÚpermutation_qÚpermutation_kÚpermutation_vÚinput_projection_nodesr+   Úadd_inÚ	matmul_inr{   r|   Únew_dims_nameÚnew_dimsÚreshape_q_namer   Útranspose_k_bnshr}   s                               r   rd   z5FusionMultiHeadAttentionSam2.fuse_sam_encoder_pattern1  sž  € ð< —
‘
×,Ñ,ØÚ6Úó
ˆð
 ˆ=Ø—J‘J×0Ñ0ØÚLÚ%óˆEð
 ˆ=Ø—J‘J×0Ñ0ØØ�Ø�óˆEð
 ˆ=Øà',¨R¡yÐ$Ø×@Ñ@Ø(¼3¸u»:Èº?±aÐPTð Aó 
ˆð ÐØàWcÑTˆ�] I¨{¸KÈô "×4Ñ4°[À&ÓIˆÜ˜=¬$Ô/°MÂ\Ò4QØô "×4Ñ4°[À&ÓIˆÜ˜=¬$Ô/°MÂ\Ò4QØô "×4Ñ4°[À&ÓIˆÜ˜=¬$Ô/°MÂ\Ò4QØà!%§¡×!=Ñ!=ØÚ(Úó"
Ðð
 "Ð)ØØ(>Ñ%ˆ
�F˜IØ%)×%GÑ%GÈ
ÐTbÐdhÓ%iÑ"ˆ�]Ø˜!ÒÜ�L‰LÐEÔFØð 3ˆØ—:‘:×-Ñ-¨mÓ<ˆØÐÜ#×.Ñ.¬r¯x©xº
È'Ô/RÐYfÔgˆHØ�J‰J×&Ñ& x°×1EÑ1EÔFØŸ™×4Ñ4°YÓ?ˆÜ×$Ñ$ØØ×%Ñ% aÑ(¨-Ð8Ø ×&Ñ& qÑ)¨FÑ2Ð3Øô	
ˆ	ð 	×Ñ× Ñ  Ô+Ø7;×7KÑ7Kˆ×$Ñ$ Y§^¡^Ñ4ð 'ÐØ$/×$5Ñ$5°aÑ$8Ð×Ñ˜qÑ!Ø%0×%6Ñ%6°qÑ%9¸GÑ%CÐ×Ñ Ñ"ä�‰Ð/ ; .Ð0@°-Ð1AÐBÔCð ×'Ñ'ØØØØó	
ˆð ÐØô �4—:‘:×*Ñ*¨=Ð:MÓNÓOÐSTÒTÐTÐTØ'Ÿ™¨qÑ1ˆ×Ñ˜!Ñà×Ñ× Ñ  Ô*Ø6:×6JÑ6Jˆ×$Ñ$ X§]¡]Ñ3Ø×Ñ×#Ñ# ] OÔ4ð  ˆÔØr   c           	      óÔ  — | j                   j                  |g d¢|ddddg«      }|€y|\  }}}}}| j                   j                  |g d¢g d¢«      }|€t        j                  d«       y|\  }	}}
}| j                   j                  |ddgddg«      }|�|\  }}nt        j                  d	«       y| j                   j                  |g d
¢g d¢«      }|€9| j                   j                  |g d¢g d¢«      }|€t        j                  d«       y|d   |
k7  ry|d   }| j                   j                  |g d
¢g d¢«      }|€t        j                  d«       y|d   |
k7  ry|\  }}}}|||
|||	fS )z%Match SDPA pattern in SAM2 enconder.*r€   Nr   )rƒ   ÚSqueezeÚSplitr‚   )r   r   r   r   zfailed to match v pathr„   r�   zfailed to match qk path)r…   rƒ   r¿   rÀ   r�   )	r…   rƒ   r‚   rƒ   ÚMaxPoolrƒ   r‚   r¿   rÀ   )	r   Nr   r   r   r   r   r   r   zfailed to match q pathr‹   r   )r   Nr   r   zfailed to match k pathrŒ   )r   rŽ   rž   Ú	out_nodesr�   r®   r¯   Úmatmul_qk_vr’   r³   r°   rr   r“   r”   r•   r–   r±   r™   Úmul_kr²   Ú
_squeeze_ks                        r   r¥   zAFusionMultiHeadAttentionSam2.match_sam_encoder_attention_subgraphµ  s•  € ð —J‘J×0Ñ0Ø(Ú?Ø˜$  a¨Ð+ó
ˆ	ð ÐØà:CÑ7ˆˆAˆ{˜M¨;ð —*‘*×.Ñ.¨{Ò<hÒjvÓwˆØˆ?Ü�L‰LÐ1Ô2ØØ3:Ñ0ˆ�a˜ Kà—:‘:×/Ñ/°¸iÈÐ=RÐUVÐXYÐTZÓ[ˆØÐØ'/Ñ$ˆ[™)ä�L‰LÐ2Ô3Øà—*‘*×.Ñ.¨yÒ:bÒdsÓtˆØˆ?Ø—j‘j×2Ñ2ØÚsÚ.óˆGð
 ˆÜ—‘Ð5Ô6Øà�2‰;˜)Ò#ØØ˜a‘jˆà—*‘*×.Ñ.¨yÒ:bÒdsÓtˆØˆ?Ü�L‰LÐ1Ô2Øà�2‰;˜)Ò#ØØ.5Ñ+ˆ�˜Z¨à˜M¨9°kÀ;ÐP[Ð[Ð[r   r²   r³   c                 ó„  — | j                   j                  d«      }|j                  d   |j                  d   |j                  d   g}|dz   }t        j                  d||g|¬«      }d|_        |j                  j                  t        j                  d|«      g«       dj                  d«      }	| j                  |	«       |S )	a  Create a MultiHeadAttention node for SAM2 encoder.

        Args:
            reshape_q (NodeProto): Reshape node for Q, output is 3D BxSxNH format
            transpose_k (NodeProto): Transpose node for K, output is BNSH format
            transpose_v (NodeProto): Transpose node for V, output is BNSH format
            num_heads (int): number of attention heads. If a model is pruned, it is the number of heads after pruning.

        Returns:
            NodeProto: the MultiHeadAttention node created.
        r   r   Ú_outrG   rK   r   rL   zself attention)r   rN   rE   r   rO   rP   rQ   rR   rS   rT   rU   )
r   r   r²   r³   r   r\   rH   rE   r^   r_   s
             r   rª   z,FusionMultiHeadAttentionSam2.create_mha_nodeì  sÊ   € ð& #Ÿj™j×9Ñ9Ð:NÓOÐð ×Ñ˜QÑØ×Ñ˜qÑ!Ø×Ñ˜qÑ!ð
ˆð % vÑ-ˆä×)Ñ)Ø ØØ�HØ$ô	
ˆð !0ˆÔØ× Ñ ×'Ñ'¬×)>Ñ)>¸{ÈIÓ)VÐ(WÔXà0×7Ñ7Ð8HÓIˆØ×Ñ˜lÔ+ØÐr   )F)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r(   r   r   r*   r3   r9   ÚboolÚtupler>   Ústrr`   r~   re   rd   r¥   rª   Ú__classcell__)r   s   @r   r   r      sO  ø„ ñð(àð(ð ð(ð õ	(ð¨yð ¸Só ð*°	ð ¸có ò8ð SXñ"&Ø"ð"&Ø4=ð"&ØKOð"&à	ˆs�Cˆx‰ó"&ðH>àð>ð ð>ð ð	>ð
 ð>ð ð>ð ð>ð ð>ð ð>ð ð>ð 
�TÑ	ó>ò@0 òd5hðtBÐdhó BóH5\ðn)àð)ð ð)ð ð	)ð
 ð)ð 
÷)r   r   )Úloggingr   Únumpyr$   Úfusion_baser   Úfusion_utilsr   Úonnxr   r   r   Ú
onnx_modelr	   rÈ   r<   r   © r   r   ú<module>r×      s4   ðõ
 ã Ý Ý $ß 0Ñ 0Ý  á	�8Ó	€ôE 6õ Er   