
    qi                        d dl mZ d dlmZ d dlZd dlmZ d dlmZmZm	Z	 ddl
mZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZmZmZmZmZmZ ddlmZmZ ddlm Z  ddl!m"Z"m#Z#m$Z$m%Z% ddl&m'Z'm(Z( ddl)m*Z* ddl+m,Z,  e%jZ                  e.      Z/ G d dej`                        Z1ejd                  e1dZ3 G d dej`                        Z4	 	 d_dej`                  dejj                  dejj                  dejj                  dejj                  dz  de6dz  de6de e#   fd Z7 G d! d"ej`                        Z8 G d# d$ej`                        Z9 G d% d&ej`                        Z: G d' d(ej`                        Z; G d) d*ej`                        Z< G d+ d,ej`                        Z= G d- d.ej`                        Z> G d/ d0ej`                        Z? G d1 d2ej`                        Z@ G d3 d4ej`                        ZA G d5 d6e      ZB G d7 d8ej`                        ZC G d9 d:ej`                        ZD G d; d<ej`                        ZE G d= d>ej`                        ZF G d? d@ej`                        ZG G dA dBej`                        ZHe$ G dC dDe             ZIe e$dEF       G dG dHe"                    ZJe$ G dI dJeI             ZK e$dKF       G dL dMeI             ZLe$ G dN dOeI             ZM G dP dQej`                        ZN e$dRF       G dS dTeI             ZO e$dUF       G dV dWeI             ZPe$ G dX dYeI             ZQe$ G dZ d[eI             ZRe$ G d\ d]eI             ZSg d^ZTy)`    )Callable)	dataclassN)nn)BCEWithLogitsLossCrossEntropyLossMSELoss   )initialization)ACT2FN)create_bidirectional_mask)GradientCheckpointingLayer)BaseModelOutputBaseModelOutputWithPoolingMaskedLMOutputMultipleChoiceModelOutputNextSentencePredictorOutputQuestionAnsweringModelOutputSequenceClassifierOutputTokenClassifierOutput)ALL_ATTENTION_FUNCTIONSPreTrainedModel)Unpack)ModelOutputTransformersKwargsauto_docstringlogging)can_return_tuplemerge_with_config_defaults)capture_outputs   )MobileBertConfigc                   X     e Zd Zd fd	Zdej
                  dej
                  fdZ xZS )NoNormc                     t         |           t        j                  t	        j
                  |            | _        t        j                  t	        j                  |            | _        y N)	super__init__r   	Parametertorchzerosbiasonesweight)self	feat_sizeeps	__class__s      d/opt/pipecat/venv/lib/python3.12/site-packages/transformers/models/mobilebert/modeling_mobilebert.pyr'   zNoNorm.__init__8   s@    LLY!78	ll5::i#89    input_tensorreturnc                 :    || j                   z  | j                  z   S r%   )r-   r+   )r.   r4   s     r2   forwardzNoNorm.forward=   s    dkk)DII55r3   r%   __name__
__module____qualname__r'   r)   Tensorr7   __classcell__r1   s   @r2   r#   r#   7   s#    :
6ELL 6U\\ 6r3   r#   )
layer_normno_normc                        e Zd ZdZ fdZ	 	 	 	 d
dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  f
d	Z	 xZ
S )MobileBertEmbeddingszGConstruct the embeddings from word, position and token_type embeddings.c                 X   t         |           |j                  | _        |j                  | _        |j                  | _        t        j                  |j                  |j                  |j                        | _	        t        j                  |j                  |j                        | _        t        j                  |j                  |j                        | _        | j                  rdnd}| j                  |z  }t        j                  ||j                        | _        t!        |j"                     |j                        | _        t        j&                  |j(                        | _        | j-                  dt/        j0                  |j                        j3                  d      d       y )N)padding_idxr	   r    position_idsr    F)
persistent)r&   r'   trigram_inputembedding_sizehidden_sizer   	Embedding
vocab_sizepad_token_idword_embeddingsmax_position_embeddingsposition_embeddingstype_vocab_sizetoken_type_embeddingsLinearembedding_transformationNORM2FNnormalization_type	LayerNormDropouthidden_dropout_probdropoutregister_bufferr)   arangeexpand)r.   configembed_dim_multiplierembedded_input_sizer1   s       r2   r'   zMobileBertEmbeddings.__init__G   sF   #11$33!--!||F,=,=v?T?Tbhbubuv#%<<0N0NPVPbPb#c %'\\&2H2H&J\J\%]"$($6$6qA"114HH(*		2EvGYGY(Z% !:!:;F<N<NOzz&"<"<= 	ELL)G)GHOOPWXej 	 	
r3   N	input_idstoken_type_idsrE   inputs_embedsr5   c           
      $   ||j                         }n|j                         d d }|d   }|| j                  d d d |f   }|:t        j                  |t        j                  | j                  j
                        }|| j                  |      }| j                  rpt        j                  t        j                  j                  |d d dd f   g dd      |t        j                  j                  |d d d df   g dd      gd	      }| j                  s| j                  | j                  k7  r| j                  |      }| j                  |      }| j!                  |      }||z   |z   }	| j#                  |	      }	| j%                  |	      }	|	S )
NrG   r    )dtypedevice)r   r   r   r    r   r           )value)r   r   r    r   r   r      dim)sizerE   r)   r*   longrg   rO   rI   catr   
functionalpadrJ   rK   rU   rQ   rS   rX   r[   )
r.   rb   rc   rE   rd   input_shape
seq_lengthrQ   rS   
embeddingss
             r2   r7   zMobileBertEmbeddings.forward]   s     #..*K',,.s3K ^
,,Q^<L!"[[EJJtO`O`OgOghN  00;M "IIMM%%mAqrE&:<NVY%Z!MM%%mAssF&;=OWZ%[
 M !4!48H8H!H 99-HM #66|D $ : :> J"%88;PP
^^J/
\\*-
r3   )NNNN)r9   r:   r;   __doc__r'   r)   
LongTensorFloatTensorr<   r7   r=   r>   s   @r2   rB   rB   D   s~    Q
0 .22604260##d*0 ((4/0 &&-	0
 ((4/0 
0r3   rB   modulequerykeyri   attention_maskscalingr[   kwargsc                    ||j                  d      dz  }t        j                  ||j                  dd            |z  }|||z   }t        j
                  j                  |d      }t        j
                  j                  ||| j                        }t        j                  ||      }	|	j                  dd      j                         }	|	|fS )NrG         rj   r	   rk   )ptrainingr    )
rm   r)   matmul	transposer   rp   softmaxr[   r   
contiguous)
rx   ry   rz   ri   r{   r|   r[   r}   attn_weightsattn_outputs
             r2   eager_attention_forwardr      s     **R.D( <<s}}Q':;gEL!#n4==((2(>L==((6??([L,,|U3K''1-88:K$$r3   c                        e Zd Z fdZ	 d
dej
                  dej
                  dej
                  dej                  dz  dee   de	ej
                     fd	Z
 xZS )MobileBertSelfAttentionc                    t         |           || _        |j                  | _        t	        |j
                  |j                  z        | _        | j                  | j                  z  | _        | j                  dz  | _        t        j                  |j
                  | j                        | _        t        j                  |j
                  | j                        | _        t        j                  |j                  r|j
                  n|j                  | j                        | _        t        j                   |j"                        | _        d| _        y )Nr   F)r&   r'   r_   num_attention_headsinttrue_hidden_sizeattention_head_sizeall_head_sizer|   r   rT   ry   rz   use_bottleneck_attentionrK   ri   rY   attention_probs_dropout_probr[   	is_causalr.   r_   r1   s     r2   r'   z MobileBertSelfAttention.__init__   s    #)#=#= #&v'>'>A[A['[#\ !558P8PP//5YYv668J8JK
99V44d6H6HIYY'-'F'FF##FL^L^`d`r`r

 zz&"E"EFr3   Nquery_tensor
key_tensorvalue_tensorr{   r}   r5   c                    |j                   d d }g |d| j                  } | j                  |      j                  | j	                  dd      } | j                  |      j                  | j	                  dd      }	 | j                  |      j                  | j	                  dd      }
t        j                  | j                  j                  t              } || ||	|
|f| j                  sdn| j                  j                  | j                  d|\  }} |j                   g |d j#                         }||fS )NrG   r    rj   rh   )r[   r|   )shaper   ry   viewr   rz   ri   r   get_interfacer_   _attn_implementationr   r   r[   r   r|   reshaper   )r.   r   r   r   r{   r}   rr   hidden_shapequery_layer	key_layervalue_layerattention_interfacer   r   s                 r2   r7   zMobileBertSelfAttention.forward   sH    #(("-CCbC$*B*BC 4djj.33\BLLQPQR-DHHZ(--|<FFq!L	3djj.33\BLLQPQR(?(M(MKK,,.E)
 %8	%
  $}}C$,,..LL	%
 	%
!\ *k));;;;FFHL((r3   r%   r9   r:   r;   r'   r)   r<   rw   r   r   tupler7   r=   r>   s   @r2   r   r      sr    , 48)ll) LL) ll	)
 ))D0) +,) 
u||	)r3   r   c                   n     e Zd Z fdZdej
                  dej
                  dej
                  fdZ xZS )MobileBertSelfOutputc                 j   t         |           |j                  | _        t        j                  |j
                  |j
                        | _        t        |j                     |j
                  |j                        | _
        | j                  s%t        j                  |j                        | _        y y Nr0   )r&   r'   use_bottleneckr   rT   r   denserV   rW   layer_norm_epsrX   rY   rZ   r[   r   s     r2   r'   zMobileBertSelfOutput.__init__   s    $33YYv668O8OP
 !:!:;F<S<SY_YnYno""::f&@&@ADL #r3   hidden_statesresidual_tensorr5   c                     | j                  |      }| j                  s| j                  |      }| j                  ||z         }|S r%   )r   r   r[   rX   r.   r   r   layer_outputss       r2   r7   zMobileBertSelfOutput.forward   s@    

=1"" LL7M}'FGr3   r8   r>   s   @r2   r   r      s2    BU\\ ELL UZUaUa r3   r   c                        e Zd Z fdZ	 ddej
                  dej
                  dej
                  dej
                  dej                  dz  dee   d	e	ej
                     fd
Z
 xZS )MobileBertAttentionc                 b    t         |           t        |      | _        t	        |      | _        y r%   )r&   r'   r   r.   r   outputr   s     r2   r'   zMobileBertAttention.__init__   s&    +F3	*62r3   Nr   r   r   layer_inputr{   r}   r5   c                 `     | j                   ||||fi |\  }}| j                  ||      }||fS r%   )r.   r   )	r.   r   r   r   r   r{   r}   attention_outputr   s	            r2   r7   zMobileBertAttention.forward   sO     *3	*

 *
&,  ;;'7E--r3   r%   r   r>   s   @r2   r   r      s    3 48.ll. LL. ll	.
 \\. ))D0. +,. 
u||	.r3   r   c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )MobileBertIntermediatec                    t         |           t        j                  |j                  |j
                        | _        t        |j                  t              rt        |j                     | _        y |j                  | _        y r%   )r&   r'   r   rT   r   intermediate_sizer   
isinstance
hidden_actstrr   intermediate_act_fnr   s     r2   r'   zMobileBertIntermediate.__init__  s]    YYv668P8PQ
f''-'-f.?.?'@D$'-'8'8D$r3   r   r5   c                 J    | j                  |      }| j                  |      }|S r%   )r   r   r.   r   s     r2   r7   zMobileBertIntermediate.forward  s&    

=100?r3   r8   r>   s   @r2   r   r     s#    9U\\ ell r3   r   c                   n     e Zd Z fdZdej
                  dej
                  dej
                  fdZ xZS )OutputBottleneckc                 .   t         |           t        j                  |j                  |j
                        | _        t        |j                     |j
                  |j                        | _
        t        j                  |j                        | _        y r   )r&   r'   r   rT   r   rK   r   rV   rW   r   rX   rY   rZ   r[   r   s     r2   r'   zOutputBottleneck.__init__  sh    YYv668J8JK
 !:!:;F<N<NTZTiTijzz&"<"<=r3   r   r   r5   c                 r    | j                  |      }| j                  |      }| j                  ||z         }|S r%   )r   r[   rX   r   s       r2   r7   zOutputBottleneck.forward$  s7    

=1]3}'FGr3   r8   r>   s   @r2   r   r     s1    >U\\ ELL UZUaUa r3   r   c                        e Zd Z fdZdej
                  dej
                  dej
                  dej
                  fdZ xZS )MobileBertOutputc                 r   t         |           |j                  | _        t        j                  |j
                  |j                        | _        t        |j                     |j                        | _
        | j                  s%t        j                  |j                        | _        y t        |      | _        y r%   )r&   r'   r   r   rT   r   r   r   rV   rW   rX   rY   rZ   r[   r   
bottleneckr   s     r2   r'   zMobileBertOutput.__init__,  s    $33YYv779P9PQ
 !:!:;F<S<ST""::f&@&@ADL.v6DOr3   intermediate_statesresidual_tensor_1residual_tensor_2r5   c                     | j                  |      }| j                  s'| j                  |      }| j                  ||z         }|S | j                  ||z         }| j	                  ||      }|S r%   )r   r   r[   rX   r   )r.   r   r   r   layer_outputs        r2   r7   zMobileBertOutput.forward6  ss     zz"56""<<5L>>,9J*JKL   >>,9J*JKL??<9JKLr3   r8   r>   s   @r2   r   r   +  s?    7
#(<<
DILL
ejeqeq
	
r3   r   c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )BottleneckLayerc                     t         |           t        j                  |j                  |j
                        | _        t        |j                     |j
                  |j                        | _
        y r   )r&   r'   r   rT   rK   intra_bottleneck_sizer   rV   rW   r   rX   r   s     r2   r'   zBottleneckLayer.__init__D  sR    YYv1163O3OP
 !:!:;F<X<X^d^s^str3   r   r5   c                 J    | j                  |      }| j                  |      }|S r%   r   rX   )r.   r   r   s      r2   r7   zBottleneckLayer.forwardI  s$    jj/nn[1r3   r8   r>   s   @r2   r   r   C  s$    u
U\\ ell r3   r   c                   \     e Zd Z fdZdej
                  deej
                     fdZ xZS )
Bottleneckc                     t         |           |j                  | _        |j                  | _        t	        |      | _        | j                  rt	        |      | _        y y r%   )r&   r'   key_query_shared_bottleneckr   r   input	attentionr   s     r2   r'   zBottleneck.__init__P  sP    +1+M+M((.(G(G%$V,
++,V4DN ,r3   r   r5   c                     | j                  |      }| j                  r|fdz  S | j                  r| j                  |      }||||fS ||||fS )N   )r   r   r   r   )r.   r   bottlenecked_hidden_statesshared_attention_inputs       r2   r7   zBottleneck.forwardX  sc    " &*ZZ%>"((.0144--%)^^M%B"*,BMSmnn!=-A[\\r3   	r9   r:   r;   r'   r)   r<   r   r7   r=   r>   s   @r2   r   r   O  s+    5]U\\ ]eELL6I ]r3   r   c                   n     e Zd Z fdZdej
                  dej
                  dej
                  fdZ xZS )	FFNOutputc                     t         |           t        j                  |j                  |j
                        | _        t        |j                     |j
                  |j                        | _
        y r   )r&   r'   r   rT   r   r   r   rV   rW   r   rX   r   s     r2   r'   zFFNOutput.__init__t  sR    YYv779P9PQ
 !:!:;F<S<SY_YnYnor3   r   r   r5   c                 P    | j                  |      }| j                  ||z         }|S r%   r   r   s       r2   r7   zFFNOutput.forwardy  s)    

=1}'FGr3   r8   r>   s   @r2   r   r   s  s2    p
U\\ ELL UZUaUa r3   r   c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )FFNLayerc                 b    t         |           t        |      | _        t	        |      | _        y r%   )r&   r'   r   intermediater   r   r   s     r2   r'   zFFNLayer.__init__  s'    26:'r3   r   r5   c                 L    | j                  |      }| j                  ||      }|S r%   )r   r   )r.   r   intermediate_outputr   s       r2   r7   zFFNLayer.forward  s*    "//>$7Gr3   r8   r>   s   @r2   r   r     s#    (
U\\ ell r3   r   c            
            e Zd Z fdZ	 ddej
                  dej                  dz  dee   de	ej
                     fdZ
 xZS )	MobileBertLayerc                    t         |           |j                  | _        |j                  | _        t	        |      | _        t        |      | _        t        |      | _	        | j                  rt        |      | _        |j                  dkD  rHt        j                  t        |j                  dz
        D cg c]  }t        |       c}      | _        y y c c}w Nr    )r&   r'   r   num_feedforward_networksr   r   r   r   r   r   r   r   r   
ModuleListranger   ffnr.   r_   _r1   s      r2   r'   zMobileBertLayer.__init__  s    $33(.(G(G%,V426:&v.(0DO**Q.}}fFeFehiFi@j%k1hv&6%klDH /%ks   6CNr   r{   r}   r5   c                 2   | j                   r| j                  |      \  }}}}n|gdz  \  }}}} | j                  |||||fi |\  }}	|}
| j                  dk7  r| j                  D ]
  } ||
      }
 | j                  |
      }| j                  ||
|      }|S )Nr   r    )r   r   r   r   r   r   r   )r.   r   r{   r}   r   r   r   r   self_attention_outputr   r   
ffn_moduler   r   s                 r2   r7   zMobileBertLayer.forward  s     BF//R_B`?L*lKCP/TUBU?L*lK#14>>$
 $
 q 1((A-"hh @
#-.>#? @ #//0@A{{#68H-Xr3   r%   r   r>   s   @r2   r   r     sW    m  48|| ))D0 +,	
 
u||	r3   r   c            
       t     e Zd Z fdZ	 ddej
                  dej                  dz  dee   de	e
z  fdZ xZS )	MobileBertEncoderc                     t         |           t        j                  t	        |j
                        D cg c]  }t        |       c}      | _        y c c}w r%   )r&   r'   r   r   r   num_hidden_layersr   layerr   s      r2   r'   zMobileBertEncoder.__init__  s<    ]]U6KcKcEd#eOF$;#ef
#es   ANr   r{   r}   r5   c                 h    t        | j                        D ]  \  }} |||fi |} t        |      S )N)last_hidden_state)	enumerater   r   )r.   r   r{   r}   ilayer_modules         r2   r7   zMobileBertEncoder.forward  sG      )4 	OA|( M	 ??r3   r%   )r9   r:   r;   r'   r)   r<   rw   r   r   r   r   r7   r=   r>   s   @r2   r   r     sX    g 48@||@ ))D0@ +,	@
 
	 @r3   r   c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )MobileBertPoolerc                     t         |           |j                  | _        | j                  r0t	        j
                  |j                  |j                        | _        y y r%   )r&   r'   classifier_activationdo_activater   rT   rK   r   r   s     r2   r'   zMobileBertPooler.__init__  sH    !776#5#5v7I7IJDJ r3   r   r5   c                     |d d df   }| j                   s|S | j                  |      }t        j                  |      }|S )Nr   )r  r   r)   tanh)r.   r   first_token_tensorpooled_outputs       r2   r7   zMobileBertPooler.forward  sE     +1a40%% JJ'9:M!JJ}5M  r3   r8   r>   s   @r2   r  r    s$    K	!U\\ 	!ell 	!r3   r  c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )!MobileBertPredictionHeadTransformc                 Z   t         |           t        j                  |j                  |j                        | _        t        |j                  t              rt        |j                     | _
        n|j                  | _
        t        d   |j                  |j                        | _        y )Nr?   r   )r&   r'   r   rT   rK   r   r   r   r   r   transform_act_fnrV   r   rX   r   s     r2   r'   z*MobileBertPredictionHeadTransform.__init__  s|    YYv1163E3EF
f''-$*6+<+<$=D!$*$5$5D! .v/A/AvG\G\]r3   r   r5   c                 l    | j                  |      }| j                  |      }| j                  |      }|S r%   )r   r  rX   r   s     r2   r7   z)MobileBertPredictionHeadTransform.forward  s4    

=1--m<}5r3   r8   r>   s   @r2   r  r    s$    ^U\\ ell r3   r  c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )MobileBertLMPredictionHeadc                    t         |           t        |      | _        t	        j
                  |j                  |j                  |j                  z
  d      | _	        t	        j
                  |j                  |j                  d      | _
        t	        j                  t        j                  |j                              | _        y )NF)r+   T)r&   r'   r  	transformr   rT   rM   rK   rJ   r   decoderr(   r)   r*   r+   r   s     r2   r'   z#MobileBertLMPredictionHead.__init__  s    :6B YYv00&2D2DvG\G\2\chi
yy!6!68I8IPTULLV->->!?@	r3   r   r5   c                    | j                  |      }|j                  t        j                  | j                  j
                  j                         | j                  j
                  gd            }|| j                  j                  z  }|S )Nr   rk   )	r  r   r)   ro   r  r-   tr   r+   r   s     r2   r7   z"MobileBertLMPredictionHead.forward  sk    }5%,,UYY8K8K8M8M8OQUQ[Q[QbQb7cij-kl***r3   r8   r>   s   @r2   r  r    s$    AU\\ ell r3   r  c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )MobileBertOnlyMLMHeadc                 B    t         |           t        |      | _        y r%   )r&   r'   r  predictionsr   s     r2   r'   zMobileBertOnlyMLMHead.__init__  s    5f=r3   sequence_outputr5   c                 (    | j                  |      }|S r%   )r  )r.   r  prediction_scoress      r2   r7   zMobileBertOnlyMLMHead.forward  s     ,,_=  r3   r8   r>   s   @r2   r  r     s#    >!u|| ! !r3   r  c                   t     e Zd Z fdZdej
                  dej
                  deej
                     fdZ xZS )MobileBertPreTrainingHeadsc                     t         |           t        |      | _        t	        j
                  |j                  d      | _        y Nrj   )r&   r'   r  r  r   rT   rK   seq_relationshipr   s     r2   r'   z#MobileBertPreTrainingHeads.__init__  s4    5f= "		&*<*<a @r3   r  r
  r5   c                 N    | j                  |      }| j                  |      }||fS r%   )r  r"  )r.   r  r
  r  seq_relationship_scores        r2   r7   z"MobileBertPreTrainingHeads.forward  s0     ,,_=!%!6!6}!E "888r3   r   r>   s   @r2   r  r  
  s8    A
9u|| 9ELL 9UZ[`[g[gUh 9r3   r  c                   t     e Zd ZU eed<   dZdZdZdZdZ	dZ
eedZ ej                          fd       Z xZS )MobileBertPreTrainedModelr_   
mobilebertT)r   
attentionsc                    t         |   |       t        |t              r?t	        j
                  |j                         t	        j                  |j                         yt        |t              r t	        j
                  |j                         yt        |t              rZt	        j                  |j                  t        j                  |j                  j                  d         j!                  d             yy)zInitialize the weightsrG   rF   N)r&   _init_weightsr   r#   initzeros_r+   ones_r-   r  rB   copy_rE   r)   r]   r   r^   )r.   rx   r1   s     r2   r*  z'MobileBertPreTrainedModel._init_weights$  s     	f%ff%KK$JJv}}% :;KK$ 45JJv**ELL9L9L9R9RSU9V,W,^,^_f,gh 6r3   )r9   r:   r;   r!   __annotations__base_model_prefixsupports_gradient_checkpointing_supports_flash_attn_supports_sdpa_supports_flex_attn_supports_attention_backendr   r   _can_record_outputsr)   no_gradr*  r=   r>   s   @r2   r&  r&    sX    $&*#N"&(-
 U]]_	i 	ir3   r&  z6
    Output type of [`MobileBertForPreTraining`].
    )custom_introc                       e Zd ZU dZdZej                  dz  ed<   dZej                  dz  ed<   dZ	ej                  dz  ed<   dZ
eej                     dz  ed<   dZeej                     dz  ed<   y)MobileBertForPreTrainingOutputa  
    loss (*optional*, returned when `labels` is provided, `torch.FloatTensor` of shape `(1,)`):
        Total loss as the sum of the masked language modeling loss and the next sequence prediction
        (classification) loss.
    prediction_logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
        Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
    seq_relationship_logits (`torch.FloatTensor` of shape `(batch_size, 2)`):
        Prediction scores of the next sequence prediction (classification) head (scores of True/False continuation
        before SoftMax).
    Nlossprediction_logitsseq_relationship_logitsr   r(  )r9   r:   r;   ru   r;  r)   rw   r/  r<  r=  r   r   r(   r3   r2   r:  r:  1  s~    	 &*D%

d
")26u((4/68<U..5<59M5**+d2926Je''(4/6r3   r:  c                       e Zd ZdZd fd	Zd Zd Zeee		 	 	 	 	 dde
j                  dz  de
j                  dz  de
j                  dz  d	e
j                  dz  d
e
j                  dz  dee   deez  fd                     Z xZS )MobileBertModelz2
    https://huggingface.co/papers/2004.02984
    c                     t         |   |       || _        d| _        t	        |      | _        t        |      | _        |rt        |      nd| _	        | j                          y)zv
        add_pooling_layer (bool, *optional*, defaults to `True`):
            Whether to add a pooling layer
        FN)r&   r'   r_   gradient_checkpointingrB   rt   r   encoderr  pooler	post_init)r.   r_   add_pooling_layerr1   s      r2   r'   zMobileBertModel.__init__P  sV    
 	 &+#.v6(02C&v. 	r3   c                 .    | j                   j                  S r%   rt   rO   r.   s    r2   get_input_embeddingsz$MobileBertModel.get_input_embeddingsa  s    ...r3   c                 &    || j                   _        y r%   rH  )r.   ri   s     r2   set_input_embeddingsz$MobileBertModel.set_input_embeddingsd  s    */'r3   Nrb   r{   rc   rE   rd   r}   r5   c                    |d u |d uz  rt        d      | j                  ||||      }t        | j                  ||      } | j                  |fd|i|}|d   }	| j
                  | j                  |	      nd }
t        |	|
      S )Nz:You must specify exactly one of input_ids or inputs_embeds)rb   rE   rc   rd   )r_   rd   r{   r{   r   )r   pooler_output)
ValueErrorrt   r   r_   rC  rD  r   )r.   rb   r{   rc   rE   rd   r}   embedding_outputencoder_outputsr  r
  s              r2   r7   zMobileBertModel.forwardg  s     -t";<YZZ??%)'	 + 
 3;;*)
 '$,,
)
 

 *!,8<8OO4UY)-'
 	
r3   )T)NNNNN)r9   r:   r;   ru   r'   rJ  rL  r   r   r   r)   rv   rw   r   r   r   r   r7   r=   r>   s   @r2   r@  r@  J  s    "/0   .237260426$
##d*$
 ))D0$
 ((4/	$

 &&-$
 ((4/$
 +,$
 
+	+$
    $
r3   r@  z
    MobileBert Model with two heads on top as done during the pretraining: a `masked language modeling` head and a
    `next sentence prediction (classification)` head.
    c                   v    e Zd ZdddZ fdZd Zd Zddedz  d	ej                  f fd
Z
ee	 	 	 	 	 	 	 ddej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dee   d	eez  fd              Z xZS )MobileBertForPreTrainingcls.predictions.bias,mobilebert.embeddings.word_embeddings.weightzcls.predictions.decoder.biaszcls.predictions.decoder.weightc                     t         |   |       t        |      | _        t	        |      | _        | j                          y r%   )r&   r'   r@  r'  r  clsrE  r   s     r2   r'   z!MobileBertForPreTraining.__init__  s4     )&1-f5 	r3   c                 B    | j                   j                  j                  S r%   rX  r  r  rI  s    r2   get_output_embeddingsz.MobileBertForPreTraining.get_output_embeddings      xx##+++r3   c                     || j                   j                  _        |j                  | j                   j                  _        y r%   rX  r  r  r+   r.   new_embeddingss     r2   set_output_embeddingsz.MobileBertForPreTraining.set_output_embeddings  ,    '5$$2$7$7!r3   Nnew_num_tokensr5   c                     | j                  | j                  j                  j                  |d      | j                  j                  _        t        |   |      S NT)rc  
transposed)rc  _get_resized_lm_headrX  r  r   r&   resize_token_embeddingsr.   rc  r1   s     r2   ri  z0MobileBertForPreTraining.resize_token_embeddings  sR    %)%>%>HH  &&~RV &? &
" w.n.MMr3   rb   r{   rc   rE   rd   labelsnext_sentence_labelr}   c           	          | j                   |f||||dd|}	|	dd \  }
}| j                  |
|      \  }}d}|u|st               } ||j                  d| j                  j
                        |j                  d            } ||j                  dd      |j                  d            }||z   }t        ||||	j                  |	j                        S )a  
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
            config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
            loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
        next_sentence_label (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair
            (see `input_ids` docstring) Indices should be in `[0, 1]`:

            - 0 indicates sequence B is a continuation of sequence A,
            - 1 indicates sequence B is a random sequence.

        Examples:

        ```python
        >>> from transformers import AutoTokenizer, MobileBertForPreTraining
        >>> import torch

        >>> tokenizer = AutoTokenizer.from_pretrained("google/mobilebert-uncased")
        >>> model = MobileBertForPreTraining.from_pretrained("google/mobilebert-uncased")

        >>> input_ids = torch.tensor(tokenizer.encode("Hello, my dog is cute", add_special_tokens=True)).unsqueeze(0)
        >>> # Batch size 1
        >>> outputs = model(input_ids)

        >>> prediction_logits = outputs.prediction_logits
        >>> seq_relationship_logits = outputs.seq_relationship_logits
        ```Tr{   rc   rE   rd   return_dictNrj   rG   )r;  r<  r=  r   r(  )	r'  rX  r   r   r_   rM   r:  r   r(  )r.   rb   r{   rc   rE   rd   rk  rl  r}   outputsr  r
  r  r$  
total_lossloss_fctmasked_lm_lossnext_sentence_losss                     r2   r7   z MobileBertForPreTraining.forward  s   R "$//
))%'
 
 *1!&48HH_m4\11
"5"A')H%&7&<&<RAWAW&XZ`ZeZefhZijN!)*@*E*Eb!*LNaNfNfgiNj!k'*<<J-/$:!//))
 	
r3   r%   NNNNNNN)r9   r:   r;   _tied_weights_keysr'   r[  ra  r   r   rL   ri  r   r   r)   rv   rw   r   r   r   r:  r7   r=   r>   s   @r2   rS  rS    s/    )?*X
,8NcDj NBLL N  .237260426*.7;@
##d*@
 ))D0@
 ((4/	@

 &&-@
 ((4/@
   4'@
 #--4@
 +,@
 
/	/@
  @
r3   rS  c                   V    e Zd ZdddZ fdZd Zd Zddedz  d	ej                  f fd
Z
ee	 	 	 	 	 	 ddej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dee   d	eez  fd              Z xZS )MobileBertForMaskedLMrT  rU  rV  c                     t         |   |       t        |d      | _        t	        |      | _        || _        | j                          y NF)rF  )r&   r'   r@  r'  r  rX  r_   rE  r   s     r2   r'   zMobileBertForMaskedLM.__init__   s=     )&EJ(0 	r3   c                 B    | j                   j                  j                  S r%   rZ  rI  s    r2   r[  z+MobileBertForMaskedLM.get_output_embeddings	  r\  r3   c                     || j                   j                  _        |j                  | j                   j                  _        y r%   r^  r_  s     r2   ra  z+MobileBertForMaskedLM.set_output_embeddings  rb  r3   Nrc  r5   c                     | j                  | j                  j                  j                  |d      | j                  j                  _        t        |   |      S re  rg  rj  s     r2   ri  z-MobileBertForMaskedLM.resize_token_embeddings  sR    %)%>%>HH  &&~RV &? &
" w.n.MMr3   rb   r{   rc   rE   rd   rk  r}   c           	      :    | j                   |f||||dd|}|d   }	| j                  |	      }
d}|Ft               } ||
j                  d| j                  j
                        |j                  d            }t        ||
|j                  |j                        S )a  
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the masked language modeling loss. Indices should be in `[-100, 0, ...,
            config.vocab_size]` (see `input_ids` docstring) Tokens with indices set to `-100` are ignored (masked), the
            loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`
        Trn  r   NrG   r;  logitsr   r(  )	r'  rX  r   r   r_   rM   r   r   r(  )r.   rb   r{   rc   rE   rd   rk  r}   rp  r  r  rs  rr  s                r2   r7   zMobileBertForMaskedLM.forward  s    $ "$//
))%'
 
 "!* HH_5')H%&7&<&<RAWAW&XZ`ZeZefhZijN$!//))	
 	
r3   r%   NNNNNN)r9   r:   r;   rv  r'   r[  ra  r   r   rL   ri  r   r   r)   rv   rw   r   r   r   r   r7   r=   r>   s   @r2   rx  rx    s    )?*X
,8NcDj NBLL N  .237260426*.'
##d*'
 ))D0'
 ((4/	'

 &&-'
 ((4/'
   4''
 +,'
 
	'
  '
r3   rx  c                   V     e Zd Z fdZdej
                  dej
                  fdZ xZS )MobileBertOnlyNSPHeadc                 l    t         |           t        j                  |j                  d      | _        y r!  )r&   r'   r   rT   rK   r"  r   s     r2   r'   zMobileBertOnlyNSPHead.__init__D  s'     "		&*<*<a @r3   r
  r5   c                 (    | j                  |      }|S r%   )r"  )r.   r
  r$  s      r2   r7   zMobileBertOnlyNSPHead.forwardH  s    !%!6!6}!E%%r3   r8   r>   s   @r2   r  r  C  s$    A&U\\ &ell &r3   r  zZ
    MobileBert Model with a `next sentence prediction (classification)` head on top.
    c                       e Zd Z fdZee	 	 	 	 	 	 ddej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  d	e	e
   d
eez  fd              Z xZS )#MobileBertForNextSentencePredictionc                     t         |   |       t        |      | _        t	        |      | _        | j                          y r%   )r&   r'   r@  r'  r  rX  rE  r   s     r2   r'   z,MobileBertForNextSentencePrediction.__init__S  s4     )&1(0 	r3   Nrb   r{   rc   rE   rd   rk  r}   r5   c           	          | j                   |f||||dd|}|d   }	| j                  |	      }
d}|2t               } ||
j                  dd      |j                  d            }t	        ||
|j
                  |j                        S )a  
        labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the next sequence prediction (classification) loss. Input should be a sequence pair
            (see `input_ids` docstring) Indices should be in `[0, 1]`.

            - 0 indicates sequence B is a continuation of sequence A,
            - 1 indicates sequence B is a random sequence.

        Examples:

        ```python
        >>> from transformers import AutoTokenizer, MobileBertForNextSentencePrediction
        >>> import torch

        >>> tokenizer = AutoTokenizer.from_pretrained("google/mobilebert-uncased")
        >>> model = MobileBertForNextSentencePrediction.from_pretrained("google/mobilebert-uncased")

        >>> prompt = "In Italy, pizza served in formal settings, such as at a restaurant, is presented unsliced."
        >>> next_sentence = "The sky is blue due to the shorter wavelength of blue light."
        >>> encoding = tokenizer(prompt, next_sentence, return_tensors="pt")

        >>> outputs = model(**encoding, labels=torch.LongTensor([1]))
        >>> loss = outputs.loss
        >>> logits = outputs.logits
        ```Trn  r    NrG   rj   r  )r'  rX  r   r   r   r   r(  )r.   rb   r{   rc   rE   rd   rk  r}   rp  r
  r$  rt  rr  s                r2   r7   z+MobileBertForNextSentencePrediction.forward\  s    L "$//
))%'
 
  
!%-!8!')H!)*@*E*Eb!*LfkkZ\o!^*#)!//))	
 	
r3   r  )r9   r:   r;   r'   r   r   r)   rv   rw   r   r   r   r   r7   r=   r>   s   @r2   r  r  M  s      .237260426*.;
##d*;
 ))D0;
 ((4/	;

 &&-;
 ((4/;
   4';
 +,;
 
,	,;
  ;
r3   r  z
    MobileBert Model transformer with a sequence classification/regression head on top (a linear layer on top of the
    pooled output) e.g. for GLUE tasks.
    c                   *    e Zd Z fdZee	 	 	 	 	 	 ddej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  d	ee	   d
e
ej                     ez  fd              Z xZS )#MobileBertForSequenceClassificationc                 n   t         |   |       |j                  | _        || _        t	        |      | _        |j                  |j                  n|j                  }t        j                  |      | _
        t        j                  |j                  |j                        | _        | j                          y r%   )r&   r'   
num_labelsr_   r@  r'  classifier_dropoutrZ   r   rY   r[   rT   rK   
classifierrE  r.   r_   r  r1   s      r2   r'   z,MobileBertForSequenceClassification.__init__  s      ++)&1)/)B)B)NF%%TZTnTn 	 zz"45))F$6$68I8IJ 	r3   Nrb   r{   rc   rE   rd   rk  r}   r5   c           	          | j                   |f||||dd|}|d   }	| j                  |	      }	| j                  |	      }
d}|| j                  j                  | j
                  dk(  rd| j                  _        nl| j
                  dkD  rL|j                  t        j                  k(  s|j                  t        j                  k(  rd| j                  _        nd| j                  _        | j                  j                  dk(  rIt               }| j
                  dk(  r& ||
j                         |j                               }n ||
|      }n| j                  j                  dk(  r=t               } ||
j                  d| j
                        |j                  d            }n,| j                  j                  dk(  rt               } ||
|      }t        ||
|j                   |j"                  	      S )
a  
        labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the sequence classification/regression loss. Indices should be in `[0, ...,
            config.num_labels - 1]`. If `config.num_labels == 1` a regression loss is computed (Mean-Square loss), If
            `config.num_labels > 1` a classification loss is computed (Cross-Entropy).
        Trn  r    N
regressionsingle_label_classificationmulti_label_classificationrG   r  )r'  r[   r  r_   problem_typer  rf   r)   rn   r   r   squeezer   r   r   r   r   r(  )r.   rb   r{   rc   rE   rd   rk  r}   rp  r
  r  r;  rr  s                r2   r7   z+MobileBertForSequenceClassification.forward  s   $ "$//
))%'
 
  
]3/{{''/??a'/;DKK,__q(fllejj.HFLL\a\e\eLe/LDKK,/KDKK,{{''<7"9??a'#FNN$4fnn6FGD#FF3D))-JJ+-B @&++b/R))-II,./'!//))	
 	
r3   r  )r9   r:   r;   r'   r   r   r)   r<   r   r   r   r   r7   r=   r>   s   @r2   r  r    s      *..2.2,0-1&*;
<<$&;
 t+;
 t+	;

 llT);
 ||d*;
 t#;
 +,;
 
u||	7	7;
  ;
r3   r  c                   J    e Zd Z fdZee	 	 	 	 	 	 	 ddej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  d	ej                  dz  d
ee	   de
ej                     ez  fd              Z xZS )MobileBertForQuestionAnsweringc                     t         |   |       |j                  | _        t        |d      | _        t        j                  |j                  |j                        | _        | j                          y rz  )
r&   r'   r  r@  r'  r   rT   rK   
qa_outputsrE  r   s     r2   r'   z'MobileBertForQuestionAnswering.__init__  sU      ++)&EJ))F$6$68I8IJ 	r3   Nrb   r{   rc   rE   rd   start_positionsend_positionsr}   r5   c           	          | j                   |f||||dd|}	|	d   }
| j                  |
      }|j                  dd      \  }}|j                  d      j	                         }|j                  d      j	                         }d }||t        |j                               dkD  r|j                  d      }t        |j                               dkD  r|j                  d      }|j                  d      }|j                  d|      }|j                  d|      }t        |      } |||      } |||      }||z   dz  }t        ||||	j                  |	j                  	      S )
NTrn  r   r    rG   rk   )ignore_indexrj   )r;  start_logits
end_logitsr   r(  )r'  r  splitr  r   lenrm   clampr   r   r   r(  )r.   rb   r{   rc   rE   rd   r  r  r}   rp  r  r  r  r  rq  ignored_indexrr  
start_lossend_losss                      r2   r7   z&MobileBertForQuestionAnswering.forward   s    "$//
))%'
 
 "!*1#)<<r<#: j#++B/::<''+668

&=+D?'')*Q."1"9"9""==%%'(1, - 5 5b 9(--a0M-33A}EO)//=AM']CH!,@J
M:H$x/14J+%!!//))
 	
r3   ru  )r9   r:   r;   r'   r   r   r)   r<   r   r   r   r   r7   r=   r>   s   @r2   r  r    s      *..2.2,0-1/3-13
<<$&3
 t+3
 t+	3

 llT)3
 ||d*3
 ,3
 ||d*3
 +,3
 
u||	;	;3
  3
r3   r  c                   *    e Zd Z fdZee	 	 	 	 	 	 ddej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  d	ee	   d
e
ej                     ez  fd              Z xZS )MobileBertForMultipleChoicec                 *   t         |   |       t        |      | _        |j                  |j                  n|j
                  }t        j                  |      | _        t        j                  |j                  d      | _        | j                          y r   )r&   r'   r@  r'  r  rZ   r   rY   r[   rT   rK   r  rE  r  s      r2   r'   z$MobileBertForMultipleChoice.__init__;  su     )&1)/)B)B)NF%%TZTnTn 	 zz"45))F$6$6: 	r3   Nrb   r{   rc   rE   rd   rk  r}   r5   c           	         ||j                   d   n|j                   d   }|!|j                  d|j                  d            nd}|!|j                  d|j                  d            nd}|!|j                  d|j                  d            nd}|!|j                  d|j                  d            nd}|1|j                  d|j                  d      |j                  d            nd} | j                  |f||||dd|}	|	d   }
| j	                  |
      }
| j                  |
      }|j                  d|      }d}|t               } |||      }t        |||	j                  |	j                        S )a[  
        input_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`):
            Indices of input sequence tokens in the vocabulary.

            Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
            [`PreTrainedTokenizer.__call__`] for details.

            [What are input IDs?](../glossary#input-ids)
        token_type_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
            Segment token indices to indicate first and second portions of the inputs. Indices are selected in `[0,
            1]`:

            - 0 corresponds to a *sentence A* token,
            - 1 corresponds to a *sentence B* token.

            [What are token type IDs?](../glossary#token-type-ids)
        position_ids (`torch.LongTensor` of shape `(batch_size, num_choices, sequence_length)`, *optional*):
            Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
            config.max_position_embeddings - 1]`.

            [What are position IDs?](../glossary#position-ids)
        inputs_embeds (`torch.FloatTensor` of shape `(batch_size, num_choices, sequence_length, hidden_size)`, *optional*):
            Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
            is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
            model's internal embedding lookup matrix.
        labels (`torch.LongTensor` of shape `(batch_size,)`, *optional*):
            Labels for computing the multiple choice classification loss. Indices should be in `[0, ...,
            num_choices-1]` where `num_choices` is the size of the second dimension of the input tensors. (See
            `input_ids` above)
        Nr    rG   Trn  r  )
r   r   rm   r'  r[   r  r   r   r   r(  )r.   rb   r{   rc   rE   rd   rk  r}   num_choicesrp  r
  r  reshaped_logitsr;  rr  s                  r2   r7   z#MobileBertForMultipleChoice.forwardH  s   T -6,Aiooa(}GZGZ[\G]>G>SINN2y~~b'9:Y]	M[Mg,,R1D1DR1HImqM[Mg,,R1D1DR1HImqGSG_|((\->->r-BCei ( r=#5#5b#9=;M;Mb;QR 	 "$//
))%'
 
  
]3/ ++b+6')HOV4D("!//))	
 	
r3   r  )r9   r:   r;   r'   r   r   r)   r<   r   r   r   r   r7   r=   r>   s   @r2   r  r  8  s      *..2.2,0-1&*N
<<$&N
 t+N
 t+	N

 llT)N
 ||d*N
 t#N
 +,N
 
u||	8	8N
  N
r3   r  c                   *    e Zd Z fdZee	 	 	 	 	 	 ddej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  dej                  dz  d	ee	   d
e
ej                     ez  fd              Z xZS ) MobileBertForTokenClassificationc                 d   t         |   |       |j                  | _        t        |d      | _        |j
                  |j
                  n|j                  }t        j                  |      | _	        t        j                  |j                  |j                        | _        | j                          y rz  )r&   r'   r  r@  r'  r  rZ   r   rY   r[   rT   rK   r  rE  r  s      r2   r'   z)MobileBertForTokenClassification.__init__  s      ++)&EJ)/)B)B)NF%%TZTnTn 	 zz"45))F$6$68I8IJ 	r3   Nrb   r{   rc   rE   rd   rk  r}   r5   c           	      H    | j                   |f||||dd|}|d   }	| j                  |	      }	| j                  |	      }
d}|<t               } ||
j	                  d| j
                        |j	                  d            }t        ||
|j                  |j                        S )z
        labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
            Labels for computing the token classification loss. Indices should be in `[0, ..., config.num_labels - 1]`.
        Trn  r   NrG   r  )	r'  r[   r  r   r   r  r   r   r(  )r.   rb   r{   rc   rE   rd   rk  r}   rp  r  r  r;  rr  s                r2   r7   z(MobileBertForTokenClassification.forward  s      "$//
))%'
 
 "!*,,71')HFKKDOO<fkk"oND$!//))	
 	
r3   r  )r9   r:   r;   r'   r   r   r)   r<   r   r   r   r   r7   r=   r>   s   @r2   r  r    s      *..2.2,0-1&*'
<<$&'
 t+'
 t+	'

 llT)'
 ||d*'
 t#'
 +,'
 
u||	4	4'
  '
r3   r  )
rx  r  r  rS  r  r  r  r   r@  r&  )Nrh   )Ucollections.abcr   dataclassesr   r)   r   torch.nnr   r   r    r
   r+  activationsr   masking_utilsr   modeling_layersr   modeling_outputsr   r   r   r   r   r   r   r   modeling_utilsr   r   processing_utilsr   utilsr   r   r   r   utils.genericr   r   utils.output_capturingr   configuration_mobilebertr!   
get_loggerr9   loggerModuler#   rX   rV   rB   r<   floatr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r&  r:  r@  rS  rx  r  r  r  r  r  r  __all__r>  r3   r2   <module>r     s  . % !   A A & ! 6 9	 	 	 G & M M I 5 6 
		H	%6RYY 6 &
9I299 If !%II%<<% 
% <<	%
 LL4'% T\% % '(%81)bii 1)h299 ".")) .8RYY ryy ryy 0	bii 	!] !]H			 		ryy 	)0 )X@		 @(!ryy !&		 " "!BII !	9 	9 i i i4 
7[ 7 7& C
/ C
 C
L _
8 _
_
D F
5 F
 F
R&BII & 
G
*C G

G
T M
*C M
M
` @
%> @
 @
F ^
"; ^
 ^
B 8
'@ 8
 8
vr3   