o
    ߥij                     @   s  d dl Z d dlZd dlmZ d dlmZ d dlZd dlmZ d dl	m  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mZ d dlmZmZ d dlm Z  e  Z!ej"ej#dd dZ$e %ddddZ&G dd dej'Z(G dd dej'Z)G dd dej'Z*G dd dej'Z+G dd dej'Z,G dd dej'Z-G d d! d!ej'Z.d"d# Z/ej0ej1ej2d$G d%d& d&eZ3d'd( Z4G d)d* d*ej'Z5G d+d, d,ej'Z6dS )-    N)
namedtuple)Dict)Tensor)BCEWithLogitsLoss)Models)MODELS)SbertConfig
SbertModel)BaseTaskModel)FaqQuestionAnsweringOutput)ConfigConfigFields)	ModelFileTasks)
get_loggerc                 C      | S N xr   r   k/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/nlp/structbert/faq_question_answering.py<lambda>       r   )relutanhlinear   g?      ?c                       s*   e Zd Z		d fdd	Zdd Z  ZS )LinearProjectionr   Tc                    sp   t    t| | _t| }tj|||d}tjj|j	t
d| | d |r/tj|j tj|| _d S )Nbiasr   )std)super__init__activations
activationactivation_coeffsnnLinearinitnormal_weightmathsqrtzeros_r    utilsweight_normmodel)selfin_featuresout_featuresr%   r    activation_coeffr   	__class__r   r   r#   (   s   

zLinearProjection.__init__c                 C   s   |  | |S r   )r%   r1   )r2   r   r   r   r   forward7   s   zLinearProjection.forward)r   T__name__
__module____qualname__r#   r8   __classcell__r   r   r6   r   r   &   s
    r   c                       $   e Zd Z fddZdd Z  ZS )RelationModulec                    sR   t t|   |jd }tjt||jd ddt|j	t|jd d| _
d S )N   r   r%      )r"   r?   r#   proj_hidden_sizetorchr'   
Sequentialr   Dropoutdropout
prediction)r2   args
input_sizer6   r   r   r#   =   s   


zRelationModule.__init__c                 C   sr   |j d }|j d }|d|dd}|dd|d}tj||||  || gdd}| |}|dS Nr   rB   dim)shape	unsqueezerepeatrD   catabsrH   squeeze)r2   queryprotosn_clsn_query
input_featdistsr   r   r   r8   F   s   



zRelationModule.forwardr9   r   r   r6   r   r?   ;   s    	r?   c                       s8   e Zd Z fddZedd Zdd Zdd Z  ZS )	MetricsLayerc                    s>   t t|   || _|jdv sJ |jdkrt|| _d S d S )N)relationcosiner\   )r"   r[   r#   rI   metricsr?   relation_netr2   rI   r6   r   r   r#   S   s   
zMetricsLayer.__init__c                 C   s   | j jS r   )rI   r^   r2   r   r   r   nameZ   s   zMetricsLayer.namec                 C   sJ   | j jdkr| ||}| jr|d9 }|S | j jdv r#| ||}|S t)Nr]      )r\   )rI   r^   cosine_similaritytrainingr_   NotImplementedError)r2   rU   rV   supervised_distsr   r   r   r8   ^   s   zMetricsLayer.forwardc                 C   sX   |j d }|j d }|j d }|d|||g}|d|||g}t||dS )Nr   rL   rB   )rO   rP   expandFrd   )r2   r   yrX   rW   rN   r   r   r   rd   i   s   


zMetricsLayer.cosine_similarity)	r:   r;   r<   r#   propertyrb   r8   rd   r=   r   r   r6   r   r[   Q   s    
r[   c                   @   s   e Zd ZdddZdS )AveragePoolingrB   c                 C   s(   t j||  |dt j| |d S )NrM   )rD   sumfloat)r2   r   maskrN   r   r   r   r8   t   s   zAveragePooling.forwardN)rB   )r:   r;   r<   r8   r   r   r   r   rl   r   s    rl   c                       s&   e Zd Zd fdd	Zdd Z  ZS )AttnPoolingNc              	      sP   t    tt||t t|ddd| _|r!t||| _d S dd | _d S )NrB   Fr   c                 S   r   r   r   r   r   r   r   r      r   z&AttnPooling.__init__.<locals>.<lambda>)r"   r#   r'   rE   r   Tanh
input_projoutput_proj)r2   rJ   hidden_sizeoutput_sizer6   r   r   r#   |   s   

zAttnPooling.__init__c                 C   sX   |  |}||  dd|    }tj|dd}| |}t|dd|dS )N     r   rB   rM   r   )	rr   rn   ri   softmaxrs   rD   matmul	transposerT   )r2   r   ro   scorefeaturesr   r   r   r8      s
   

zAttnPooling.forwardNNr9   r   r   r6   r   rp   z   s    rp   c                       r>   )PoolingLayerc                    sP   t t|   |jdkrt|j|j|j| _d S |jdkr#t | _d S t|j)Nattnavg)r"   r}   r#   poolingrp   rC   rl   rf   r`   r6   r   r   r#      s   



zPoolingLayer.__init__c                 C   s   |  ||S r   r   )r2   r   ro   r   r   r   r8         zPoolingLayer.forwardr9   r   r   r6   r   r}      s    r}   c                       s,   e Zd Z fddZdd Zdd Z  ZS )	Alignmentc                    s   t    d S r   )r"   r#   ra   r6   r   r   r#      s   zAlignment.__init__c                 C   s   t ||ddS )NrB   r   )rD   rx   ry   )r2   abr   r   r   
_attention   s   zAlignment._attentionc                 C   sB   |  ||}t| |dd }| }|| d |S )NrB   r   rv   )r   rD   rx   rn   ry   boolmasked_fill_)r2   r   r   mask_amask_br~   ro   r   r   r   r8      s
   zAlignment.forward)r:   r;   r<   r#   r   r8   r=   r   r   r6   r   r      s    r   c                 C   s<   |  dd}|  dd}tdg d}||||d|d}|S )Nmetricr]   r   r   rI   )r^   rC   rt   rG   r   g        )getr   )model_configrt   r   pooling_methodArgrI   r   r   r   _create_args   s   r   )module_namec                       sl   e Zd ZdZdZdZedd Z fddZde	e
ef d	efd
dZdd Zdd Z		dddZ  ZS )SbertForFaqQuestionAnswering protonetmgimnnetc                 K   s(   | d}| |fi |}|| |S )N	model_dir)popload_checkpoint)clskwargsr   r1   r   r   r   _instantiate   s   

z)SbertForFaqQuestionAnswering._instantiatec                    s   t  j|g|R i | t|}ttj|t	j
tji }|| |d| j}|| jkr9t||}n|| jkrDt||}nt|td| d || _d S )Nnetworkzfaq task build z network)r"   r#   r   from_pretrainedr   	from_fileospathjoinr   CONFIGURATIONr   r   r1   update	PROTO_NETProtoNet	MGIMN_NETMGIMNNetrf   loggerinfor   )r2   r   rI   r   backbone_cfgr   network_namer   r6   r   r   r#      s$   





z%SbertForFaqQuestionAnswering.__init__inputreturnc                 C   s   |d }|d }|d }|d }|d }|  |||||\}}d|v rE|d }	t|d }
| ||	|
}tj|dd}t|||d	 S t|d
S )u
  
        Args:
            input (Dict[str, Tensor]): the preprocessed data, it contains the following keys:

                - query(:obj:`torch.LongTensor` of shape :obj:`(batch_size, sequence_length)`):
                    The query to be predicted.
                - support(:obj:`torch.LongTensor` of shape :obj:`(support_size, sequence_length)`):
                    The support set.
                - support_label(:obj:`torch.LongTensor` of shape :obj:`(support_size, )`):
                    The labels of support set.

        Returns:
            Dict[str, Tensor]: result, it contains the following key:

                - scores(:obj:`torch.FloatTensor` of shape :obj:`(batch_size, num_cls)`):
                    Predicted scores of all classes for each query.

        Examples:
            >>> from modelscope.hub.snapshot_download import snapshot_download
            >>> from modelscope.preprocessors import FaqQuestionAnsweringTransformersPreprocessor
            >>> from modelscope.models.nlp import SbertForFaqQuestionAnswering
            >>> cache_path = snapshot_download('damo/nlp_structbert_faq-question-answering_chinese-base')
            >>> preprocessor = FaqQuestionAnsweringTransformersPreprocessor.from_pretrained(cache_path)
            >>> model = SbertForFaqQuestionAnswering.from_pretrained(cache_path)
            >>> param = {
            >>>            'query_set': ['如何使用优惠券', '在哪里领券', '在哪里领券'],
            >>>            'support_set': [{
            >>>                    'text': '卖品代金券怎么用',
            >>>                    'label': '6527856'
            >>>               }, {
            >>>                    'text': '怎么使用优惠券',
            >>>                    'label': '6527856'
            >>>                }, {
            >>>                    'text': '这个可以一起领吗',
            >>>                    'label': '1000012000'
            >>>                }, {
            >>>                    'text': '付款时送的优惠券哪里领',
            >>>                    'label': '1000012000'
            >>>                }, {
            >>>                    'text': '购物等级怎么长',
            >>>                    'label': '13421097'
            >>>                }, {
            >>>                    'text': '购物等级二心',
            >>>                    'label': '13421097'
            >>>               }]
            >>>           }
            >>> result = model(preprocessor(param))
        rU   supportquery_attention_masksupport_attention_masksupport_labelslabelsrB   rM   )losslogitsr   )scores)r   rD   max_compute_lossargmaxr   to_dict)r2   r   rU   r   
query_masksupport_maskr   r   r   query_labelsnum_clsr   pred_labelsr   r   r   r8      s&   1
z$SbertForFaqQuestionAnswering.forwardc                 C   s   t ||}tdd||}|S )Nmean)	reduction)get_onehot_labelsr   )r2   r   targetr   onehot_labelsr   r   r   r   r     s   
z*SbertForFaqQuestionAnswering._compute_lossc                 C   s   | j |S r   )r   sentence_embedding)r2   inputsr   r   r   forward_sentence_embedding$  r   z7SbertForFaqQuestionAnswering.forward_sentence_embeddingNc                 K   s   t j|d}tj|dd}i }| D ]\}}	|}
t|ds&d| }
|	||
< q|d ur4t| | j	||ddd\}}}}||||dS )	Nzpytorch_model.bincpu)map_locationr   znetwork.T)load_state_fnignore_mismatched_sizes
_fast_init)missing_keysunexpected_keysmismatched_keys
error_msgs)
r   r   r   rD   loaditemsstr
startswithset_default_dtype_load_checkpoint)r2   model_local_dirdefault_dtyper   r   	ckpt_file
state_dictnew_state_dictvar_name	var_valuenew_var_namer   r   r   r   r   r   r   r   '  s*   


z,SbertForFaqQuestionAnswering.load_checkpointr|   )r:   r;   r<   _backbone_prefixr   r   classmethodr   r#   r   r   r   r   r8   r   r   r   r=   r   r   r6   r   r      s    
Cr   c                 C   sH   |  dd} | jd }t||| }|jd| dd | || S )NrL   rB   r   )rN   indexvalue)viewrO   rD   zerostoscatter_rn   )r   r   size	target_ohr   r   r   r   G  s
   
r   c                       s:   e Zd Z fddZdd Zdeeef fddZ  Z	S )r   c                    s@   t t|   t|| _t|| jjj}t|| _	t
|| _d S r   )r"   r   r#   r	   bertr   configrt   r[   metrics_layerr}   r   )r2   backbone_configr   rI   r6   r   r   r#   Q  s
   

zProtoNet.__init__c                 C   s   |j d }t|d }t||}t||g}	tj||gdd}
| |	|
d}|d | }||d  }tj|ddd }t|dd||	d }| 
||||g}| j
jdkrgt|}||fS |}||fS )	Nr   rB   rM   )	input_idsattention_maskgh㈵>rL   r\   )rO   rD   r   r   rR   r   rm   rx   ry   rP   r   r   rb   sigmoid)r2   rU   r   r   r   r   rX   r   r   r   
input_maskpooled_representationz_query	z_supportcls_n_supportrV   r   r   r   r   r   __call__X  s.   


zProtoNet.__call__r   c                 C   s   |d }|d }t |tst|}t |tst|}|| jj}|| jj}| ||}|j}t|j	dkr?|
d}| ||}|S Nr   r   r   rL   )
isinstancer   rD   	IntTensorr   r   devicelast_hidden_statelenrO   rP   r   r2   r   r   r   rstlast_hidden_statesr   r   r   r   r   s  s   




zProtoNet.sentence_embedding)
r:   r;   r<   r#   r   r   r   r   r   r=   r   r   r6   r   r   O  s    r   c                       s   e Zd ZdZdZ fddZdd Zdd Zd	d
 Zdd Z	dd Z
			dddZ			dddZdd Zdeeef fddZdddZ  ZS )r   instance_level_interactionepisode_level_interactionc           	         s  t t|   t|| _|| _t | _| jjj	}| 
| jd}| 
| jd}dt| t| }td| d|  t||d |  |dd| _t||}t|| _|jdd	}t|| _tjt|d
 |dd| _tjt|d |ddtdt|d| _d S )NTrB   zIfaq MGIMN model class-level-interaction:true, instance-level-interaction:z(,             episode-level-interaction:   r   rA   r   r   r@   r   r   )r"   r   r#   r	   r   r   r   	alignmentr   rt   safe_getINSTANCE_LEVEL_INTERACTIONEPISODE_LEVEL_INTERACTIONintr   r   r   	fuse_projr   r}   r   _replaceavg_poolingrD   r'   rE   instance_compare_layerrF   rH   )	r2   r   r   rt   use_instance_level_interactionuse_episode_level_interactionru   rI   new_argsr6   r   r   r#     sF   





zMGIMNNet.__init__c                 C   s  |  ||||\}}tt|d }|j\}	}
|jd }|| }||dd|	i}}| | jdrD| ||||\}}||d< ||d< | |||||\}}||d< ||d	< | | j	drp| 
||||\}}||d
< ||d< | j|fi |}| j|fi |}|dd|d|	| |
d}|d|	dd|	| |
d}| ||}| ||}| |||	||}| |}||	|}|t|fS )NrB   r   )rW   k_shotrX   Tins_z_queryins_z_supportcls_z_querycls_z_supporteps_z_queryeps_z_support)context_embeddingr  rD   r   rO   r  r  _instance_level_interaction_class_level_interactionr  _episode_level_interaction_fuse_query_fuse_supportrP   rQ   r   r   _instance_comparerH   r   )r2   rU   r   r   r   r   r   r   rW   rX   sent_len	n_supportr  q_paramss_paramsr  r  r  r  r  r  fused_z_queryfused_z_supportquery_mask_expandedsupport_mask_expandedQSmatching_featurer   r   r   r   r     s`   






zMGIMNNet.__call__c                 C   s   |j d }|||| |}|||| |}tj|||| ||  gdd}| |}|||||}|d}	|d\}
}tj|	|
gdd}|S )NrL   rM   r   )rO   r   rD   rR   rS   r
  r   r   )r2   r$  r%  rX   rW   r  z_dimcat_featuresinstance_matching_featurecls_matching_feature_meancls_matching_feature_max_cls_matching_featurer   r   r   r    s   
"

zMGIMNNet._instance_comparec                 C   s   |j \}}}|j d }|dd|dd|| ||}|dd|d|| |d}|d|ddd|| ||}|d|ddd|| |d}| ||||}	tj|	dd}
tj|	dd}t|
	dd|}t||}||fS )Nr   rB   rM   r   )
rO   rP   rQ   r   r  ri   rw   rD   rx   ry   )r2   r   r   r   r   rX   r  r'  r  r~   attn_aattn_bins_support	ins_queryr   r   r   r    s0   



z$MGIMNNet._instance_level_interactionc                 C   sl  |}|}|j \}}	}
|j d }|| }|dd|dd|| |	|
}|ddd|dd|| |	d}|d|ddd|| ||	 |
}|dd|ddd|| ||	 d}| ||||}tj|dd}t||}||||	|
}||||	 |
}||||	 d}| ||||}tj|dd}t||}||| |	|
}||fS Nr   rB   rL   r   rM   )	rO   rP   rQ   r   r  ri   rw   rD   rx   )r2   r   r   r   r   rW   z_support_orisupport_mask_orirX   r  r'  r  r  r~   r/  	cls_querycls_supportr   r   r   r    sH   
z!MGIMNNet._class_level_interactionc                 C   s"  |}|}|j \}}}	|j d }
|||d}|d|ddd||
| |	}|dd|ddd||
| d}| ||||}tj|dd}t||}|d|
| |	|
dd}|d|
| d|
dd}| |||d|}tj|dd}t||}||
||	}||fS r2  )	rO   r   rP   rQ   r  ri   rw   rD   rx   )r2   r   r   r   r   r3  r4  rX   r  r'  r  r~   r/  	eps_query
z_support2eps_supportr   r   r   r    sB   




z#MGIMNNet._episode_level_interactionNc                 C   s  |j \}}}	|d usJ |ddd|dd|| | ||	}
|dd|| dd|| | ||	}||
||
 ||
  g}|d urU|||| ||  g |d ur}|dd|| dd|| | ||	}|||| ||  g tj|dd}| |}|S )Nr   rB   rL   rM   	rO   rP   rQ   r   rS   extendrD   rR   r  )r2   r   rW   r  r  r  r  rX   r  r'  cls_featuresr{   fusion_featr   r   r   r  4  sD   



zMGIMNNet._fuse_queryc                 C   s   |d usJ |j \}}}|d|ddd|| ||}|d|ddd|| ||}	||	||	 ||	  g}
|d urN|
||| ||  g |d urr|d|ddd|| ||}|
||| ||  g tj|
dd}
| |
}|S rK   r:  )r2   r   rX   r  r  r  r  r  r'  r<  r{   r=  r   r   r   r  R  s<   


zMGIMNNet._fuse_supportc                 C   s   |j d }|j d }tj||gdd}tj||gdd}| ||j}	|	j d }
|	j d }|	d | |||
g}|	|d  |||
g}||fS )Nr   rM   rL   r   )rO   rD   rR   r   r   r   )r2   rU   r   r   r   rX   r  r   x_maskr   r'  r  r   r   r   r   r   r  m  s   



zMGIMNNet.context_embeddingr   c                 C   sr   |d }|d }t |tst|}t |tst|}| ||}|j}t|jdkr1|d}| 	||}|S r   )
r   r   rD   r   r   r   r   rO   rP   r	  r   r   r   r   r   z  s   




zMGIMNNet.sentence_embeddingc              
   C   sX   z| j ||W S  ty+ } zt| d|  t| |W  Y d }~S d }~ww )Nz" not in model_config, use default:)r   r   	Exceptionr   debug)r2   kdefaulter   r   r   r    s   
zMGIMNNet.safe_get)NNNr   )r:   r;   r<   r  r  r#   r   r  r  r  r  r  r  r  r   r   r   r   r  r=   r   r   r6   r   r     s(    +!"
!
r   )7r,   r   collectionsr   typingr   rD   torch.nnr'   torch.nn.functional
functionalri   r   r   modelscope.metainfor   modelscope.models.builderr    modelscope.models.nlp.structbertr   r	   ,modelscope.models.nlp.task_models.task_modelr
   modelscope.outputsr   modelscope.utils.configr   r   modelscope.utils.constantr   r   modelscope.utils.loggerr   r   r   r   r$   r-   r&   Moduler   r?   r[   rl   rp   r}   r   r   register_modulefaq_question_answering
structbertr   r   r   r   r   r   r   r   <module>   sT   ! 
5