a
    d                     @   s   d dl Z d dlmZ d dlmZ zd dlZ d dl mZ dZW n e	yR   dZY n0 zd dl
m Z W n e	yz   dZY n0 dddZG d	d
 d
ejZG dd deZG dd deZdS )    N)
functional)distributedTF   c                    s  t sJ d|rtd us J d|r:t }t}nt $ t }t}W d    n1 sl0    Y  |st|j|dd}	t|j|dd}
 |	|< |
|< tj|	dd}tj|
dd}n|rtjtjj	
 dd}tjtjj	
dd}nv fddt|D }	fddt|D }
t
|	  t
|
 |s^ |	|< |
|< tj|	dd}tj|
dd}||fS )NzVtorch.distributed did not import correctly, please use a PyTorch version with support.zPlease install horovodr   Zdimc                    s   g | ]}t  qS  torchZ
zeros_like.0_)image_featuresr   W/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/open_clip/loss.py
<listcomp>4       z#gather_features.<locals>.<listcomp>c                    s   g | ]}t  qS r   r   r	   )text_featuresr   r   r   5   r   )has_distributedhvdZ	allgatherr   Zno_gradlistchunkcatr   nnZ
all_gatherrangedist)r   r   
local_lossgather_with_gradrank
world_sizeuse_horovodall_image_featuresall_text_featuresZgathered_image_featuresZgathered_text_featuresr   )r   r   r   gather_features   s:    	


(r    c                       s@   e Zd Zd fdd	ZejdddZd	d
 ZdddZ  Z	S )ClipLossFr   r   c                    s>   t    || _|| _|| _|| _|| _|| _d| _i | _	d S )Nr   )
super__init__r   r   cache_labelsr   r   r   prev_num_logitslabels)selfr   r   r$   r   r   r   	__class__r   r   r#   D   s    	
zClipLoss.__init__)returnc                 C   sj   | j |ks|| jvr\tj||tjd}| jdkrD| jrD||| j  }| jrf|| j|< || _ n
| j| }|S )N)deviceZdtyper   )	r%   r&   r   Zarangelongr   r   r   r$   )r'   r+   Z
num_logitsr&   r   r   r   get_ground_truthY   s    

zClipLoss.get_ground_truthc                 C   s   | j dkrft||| j| j| j| j | j\}}| jrP|| |j }|| |j }q|| |j }|j}n|| |j }|| |j }||fS )Nr   )r   r    r   r   r   r   T)r'   r   r   logit_scaler   r   logits_per_imagelogits_per_textr   r   r   
get_logitsf   s    
zClipLoss.get_logitsc           
      C   sV   |j }| |||\}}| ||jd }t||t|| d }	|rRd|	iS |	S )Nr      contrastive_loss)r+   r2   r-   shapeFcross_entropy)
r'   r   r   r/   output_dictr+   r0   r1   r&   Z
total_lossr   r   r   forwardx   s    

zClipLoss.forward)FFFr   r   F)F)
__name__
__module____qualname__r#   r   ZTensorr-   r2   r9   __classcell__r   r   r(   r   r!   B   s         r!   c                       s,   e Zd Zd fdd	Zd	 fdd	Z  ZS )
CoCaLossr   Fr   c
           
         s6   t  j||||||	d || _|| _tj|d| _d S )N)r   r   r$   r   r   r   )Zignore_index)r"   r#   clip_loss_weightcaption_loss_weightr   ZCrossEntropyLosscaption_loss)
r'   r@   r?   Zpad_idr   r   r$   r   r   r   r(   r   r   r#      s    	zCoCaLoss.__init__c           	         sP   t  |||}| j| }| |ddd|}|| j }|rH||dS ||fS )Nr   r3   r   )r4   rA   )r"   r9   r?   rA   Zpermuter@   )	r'   r   r   Zlogitsr&   r/   r8   Z	clip_lossrA   r(   r   r   r9      s    


zCoCaLoss.forward)r   FFFr   r   F)F)r:   r;   r<   r#   r9   r=   r   r   r(   r   r>      s          r>   c                   @   s   e Zd Zdd ZdddZdS )DistillClipLossc                 C   s*   |j dd|jdd jddjdd S )Nr   r   r   )ZsoftmaxZlog_softmaxsummean)r'   Zteacher_logitsZstudent_logitsr   r   r   	dist_loss   s    zDistillClipLoss.dist_lossFc                 C   s   |  |||\}}	|  |||\}
}| |j|jd }t||t|	| d }| |
|| ||	 d }|r~||dS ||fS )Nr   r3   )r4   distill_loss)r2   r-   r+   r5   r6   r7   rE   )r'   r   r   r/   Zdist_image_featuresZdist_text_featuresZdist_logit_scaler8   r0   r1   Zdist_logits_per_imageZdist_logits_per_textr&   r4   rF   r   r   r   r9      s$    




zDistillClipLoss.forwardN)F)r:   r;   r<   rE   r9   r   r   r   r   rB      s    rB   )FFr   r   F)r   Ztorch.nnr   r   r6   Ztorch.distributed.nnr   r   r   ImportErrorZhorovod.torchr   r    Moduler!   r>   rB   r   r   r   r   <module>   s*   

     
/D*