Ë
    \›¾j37  ã                   ó  — d Z ddlZddlmZ ddlZddlZddlZddlZddlZddl	Z	ddl
mZ ddlmZ ddlmZmZ ddlmZmZmZmZmZ ddlmZ  ej2                  d	«      Zd
„ Zdd„Zd„ Zdd„Zd„ Zd„ Z e!dk(  r e«        yy)aê  
Entry point for training and evaluating a neural tokenizer.

This tokenizer treats tokenization and sentence segmentation as a tagging problem, and uses a combination of
recurrent and convolutional architectures.
For details please refer to paper: https://nlp.stanford.edu/pubs/qi2018universal.pdf.

Updated: This new version of tokenizer model incorporates the dictionary feature, especially useful for languages that
have multi-syllable words such as Vietnamese, Chinese or Thai. In summary, a lexicon contains all unique words found in 
training dataset and external lexicon (if any) is created during training and saved alongside the model after training.
Using this lexicon, a dictionary is created which includes "words", "prefixes" and "suffixes" sets. During data preparation,
dictionary features are extracted at each character position, to "look ahead" and "look backward" to see if any words formed
found in the dictionary. The window size (or the dictionary feature length) is defined at the 95-percentile among all the existing
words in the lexicon, this is to eliminate the less frequent but long words (avoid having a high-dimension feat vector). Prefixes 
and suffixes are used to stop early during the window-dictionary checking process.  
é    N)Úcopy)Úutils)ÚTrainer)Ú
DataLoaderÚTokenizationDataset)Úload_mwt_dictÚ
eval_modelÚoutput_predictionsÚload_lexiconÚcreate_dictionary)Ú_training_loggingÚstanzac                  óŠ	  — t        j                  «       } | j                  dt        d¬«       | j                  dt        dd¬«       | j                  dt        dd	¬«       | j                  d
t        dd¬«       | j                  dt        d¬«       | j                  dt        dd¬«       | j                  dt        dd¬«       | j                  dt        d¬«       | j                  dt        d¬«       | j                  ddddg¬«       | j                  ddd¬«       | j                  dt        dd ¬«       | j                  d!t        d"d#¬«       | j                  d$t        d%d&¬«       | j                  d'd(d)d*¬+«       | j                  d,d-d)d.¬+«       | j                  d/t
        d0d1¬«       | j                  d2dd3¬«       | j                  d4t        dd5¬«       | j                  d6t        d7d8¬«       | j                  d9dd:¬«       | j                  d;t
        d<d=¬«       | j                  d>t
        d?d@¬«       | j                  dAt        dBdC¬«       | j                  dDt
        dEdF¬«       | j                  dGt
        dHdI¬«       | j                  dJt
        dHdK¬«       | j                  dLt
        dMdN¬«       | j                  dOt
        dHdP¬«       | j                  dQt
        dRdS¬«       | j                  dTt
        dUdV¬«       | j                  dWt
        dUdX¬«       | j                  dYt
        dZd[¬«       | j                  d\t        d]d^¬«       | j                  d_t        dd`¬«       | j                  dat        dbdc¬«       | j                  ddt        dedf¬«       | j                  dgt        dhdi¬«       | j                  djt        d]dk¬«       | j                  dlt        dmdn¬«       | j                  dot        dpdq¬«       | j                  drt        dds¬«       | j                  dtt        ddu¬«       | j                  dvt        dwdx¬«       t        j                  | «       | j                  dyt        dz¬{«       | j                  d|d}ddd~¬«       | j                  d€d}d)d�¬+«       | j                  d‚ddƒ¬«       | j                  d„dd…¬†«       | S )‡z4
    If args == None, the system args are used.
    z
--txt_filezInput plaintext file)ÚtypeÚhelpz--label_fileNzCharacter-level label file)r   Údefaultr   z--mwt_json_filezJSON file for MWT expansionsz--conll_filezCoNLL file for outputz--dev_txt_filez1(Train only) Input plaintext file for the dev setz--dev_label_filez7(Train only) Character-level label file for the dev setz--dev_conll_goldz<(Train only) CoNLL-U file for the dev set for early stoppingz--langÚLanguagez--shorthandzUD treebank shorthandz--modeÚtrainÚpredict)r   Úchoicesz--skip_newlineÚ
store_truez\Whether to skip newline characters in input. Particularly useful for languages like Chinese.)Úactionr   z	--emb_dimé    zDimension of unit embeddingsz--hidden_dimé@   zDimension of hidden unitsz--conv_filtersz1,9zbConfiguration of conv filters. ,, separates layers and , separates filter sizes in the same layer.z--no-residualÚresidualÚstore_falsezAdd linear residual connections)Údestr   r   z--no-hierarchicalÚhierarchicalz"Hierarchical" RNN tokenizerz--hier_invtempç      à?zSInverse temperature used in propagating tokenization predictions between RNN layersz--input_dropoutz Dropout input embeddings as wellz
--conv_resz)Convolutional residual layers for the RNNz--rnn_layersé   zLayers of RNN in the tokenizerz--use_dictionarya(  Use dictionary feature. The lexicon is created using the training data and external dict (if any) expected to be found under the same folder of training dataset, formatted as SHORTHAND-externaldict.txt where each line in this file is a word. For example, data/tokenize/zh_gsdsimp-externaldict.txtz--max_grad_normg      ð?z Maximum gradient norm to clip toz--annealg+‡ÙÎ÷ï?zHAnneal the learning rate by this amount when dev performance deterioratez--anneal_afteriÐ  z2Anneal the learning rate no earlier than this stepz--lr0gü©ñÒMb`?zInitial learning ratez	--dropoutg…ëQ¸Õ?zDropout probabilityz--unit_dropoutzUnit dropout probabilityz--feat_dropoutgš™™™™™©?z?Features dropout probability for each element in feature vectorz--feat_unit_dropoutz.The whole feature of units dropout probabilityz--tok_noiseg{®Gáz”?z:Probability to induce noise to the input of the higher RNNz--sent_drop_probgš™™™™™É?z|Probability to drop sentences at the end of batches during training uniformly at random.  Idea is to fake paragraph endings.z--last_char_drop_probzùProbability to drop the last char of a block of text during training, uniformly at random.  Idea is to fake a document ending w/o sentence final punctuation, hopefully to avoid the tokenizer learning to always tokenize the last character as a periodz--weight_decayg        zWeight decayz--max_seqlenéd   z-Maximum sequence length to consider at a timez--batch_sizezBatch size to usez--epochsé
   z#Total epochs to train the model forz--stepsiPÃ  z7Steps to train the model for, if unspecified use epochsz--report_stepsé   z#Update step interval to report lossz--shuffle_stepsz8Step interval to shuffle each paragraph in the generatorz--eval_stepséÈ   zEStep interval to evaluate the model on the dev set for early stoppingz--max_steps_before_stopiˆ  zJEarly terminates after this many steps if the dev scores are not improvingz--save_namezFile name to save the modelz--load_namezFile name to load a saved modelz
--save_dirzsaved_models/tokenizezDirectory to save models inz--seediÒ  )r   r   z	--use_mwtÚuse_mwtz}Whether or not to include mwt output layers.  If set to None, this will be determined by examining the training data for MWTs)r   r   r   r   z--no_use_mwtz+Whether or not to include mwt output layersz--wandbzStart a wandb session and write the results of training.  Only applies to training.  Use --wandb_name instead to specify a namez--wandb_namezWName of a wandb session to start when training.  Will default to the dataset short name)r   r   )ÚargparseÚArgumentParserÚadd_argumentÚstrÚintÚfloatr   Úadd_device_args)Úparsers    úa/home/spazio/kingdom_calls/work5/transenv/lib/python3.12/site-packages/stanza/models/tokenizer.pyÚbuild_argparser/   "   s<  € ô ×$Ñ$Ó&€FØ
×Ñ˜¬3Ð5KÐÔLØ
×Ñ˜¬S¸$ÐEaÐÔbØ
×ÑÐ)´¸TÐHfÐÔgØ
×Ñ˜¬S¸$ÐE\ÐÔ]Ø
×ÑÐ(¬sÐ9lÐÔmØ
×ÑÐ*´¸dð  JCÐô  DØ
×ÑÐ*´¸dð  JHÐô  IØ
×Ñ˜¤s°ÐÔ<Ø
×Ñ˜¬CÐ6MÐÔNà
×Ñ˜¨'¸GÀYÐ;OÐÔPØ
×ÑÐ(°ð  EcÐô  dà
×Ñ˜¬#°rÐ@^ÐÔ_Ø
×Ñ˜¬S¸"ÐC^ÐÔ_Ø
×ÑÐ(¬s¸Eð  ImÐô  nØ
×Ñ˜¨jÀÐUvÐÔwØ
×ÑÐ+°.ÈÐ]}ÐÔ~Ø
×ÑÐ(¬u¸cð  I^Ðô  _Ø
×ÑÐ)°,ÐEgÐÔhØ
×Ñ˜¬3¸ÐCnÐÔoØ
×Ñ˜¬S¸!ÐBbÐÔcØ
×ÑÐ*°<ð  GqÐô  rà
×ÑÐ)´¸sÐIkÐÔlØ
×Ñ˜
¬¸ð  DNÐô  OØ
×ÑÐ(¬s¸DÐG{ÐÔ|Ø
×Ñ˜¤e°TÐ@WÐÔXØ
×Ñ˜¬%¸ÐDYÐÔZØ
×ÑÐ(¬u¸dÐIcÐÔdØ
×ÑÐ(¬u¸dð  JKÐô  LØ
×ÑÐ-´EÀ4ÐN~ÐÔØ
×Ñ˜¬E¸4ð  GCÐô  DØ
×ÑÐ*´Àð  KIÐô  JØ
×ÑÐ/´eÀSð  PKÐô  LØ
×ÑÐ(¬u¸cÈÐÔWØ
×Ñ˜¬S¸#ÐDsÐÔtØ
×Ñ˜¬S¸"ÐCVÐÔWØ
×Ñ˜
¬°bÐ?dÐÔeØ
×Ñ˜	¬°UÐAzÐÔ{Ø
×ÑÐ(¬s¸BÐEjÐÔkØ
×ÑÐ)´¸Sð  HBÐô  CØ
×Ñ˜¬S¸#ð  ELÐô  MØ
×ÑÐ1¼ÀTð  Q]Ðô  ^Ø
×Ñ˜¬C¸ÐDaÐÔbØ
×Ñ˜¬C¸ÐDeÐÔfØ
×Ñ˜¬3Ð8OÐVsÐÔtÜ	×Ñ˜&Ô!Ø
×Ñ˜¤s°DÐÔ9à
×Ñ˜¨)¸TÈ,ð  ^]Ðô  ^Ø
×Ñ˜¨Y¸}ð  TAÐô  Bà
×Ñ˜	¨,ð  >Ðô  @Ø
×Ñ˜°ð  <UÐô  VØ€Mó    c                 óz   — t        «       }|j                  | ¬«      } | j                  rd| _        t	        | «      } | S )N©ÚargsT)r/   Ú
parse_argsÚ
wandb_nameÚwandbÚvars)r3   r-   s     r.   r4   r4   `   s9   € ÜÓ€FØ×Ñ $ÐÓ'€Dà‡‚ØˆŒ
ä�‹:€DØ€Kr0   c                 ó0  — | d   �| d   }n| d   dz   }t         j                  j                  t         j                  j                  | d   |«      «      s!t         j                  j                  |«      r|S t         j                  j                  | d   |«      S )NÚ	save_nameÚ	shorthandz_tokenizer.ptÚsave_dir)ÚosÚpathÚexistsÚjoin)r3   r9   s     r.   Úmodel_file_namer@   j   sz   € ØˆKÑÐ$Ø˜Ñ%‰	à˜Ñ%¨Ñ7ˆ	ä�7‰7�>‰>œ"Ÿ'™'Ÿ,™, t¨JÑ'7¸ÓCÔDÌÏÉÏÉÐXaÔIbØÐÜ�7‰7�<‰<˜˜ZÑ(¨)Ó4Ð4r0   c                 ó”  — t        | ¬«      } t        j                  | d   «       t        j	                  dj                  | d   «      «       g d¢| d<   t        | d   «      | d<   t        | «      | d<   t        j                  t        j                  j                  | d   «      d	   «       | d   d
k(  rt        | «       y t        | «       y )Nr2   ÚseedzRunning tokenizer in {} modeÚmode)Úspace_beforeÚcapitalizedÚnumericÚend_of_paraÚstart_of_paraÚ
feat_funcsÚfeat_dimr9   r   r   )r4   r   Úset_random_seedÚloggerÚinfoÚformatÚlenr@   Ú
ensure_dirr<   r=   Úsplitr   Úevaluater2   s    r.   ÚmainrS   t   s¦   € Ü˜4Ô €Dä	×Ñ˜$˜v™,Ô'ä
‡K�KÐ.×5Ñ5°d¸6±lÓCÔDâc€DˆÑÜ˜4 Ñ-Ó.€DˆÑÜ'¨Ó-€DˆÑÜ	×Ñ”R—W‘W—]‘] 4¨Ñ#4Ó5°aÑ8Ô9àˆF�|�wÒÜˆd�ä��r0   c                 óF  — | d   r0t        | «      \  }| d<   t        |«      }| dxx   | d   dz  z  cc<   n	d| d<   d }d }t        | d   «      }| d   | d   d	œ}t        | ||¬
«      }|j                  }t        |«      | d<   | d   | d   d	œ}t        | ||d|¬«      }| d   €B|j                  «       | d<   t        j                  dj                  | d   rdnd| d   «      «       t        | |||| d   ¬«      }	| d   �7t        j                  j                  | d   | d   «      }
|	j                  |
«       |	j!                  | d   «       t        |«      }| d   �| d   nt#        || d   z  | d   z  dz   «      }| d   }d}d}d}| d   rcdd l}| d   r| d   nd | d!   z  }|j'                  || ¬"«       |j(                  j+                  d#d$¬%«       |j(                  j+                  d&d'¬%«       t-        d(|d(z   «      D �]¿  }|j/                  | d)   | d*   ¬+«      }|	j1                  |«      }|| d,   z  dk(  r@t        j                  d-j                  |||«      «       | d   rj3                  d#|i|¬.«       | d/   dkD  r|| d/   z  dk(  r|j5                  «        || d0   z  dk(  sŒ¨t7        | |	|||«      }| d   rj3                  d&|i|¬.«       d1j                  |d2z  «      g}|| d3   k\  r:||k  r5|d4j                  ||| d5   z  «      gz  }|| d5   z  }|	j!                  |«       |}||kD  r|d6gz  }|}|}|	j9                  | d7   «       nN|dkD  rI||z
  | d8   kD  r>|d9j                  ||z
  «      gz  }t        j                  d:j                  |«      «        n't        j                  d:j                  |«      «       �ŒÂ | d   rj;                  «        |dkD  r&t        j                  d;j                  ||«      «       y t        j                  d<«       |	j9                  | d7   «       y )=NÚuse_dictionaryÚnum_dict_featrJ   é   r   Úmwt_json_fileÚtxt_fileÚ
label_file©ÚtxtÚlabel)Úinput_filesÚ
dictionaryÚ
vocab_sizeÚdev_txt_fileÚdev_label_fileT©r^   ÚvocabÚ
evaluationr_   r%   z9Found {}mwts in the training data.  Setting use_mwt to {}Ú zno Údevice)r3   rd   Úlexiconr_   rg   Ú	load_namer;   Úlr0ÚstepsÚepochsÚ
batch_sizer   éÿÿÿÿr6   r5   z%s_tokenizerr:   )ÚnameÚconfigÚ
train_lossÚmin)ÚsummaryÚ	dev_scoreÚmaxr    Úunit_dropoutÚfeat_unit_dropout)rv   rw   Úreport_stepszStep {:6d}/{:6d} Loss: {:.3f})ÚstepÚshuffle_stepsÚ
eval_stepszDev score: {:6.3f}r!   Úanneal_afterzlr: {:.6f} -> {:.6f}ÚannealzNew best dev score!r9   Úmax_steps_before_stopz4Stopping training after {} steps with no improvementú	zBest dev score={} at step {}z,Dev set never evaluated.  Saving final model)r   r   r   r   rd   rO   r   Úhas_mwtrL   rM   rN   r   r<   r=   r?   ÚloadÚ	change_lrr*   r6   ÚinitÚrunÚdefine_metricÚrangeÚnextÚupdateÚlogÚshuffler	   ÚsaveÚfinish)r3   rh   r_   Úmwt_dictÚtrain_input_filesÚtrain_batchesrd   Údev_input_filesÚdev_batchesÚtrainerri   ÚNrk   ÚlrÚprev_dev_scoreÚbest_dev_scoreÚbest_dev_stepr6   r5   ry   ÚbatchÚlossrt   Úreportss                           r.   r   r   …   sª  € ØÐÒä)5°dÓ);Ñ&ˆ��oÑ&ä& wÓ/ˆ
àˆZÓ˜D Ñ1°!Ñ3Ñ3Ôà !ˆˆ_ÑØˆØˆ
ä˜T /Ñ2Ó3€Hð ˜
Ñ#Ø˜,Ñ'ñÐô ˜tÐ1BÈzÔZ€MØ×Ñ€Eä˜U›€DˆÑð ˜Ñ'ØÐ*Ñ+ñ€Oô & d¸ÈuÐaeÐr|Ô}€KàˆI�ÐØ'×/Ñ/Ó1ˆˆY‰Ü�‰ÐO×VÑVÐ^bÐclÒ^mÑXZÐsxÐ{ð  AJñ  |Kó  Lô  	Mä˜4 u°gÈ*Ð]aÐbjÑ]kÔl€GàˆKÑÐ$Ü—G‘G—L‘L  jÑ!1°4¸Ñ3DÓEˆ	Ø�‰�YÔØ×Ñ�d˜5‘kÔ"äˆMÓ€AØ! '™]Ð6ˆD�ŠM¼CÀÀDÈÁNÑ@RÐUYÐZfÑUgÑ@gÐjlÑ@lÓ<m€EØ	ˆe‰€Bà€NØ€NØ€MàˆG‚}ÛØ+/°Ò+=�T˜,Ò'À>ÐTXÐYdÑTeÑCeˆ
Ø�
‰
˜
¨4ˆ
Ô0Ø�	‰	×Ñ °eÐÔ<Ø�	‰	×Ñ °UÐÔ;ô �a˜˜q™Ó!ó ",ˆØ×"Ñ"°°^Ñ0DÐZ^Ð_rÑZsÐ"Ótˆà�~‰~˜eÓ$ˆØ�$�~Ñ&Ñ&¨!Ò+Ü�K‰KÐ7×>Ñ>¸tÀUÈDÓQÔRØ�GŠ}Ø—	‘	˜<¨Ð.°T�	Ô:à�Ñ  1Ò$¨°°_Ñ0EÑ)EÈÒ)JØ×!Ñ!Ô#à�$�|Ñ$Ñ$¨Ó)Ü" 4¨°+¸uÀhÓOˆIØ�GŠ}Ø—	‘	˜;¨	Ð2¸�	Ô>Ø+×2Ñ2°9¸s±?ÓCÐDˆGØ�t˜NÑ+Ò+°	¸NÒ0JØÐ2×9Ñ9¸"¸bÀ4ÈÁ>Ñ>QÓRÐSÑS�Ø�d˜8‘nÑ$�Ø×!Ñ! "Ô%à&ˆNà˜>Ò)ØÐ1Ð2Ñ2�Ø!*�Ø $�Ø—‘˜T +Ñ.Õ/Ø Ò" t¨mÑ';¸dÐCZÑ>[Ò'[ØÐR×YÑYÐZ^ÐanÑZnÓoÐpÑp�Ü—‘˜DŸI™I gÓ.Ô/Ùä�K‰K˜Ÿ	™	 'Ó*Ö+ðE",ðH ˆG‚}Ø�‰Œà�rÒÜ�‰Ð2×9Ñ9¸.È-ÓXÕYä�‰ÐBÔCØ�‰�T˜+Ñ&Õ'r0   c           	      ó¨  — t        | d   «      }t        | d   xs | d   | d   ¬«      }|j                  |j                  }}|D ]!  }|j	                  d«      rŒ|dvsŒ||   | |<   Œ# | d   | d	   d
œ}t        | ||d|j                  ¬«      }t        | d   ||||| d   «      \  }}	}
}
t        j                  dj                  ||	z  dz  ||	«      «       y )NrX   ri   r9   rg   )Ú
model_filerg   Ú_file)rg   rC   r;   ri   r9   rY   rZ   r[   Trc   Ú
conll_fileÚ
max_seqlenz OOV rate: {:6.3f}% ({:6d}/{:6d})r!   )r   r   r3   rd   Úendswithr   r_   r
   rL   rM   rN   )r3   r�   r’   Úloaded_argsrd   ÚkÚeval_input_filesÚbatchesÚ	oov_countr“   Ú_s              r.   rR   rR   ë   s  € Ü˜T /Ñ2Ó3€HÜ  kÑ!2Ò!G°d¸;Ñ6GÐPTÐU]ÑP^Ô_€GØ Ÿ™ w§}¡}�€Kàò %ˆØ�z‰z˜'Õ" qÐ0hÒ'hØ! !‘nˆD�ŠGð%ð
 ˜
Ñ#Ø˜,Ñ'ñÐô " $Ð4DÈEÐ^bÐov÷  pBñ  pBô  C€Gä+¨D°Ñ,>ÀÈÐRWÐYaÐcgÐhtÑcuÓvÑ€Iˆq�!�Qä
‡K�KÐ2×9Ñ9¸)Àa¹-È#Ñ:MÈyÐZ[Ó\Õ]r0   Ú__main__)N)"Ú__doc__r&   r   ÚloggingÚrandomÚnumpyÚnpr<   ÚtorchÚjsonÚstanza.models.commonr   Ú"stanza.models.tokenization.trainerr   Ústanza.models.tokenization.datar   r   Ú stanza.models.tokenization.utilsr   r	   r
   r   r   Ústanza.modelsr   Ú	getLoggerrL   r/   r4   r@   rS   r   rR   Ú__name__© r0   r.   ú<module>r·      s~   ðñó" Ý Û Û Û Û 	Û Û Ý &Ý 6ß Kß {Õ {Ý +à	ˆ×	Ñ	˜8Ó	$€ò<ó|ò5óò"d(òL^ð, ˆzÒÙ…Fð r0   