o
    *Îj1V  ã                   @   s€  d dl Z d dlZd dlZd dlZd dlmZmZmZ d dlZd dl	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 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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-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8m9Z9 e)ƒ Z:ej;ej<dG dd„ deƒƒZ=dS )é    N)ÚCallableÚDictÚOptional)ÚSummaryWriter)Únn)Úoptim)Ú
DataLoader)ÚTrainers)ÚModelÚ
TorchModel)Úkws_nearfield_dataset)ÚBaseTrainer)ÚTRAINERS)Úload_checkpointÚsave_checkpoint)ÚConfig)ÚDEFAULT_MODEL_REVISIONÚ	ModelFile)Úcreate_device)Ú
get_logger)Úset_random_seedé   )Úexecutor_cvÚexecutor_testÚexecutor_train)Úcompute_det)Úquery_token_setÚread_lexiconÚ
read_token)Úaverage_modelÚconvert_to_kaldiÚcount_parameters)Úmodule_namec                       sŒ   e Zd Zddefdededee dee dee f
‡ fdd„Zd	d
„ Zdede	ee
f fdd„Zdejfdd„Zddd„Zddd„Z‡  ZS )ÚKWSNearfieldTrainerNÚmodelÚwork_dirÚcfg_fileÚarg_parse_fnÚmodel_revisionc                    sô  t |tƒr|  ||¡| _|du rtj | jtj¡}n|dus"J dƒ‚tj 	|¡| _t
ƒ  ||¡ t |¡}d| _|j dd¡| _t| dd¡ƒ |  ¡  || _| jdkritj | j¡sat | j¡ t d	|› ¡ tj | jd
¡}tj |¡s~J |› dƒ‚t|ƒ| _tj | jd¡}	tj |	¡s˜J |	› dƒ‚t|	ƒ| _tj | jd¡}
tj |
¡s²J |
› dƒ‚|
|jd< || _| jdkrøtj | j¡sÌt | j¡ tj | jd¡}t |dƒ}t! "| #¡ ¡}| $|¡ W d  ƒ dS 1 sñw   Y  dS dS )a  
        Args:
            model (str): model id in modelscope
            work_dir (str): main directory for training and evaluating
            cfg_file (str): config file for training and evaluating
            kwargs:
                seed (int): random seed
        Nz?Config file should not be None if model is not from pretrained!ZpytorchÚdist_backendZncclÚseediš  r   zCurrent working dir is ztrain/tokens.txtz is missingztrain/lexicon.txtz&train/feature_transform.txt.80dim-l2r2Z	cmvn_fileúconfig.yamlÚw)%Ú
isinstanceÚstrZget_or_download_model_dirÚ	model_dirÚosÚpathÚjoinr   ZCONFIGURATIONÚdirnameÚsuperÚ__init__r   Ú	from_fileÚlauncherÚtrainÚgetr)   r   Ú	init_distr%   ÚrankÚexistsÚmakedirsÚloggerÚinfor   Útoken_tabler   Úlexicon_tabler$   ÚconfigsÚopenÚyamlÚdumpÚto_dictÚwrite)Úselfr$   r%   r&   r'   r(   ÚkwargsrB   Z
token_fileZlexicon_fileZfeature_transform_fileÚsaved_config_pathÚfoutÚdata©Ú	__class__© úp/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/trainers/audio/kws_nearfield_trainer.pyr5   )   sZ   
ÿ
ÿ€



ÿÿ

"þüzKWSNearfieldTrainer.__init__c               	   O   s”  |  dd¡}|durtj |¡r|| _n	tj | jd¡| _|  dd¡| _|d s,J dƒ‚|d s4J d	ƒ‚|d
 s<J dƒ‚|d | _|d | _	|d
 | _
|  dd¡oY| jdkrXdnd| _| jd }t |¡}d|d< d|d< d|d< tj | jd¡}tj | jd¡}t| j| j
|| j| j| j|dƒ| _t| j	| j
|| j| j| j|dƒ| _t| jd|  dd¡| jjjj| jjj  dd¡d| _t| jd|  dd¡| jjjj| jjj  dd¡d| _|  | j¡| _t| jƒ}| jdkrðt  !d "|¡¡ | jdur5tj | j¡r5t#| j| jƒ t$ %dd| j¡}	i }
tj |	¡r4t&|	dƒ}t'j(|t'j)d}
W d  ƒ n	1 s/w   Y  nt  !d¡ i }
|
  d d!¡d" | _*| j*| jd# d$< |
  d%| jd# d& d% ¡}|| jd# d& d%< |  d'd(¡}| j+d"krud)| j,› }t-|ƒ| _.| j+d"kršt/j0 1¡ sˆJ ‚| j 2| j.¡| _t/j3j4 5| j¡| _n| j 2| j.¡| _| jdkrátj | j¡s¶t 6| j¡ tj | jd*¡}t&|d+ƒ}t' 7| j 8¡ ¡}| 9|¡ W d  ƒ n	1 sÜw   Y  t  :d,¡ d}| jdkrtj6| jdd- t;tj | j| j¡ƒ}| jd#   d.d/¡}| jd# d& }t<j=| j >¡ |d% |d0 d1}t<j?j@|d2d3d4d5d6d7}d}| j*dkrM| jdkrMtj | jd8¡}tA| j|dddddƒ t  :d,¡ i }|d9 |d9< |  d:d"¡|d:< ||d.< | j+|d;< | j|d<< | j,|d=< | jd# d> }tBjB C¡ }tD| j*|ƒD ]ž}| j E|¡ ||d < |jFd d% }t  :d? "||¡¡ tG| j|| j| j.||ƒ tH| j| j| j.|ƒ\}}t  :d@ "|||¡¡ | jdkrtj | jdA "|¡¡}tA| j|dddddƒ t$ %dd|¡}	tI|||dB}t&|	d+ƒ}t' 7|¡}| 9|¡ W d  ƒ n	1 s
w   Y  | JdC||¡ | JdD||¡ |}| K|¡ q‡|dur5| jdkr5| L¡  tBjB C¡ | }t  :dE "| M¡ dF ¡¡ dS )Gau  
        Args:
            kwargs:
                train_data (int): wave list with kaldi style for training
                cv_data (int): wave list with kaldi style for cross validation
                trans_data (str): transcription list with kaldi style, merge train and cv
                checkpoint (str): basemodel checkpoint, if None, default to use base.pt in model path
                tensorboard_dir (str): path to save tensorboard results,
                                       create 'tensorboard_dir' in work_dir by default
                need_dump (bool): wether to dump data with mapping tokens or not
        Ú
checkpointNztrain/base.ptÚtensorboard_dirZtensorboardÚ
train_dataz'please config train data in dict kwargsÚcv_dataz$please config cv data in dict kwargsÚ
trans_dataz/please config transcription data in dict kwargsÚ	need_dumpFr   TÚpreprocessorÚspeed_perturbÚspec_augÚshufflezdump_train.txtzdump_cv.txtÚ
pin_memoryÚprefetché   )Ú
batch_sizer[   Únum_workersÚprefetch_factorzthe number of model params: {}z.pt$z.yamlÚr)ÚLoaderz'Training with random initialized paramsÚepochéÿÿÿÿr   r8   Ústart_epochÚlrÚ	optimizerÚdeviceÚgpuúcuda:r+   r,   zStart training...)Úexist_okÚlog_intervalé
   Úweight_decay)rf   rn   Úming      à?é   gíµ ÷Æ°>g{®Gáz„?)ÚmodeÚfactorZpatienceZmin_lrÚ	thresholdzinit.ptZ	grad_clipZ
grad_accumÚ
world_sizer;   Ú
local_rankZ
max_epochszEpoch {} TRAIN info lr {}z0Epoch {} EVAL info cv_loss {:.6f}, cv_acc {:.2f}z{}.pt)rc   rf   Úcv_losszepoch/cv_losszepoch/lrúTotal time spent: {:.2f} hoursç      ¬@)Nr9   r0   r1   r<   rQ   r2   r/   rR   rS   rT   rU   r;   rV   rB   ÚcopyÚdeepcopyr%   r   r@   rA   Ztrain_datasetZ
cv_datasetr   r8   Ú
dataloaderÚworkers_per_gpuZtrain_dataloaderÚ
evaluationZcv_dataloaderÚbuild_modelr$   r!   r>   ÚwarningÚformatr   ÚreÚsubrC   rD   ÚloadZ
FullLoaderre   rt   ru   r   Ztrain_deviceÚtorchÚcudaÚis_availableÚtor   ZparallelZDistributedDataParallelr=   rE   rF   rG   r?   r   r   ZAdamÚ
parametersÚlr_schedulerZReduceLROnPlateaur   ÚdatetimeÚnowÚrangeZ	set_epochZparam_groupsr   r   ÚdictZ
add_scalarÚstepÚcloseÚtotal_seconds) rH   ÚargsrI   Ztrain_checkpointZ
train_confZcv_confZdump_train_fileZdump_cv_fileZ
num_paramsZ	info_pathÚinfosZfinZlr_last_epochÚdevice_namerJ   rK   rL   Úwriterrl   Z
optim_confrg   r‰   Zfinal_epochZsave_model_pathZtraining_configZ	max_epochÚ	totaltimerc   rf   rv   Zcv_accZ	info_dictrO   rO   rP   r8   k   sX  ÿÿ


ÿÿ

þ
ü

û


ÿû	

ÿ€
ÿ
þ
ÿýú	ÿ




ÿ
ÿÿÿ
ÿÿý
þ

ÿzKWSNearfieldTrainer.trainÚcheckpoint_pathÚreturnc               
      sŠ  d| _ |durtj |¡rt d|› ¡ |}nU| j du ra| dd¡}tj | jd|› d¡| _ t d| j › ¡ t	| j | jd|d	}t
d>i |¤Ž| _ |  | j¡}t|| j | jƒ}t d
|› ¡ | j }t d| j › ¡ | dd¡dur‹| dd¡dur‹t d¡ |d }	|d }
nt d¡ | j}	| j}
t d|	› ¡ t d|
› ¡ t | jd ¡}d|d d< d|d d< d|d< d|d< d|d< | dd¡durÖ|d |d d< t|	|
|| j| jdddƒ}t|d| dd¡d| jjjj| jjj d d!¡d"}| d#d¡dus	J d$ƒ‚|d# }| ¡  d%d¡ d&¡}i }dh‰ d'h‰d'di}|D ]O}t|| j| jƒ\}}i ||< ||| d(< d d)d*„ |D ƒ¡|| d+< ‡fd,d-„|D ƒ ‡ fd.d-„|D ƒ t||ƒD ]\}}| |d¡du rr|||< qaq&d}| ¡ D ]\}}||› d/|› d07 }q|t d1|› ¡ | d2d3¡dko¡tj  !¡ }| d4d5¡}| j"d6kr·|r·d7| j#› }t$|ƒ| _%|  | j¡| _&t'|| j&ƒ | j& (| j%¡| _&i }| d8d¡durã|d8 |d8< ntj )|¡}tj | jd9| ¡|d8< |d8 | _*tj | j*¡st +| j*¡ t ,d:¡ t-j- .¡ }t/| j&|| j%|ˆ |ƒ}t-j- .¡ | }t ,d; 0| 1¡ d< ¡¡ t	||	|
|d=}t2d>i |¤Ž}t3|ƒ dS )?ab  
        Args:
            checkpoint_path (str): evaluating with ckpt or default average ckpt
            kwargs:
                test_dir (str): local path for saving test results
                test_data (str): wave list with kaldi style
                trans_data (str): transcription list with kaldi style
                average_num (int): the NO. to do model averaging(checkpoint_path==None)
                batch_size (int): batch size during evaluating
                keywords (str): keyword string, split with ','
                gpu (int): evaluating with cpu/gpu: -1 for cpu; >=0 for gpu
        Nz evaluating with specific model: Zaverage_numrm   Zavg_z.ptz!default average model not exist: T)Z	dst_modelZsrc_pathZval_bestÚavg_numz(average model convert to kaldi network: zevaluating with average model: Ú	test_datarU   z/evaluating with specific data and transcriptionz5evaluating with cross validation data during trainingztest data: ztrans data: rW   i  Zfilter_confÚ
max_lengthr   Z
min_lengthFrX   rY   rZ   r^   Z
batch_confÚ r[   r\   r]   )r^   r[   Zpersistent_workersr_   r`   Úkeywordszat least one keyword is neededú ú,z<blk>Ztoken_idc                 s   s    | ]	}d t |ƒ V  qdS )z%s N)r.   ©Ú.0ÚirO   rO   rP   Ú	<genexpr>‘  s   € ÿz/KWSNearfieldTrainer.evaluate.<locals>.<genexpr>Z	token_strc                    ó   g | ]}ˆ   |¡‘qS rO   ©ÚaddrŸ   )Úkeywords_strsetrO   rP   Ú
<listcomp>“  ó    z0KWSNearfieldTrainer.evaluate.<locals>.<listcomp>c                    r£   rO   r¤   rŸ   )Úkeywords_idxsetrO   rP   r§   ”  r¨   ú(z) zToken set is: ri   rd   rh   Úcpur   rj   Útest_dirZtest_zStart evaluating...rw   rx   )rœ   r™   rU   Ú
score_filerO   )4Zavg_checkpointr0   r1   r<   r>   r   r9   r2   r%   r   r   r~   rB   r    rT   rU   ry   rz   r   r@   rA   r   r}   r{   r|   ÚstripÚreplaceÚsplitr   ÚzipÚitemsr„   r…   r†   rt   ru   r   Ztest_deviceZ
test_modelr   r‡   Úbasenamer¬   r=   r?   rŠ   r‹   r   r€   r   r   Úprint) rH   r–   r‘   rI   Zeval_checkpointr˜   Z
avg_kwargsZ	model_cvtZ	kaldi_cvtr™   rU   Z	test_confZtest_datasetZtest_dataloaderZkeywords_strZkeywords_listZkeywords_tokenZkeywords_tokenmapÚkeywordÚstrsZindexesÚtxtÚidxZtoken_printZuse_cudar“   Ztesting_configÚ	base_namer•   r­   Z
det_kwargsZdet_resultsrO   )r©   r¦   rP   Úevaluate-  s  ÿ


ÿ
ÿüýÿ
ÿ

ÿý


ÿú
ÿÿÿÿ
ÿ€þ

ÿ


þ
ÿüzKWSNearfieldTrainer.evaluatec                 C   s@   t j| j|dd}t|tƒrt|dƒr|jS t|tjƒr|S dS )z¸ Instantiate a pytorch model and return.

        By default, we will create a model using config from configuration file. You can
        override this method in a subclass.

        T)Zcfg_dictZtrainingr$   N)	r
   Zfrom_pretrainedr/   r-   r   Úhasattrr$   r   ÚModule)rH   rB   r$   rO   rO   rP   r~   Ê  s   ÿÿzKWSNearfieldTrainer.build_modelr   c              	   C   sF  t  dd ¡d u rdt jd< t  dd ¡d u rdt jd< t  dd ¡d u r'dt jd< t  dd ¡d u r4dt jd< t  dd ¡d u rAd	t jd< tt jd ƒ| _tt jd ƒ| _tt jd ƒ| _t jd | _t jd | _|d
kr€| jd
krt	 
d | j¡¡ tj| jdd n|d
krtj| jdd t ¡  t	 
d | j| j| j| j| j¡¡ d S )NZRANKÚ0Z
LOCAL_RANKZ
WORLD_SIZEÚ1ZMASTER_ADDRÚ	localhostZMASTER_PORTZ29500r   z'init dist on multiple gpus, this gpu {}zenv://)ÚbackendZinit_methodz-RANK {}/{}/{}, Master addr:{}, Master port:{})r0   ÚgetenvÚenvironÚintr;   ru   rt   Zmaster_addrZmaster_portr>   r?   r€   ÚdistZinit_process_groupr)   Úbarrier©rH   Ztrain_nodesrO   rO   rP   r:   Ø  sB   





ÿÿ€ÿ
þzKWSNearfieldTrainer.init_distc                 C   sT   |dkr| j dkrt d | j¡¡ t ¡  d S d S |dkr(t ¡  t ¡  d S d S )Nr   z*destory dist on multiple gpus, this gpu {})rt   r>   r?   r€   ru   rÄ   Zdestroy_process_grouprÅ   rÆ   rO   rO   rP   Úuninit_distù  s   
ÿÿüþzKWSNearfieldTrainer.uninit_dist)r   )Ú__name__Ú
__module__Ú__qualname__r   r.   r   r   r5   r8   r   Úfloatrº   r   r¼   r~   r:   rÇ   Ú__classcell__rO   rO   rM   rP   r#   %   s0    ûÿþýüûB C

ÿ 
!r#   )>ry   rŠ   r0   r   Útypingr   r   r   r„   Ztorch.distributedÚdistributedrÄ   rD   ZtensorboardXr   r   r   Ztorch.utils.datar   Zmodelscope.metainfor	   Zmodelscope.modelsr
   r   ZMmodelscope.msdatasets.dataset_cls.custom_datasets.audio.kws_nearfield_datasetr   Zmodelscope.trainers.baser   Zmodelscope.trainers.builderr   Zmodelscope.utils.checkpointr   r   Zmodelscope.utils.configr   Zmodelscope.utils.constantr   r   Zmodelscope.utils.devicer   Zmodelscope.utils.loggerr   Zmodelscope.utils.torch_utilsr   Zkws_utils.batch_utilsr   r   r   Zkws_utils.det_utilsr   Zkws_utils.file_utilsr   r   r   Zkws_utils.model_utilsr   r    r!   r>   Zregister_moduleZ"speech_kws_fsmn_char_ctc_nearfieldr#   rO   rO   rO   rP   Ú<module>   s@   ÿ