
    Nj'                       d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
Zd dl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  ej,                  e      Zeez  Zedz  ez  e	d   z  ZdZ G d dee      Zej@                  f	 	 	 	 	 	 	 	 	 	 	 ddZ!	 	 	 	 	 	 ddZ" ejF                         dd       Z$ ejF                         dd       Z% ejF                         dd       Z& ejF                         dd       Z'ddZ(ddZ)y)    )annotationsN)Enum)Path)Literal)PCA)pad_sequence)tqdm),BaseModelOutputWithPoolingAndCrossAttentions)PreTrainedModelauto   c                       e Zd ZdZdZdZdZdZy)PoolingModea  Pooling modes for embedding creation.

    - MEAN: masked mean over all tokens.
    - LAST: last non-padding token (often EOS, common in decoder-style models).
    - FIRST: first token hidden state (position 0). In BERT-style encoders,
               this corresponds to the [CLS] token representation.
    - POOLER: use the model's `pooler_output`. In BERT-like models this is
               computed as the hidden state at [CLS], passed through a learned
               dense layer + activation. Not all models provide this.
    meanlastfirstpoolerN)__name__
__module____qualname____doc__MEANLASTFIRSTPOOLER     l/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/model2vec/distill/inference.pyr   r      s    	 DDEFr   r   c           	     `   | j                  |      j                         } g }dt        j                  | j                        j
                  v }t        j                  |D cg c]  }t        |       c}      }t        j                  |      }	|	D 
cg c]  }
||
   	 }}
t        t        |      dd      }t        dt        |      t              D ]  }|||t        z    }|D cg c]'  }t        j                  |t        j                        ) }}i }t!        |d|      |d	<   |d	   j#                  d
      }t        j                  |D cg c]  }t        |       c}|d	   j$                        }t        j&                  ||d	   j$                        }|j)                  d      |j)                  d
      k  }|j                  t        j                        |d<   |rt        j*                  |d	         |d<   |t,        j.                  k(  rt1        | |      }nn|t,        j2                  k(  rt5        | |      }nN|t,        j6                  k(  rt9        | |      }n.|t,        j:                  k(  rt=        | |      }nt?        d|       |jA                  |jC                                |jE                  t        |              t        j                  |	      D 
cg c]  }
||
   	 }}
t        jF                  |      }t        jH                  |      }|S c c}w c c}
w c c}w c c}w c c}
w )a  Create output embeddings for a bunch of tokens using a pretrained model.

    It does a forward pass for all tokens passed in `tokens`.

    :param model: The model to use.
        This should be a transformers model.
    :param tokenized: All tokenized tokens.
    :param device: The torch device to use.
    :param pad_token_id: The pad token id. Used to pad sequences.
    :param pooling: The pooling mode to use.
    :return: The output embeddings.
    :raises ValueError: If the pooling mode is unknown.
    token_type_idszEncoding tokensz tokens)totaldescunitr   )dtypeT)batch_firstpadding_value	input_ids   deviceattention_maskzUnknown pooling: )%toevalinspectgetfullargspecforwardargsnpasarraylenargsortr	   range_DEFAULT_BATCH_SIZEtorchtensorlongr   sizer*   arange	unsqueeze
zeros_liker   r   _encode_mean_with_modelr   _encode_last_with_modelr   _encode_first_with_modelr   _encode_pooler_with_model
ValueErrorextendnumpyupdatestack
nan_to_num)model	tokenizedr*   pad_token_idpoolingintermediate_weightsadd_token_type_idssequencelengths
sort_orderisorted_tokenizedpbar	batch_idx
batch_listxbatchencodedseq_lenbatch_lengthstoken_positionsr+   outout_weightss                           r   create_embeddingsr_   +   s   ( HHV!!#E .0 *W-C-CEMM-R-W-WWjj	B	H#h-	BCGG$J.89j	!j9c*+2C)TD1c"235HI	%i)>Q2QR
<FGJqauzz2JG+EtS_` +&++A.j%Ajc!fj%A'R]J^JeJef,,ww{7K7R7RS(22158O8OPQ8RR$2$5$5EJJ$5$G !(-(8(89M(NG$%k&&&)%9C((()%9C)))*5':C***+E7;C0	:;;##CIIK0CJ? JD >@ZZ
=ST=S03=ST((/0K--,K[ C : H &B2 Us    LL%,L!L&
L+c                   |j                         D ci c]!  \  }}||j                  | j                        # }}} | di |}|j                  }|j	                         }t        |dd      }||j	                         }|||fS c c}}w )at  Move inputs to the model device, run a forward pass, and standardize dtypes.

    :param model: The model to use.
    :param encodings: The encoded tokens to turn into features.
    :return: a tuple consisting of:
      - hidden: last_hidden_state
      - pooler: pooler_output if present, else None
      - encodings_on_device: the device-moved encodings (for masks)
    pooler_outputNr   )itemsr,   r*   last_hidden_statefloatgetattr)rI   	encodingskvencodings_on_deviceoutputshiddenr   s           r   _encode_with_modelrl   w   s     >G__=NO=NTQ1add5<<00=NO<A<XDW<XG"44F \\^FWot4F6... Ps   &Bc                ^   t        | |      \  }}}|d   j                         j                         }|j                  dd      j	                  d      }||z  }t        j                  |j                  |j                        dddddf   |      j                  d      j                         S )zEncode a batch of tokens using mean pooling.

    :param model: The model to use.
    :param encodings: The encoded tokens to turn into features.
    :return: The mean of the output for each token.
    r+   r(   T)keepdimg      ?N)
rl   cpurd   sum
clamp_min_r8   bmmr,   r*   squeeze)rI   rf   rk   _ri   maskrP   s          r   r?   r?      s     &8y%I"FA"/0446<<>Dhhq$h'2237G'>D99TWWV]]+AtQJ7@HHKOOQQr   c                <   t        | |      \  }}}|d   j                         }|j                  d      dz
  j                  d      j	                         }t        j                  |j                  d      |j                        }|||ddf   j                         S )zEncode a batch of tokens using last token pooling.

    :param model: The model to use.
    :param encodings: The encoded tokens to turn into features.
    :return: The last hidden state for each token.
    r+   r(   )dimr   r)   N)
rl   boolrp   	clamp_minr:   r8   r<   r;   r*   ro   )rI   rf   rk   rt   ri   ru   last_idxbatch_indicess           r   r@   r@      s     &8y%I"FA"/0557DQ!#..q1668HLLQFM-1,-1133r   c                V    t        | |      \  }}}|dddddf   j                         S )zEncode a batch of tokens using first token (CLS) pooling.

    :param model: The model to use.
    :param encodings: The encoded tokens to turn into features.
    :return: The first token representation for each token.
    Nr   )rl   ro   )rI   rf   rk   rt   s       r   rA   rA      s/     &eY7LFAq!Q'?  r   c                \    t        | |      \  }}}|t        d      |j                         S )a
  Encode a batch of tokens using pooler output.

    :param model: The model to use.
    :param encodings: The encoded tokens to turn into features.
    :return: The pooler output for each token.
    :raises ValueError: If the model does not return pooler_output.
    zAPOOLER pooling requested, but model did not return pooler_output.)rl   rC   ro   )rI   rf   rt   r   s       r   rB   rB      s3     &eY7LAvq~\]]::<r   c                    |t        j                  |       S t        j                  d       dt        j                  d| dz         z  }|t        j
                  |      z  }|||z   z  }|S )z>Compute the weights based on Zipf's law and a SIF coefficient.zDEstimating word frequencies using Zipf's law, and then applying SIF.r(      )r2   onesloggerinfor<   rp   )n_embeddingssif_coefficientinv_rankprobaweights        r   compute_weightsr      se    ww|$$
KKVWBIIa!123Hrvvh''E% 78FMr   c                   ||dk(  r| j                   d   }|| j                   d   kD  r8t        j                  d| d| j                   d    d       | j                   d   }|| j                   d   k\  r+t        j                  d| d| j                   d    d       | S || j                   d   k  rt        |t              rt        j                  d	| d
       nt        j                  d|        | j                   d   }t        |d      }|j                  |       } | j                   d   |k  rt        j                  |j                        }t        j                  |j                        }t        j                  d| d| j                   d    d       t        j                  d|dd       t        j                  d|dd       | S )zApply PCA to the embeddings.r   r(   zPCA dimension (z=) is larger than the number of dimensions in the embeddings (z). Applying PCA, but not reducing dimensionality. Is this is not desired, please set `pca_dims` to None. Applying PCA will probably improve performance, so consider just leaving it.r   z9) is larger than the number of tokens in the vocabulary (z). Not applying PCA.zApplying PCA with z explained variance.zApplying PCA with n_components full)n_components
svd_solverzReduced dimensionality from z to .zExplained variance ratio: z.3fzExplained variance: )shaper   warning
isinstancerd   r   r   fit_transformr2   rp   explained_variance_ratio_explained_variance_)
embeddingspca_dims	orig_dimspexplained_variance_ratioexplained_variances         r   	apply_pcar      s   v!''*Hj&&q))NN!(+hisiyiyz{i|h} ~_ _
 "''*Hz''**NN!(+deoeueuvwexdy  zN  O( # ))!,,(E*0
:NOP=hZHI"((+If=A4J"Y.+-66!2M2M+N(%'VVA,A,A%B":9+T*JZJZ[\J]I^^_`a89QRU8VVWXY23Ec2J!LMr   )rI   r   rJ   zlist[list[int]]r*   strrK   intrL   zPoolingMode | strreturn
np.ndarray)rI   r   rf   dict[str, torch.Tensor]r   zAtuple[torch.Tensor, torch.Tensor | None, dict[str, torch.Tensor]])rI   r   rf   r   r   ztorch.Tensor)r   r   r   zfloat | Noner   r   )r   r   r   
PCADimTyper   r   )*
__future__r   r.   loggingenumr   pathlibr   typingr   rE   r2   r8   sklearn.decompositionr   torch.nn.utils.rnnr   r	   transformers.modeling_outputsr
   transformers.modeling_utilsr   	getLoggerr   r   r   PathLiker   rd   r   r7   r   r   r_   rl   inference_moder?   r@   rA   rB   r   r   r   r   r   <module>r      sg   "        % +  V 7			8	$#:4Z%'&/1
 #t . "-!1!1III I 	I
 I IX//'>/F/2 R R 4 4 ! !  	!r   