o
    
j>                     @   sH   d dl Z d dlZd dlmZ d dlmZ d dlmZ G dd deZdS )    N)nn)GPT2PreTrainedModel)!CausalLMOutputWithCrossAttentionsc                       sd   e Zd ZdZ fddZdd ZdddZ														dd	d
Zedd Z	  Z
S )GPT2InferenceModelz:Override GPT2LMHeadModel to allow for prefix conditioning.c                    s<   t  | || _|| _|| _|| _t||| _|| _	d S N)
super__init__transformerpos_embedding
embeddings
final_normr   
Sequentiallm_headkv_cache)selfconfiggptpos_embr   normlinearr   	__class__ T/home/kuhnn/.local/lib/python3.10/site-packages/TTS/tts/layers/xtts/gpt_inference.pyr      s   
zGPT2InferenceModel.__init__c                 C   s
   || _ d S r   )cached_prefix_emb)r   
prefix_embr   r   r   store_prefix_emb   s   
z#GPT2InferenceModel.store_prefix_embNc                 K   s   | dd }| jsd }|d ur)|d d df d}|d ur)|d d df d}| dd }| dd }|d ur^|d u r^| dd }||dkd |d ur]|d d df d}nd }||| d|||dS )	Ntoken_type_idsattention_maskposition_ids   r   	use_cache)	input_idspast_key_valuesr"   r    r   r   )getr   	unsqueezelongcumsummasked_fill_)r   r#   r$   kwargsr   r   r    r   r   r   prepare_inputs_for_generation   s.   z0GPT2InferenceModel.prepare_inputs_for_generationc                 C   sl  | j d usJ |d u sJ |
d u sJ |d ur|n| jj}| j jd }|jd dkrm|d d |d f }| |}|| | }| j jd |jd kr\| j |jd | j jd  d}n| j |j}t	j
||gdd}n| |}|| j|jd |d  |j }| j||||||||	||||d}|d }| |}|s|f|dd   S td ||j|j|j|jdS )Nr!   r   )dim)inputs_embedsr$   r   r   r    	head_maskencoder_hidden_statesencoder_attention_maskr"   output_attentionsoutput_hidden_statesreturn_dict)losslogitsr$   hidden_states
attentionscross_attentions)r   r   use_return_dictshaper   r
   repeat_interleavetodtypetorchcatget_fixed_embeddingdevicer	   r   r   r$   r6   r7   r8   )r   r#   r$   r   r   r    r.   r-   r/   r0   labelsr"   r1   r2   r3   
prefix_len
gen_inputsgen_embr   embtransformer_outputsr6   	lm_logitsr   r   r   forward7   sZ   


zGPT2InferenceModel.forwardc                    s   t  fdd| D S )a>  
        This function is used to re-order the :obj:`past_key_values` cache if
        :meth:`~transformers.PreTrainedModel.beam_search` or :meth:`~transformers.PreTrainedModel.beam_sample` is
        called. This is required to match :obj:`past_key_values` with the correct beam_idx at every generation step.
        c                 3   s&    | ]}t  fd d|D V  qdS )c                 3   s$    | ]}| d  |jV  qdS )r   N)index_selectr<   rA   ).0
past_statebeam_idxr   r   	<genexpr>   s   " z>GPT2InferenceModel._reorder_cache.<locals>.<genexpr>.<genexpr>Ntuple)rK   
layer_pastrM   r   r   rO      s
    
z4GPT2InferenceModel._reorder_cache.<locals>.<genexpr>rP   )pastrN   r   rM   r   _reorder_cache~   s   z!GPT2InferenceModel._reorder_cacher   )NNNNNNNNNNNNNN)__name__
__module____qualname____doc__r   r   r+   rI   staticmethodrT   __classcell__r   r   r   r   r   	   s,    	
!
Gr   )mathr>   r   transformersr   transformers.modeling_outputsr   r   r   r   r   r   <module>   s    