o
    h>                     @   s
  d 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
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 e ZdddddddZddddZdZddddZedZdddddddZdd ZdMd d!Zi d"ej d#ej!d$ej"d%ej#d&ej$d'ej%d(ej&d)ej'd*ej(d+ej)d,ej*d-ej+d.ej,d/ej-d0ej.d1ej/d2ej0Z1g d3Z2e2D ]Z3e4ee3re5ee3e1e36 < qd4d5 Z7dNd7d8Z8dNd9d:Z9d;d< Z:d=d> Z;d?d@ Z<dAdB Z=dCdD Z>dMdEdFZ?dGdH Z@dIdJ ZAdKdL ZBdS )OzN
Collects a few of the conparser utility methods which don't belong elsewhere
    )CounterN)optim)TEXTDocument)get_optimizer)SimpleModel)TransitionScheme)Tree)get_tqdmg-C6*?g      ?gMbP?g-C6
?g_eG|>)adamwadadeltasgd	adabeliefmadgradmirror_madgradg-q=gư>g:0yE>)r   r   r   ?)r   r   r   zstanza.constituency.trainerg?g{Gz?g{Gz?gv!>g>c                    sF   g }|D ]}|| } |  fdd| jD  qdd t| D }|S )z
    Returns a list of list of tags for the items in doc

    doc can be anything which feeds into the pipeline(s)
    pipelines are a list of 1 or more retag pipelines
    if multiple pipelines are given, majority vote wins
    c                    s    g | ]} fd d|j D qS )c                    s   g | ]
} r	|j n|jqS  )xposupos.0xr   r   [/var/www/html/env_mimamsha/lib/python3.10/site-packages/stanza/models/constituency/utils.py
<listcomp>7       )retag_tags.<locals>.<listcomp>.<listcomp>)wordsr   sentencer   r   r   r   7   s     zretag_tags.<locals>.<listcomp>c                 S   s   g | ]}d d t | D qS )c                 S   s"   g | ]}t |d d d qS    r   )r   most_commonr   tagr   r   r   r   =   s   " r   )zipr   r   r   r   r   =   s    )append	sentencesr%   )doc	pipelinesr   	tag_listspipeliner   r   r   
retag_tags,   s   r,   Tc                 C   s  t | dkr| S g }d}tt | d}tdt | |D ]}t|| t | }| || }g }	zt|D ]\}
}dd | D }|	| q4W n ty] } z	td|
|  |d}~ww t|	}t	|||}tt
||D ]>\}\}}z#tdd	 |D rtd
|||||}|| |d W qo ty } z	td|||d}~ww qW d   n1 sw   Y  t |t | krtdt |t | |S )z[
    Retag all of the trees using the given processor

    Returns a list of new trees
    r   i  totalc                 S   s   g | ]
}t |jd  jiqS )r   )r   childrenlabel)r   ptr   r   r   r   S   r   zretag_trees.<locals>.<listcomp>zUnable to process tree %dNc                 s   s    | ]}|d u V  qd S )Nr   r#   r   r   r   	<genexpr>]   s    zretag_trees.<locals>.<genexpr>z&Tagged tree #{} with a None tag!
{}
{}r!   z%Failed to properly retag tree #{}: {}z,Retagged tree counts did not match: {} vs {})lentqdmrangemin	enumerateyield_preterminalsr&   
ValueErrorr   r,   r%   anyRuntimeErrorformatreplace_tagsupdateAssertionError)treesr)   r   	new_trees
chunk_sizepbarchunk_start	chunk_endchunkr'   idxtreetokenser(   r*   tree_idxtagsnew_treer   r   r   retag_treesA   sJ   

rN   celuelugelu
hardshrinkhardtanh
leaky_relu
logsigmoidprelurelurelu6rreluselusoftplus
softshrinksoftsign
tanhshrinktanh)GLUHardsigmoid	HardswishMishSiLUc                 C   s   | t v r	t |   S td|  )zf
    Look up "nonlinearity" in a map from function name to function, build the appropriate layer.
    z/Chosen value of nonlinearity, "%s", not handled)NONLINEARITYr9   nonlinearityr   r   r   build_nonlinearity   s   
rh   Fc                 C   s   d}| d }|r)d}|  dd}|r| d }d}td }| d }	t}
d	}td }n*| d
  }|  dd}|r;| d }| d }| d }| d }	| d }
| d }| d }t|||	d|f|||||| |  dd| d tdS )z
    Build an optimizer based on the arguments given

    If we are "multistage" training and epochs_trained < epochs // 2,
    we build an AdaDelta optimizer instead of whatever was requested
    The build_simple_adadelta parameter controls this
    g        bert_weight_decayr   stage1_bert_finetuneFstage1_bert_learning_rateg+?stage1_learning_rateNr   bert_finetunebert_learning_ratelearning_beta2learning_epslearning_ratelearning_rholearning_momentumlearning_weight_decayr   use_peftbert_finetune_layers)namemodellrbetasepsmomentumweight_decayrn   ri   is_peftrv   
opt_logger)getDEFAULT_LEARNING_EPSDEFAULT_LEARNING_RHODEFAULT_WEIGHT_DECAYlowerr   tlogger)argsrx   build_simple_adadeltarn   ri   
optim_typerm   ro   rp   rq   rr   r|   r}   r   r   r   build_optimizer   sH   

r   c                 C   s\   |rt jj|d| d | d | d | d d}|S t jj|d| d | d | d | d d}|S )z
    Build the scheduler for the conparser based on its args

    Used to use a warmup for learning rate, but that wasn't working very well
    Now, we just use a ReduceLROnPlateau, which does quite well
    maxlearning_rate_factorlearning_rate_patiencelearning_rate_cooldownstage1_learning_rate_min_lr)modefactorpatiencecooldownmin_lrlearning_rate_min_lr)r   lr_schedulerReduceLROnPlateau)r   	optimizerfirst_optimizer	schedulerr   r   r   build_scheduler   s
   ((r   c                 C   s@   |dv rt jj| j|d t j| jdd|d d   dS dS )zU
    Initializes the bias to a positive value, hopefully preventing dead neurons
    )rW   rT   rf   r   r!      g      ?N)nninitkaiming_normal_weightuniform_bias)linearrg   r   r   r   r   initialize_linear  s   "r   c                 C   sL   | j dtddd | j dtddd | j dtd	d
d | j ddddd dS )z;
    Args specifically for the output location of data
    z--predict_dir.zWhere to write the predictions during --mode predict.  Pred and orig files will be written - the orig file will be retagged if that is requested.  Writing the orig file is useful for removing None and retagging)typedefaulthelpz--predict_fileNz!Base name for writing predictionsz--predict_formatz{:_O}z&Format to use when writing predictionsz--predict_output_gold_tagsF
store_truezWOutput gold tags as part of the evaluation - useful for putting the trees through EvalB)r   actionr   )add_argumentstr)parserr   r   r   add_predict_output_args	  s   r   c                 C   sN   t | d dkst | d dkr#| d dr%d| d  d | d< d S d S d S )Npredict_formatr      Viz{:})r3   endswith)r   r   r   r   postprocess_predict_output_args  s   .r   c                 C   s@   |t ju r
t| S |t ju rtj| ddS dd t| D S )z
    Return a list of all open nodes in the given dataset.
    Depending on the parameters, may be single or compound open transitions.
    T)separate_rootc                 S   s   g | ]}|fqS r   r   r   r   r   r   r   "  s    z"get_open_nodes.<locals>.<listcomp>)r   TOP_DOWN_COMPOUNDr	   get_compound_constituentsIN_ORDER_COMPOUNDget_unique_constituent_labels)r@   transition_schemer   r   r   get_open_nodes  s
   


r   c                 C   s   t ||||}tdt|  t| |}t tjkr&tt| |t| d}t	|D ]J\}	\}
}|
|
gd }t	|D ]\}}|||sRtd|	||||
||||}q<||j}|re| }|
|krttd|	||
||q*dS )zk
    Given a list of trees and their transition sequences, verify that the sequences rebuild the trees
    z/Verifying the transition sequences for %d treesr-   r   zpTree {} of {} failed: transition {}:{} was not legal in a transition sequence:
Original tree: {}
Transitions: {}zsTree {} of {} failed: transition sequence did not match for a tree!
Original tree:{}
Transitions: {}
Result tree:{}N)r   r   infor3   r%   getEffectiveLevelloggingINFOr4   r7   initial_state_from_gold_treesis_legalr;   r<   applyget_top_constituentconstituentsreverse)r@   	sequencesr   unary_limitr   rw   root_labelsrx   datarK   rH   sequencestaterG   transresultr   r   r   verify_transitions%  s$   
r   c              	   C   s   t |}|D ]>}|| vrEd}d}t|D ]\}}	t |	}||v r,|d7 }|du r,|}qd||||d || }
|r@t|
t|
 qdS )zY
    Check that all the constituents in the other dataset are known in the train set
    Nr   r!   a'  Found constituent label {} in the {} set which don't exist in the train set.  This constituent label occured in {} trees, with the first tree index at {} counting from 1
The error tree (which may have POS tags changed from the retagger and may be missing functional tags or empty nodes) is:
{:P})r	   r   r7   r<   r;   warningswarn)train_constituentsr@   treebank_namefailr   confirst_error
num_errorsrK   rH   errorr   r   r   check_constituents=  s$   


r   c                 C   s,   t |D ]}|| vrtd||qdS )zX
    Check that all the root states in the other dataset are known in the train set
    zLFound root state {} in the {} set which is not a ROOT state in the train setN)r	   get_root_labelsr;   r<   )r   other_treesr   
root_stater   r   r   check_root_labelsR  s
   r   c                 C   sj   g }t  }| D ]}d|}||v rq|| || qt|t| k r3tdt| t| | |S )z2
    Filter duplicates from the given dataset
    z{}z&Filtered %d duplicates from %s dataset)setr<   addr&   r3   r   r   )r@   r   rA   known_treesrH   tree_strr   r   r   remove_duplicate_treesZ  s   

r   c                 C   s>   dd | D }t | t | dkrtdt | t |  |S )z~
    remove trees which are just a root and a single word

    TODO: remove these trees in the conversion instead of here
    c                 S   s|   g | ]:}t |jd ks:t |jd krt |jd jd ks:t |jd krt |jd jd krt |jd jd jd kr|qS r    )r3   r/   r   r   r   r   r   p  s    "<z*remove_singleton_trees.<locals>.<listcomp>r   z*Eliminated %d trees with missing structure)r3   r   r   )r@   rA   r   r   r   remove_singleton_treesj  s   r   )T)F)C__doc__collectionsr   r   r   torch.nnr   torchr   stanza.models.common.docr   r   stanza.models.common.utilsr   %stanza.models.constituency.base_modelr   ,stanza.models.constituency.parse_transitionsr   %stanza.models.constituency.parse_treer	   stanza.utils.get_tqdmr
   r4   DEFAULT_LEARNING_RATESr   r   DEFAULT_MOMENTUM	getLoggerr   r   r,   rN   CELUELUGELU
HardshrinkHardtanh	LeakyReLU
LogSigmoidPReLUReLUReLU6RReLUSELUSoftplus
SoftshrinkSoftsign
TanhshrinkTanhre   nonlinearity_listrg   hasattrgetattrr   rh   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s    

L	



/

