o
    ॵi                      @   s   d dl Z d dlmZmZmZm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ZeeZeje	jdG dd	 d	eZdS )
    N)DictOptionalTupleUnion)Trainers)BaseTrainer)TRAINERS)
get_logger)module_namec                       sj   e Zd Zdef fddZdd Zdedeeeef  fdd	Z		
dde
e deeef fddZ  ZS )SequenceClassificationTrainercfg_filec                    s   t  | dS )a   A trainer is used for Sequence Classification

        Based on Config file (*.yaml or *.json), the trainer trains or evaluates on a dataset

        Args:
            cfg_file (str): the path of config file
        Raises:
            ValueError: _description_
        N)super__init__)selfr   argskwargs	__class__ k/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/trainers/nlp/sequence_classification_trainer.pyr      s   
z&SequenceClassificationTrainer.__init__c                 O   s   t d d S )NTrain)loggerinfo)r   r   r   r   r   r   train    s   
z#SequenceClassificationTrainer.trainattrreturnc                 C   s   | d}d|}t| j|d r| j|d  nd}|dd D ]}t||s.|df  S || }q!|r=|dkr=||fS |dfS )a  get attribute from config, if the attribute does exist, return false

        Example:

        >>> self.__attr_is_exist("model path")
        >>> out: (model-path, "/workspace/bert-base-sst2")
        >>> self.__attr_is_exist("model weights")
        >>> out: (model-weights, False)

        Args:
            attr (str): attribute str, "model path" -> config["model"][path]

        Returns:
            Tuple[Union[str, bool]]:[target attribute name, the target attribute or False]
         -r   N   F )splitjoinhasattrcfg)r   r   pathsattr_strtargetpath_r   r   r   __attr_is_exist$   s   

"

z-SequenceClassificationTrainer.__attr_is_existNcheckpoint_pathc           ,   	      sx  ddl ddlm} ddlm} ddlm} ddlm} ddl	m
} ddlm}	 d	}
| d
}| d}| d}|||g}|D ]}|d sOt|
|d q@|s_| dd }|s_td|d| dd }|sptd||d d }|d }||||}|	||d d|jd}||}|  d}d}d}d}d}t }t }d}j rdnd |  t|D ]\}}z fdd| D }W n ty   dd | D }Y nw t }   |d}!||}"W d   n1 sw   Y  t }#||#|  7 }d|"v sJ |"d }$| |!!  | |$!  |"j#|$dd|!k$ 7 }||!j%d 7 }t&|$j%d ksK|$j%d d krR|'|$|!}%nt&|$j%d!kra|(|$|!}%nt||%) $ 7 }|d 7 }||j*7 }|d  d" dkrt&|j+|j* }&t,-d#|d  |& qt,-d$||d% |  || }'t,-d&|' t./|}t }(|d D ]})|)0d'r|| }*t,-d(|* |(1d'|*f q|)d)kr2|j2j3d!kr||t.j#|dd*}+t,-d+|+ |(1d)|+f q||t.j#|dd*d,d-}+t,-d.|+ |(1d/|+f ||t.j#|dd*d0d-}+t,-d1|+ |(1d2|+f qt4d3|) t5|(S )4a  evaluate a dataset

        evaluate a dataset via a specific model from the `checkpoint_path` path, if the `checkpoint_path`
        does not exist, read from the config file.

        Args:
            checkpoint_path (Optional[str], optional): the model path. Defaults to None.

        Returns:
            Dict[str, float]: the results about the evaluation
            Example:
            {"accuracy": 0.5091743119266054, "f1": 0.673780487804878}
        r   N)load_dataset)GeneralDataset)SequenceClassification)losses)f1_score)
DataLoaderz)Attribute {} is not given in config file!zevaluation metricszevaluation batch_sizezdataset valid filezevaluation model_pathz_Argument checkout_path must be passed if the evaluation-model_path is not given in config file!max_sequence_lengthzevaluation max_sequence_lengthzpArgument max_sequence_length must be passed if the evaluation-max_sequence_length does not exist in config file!/
validationF)
batch_sizeshuffle
collate_fng        zcuda:0cpuc                    s,   i | ]\}}|t |jr| n|qS r   )
isinstanceTensorto.0keyvaldevicetorchr   r   
<dictcomp>   s
    z:SequenceClassificationTrainer.evaluate.<locals>.<dictcomp>c                 S   s   i | ]\}}||qS r   r   r;   r   r   r   rB      s    	label_idslogits)dimr      d   zEval: {}/{} steps finishedz/Inference time = {:.2f}s, [{:.4f} ms / sample] i  zEval loss: {}accuracyzAccuracy: {}f1)axiszF1: {}macro)averagezMacro F1: {}zmacro-f1microzMicro F1: {}zmicro-f1zMetric %s not implemented)6rA   easynlp.appzoor*   easynlp.appzoo.datasetr+   ,easynlp.appzoo.sequence_classification.modelr,   easynlp.utilsr-   sklearn.metricsr.   torch.utils.datar/   -_SequenceClassificationTrainer__attr_is_existAttributeErrorformat
ValueErrorgetr    batch_fnfrom_pretrainedevallistcudais_availabler:   	enumerateitemsRuntimeErrortimeno_gradpopextendtolistsumargmaxitemshapelenmse_losscross_entropymeanr4   datasetr   r   nparrayendswithappendconfig
num_labelsNotImplementedErrordict),r   r)   r   r   r*   r+   r,   r-   r.   r/   	raise_strmetricseval_batch_sizetest_dataset_pathattrsattr_r1   raw_datasetvalid_datasetpre_datasetvalid_dataloadermodel
total_losstotal_stepstotal_sampleshit_num	total_numlogits_listy_truestotal_spent_time_stepbatchinfer_start_timerC   outputsinfer_end_timerD   tmp_loss
total_step	eval_losseval_outputsmetricaccrI   r   r?   r   evaluateA   s  









 


z&SequenceClassificationTrainer.evaluate)N)__name__
__module____qualname__strr   r   r   r   boolrT   r   r   floatr   __classcell__r   r   r   r   r      s    
r   )rb   typingr   r   r   r   numpyrp   modelscope.metainfor   modelscope.trainers.baser   modelscope.trainers.builderr   modelscope.utils.loggerr	   PATHr   register_modulebert_sentiment_analysisr   r   r   r   r   <module>   s   