o
    #i8                     @   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Zd dlmZ d dl	m
Z
 ddlmZ ddiZdd	iZdd
iZd!ddZdd Z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jZd#ddZd$dd ZdS )%    N)
namedtuple)tqdm)models   )print0	vgg_lpipsz=https://heibox.uni-heidelberg.de/f/607503859c864bc1b30b/?dl=1zvgg.pthZ d507d7349b931f0638a25a48a722f98a   c              
   C   s   t jt j|d dd tj| dd[}t|jdd}t|ddd2}t	|d}|j
|d	D ]}|r@|| || q2W d    n1 sKw   Y  W d    n1 sZw   Y  W d    d S W d    d S 1 srw   Y  d S )
Nr   T)exist_ok)streamzcontent-lengthB)totalunit
unit_scalewb)
chunk_size)osmakedirspathsplitrequestsgetintheadersr   openiter_contentwriteupdate)url
local_pathr   r
total_sizepbarfdata r$   3/data/cameron/vidgen/VidTok/vidtok/modules/lpips.pydownload   s"   

"r&   c                 C   s@   t | d}| }W d    n1 sw   Y  t| S )Nrb)r   readhashlibmd5	hexdigest)r   r"   contentr$   r$   r%   md5_hash    s   
r-   Fc                 C   s   | t v sJ tj|t|  }tj|r)|rt|t|  kr)td	| | |S td	| t |  | t
t |  | t|}|t|  ksIJ ||S )Nzc[bold cyan]\[vidtok.modules.lpips]\[get_ckpt_path][/bold cyan] Using existing path for {} model: {}za[bold cyan]\[vidtok.modules.lpips]\[get_ckpt_path][/bold cyan] Downloading {} model from {} to {})URL_MAPr   r   joinCKPT_MAPexistsr-   MD5_MAPr   formatr&   )namerootcheckr   r*   r$   r$   r%   get_ckpt_path&   s$    
r7   c                       s0   e Zd Zd	 fdd	Zd
ddZdd Z  ZS )LPIPSTc                    s   t    t | _g d| _tddd| _t| jd |d| _t| jd |d| _	t| jd |d| _
t| jd	 |d| _t| jd
 |d| _|   |  D ]}d|_qOd S )N)@            r<   TF)
pretrainedrequires_gradr   )use_dropoutr            )super__init__ScalingLayerscaling_layerchnsvgg16netNetLinLayerlin0lin1lin2lin3lin4load_from_pretrained
parametersr>   )selfr?   param	__class__r$   r%   rD   ?   s   

zLPIPS.__init__r   c                 C   s:   t |d}| jtj|tdddd td| d S )Nzcheckpoints/lpipscpu)map_locationF)strictzZ[bold cyan]\[vidtok.modules.lpips][LPIPS][/bold cyan] loaded pretrained LPIPS loss from {})r7   load_state_dicttorchloaddevicer   r3   )rR   r4   ckptr$   r$   r%   rP   M   s   
zLPIPS.load_from_pretrainedc                    s   |  ||  |}}| || |}}i i i }} | j| j| j| j| jgtt| j	D ]}	t
||	 t
||	 ||	< ||	< ||	 ||	  d  |	< q1 fddtt| j	D }
|
d }tdt| j	D ]}||
| 7 }ql|S )Nr@   c                    s&   g | ]}t |  | d dqS )Tkeepdim)spatial_averagemodel).0kkdiffslinsr$   r%   
<listcomp>[   s   & z!LPIPS.forward.<locals>.<listcomp>r   r   )rF   rI   rK   rL   rM   rN   rO   rangelenrG   normalize_tensor)rR   inputtarget	in0_input	in1_inputouts0outs1feats0feats1rc   resvallr$   rd   r%   forwardR   s   "zLPIPS.forwardT)r   )__name__
__module____qualname__rD   rP   rv   __classcell__r$   r$   rT   r%   r8   =   s    
r8   c                       s$   e Zd Z fddZdd Z  ZS )rE   c                    s^   t t|   | dtg dd d d d d f  | dtg dd d d d d f  d S )Nshift)gQgI+gMbȿscale)gZd;O?gy&1?g?)rC   rE   rD   register_bufferrZ   Tensor)rR   rT   r$   r%   rD   c   s   &*zScalingLayer.__init__c                 C   s   || j  | j S )N)r|   r}   )rR   inpr$   r$   r%   rv   h   s   zScalingLayer.forwardrx   ry   rz   rD   rv   r{   r$   r$   rT   r%   rE   b   s    rE   c                       s"   e Zd ZdZd fdd	Z  ZS )rJ   z+A single linear layer which does a 1x1 convr   Fc              	      sL   t t|   |rt gng }|tj||dddddg7 }tj| | _d S )Nr   r   F)stridepaddingbias)rC   rJ   rD   nnDropoutConv2d
Sequentialra   )rR   chn_inchn_outr?   layersrT   r$   r%   rD   o   s   zNetLinLayer.__init__)r   F)rx   ry   rz   __doc__rD   r{   r$   r$   rT   r%   rJ   l   s    rJ   c                       s&   e Zd Zd fdd	Zdd Z  ZS )rH   FTc                    s:  t t|   tj|dj}tj | _tj | _	tj | _
tj | _tj | _d| _tdD ]}| jt|||  q3tddD ]}| j	t|||  qFtddD ]}| j
t|||  qYtddD ]}| jt|||  qltddD ]}| jt|||  q|s|  D ]}d|_qd S d S )	N)r=      rB   	            F)rC   rH   rD   r   featuresrZ   r   r   slice1slice2slice3slice4slice5N_slicesrh   
add_modulestrrQ   r>   )rR   r>   r=   vgg_pretrained_featuresxrS   rT   r$   r%   rD      s.   zvgg16.__init__c           
      C   sh   |  |}|}| |}|}| |}|}| |}|}| |}|}tdg d}||||||}	|	S )NZ
VggOutputs)relu1_2relu2_2relu3_3relu4_3relu5_3)r   r   r   r   r   r   )
rR   Xh	h_relu1_2	h_relu2_2	h_relu3_3	h_relu4_3	h_relu5_3Zvgg_outputsoutr$   r$   r%   rv      s   




zvgg16.forward)FTr   r$   r$   rT   r%   rH   ~   s    rH   绽|=c                 C   s&   t t j| d ddd}| ||  S )Nr@   r   T)dimr_   )rZ   sqrtsum)r   epsnorm_factorr$   r$   r%   rj      s   rj   Tc                 C   s   | j ddg|dS )Nr@   rA   r^   )mean)r   r_   r$   r$   r%   r`      s   r`   )r   )F)r   rw   )r)   r   collectionsr   r   r   rZ   torch.nnr   torchvisionr   utilr   r.   r0   r2   r&   r-   r7   Moduler8   rE   rJ   rH   rj   r`   r$   r$   r$   r%   <module>   s*    

%

(