o
    }oi(                     @   s   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	m
Z
 d dlmZ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 d dlmZmZmZ d dlmZ dgZG dd deZ dS )    )DictListOptionalTupleN)Trainer)
DictConfig	OmegaConf)	AutoModelBartForConditionalGenerationEncoderDecoderModel)
Perplexity)Text2SparqlDataset)get_tokenizer)	typecheck)ModelPT)ChannelTypeMaskType
NeuralType)loggingText2SparqlModelc                       s  e Zd Zedeeeef  fddZd-de	de
f fddZe 			d.d	ejd
ejdejdejdeejeej eej f f
ddZe d	ejdejfddZdededefddZdededefddZdee defddZe dededejfddZe deej deeee f fddZde	fddZd ee	 fd!d"Zd#ee	 fd$d%Zd&ee	 fd'd(Zde	fd)d*Zedeeeef  fd+d,Z   Z!S )/r   returnc                 C   s:   t dt t dt ddt dt ddt dt dddS )N)BTT)optional	input_idsattention_maskdecoder_input_idslabels)r   r   r   self r!   m/home/ubuntu/.local/lib/python3.10/site-packages/nemo/collections/nlp/models/text2sparql/text2sparql_model.pyinput_types&   s
   
zText2SparqlModel.input_typesNcfgtrainerc                    s>  |j jr%|j js|j jrtd| |j| _|jj| _| j| _	| j| _
n$|j jr-|j js1td| |j| _|jj| _| |j	| _	|j	j| _
| jsPtd| j	sWtdt j||d |j jr{d|j jv rrt|j j| _n!t|j j| _n|j jr|j jstdtj|j j|j jd| _t | _| |j d S )NzoMust have either pretrained_model_name or both pretrained_encoder_model name and pretrained_decoder_model_name.z*Both encoder and decoder must be specifiedz&encoder_tokenizer failed to initializez&decoder_tokenizer failed to initialize)r$   r%   bart)encoderdecoder)language_modelpretrained_model_namepretrained_encoder_model_namepretrained_decoder_model_name
ValueErrorsetup_tokenizerencoder_tokenizeradd_special_tokensencoder_add_special_tokensdecoder_tokenizerdecoder_add_special_tokens	TypeErrorsuper__init__r
   from_pretrainedmodelr	   r   from_encoder_decoder_pretrainedr   validation_perplexitysetup_optimizationoptim)r    r$   r%   	__class__r!   r"   r6   /   sL   



zText2SparqlModel.__init__r   r   r   r   c                 C   s   | j ||||dd}|S )z
        No special modification required for Lightning, define it as you normally would
        in the `nn.Module` in vanilla PyTorch.
        F)r   r   r   r   return_dict)r8   )r    r   r   r   r   outputsr!   r!   r"   forwardk   s   zText2SparqlModel.forwardc                 C   s6   | j jd|| jj| jj| jj| jjd| jj}|S )z,Wraps huggingface EncoderDecoder.generate().)r   pad_token_idbos_token_ideos_token_iddecoder_start_token_idNr!   )r8   generater/   pad_idbos_ideos_idr2   _cfg)r    r   r@   r!   r!   r"   rF      s   zText2SparqlModel.generatebatch	batch_idxc           	      C   sB   |\}}}}| j ||||dd }|| jjd d d}||dS )z
        Lightning calls this inside the training loop with the data from the training dataloader
        passed in as `batch`. Loss calculation from HuggingFace's BartForConditionalGeneration.
        r   r   lr)
train_lossrM   )losslog)rA   
_optimizerparam_groups)	r    rK   rL   r   
input_maskr   r   rO   tensorboard_logsr!   r!   r"   training_step   s   
zText2SparqlModel.training_stepc           
      C   sH   |\}}}}| j ||||ddd \}}| j|d d|i}	||	dS )z
        Lightning calls this inside the validation loop with the data from the validation dataloader
        passed in as `batch`. Loss calculation from HuggingFace's BartForConditionalGeneration.
        r   N   )logitsval_lossrX   rP   )rA   r:   )
r    rK   rL   r   rS   r   r   rO   rW   rT   r!   r!   r"   validation_step   s   
z Text2SparqlModel.validation_stepr@   c                 C   sV   t dd |D  }| j }||d}td|   | d| ||dS )z
        Called at the end of validation to aggregate outputs.
        :param outputs: list of individual outputs of each validation step.
        c                 S   s   g | ]}|d  qS )rX   r!   ).0xr!   r!   r"   
<listcomp>   s    z<Text2SparqlModel.on_validation_epoch_end.<locals>.<listcomp>)rX   
perplexityzevaluation perplexity rX   rY   )	torchstackmeanr:   computer   infoitemrP   )r    r@   avg_lossr^   rT   r!   r!   r"   on_validation_epoch_end   s   


z(Text2SparqlModel.on_validation_epoch_endc                 C   s   |\}}}}| j |d}|S )zMLightning calls this inside the test loop with data from the test dataloader.)r   )rF   )r    rK   rL   r   rS   r   r   	sequencesr!   r!   r"   	test_step   s   zText2SparqlModel.test_stepc                    s&    fdd|D }d|ig _ d|iS )z?Called at the end of test to aggregate outputs and decode them.c                    s"   g | ]}|D ]} j |qqS r!   )r/   ids_to_text)r[   rK   seqr   r!   r"   r]      s   " z6Text2SparqlModel.on_test_epoch_end.<locals>.<listcomp>texts)test_output)r    r@   rk   r!   r   r"   on_test_epoch_end   s   z"Text2SparqlModel.on_test_epoch_endc                 C   s,   t |j|j|jrt|jnd |jd}|S )N)tokenizer_nametokenizer_modelspecial_tokens
vocab_file)r   rn   ro   rp   r   to_containerrq   )r    r$   	tokenizerr!   r!   r"   r.      s   z Text2SparqlModel.setup_tokenizertrain_data_configc                 C      | j |d| _d S N)r$   )setup_dataloader_from_config	_train_dl)r    rt   r!   r!   r"   setup_training_data      z$Text2SparqlModel.setup_training_dataval_data_configc                 C   ru   rv   )rw   _validation_dl)r    r{   r!   r!   r"   setup_validation_data   rz   z&Text2SparqlModel.setup_validation_datatest_data_configc                 C   ru   rv   )rw   _test_dl)r    r~   r!   r!   r"   setup_test_data   rz   z Text2SparqlModel.setup_test_datac                 C   sn   t |j| j| j| j| j| jj|dd| jj	d}t
jjj|| jj|j|dd|dd|dd|jd	S )
Nnum_samples)filepathr/   r2   r1   r3   max_seq_lengthr   convert_labelsnum_workersrV   
pin_memoryF	drop_last)dataset
batch_sizeshuffler   r   r   
collate_fn)r   r   r/   r2   r1   r3   rJ   r   getr   r_   utilsdata
DataLoaderr   r   r   )r    r$   r   r!   r!   r"   rw      s&   



z-Text2SparqlModel.setup_dataloader_from_configc                 C   s   d S Nr!   )clsr!   r!   r"   list_available_models   s   z&Text2SparqlModel.list_available_modelsr   )NNN)"__name__
__module____qualname__propertyr   r   strr   r#   r   r   r6   r   r_   Tensorr   rA   disable_checksrF   intrU   rZ   r   rf   rh   rm   r.   ry   r}   r   rw   classmethodr   __classcell__r!   r!   r=   r"   r   %   sF    <&	$)!typingr   r   r   r   r_   lightning.pytorchr   	omegaconfr   r   transformersr	   r
   r   nemo.collections.common.metricsr   %nemo.collections.nlp.data.text2sparqlr   3nemo.collections.nlp.modules.common.tokenizer_utilsr   nemo.core.classes.commonr   nemo.core.classes.modelPTr   nemo.core.neural_typesr   r   r   
nemo.utilsr   __all__r   r!   r!   r!   r"   <module>   s   