o
    i                     @   sz   d dl Zd dlZd dlZd dlmZ d dlmZmZ G dd dej	Z
G dd dej	ZG dd	 d	eZd
efddZdS )    N)override)ComfyExtensionioc                   @   s6   e Zd ZdZedd Zed
dejfddZeZ	d	S )SkipLayerGuidanceDiTa
  
    Enhance guidance towards detailed dtructure by having another set of CFG negative with skipped layers.
    Inspired by Perturbed Attention Guidance (https://arxiv.org/abs/2403.17377)
    Original experimental implementation for SD3 by Dango233@StabilityAI.
    c                 C   s   t jddddt jdt jjddddt jjd	dddt jjd
dddddt jjdddddddt jjdddddddt jjddddddgt j gdS )Nr   advanced/guidancezNGeneric version of SkipLayerGuidance node that can be used on every DiT model.Tmodeldouble_layers7, 8, 9defaultadvancedsingle_layersscaleg      @        g      $@g?)r   minmaxstepstart_percentg{Gz?      ?MbP?r   r   r   r   r   end_percentg333333?rescaling_scalenode_idcategorydescriptionis_experimentalinputsoutputsr   SchemaModelInputStringFloatOutputcls r)   4/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_slg.pydefine_schema   s    

z"SkipLayerGuidanceDiT.define_schema r   returnc           
   	      s   dd | d|td  dd  D  tddd D t dkr>tdkr>t|S  f	d	d
}| }	|	| t|	S )Nc                 S      | S Nr)   args
extra_argsr)   r)   r*   skip'      z*SkipLayerGuidanceDiT.execute.<locals>.skipmodel_sampling\d+c                 S      g | ]}t |qS r)   int.0ir)   r)   r*   
<listcomp>/       z0SkipLayerGuidanceDiT.execute.<locals>.<listcomp>c                 S   r7   r)   r8   r:   r)   r)   r*   r=   2   r>   r   c                    s  | d }| d }| d }| d }| d }| d }| d   } D ]}tj|dd	|}q D ]}tj|dd
|}q/ |d  }	dkr|	kr|	krtj||g|||\}
|||
   }dkr| |  }| d  }||9 }|S )Nr   cond_denoisedconddenoisedsigmainputmodel_optionsditdouble_blocksingle_blockr      )	copycomfymodel_patcherset_model_options_patch_replacepercent_to_sigmaitemsamplerscalc_cond_batchstd)r1   r   	cond_predr@   
cfg_resultrB   xrD   layersigma_slgfactor	r   r5   r   r   	sigma_endsigma_startr   r3   r   r)   r*   post_cfg_function7   s*   
z7SkipLayerGuidanceDiT.execute.<locals>.post_cfg_function)	get_model_objectrM   refindalllenr   
NodeOutputclone#set_model_sampler_post_cfg_function)
r(   r   r   r   r   r   r   r   r\   mr)   rY   r*   execute$   s   





zSkipLayerGuidanceDiT.executeN)r,   r,   r   
__name__
__module____qualname____doc__classmethodr+   r   ra   re   skip_guidancer)   r)   r)   r*   r      s    
3r   c                   @   s6   e Zd ZdZedd Zed	dejfddZeZ	dS )
SkipLayerGuidanceDiTSimplez]
    Simple version of the SkipLayerGuidanceDiT node that only modifies the uncond pass.
    c                 C   st   t jddddt jdt jjddddt jjd	dddt jjd
ddddddt jjdddddddgt j gdS )Nrm   r   zSSimple version of the SkipLayerGuidanceDiT node that only modifies the uncond pass.Tr   r   r	   r
   r   r   r   r   r   r   r   r   r    r'   r)   r)   r*   r+   _   s   
z(SkipLayerGuidanceDiTSimple.define_schemar,   r-   c           	         s   dd | d}||||td  dd  D  tddd D t dkr>tdkr>t|S  fd	d
}| }|| t|S )Nc                 S   r.   r/   r)   r0   r)   r)   r*   r3   t   r4   z0SkipLayerGuidanceDiTSimple.execute.<locals>.skipr5   r6   c                 S   r7   r)   r8   r:   r)   r)   r*   r=   |   r>   z6SkipLayerGuidanceDiTSimple.execute.<locals>.<listcomp>c                 S   r7   r)   r8   r:   r)   r)   r*   r=      r>   r   c                    s   | d }| d }| d }| d }| d }|  } D ]}tj|dd|}qD ]}tj|dd|}q)|\}}	|d	  }
|
krn|
krn|	d urntj||d g|||\}}tj|d |	g|||\}}||g}|S tj|||||}|S )
NrC   r   condsrB   rD   rE   rF   rG   r   )rI   rJ   rK   rL   rN   rO   rP   )r1   rT   r   rn   rB   rD   slg_model_optionsrU   r@   uncondrV   cond_out_
uncond_outoutr   rZ   r[   r   r3   r)   r*   calc_cond_batch_function   s&   zDSkipLayerGuidanceDiTSimple.execute.<locals>.calc_cond_batch_function)	r]   rM   r^   r_   r`   r   ra   rb   *set_model_sampler_calc_cond_batch_function)	r(   r   r   r   r   r   r5   rv   rd   r)   ru   r*   re   r   s   





z"SkipLayerGuidanceDiTSimple.executeN)r,   r,   rf   r)   r)   r)   r*   rm   [   s    
0rm   c                   @   s(   e Zd Zedeeej  fddZdS )SkipLayerGuidanceExtensionr-   c                    s
   t tgS r/   )r   rm   )selfr)   r)   r*   get_node_list   s   z(SkipLayerGuidanceExtension.get_node_listN)	rg   rh   ri   r   listtyper   	ComfyNoderz   r)   r)   r)   r*   rx      s    rx   r-   c                      s   t  S r/   )rx   r)   r)   r)   r*   comfy_entrypoint   s   r~   )comfy.model_patcherrJ   comfy.samplersr^   typing_extensionsr   comfy_api.latestr   r   r}   r   rm   rx   r~   r)   r)   r)   r*   <module>   s    SK	