
    h:                        S SK r S SKrS SKrS SKJr  S SKJr  S SKJ	r	J
r
JrJrJrJrJrJrJrJr  S SKJrJrJrJrJr  S SKJr  SSKJr  SS	KJr  SS
KJ r J!r!J"r"  SSK#J$r$  \
(       a  SSK%J&r&  Sr'Sr( S3S\RR                  \RT                  S.SSS\\   S\+S\	S\	S\S\\   4   4S jjjr,SSS\S\-S\+S\+S\+S\+S \\.   S!\\.   S"\\S\\.\4   /S4      4S# jr/S$ r0SSS%\S&\\.\-4   S\/ \\-\\.\-4   4   4   4S' jr1SSS(\S/\\$   4   S)\\\$   /\\$   4   S*\+4S+ jr2S,\\\.\4   \4   SSS-\\.\4   SS4S. jr3S/\\S/S4      S\S/S4   4S0 jr4S1\\   SS4S2 jr5g)4    N)Path)default_timer)
IOTYPE_CHECKINGAnyCallableDictIterableListOptionalTupleUnion)Config	Optimizerconstantfix_random_seedset_gpu_allocator)Printer   )Errors)ConfigSchemaTraining)loggerregistryresolve_dot_names   )ExampleLanguagez
model-bestz
model-last)use_gpustdoutstderrnlpr   output_pathr    r!   r"   returnc                  ^ ^^^ [        SS9nT R                  R                  5       nUS   S   b  [        US   S   5        US   S   nUS:  a  U(       a  [	        U5        [
        R                  " US   [        S9nUS	   US
   /n	[        Xi5      u  pUS   mUS   nUS   nUS   n[        US   5      mUS   nUU UU4S jnUS   nUS   n[        T T[        T XUS   5      [        T X5      US   US   US   US   US   UUUS9n[        T5        UR                  UR                  ST R                    35      S-   5        U(       a&  UR                  UR                  SU 35      S-   5        U(       a&  UR                  UR                  SU 35      S-   5        UR                  UR                  STR"                   35      S-   5        T R%                  US 9   U" T X45      u  nnSSS5         U H\  u  nnnUbE  T R%                  US 9   ['        UT U5        SSS5        Tb  U" U5        [)        T[*        -  5      US!'   W" Ub  UOS5        M^      W" 5         Tb  U" S#5        TR2                  (       a  T R5                  TR2                  5        Tb6  UR                  UR7                  S$T[*        -  5      S-   5        T T[*        -  4$ T S4$ ! , (       d  f       N= f! , (       d  f       N= f! [,         a9  nTb/  UR                  UR/                  S"[1        U5       35      S-   5        UeSnAff = f! W" 5         Tb	  U" S#5        f f = f)%a-  Train a pipeline.

nlp (Language): The initialized nlp object with the full config.
output_path (Optional[Path]): Optional output path to save trained model to.
use_gpu (int): Whether to train on GPU. Make sure to call require_gpu
    before calling this function.
stdout (file): A file-like object to write output messages. To disable
    printing, set to io.StringIO.
stderr (file): A second file-like object to write output messages. To disable
    printing, set to io.StringIO.

RETURNS (tuple): The final nlp object and the path to the exported model.
T)no_printtrainingseedNgpu_allocatorr   )schematrain_corpus
dev_corpus	optimizerscore_weightsbatcherr   before_to_diskbefore_updatec                 x  > TR                  TR                  5         T" T5      R                  T[        -  5        S S S 5        U (       a_  T[        -  R                  5       (       a  [        R                  " T[        -  5        [        R                  " T[        -  T[        -  5        g g ! , (       d  f       Nu= fN)	
use_paramsaveragesto_diskDIR_MODEL_LASTDIR_MODEL_BESTexistsshutilrmtreecopytree)is_bestr1   r#   r.   r$   s    M/home/james-whalen/.local/lib/python3.13/site-packages/spacy/training/loop.pysave_checkpointtrain.<locals>.save_checkpointM   s    ^^I../3''n(DE 0 n,4466kN:;OOK.8+:VW  0/s   B++
B9frozen_componentsannotating_components
max_epochsdropoutaccumulate_gradientpatience	max_stepseval_frequency)rE   rF   rG   rH   rI   excluderC   r2   z
Pipeline: 
zFrozen components: zSet annotations on update for: zInitial learn rate: )disabler$   zAAborting and saving the final best model. Encountered exception: Fz"Saved pipeline to output directory)r   configinterpolater   r   r   resolver   r   create_before_to_disk_callbacktrain_while_improvingcreate_train_batchescreate_evaluation_callbackclean_output_dirwriteinfo
pipe_names
learn_rateselect_pipesupdate_metastrr8   	Exceptionwarnreprr6   r5   good)r#   r$   r    r!   r"   msgrM   	allocatorT	dot_namesr,   r-   r/   r0   train_loggerr2   r@   rB   rC   training_step_iteratorlog_stepfinalize_loggerbatchrV   is_best_checkpointer1   r.   s   ``                        @@r?   trainrk   #   s   , 4
 CZZ##%Fj&!-z*623z"?3I!|	)$
+4HIA>"AlO4I0CL+Io&M	lGX;L3A6F4GHNo&MX X -.562S,<I"3
B)34:K.)*!3# [!
LLJs~~&6784?@SXX 34E3FGH4OPHH67L6MNORVV	
 LL01E1E0FGH4OP			"3		4$0f$E!/ 
5#/E+E4+!-%%.?%@3- A*#$67*-kN.J*KD'/;TF 0F& 	"E"y))*HH9;;WX	
 [>122T{G 
5	4
 A@  	"LL..21gY8 	 	 	"E" #sH   K4K4 K#9K4 
K #
K1	-K4 4
L7>4L22L77L: :Mr.   rE   rI   rF   rG   rH   rJ   rC   r2   c             #   <  #    [        U[        5      (       a  [        U5      nOUn/ n0 nSn[        5       n[	        U5       GH  u  nu  nnU(       a  UUS.nU" U U5        [        U5      n[        UU5       H  nU R                  UUUSU	U
S9  M     U R                   HW  u  nnUU	;  d  M  [        US5      (       d  M!  UR                  (       d  M4  UR                  S;  d  MF  UR                  U5        MY     UR                  5         UU-  (       do  UR                  (       a/  U R                  UR                  5         U" 5       u  nnSSS5        O
U" 5       u  nnUR!                  WU45        U[#        U5      S   :H  nOSu  nnSnU[%        S	 U 5       5      -  nUUUWUU['        [        5       U-
  5      US
.nUUU4v   Ub  0 n[#        S U 5       5      nUS   * nU(       a  UU-
  U:  a    gU(       d  GM  UU:  d  GM    g   g! , (       d  f       N= f7f)a  Train until an evaluation stops improving. Works as a generator,
with each iteration yielding a tuple `(batch, info, is_best_checkpoint)`,
where info is a dict, and is_best_checkpoint is in [True, False, None] --
None indicating that the iteration was not evaluated as a checkpoint.
The evaluation is conducted by calling the evaluate callback.

Positional arguments:
    nlp: The spaCy pipeline to evaluate.
    optimizer: The optimizer callable.
    train_data (Iterable[Batch]): A generator of batches, with the training
        data. Each batch should be a Sized[Tuple[Input, Annot]]. The training
        data iterable needs to take care of iterating over the epochs and
        shuffling.
    evaluate (Callable[[], Tuple[float, Any]]): A callback to perform evaluation.
        The callback should take no arguments and return a tuple
        `(main_score, other_scores)`. The main_score should be a float where
        higher is better. other_scores can be any object.

Every iteration, the function yields out a tuple with:

* batch: A list of Example objects.
* info: A dict with various information about the last update (see below).
* is_best_checkpoint: A value in None, False, True, indicating whether this
    was the best evaluation so far. You should use this to save the model
    checkpoints during training. If None, evaluation was not conducted on
    that iteration. False means evaluation was conducted, but a previous
    evaluation was better.

The info dict provides the following information:

    epoch (int): How many passes over the data have been completed.
    step (int): How many steps have been completed.
    score (float): The main score from the last evaluation.
    other_scores: : The other scores from the last evaluation.
    losses: The accumulated losses throughout training.
    checkpoints: A list of previous results, where each result is a
        (score, step, epoch) tuple.
r   )stepepochF)droplossessgdrJ   	annotatesis_trainable)TFNN)NNc              3   8   #    U  H  n[        U5      v   M     g 7fr4   )len).0egs     r?   	<genexpr>(train_while_improving.<locals>.<genexpr>   s     2Eb#b''Es   )rn   rm   scoreother_scoresrp   checkpointssecondswordsc              3   .   #    U  H  u  pX* 4v   M     g 7fr4    )rv   r_scorer_steps      r?   rx   ry   
  s     LG7G,Gs   r   )
isinstancefloatr   timer	enumeratenextsubdivide_batchupdatepipelinehasattrrs   modelfinish_updatestep_schedulesr6   r5   appendmaxsumint)r#   r.   
train_dataevaluaterE   rI   rF   rG   rH   rJ   rC   r2   dropoutsresultsrp   
words_seen
start_timerm   rn   rh   before_update_argssubbatchnameprocrz   r{   ri   rV   best_result	best_steps                                 r?   rQ   rQ      s"    j '5!!G$G!FJJ )* 5nue*.!?#12x.'/BCHJJ/   D ,,JD$G#D.11%%%JJ&99""9- ' 	  "~%!!^^I$6$67*2*'E< 87 '/j#|NNE4=)!&#g,q/!9".E<!%c2E222
("57Z/0	
 T---)F LGLL ^O		)h69*u !64 87sD   B&H,H?HH$AH?H
B.H=HH
H	Hc              #      #    [        U 5      n U R                  S S9  [        U 5      U-  nSn[        U5       H"  nXX2-    nU(       a  Uv   U[        U5      -  nM$     XS  nU(       a  Uv   g g 7f)Nc                 ,    [        U R                  5      $ r4   )ru   	predicted)rw   s    r?   <lambda>!subdivide_batch.<locals>.<lambda>  s    c",,/    )keyr   )listsortru   range)rh   rF   sub_lenstartir   s         r?   r   r     s{     KE	JJ/J0%j//GE&'1NX	 (
 V}H s   A.A0r-   weightsc                    ^ ^^ TR                  5        VVs0 s H  u  p4Uc  M
  X4_M     snnmS[        [        [        [        [        4   4   4UU U4S jjnU$ s  snnf )Nr%   c            	      N  >^  TR                  T" T5      5      mTR                  5        VVs0 s H  u  pUc  M
  X_M     snnmT	R                  5        VVs0 s H  u  pUT;   d  M  X_M     snnm	TR                  5        HX  u  pUT	;   d  M  [        U[        [        45      (       a  M*  [        [        R                  R	                  U[        U5      S95      e    [        UU	4S jT	 5       5      nUT4$ ! [         a6  n [        [        R                  R	                  TR
                  S95      U eS n A ff = fs  snnf s  snnf ! [         aR  n [        TR                  5       5      n[        R                   R	                  S[#        U 5      US9n[        U5      S eS n A ff = f)N)r   )r   
score_typec              3   n   >#    U  H*  nTR                  US 5      TR                  US 5      -  v   M,     g7f)        N)get)rv   sscoresr   s     r?   rx   ?create_evaluation_callback.<locals>.evaluate.<locals>.<genexpr>6  s/      !BIQ

1c"W[[C%88's   25r/   )dictr   keys)r   KeyErrorr   E900formatrW   itemsr   r   r   
ValueErrorE915typer   r   r   E983r[   )
rj   r   valueweighted_scorer   errr   r-   r#   r   s
         @r?   r   ,create_evaluation_callback.<locals>.evaluate'  sf   	O\\*S/2F 06||~S~*#*~S07Q*#3&=:3:Q ,,.JCg~je&E&E !3!3e!3!UVV )	*  !BI! N v%%%  	O6;;--s~~-FGQN	O
 TQ  	*&D++$$/s1vD$QC3-T)	*sF   C9 	D<D<E(EE 9
D91D44D9
F$AFF$)r   r   r   r	   r[   )r#   r-   r   r   r   r   s   ```   r?   rS   rS   "  sX     -4MMOQOjcuzszOQG&eE4U
#334 & &0 O5 Rs
   	AAcorpusr0   rD   c              #   0  #    SnUS:  a1  [        U" U 5      5      nU(       d  [        [        R                  5      eUS:  d  XC:w  aN  US:  a  [        R
                  " W5        OU" U 5      nU" U5       H  nXF4v   M
     US-  nUS:  a  MF  XC:w  a  MM  g g 7f)Nr   r   )r   r   r   E986randomshuffle)r#   r   r0   rD   rn   examplesrh   s          r?   rR   rR   B  s      EQs$V[[))
q.E/?NN8$c{HX&E, '
 q.E/s   B	BBBr(   rV   c                     0 UR                   S'   U S    H-  nUc  M  US   R                  US5      UR                   S   U'   M/     UR                   H(  nXBS   ;   d  M  US   U   UR                   S   U S3'   M*     g )Nperformancer/   r{   r   rp   _loss)metar   rW   )r(   r#   rV   metric	pipe_names        r?   rZ   rZ   X  s     !CHH]?+.2>.B.F.Fvs.SCHH]#F+ , ^^	X&;?>);TCHH]#yk$78 $r   callbackc                 0   ^ ^ SSK Jm  STST4UU 4S jjnU$ )Nr   r   r#   r%   c                    > T(       d  U $ T" U 5      n[        UT5      (       d2  [        R                  R                  S[	        U5      S9n[        U5      eU$ )Nr1   )r   r   )r   r   E914r   r   r   )r#   modified_nlpr   r   r   s      r?   r1   6create_before_to_disk_callback.<locals>.before_to_diski  sP    J},11++$$*:$|BT$UCS/!r   )languager   )r   r1   r   s   ` @r?   rP   rP   d  s(     $H    r   pathc                 x   U b~  U R                  5       (       ah  U [        -  U [        -  4 HQ  nUR                  5       (       d  M   [        R                  " [        U5      5        [        R                  " SU5        MS     ggg! [         a,  n[        [        R                  R                  U S95      UeSnAff = f)zRemove an existing output directory. Typically used to ensure that that
a directory like model-best and its contents aren't just being overwritten
by nlp.to_disk, which could preserve existing subdirectories (e.g.
components that don't exist anymore).
Nz%Removed existing output directory: %s)r   )r:   r9   r8   r;   r<   r[   r   debugr\   IOErrorr   E901r   )r   subdirrj   s      r?   rT   rT   u  s     DKKMMn,d^.CDF}}HMM#f+.LL!H&Q	 E * ! H!&++"4"4$"4"?@aGHs   6B
B9'B44B9r4   )6r   r;   syspathlibr   timeitr   r   typingr   r   r   r   r	   r
   r   r   r   r   	thinc.apir   r   r   r   r   wasabir   errorsr   schemasr   utilr   r   r   exampler   r   r   r9   r8   r!   r"   r   rk   r   r[   rQ   r   rS   rR   rZ   rP   rT   r   r   r?   <module>r      s     
  )   V U   * 6 6 # 
 #'s s	s$s 	s
 s s :x~%&slw	ww w w w w w #Yw  9w Hj$sCx.%A4%GHIwt	!)48e4Db%tCJ//001@	j\8G#445 x()8G+<<= 	,	UDcNF*+	U2<	UDHcN	U		Uxj 89:zlJ&'"H8D> Hd Hr   