o
    h@                     @   s  d 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	  m
  mZ ddlm	  m
  mZ ddlm	  m
  mZ ddlmZmZ ddlmZmZ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" dd
l#m$Z$ ddl%m&Z& ddl'Z'e(dZ)G dd dZ*dS )zx
Organizes the model itself and its optimizer in one place

Saving the optimizer allows for easy restarting of training
    N)SimpleNamespace)	CNNConfigConstituencyConfig)	ModelTypeWVTypeExtraVectors)	load_bertload_bert_with_peftload_charlmload_pretrain)build_peft_wrapperload_peft_wrapper)Pretrain)get_split_optimizer)TreeEmbedding)UnpicklingErrorstanzac                   @   sR   e Zd ZdZdddZdddZedd
dZdd Zedd Z	edd Z
dS )Trainerz7
    Stores a constituency model and its optimizer
    Nr   c                 C   s"   || _ || _|| _|| _|| _d S N)model	optimizerepochs_trainedglobal_step
best_score)selfr   r   r   r   r    r   \/var/www/html/env_mimamsha/lib/python3.10/site-packages/stanza/models/classifiers/trainer.py__init__"   s
   
zTrainer.__init__Tc                 C   s   |du r| j }tj|d }tj|dd | j|}||| j| jd}|r8| j	dur8dd | j	
 D |d< tj||d	d
 td| dS )z
        save the current model, optimizer, and other state to filename

        epochs_trained can be passed as a parameter to handle saving at the end of an epoch
        Nr   T)exist_ok)paramsr   r   r   c                 S   s   i | ]	\}}||  qS r   )
state_dict).0opt_nameoptr   r   r   
<dictcomp>?   s    z Trainer.save.<locals>.<dictcomp>optimizer_state_dictF)_use_new_zipfile_serializationzModel saved to {})r   ospathsplitmakedirsr   
get_paramsr   r   r   itemstorchsaveloggerinfoformat)r   filenamer   skip_modulessave_optimizersave_dirmodel_paramsr   r   r   r   r.   -   s   zTrainer.saveFc                 C   s  t j| s5|jd u rtd| t jt j|j| r't j|j| } ntd| t j|j| z0ztj| dd dd}W n! t	yc } ztj| dd dd}t
d	 W Y d }~nd }~ww W n tyu   td
|   w td|  |dd}|dd}|dd }d|vr|d |d |d |d d}	n|d }	t|	d trt|	d |	d< |	d d }
t|
trt|
 }
|
|	d d< |
tjkrd|	d vr|jd u|	d d< d|	d vr|jd u|	d d< dD ]}|	d |d |	d |< qt|	d d trt|	d d  |	d d< t|	d d tr-t|	d d  |	d d< td-i |	d |	d< t||}|jrHt |j!nd }|	d j"rWt#|j|}nd }|	d j$rft#|j|}nd }|	d j%}t&|	d dd}t&|	d dd}d }|rt'|d|\}}}t(||	d t|	d t|}n|rt)|\}}nt)||\}}t*j+||	d |	d ||||||||	d d }n9|
tj,krd}|j-|j|jd!}t./|	d" ||}t0d-i |	d |	d< t1j2||	d |	d d#}nt3d$|
|j4|	d dd% |5|j6}td& |j7j8D ]}td'||j7j8|  qtd( td)d*|j9 d }|rbt:||}|d+d d ur]|d+ ; D ]\}}|| 4| qOnt<d, t|||||}|S ).Nz1Cannot find model in {} and args.save_dir is Nonez Cannot find model in {} or in {}c                 S      | S r   r   storagelocr   r   r   <lambda>P       zTrainer.load.<locals>.<lambda>T)weights_onlyc                 S   r7   r   r   r8   r   r   r   r;   R   r<   Fa<  The saved classifier has an old format using SimpleNamespace and/or Enum instead of a dict to store config.  This version of Stanza can support reading both the new and the old formats.  Future versions will only allow loading with weights_only=True.  Please resave the pretrained classifier using this version ASAP.zCannot load model from {}zLoaded model {}r   r   r   r   r   r   configlabelsextra_vocab)r   r>   r?   r@   
model_typehas_charlm_forwardhas_charlm_backward)	bert_hidden_layersbert_finetuneforce_bert_saveduse_peft	lora_rank
lora_alphalora_dropoutlora_modules_to_savelora_target_moduleswordvec_typeextra_wordvec_methodrG   rF   
classifier	bert_lorapretrainr@   r?   charmodel_forwardcharmodel_backward
elmo_model
bert_modelbert_tokenizerrF   	peft_nameargs)wordvec_pretrain_filecharlm_forward_filecharlm_backward_filetree_embeddingr]   r?   rY   zUnknown model type {})strictz-- MODEL CONFIG --z
  --{}: {}z-- MODEL LABELS --z  {} r%   z`Attempted to load optimizer to resume training, but optimizer not saved.  Creating new optimizerr   )=r'   r(   existsr5   FileNotFoundErrorr1   joinr-   loadr   warningswarnBaseExceptionr/   	exceptiondebugget
isinstancer   varsstrr   CNNr[   r\   r   r   r   r   r   use_elmoutils	load_elmorU   rB   r
   rC   rV   getattrr	   r   r   cnn_classifierCNNClassifierCONSTITUENCYrZ   r   model_from_paramsr   constituency_classifierConstituencyClassifier
ValueErrorload_state_dicttodevicer>   __dict__r?   build_optimizerr,   r0   )r2   rY   foundation_cacheload_optimizer
checkpointer   r   r   r6   rA   argnamerR   rU   rS   rT   rV   rG   rF   rX   rW   r   pretrain_argsr]   kr   r"   opt_state_dicttrainerr   r   r   rd   C   s   





zTrainer.loadc                 C   s   | j r| j }n| jrd| j| j| jj }ntdt	d| t
j|r/t||S | jr>| j}t	d| nt| j| j| jj }t	d| t||| j}t	dt|jj  |S )Nz{}/{}.{}.pretrain.ptz8TODO: need to get the wv type back from get_wordvec_filez$Looking for pretrained vectors in {}z"Pretrain not found.  Looking in {}zEmbedding shape: %s)rZ   rM   r1   r5   	shorthandnamelowerRuntimeErrorr/   ri   r'   r(   ra   r   wordvec_raw_filerp   get_wordvec_filewordvec_dirr   pretrain_max_vocabrm   embshape)rY   r   pretrain_filevec_filerR   r   r   r   r      s    
zTrainer.load_pretrainc                 C   sv  |du rt dt|}| jtjkrktj| dd}| jr#t	
| jnd}t| j}t| j}d}t| j\}}	t| dd}
|
rLd}t|t| t|d}t|}| j}tj||||||||	||| d}|| j}nE| jtjkrd	d
 t|  D }|| j| j| j| jddd td| j   t!"|}t#j$||| d}|| j}nt d%| jt&|| }t||S )zC
        Load pretrained pieces and then build a new model
        NzUMust have a train set to build a new model - needed for labels and delta word vectors)r   rG   F	sentiment)adapter_namerQ   c                 S   s,   i | ]\}}| d r|td d |qS )constituency_N)
startswithlen)r!   xyr   r   r   r$     s   , z+Trainer.build_new_model.<locals>.<dictcomp>)rZ   r[   r\   rV   rE   stage1_bert_finetunez;Building constituency classifier using %s as the base modelr^   zUnhandled model type {})'ry   datadataset_labelsrA   r   rn   r   r   ro   rp   rq   rU   r
   r[   r\   r   rV   rr   r   rl   r/   dataset_vocabrE   rs   rt   r{   r|   ru   r,   updaterZ   r0   constituency_modelr   from_parser_filerw   rx   r1   r~   )rY   	train_setr?   rR   rU   rS   rT   rX   rV   rW   rG   r@   rF   r   parser_argsr]   r   r   r   r   build_new_model   sb   





zTrainer.build_new_modelc              
   C   s0   t |j | |j|j|j|j|j|j |jdS )N)momentumweight_decaybert_learning_ratebert_weight_decayis_peft)	r   optimr   learning_rater   r   r   r   rG   )r   rY   r   r   r   r~   .  s   0zTrainer.build_optimizer)Nr   r   N)NTT)NF)__name__
__module____qualname____doc__r   r.   staticmethodrd   r   r   r~   r   r   r   r   r      s    

 
Er   )+r   loggingr'   r-   torch.optimr   typesr   stanza.models.classifiers.datamodelsclassifiersr   (stanza.models.classifiers.cnn_classifierrs   1stanza.models.classifiers.constituency_classifierrw    stanza.models.classifiers.configr   r   stanza.models.classifiers.utilsr   r   r   %stanza.models.common.foundation_cacher   r	   r
   r    stanza.models.common.peft_configr   r   stanza.models.common.pretrainr   stanza.models.common.utilsr   )stanza.models.constituency.tree_embeddingr   pickler   re   	getLoggerr/   r   r   r   r   r   <module>   s(    
