o
    i7                    @  s  d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	m
Z
 ddlZddlZddlZddlZddlZddlZddlZddlmZ ddlmZ ddlmZmZmZ ddlZd2dd	Zd3ddZd3ddZd4ddZdd Z dd Z!dd Z"dd Z#G dd dZ$dZ%dd Z&d d! Z'd"d# Z(G d$d% d%Z)G d&d' d'Z*e+d(d)d*gd+dZ,G d,d- d-ej-j.Z/G d.d/ d/Z0G d0d1 d1e0Z1e0Z2dS )5a  
    This file is part of ComfyUI.
    Copyright (C) 2024 Comfy

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
    )annotationsN)CallableOptional)UnetWrapperFunction)QuantizedTensor)CallbacksMPPatcherInjection
WrappersMPc                 C  s   | d   }d|vri |d< n|d   |d< ||d vr$i |d |< n|d |   |d |< |d ur:|||f}n||f}||d | |< || d< | S )Ntransformer_optionspatches_replacecopy)model_optionspatchname
block_namenumbertransformer_indextoblock r   1/mnt/c/Users/fbmor/ComfyUI/comfy/model_patcher.pyset_model_options_patch_replace*   s   
r   Fc                 C  &   |  dg |g | d< |rd| d< | S )Nsampler_post_cfg_functionTdisable_cfg1_optimizationget)r   post_cfg_functionr   r   r   r   #set_model_options_post_cfg_function?      r   c                 C  r   )Nsampler_pre_cfg_functionTr   r   )r   pre_cfg_functionr   r   r   r   "set_model_options_pre_cfg_functionE   r    r#   orig_model_optionsdictc                 C  s   t j| S N)comfypatcher_extensioncopy_nested_dicts)r$   r   r   r   create_model_options_cloneK      r*   c                 C  sD   i }| D ]}i ||< | | D ]}| | | d d  || |< qq|S r&   r   )orig_hook_patchesnew_hook_patcheshook_refkr   r   r   create_hook_patches_cloneN   s   r0   c                 C  s>   t | dr| j| _| `t | drg | _t | drg | _d S d S )Nprev_comfy_cast_weightsweight_functionbias_function)hasattrr1   comfy_cast_weightsr2   r3   )mr   r   r   wipe_lowvram_weightV   s   



r7   c                 C  st   |d u rdS d}t | dr | jD ]}t |dr||j|d7 }qt | dr8| jD ]}t |dr7||j|d7 }q(|S )Nr   r2   move_todevicer3   )r4   r2   r8   r3   )r6   r:   memoryfr   r   r   move_weight_functionsa   s   





r=   c                 C  s   t d tj| S )NzIWARNING: string_to_seed has moved from comfy.model_patcher to comfy.utils)loggingwarningr'   utilsstring_to_seed)datar   r   r   rA   q   s   
rA   c                   @  s   e Zd ZdddZdd ZdS )LowVramPatchNc                 C  s   || _ || _|| _|| _d S r&   )keypatchesconvert_funcset_func)selfrD   rE   rF   rG   r   r   r   __init__v      
zLowVramPatch.__init__c                 C  s    t jj| j| j || j|jdS )Nintermediate_dtype)r'   loracalculate_weightrE   rD   dtype)rH   weightr   r   r   __call__|   s    zLowVramPatch.__call__NN)__name__
__module____qualname__rI   rQ   r   r   r   r   rC   u   s    
rC      c                 C  sJ   t | |\}}}|d u rdS t| dtj}|d u r|j}| |j t S )Nr   manual_cast_dtype)get_key_weightgetattrtorchfloat32rO   numelitemsize"LOWVRAM_PATCH_ESTIMATE_MATH_FACTOR)modelrD   rP   rG   rF   model_dtyper   r   r   low_vram_patch_estimate_vram   s   ra   c                 C  s   d }d }| dd}t|dk rtj| |}nGtj| |d }zt|d|d }W n	 ty6   Y nw zt|d|d }W n	 tyL   Y nw t||d }|d ur_tj| |}|||fS )N.   rV   r   zset_{}z
convert_{})rsplitlenr'   r@   get_attrrY   formatAttributeError)r_   rD   rG   rF   op_keysrP   opr   r   r   rX      s(   
rX   c                 C  s   t | dkr|S d| |S )Nr   z{}.{})re   rg   )rD   paramr   r   r   key_param_name_to_key   s   rl   c                   @  s(   e Zd ZddddZdd Zdd	 Zd
S )AutoPatcherEjectorFr_   'ModelPatcher'c                 C  s   || _ d| _d| _|| _d S NF)r_   was_injectedprev_skip_injectionskip_and_inject_on_exit_only)rH   r_   rr   r   r   r   rI      rJ   zAutoPatcherEjector.__init__c                 C  s>   d| _ | jj| _| jrd| j_| jjr| j  d| _ d S d S )NFT)rp   r_   skip_injectionrq   rr   is_injectedeject_modelrH   r   r   r   	__enter__   s   


zAutoPatcherEjector.__enter__c                 G  s@   | j r| j| j_| j  | jr| jjs| j  | j| j_d S r&   )rr   rq   r_   rs   inject_modelrp   )rH   argsr   r   r   __exit__   s   


zAutoPatcherEjector.__exit__NF)r_   rn   )rS   rT   rU   rI   rw   rz   r   r   r   r   rm      s    	rm   c                   @  s6   e Zd ZddddZddd	ZdddZdddZdS )MemoryCounterr   initialintc                 C     || _ || _d S r&   valueminimum)rH   r}   r   r   r   r   rI         
zMemoryCounter.__init__rP   torch.Tensorc                 C  s,   |  |  }| |r| | dS dS )NTF)nelementelement_size
is_useable	decrement)rH   rP   weight_sizer   r   r   use   s
   

zMemoryCounter.useusedc                 C  s   | j | | jkS r&   r   rH   r   r   r   r   r         zMemoryCounter.is_useablec                 C  s   |  j |8  _ d S r&   )r   r   r   r   r   r         zMemoryCounter.decrementN)r   )r}   r~   )rP   r   )r   r~   )rS   rT   rU   rI   r   r   r   r   r   r   r   r|      s
    

r|   
FakeDevicetypeindexzcomfy-lazy-casterc                      s8   e Zd Z fddZdd Zedd Zdd Z  ZS )	LazyCastingParamc                   s   t  | |S r&   )super__new__)clsr_   rD   tensor	__class__r   r   r         zLazyCastingParam.__new__c                 C  r   r&   )r_   rD   )rH   r_   rD   r   r   r   r   rI      r   zLazyCastingParam.__init__c                 C  s   t S r&   )CustomTorchDevicerv   r   r   r   r:         zLazyCastingParam.devicec                 O  s   | j j| j| j jdddS )NT)	device_toreturn_weightcpu)r_   patch_weight_to_devicerD   load_devicer   )rH   ry   kwargsr   r   r   r      s   zLazyCastingParam.to)	rS   rT   rU   r   rI   propertyr:   r   __classcell__r   r   r   r   r      s    
r   c                   @  sD  e Zd Zd ddZdd Zdd Zdd	d
Zdd Zdd Zdd Z	dd Z
dddZdd ZdddZdd Zdd Zdd d!Zdd"d#Zdd$d%Zd&d' Zdd*d+Zd,d- Zd.d/ Zdd0d1Zd2d3 Zd4d5 Zdd6d7Zdd8d9Zd:d; Zd<d= Zd>d? Zd@dA ZdBdC Z dDdE Z!dFdG Z"dHdI Z#dJdK Z$dLdM Z%dNdO Z&dPdQ Z'dRdS Z(dTdU Z)ddZd[Z*d\d] Z+d^d_ Z,d`i fdadbZ-dcdd Z.ddfdgZ/ddhdiZ0ddjdkZ1ddldmZ2dndo Z3dpdq Z4drds Z5ddtduZ6d	dvdwZ7d
dydzZ8dd{d|Z9d d}d~Z:d ddZ;dd Z<dd Z=dddZ>dd Z?e@jAfddZBdd ZCdddZDdddZEdddZFdddZGdddZHdddZIdddZJdddZKdddZLdddZMdddZNdddZOdddZPdddZQdddZRdddZSdddZTdddZUdddZVdd ZWdd ZXdddZYddĄ ZZddƄ Z[ddȄ Z\ddʄ Z]dd̄ Z^dddЄZ_ddd؄Z`		ddddބZaddddZbdddZcddddZddddZed ddZfdd Zgd!ddZhdd"ddZidd Zjd#ddZkdd ZldS ($  ModelPatcherr   Fc                 C  sx  || _ || _t| jdstd || j_n
| jjd u r || j_i | _i | _i | _i | _	i | _
i | _di i| _|| _|| _|| _d| _t | _d | _t | _i | _i | _t | _t | _d| _d| _ i | _!i | _"d | _#i | _$i | _%d | _&d | _'d| _(t)j*j+j,| _-d | _.t| jdsd| j_/t| jdsd| j_0t| jdsd| j_1t| jd	sd | j_2t| jd
sd| j_3d S d S )Nr:   z&Model doesn't have a device attribute.r
   Fmodel_loaded_weight_memoryr   lowvram_patch_countermodel_lowvramcurrent_weight_patches_uuidmodel_offload_buffer_memory)4sizer_   r4   r>   debugr:   rE   backupbackup_buffersobject_patchesobject_patches_backupweight_wrapper_patchesr   r   offload_deviceweight_inplace_updateforce_cast_weightsuuiduuid4patches_uuidparentsetpinnedattachmentsadditional_modelsr   init_callbacks	callbacksr	   init_wrapperswrappersrt   rs   
injectionshook_patcheshook_patches_backuphook_backupcached_hook_patchescurrent_hooksforced_hooksis_clipr'   hooksEnumHookModeMaxSpeed	hook_modecached_patcher_initr   r   r   r   r   rH   r_   r   r   r   r   r   r   r   rI      s`   





zModelPatcher.__init__c                 C     dS ro   r   rv   r   r   r   
is_dynamic#     zModelPatcher.is_dynamicc                 C  s&   | j dkr| j S tj| j| _ | j S Nr   )r   r'   model_managementmodule_sizer_   rv   r   r   r   
model_size&  s   
zModelPatcher.model_sizec                 C  s   t jj| j|dS )N)free)r'   r   module_mmap_residencyr_   )rH   r   r   r   r   model_mmap_residency,  r   z!ModelPatcher.model_mmap_residencyc                 C     | j jS r&   )r_   r   rv   r   r   r   loaded_size/     zModelPatcher.loaded_sizec                 C  r   r&   )r_   r   rv   r   r   r   r   2  r   z"ModelPatcher.lowvram_patch_counterc                 C  s&   d}t jjrtj }t j|| S r   )r'   memory_managementaimdo_enabledcomfy_aimdo
model_vbarvbars_analyzer   get_free_memory)rH   r:   	aimdo_memr   r   r   r   5  s   
zModelPatcher.get_free_memoryc                 C  s   | j | j| j| j| jffS r&   )r_   r   r   r   r   rv   r   r   r   get_clone_model_override>  s   z%ModelPatcher.get_clone_model_overrideNc                 C  s  | j }|  r)|r)t}|d u r)| jd u rtd| jd | jd ddi}| }|d u r1|  }||d | j| j|  | j	d}i |_
| j
D ]}| j
| d d  |j
|< qG| j|_| j |_| j |_tj| j|_| |_| j|_|d \|_|_|_|_i |_| jD ]}t| j| dr| j|  |j|< q| j| |j|< q| j D ]\}}dd	 |D |j|< q| j D ]\}}i |j|< | D ]\}}	|	 |j| |< qq| j D ]\}}
i |j|< |
 D ]\}}| |j| |< qq| j |_ | j!|_!| j" D ]\}}| |j"|< qt#| j$|_$| j%r$t#| j%n| j%|_%| j&D ]}i |j&|< | j&| D ]}| j&| | |j&| |< q7q+| j'|_'| j(rV| j() n| j(|_(| j*rc| j*) n| j*|_*| j+|_+| j,|_,| j|_| -t.j/D ]}|| | qy|S )
NzKCannot create non-dynamic delegate: cached_patcher_init is not initialized.r   rc   disable_dynamicT)r   on_model_patcher_clonec                 S  s   g | ]}|  qS r   )clone).0xr   r   r   
<listcomp>e      z&ModelPatcher.clone.<locals>.<listcomp>)0r   r   r   r   RuntimeErrorr   r   r   r   r   rE   r   r   r   r   r'   r@   deepcopy_list_dictr   r   r   r   r   r   r   r   r4   r   r   itemsr   r   rt   rs   r   r0   r   r   r   r   r   r   r   r   r   get_all_callbacksr   ON_CLONE)rH   r   model_overrideclass_temp_model_patchernr/   ck1c1ww1igroupcallbackr   r   r   r   A  st   
 





zModelPatcher.clonec                 C  s   t |dr| j|ju rdS dS )Nr_   TF)r4   r_   )rH   otherr   r   r   is_clone  s   zModelPatcher.is_cloner   rn   c                 C  s@  |  |sdS | j|jkrdS | j|jkrdS | j |j kr#dS | j |j kr/dS | j |j kr;dS | jD ]}t| j| t|j| krQ dS q>| j	D ]}t| j	| t|j	| krh dS qU| j
 |j
 krudS t| jdkrt|jdkrdS | j|jkrt| jt|jkrtd d S dS d S )NFr   TzOWARNING: something went wrong, same patch uuid but different length of patches.)r   r   r   r   keysr   r   r   re   r   r   rE   r   r>   r?   )rH   r   rD   r   r   r   clone_has_same_weights  s:   


z#ModelPatcher.clone_has_same_weightsc                 C  s   | j j|dS )Ninput_shape)r_   memory_requiredrH   r   r   r   r   r    r   zModelPatcher.memory_requiredc                 C  s   d| j d< d S )NTr   r   rv   r   r   r   disable_model_cfg1_optimization  r   z,ModelPatcher.disable_model_cfg1_optimizationc                   sF   t t jdkr fdd| jd< n | jd< |r!|   d S d S )N   c                   s    | d | d | d S )Nconduncond
cond_scaler   )ry   sampler_cfg_functionr   r   <lambda>  s    z=ModelPatcher.set_model_sampler_cfg_function.<locals>.<lambda>r
  )re   inspect	signature
parametersr   r  )rH   r
  r   r   r	  r   set_model_sampler_cfg_function  s   
z+ModelPatcher.set_model_sampler_cfg_functionc                 C     t | j||| _d S r&   )r   r   )rH   r   r   r   r   r   #set_model_sampler_post_cfg_function     z0ModelPatcher.set_model_sampler_post_cfg_functionc                 C  r  r&   )r#   r   )rH   r"   r   r   r   r   "set_model_sampler_pre_cfg_function  r  z/ModelPatcher.set_model_sampler_pre_cfg_functionc                 C     || j d< d S )N sampler_calc_cond_batch_functionr  )rH   r  r   r   r   *set_model_sampler_calc_cond_batch_function  r   z7ModelPatcher.set_model_sampler_calc_cond_batch_functionunet_wrapper_functionr   c                 C  r  )Nmodel_function_wrapperr  )rH   r  r   r   r   set_model_unet_function_wrapper  r   z,ModelPatcher.set_model_unet_function_wrapperc                 C  r  )Ndenoise_mask_functionr  )rH   r  r   r   r   set_model_denoise_mask_function  r   z,ModelPatcher.set_model_denoise_mask_functionc                 C  s<   | j d }d|vri |d< |d |g |g |d |< d S )Nr
   rE   r   r   )rH   r   r   r   r   r   r   set_model_patch  s   
"zModelPatcher.set_model_patchc                 C  s   t | j|||||d| _d S )N)r   )r   r   )rH   r   r   r   r   r   r   r   r   set_model_patch_replace  s   z$ModelPatcher.set_model_patch_replacec                 C     |  |d d S )Nattn1_patchr  rH   r   r   r   r   set_model_attn1_patch  r   z"ModelPatcher.set_model_attn1_patchc                 C  r  )Nattn2_patchr!  r"  r   r   r   set_model_attn2_patch  r   z"ModelPatcher.set_model_attn2_patchc                 C     |  |d||| d S )Nattn1r  rH   r   r   r   r   r   r   r   set_model_attn1_replace     z$ModelPatcher.set_model_attn1_replacec                 C  r&  )Nattn2r(  r)  r   r   r   set_model_attn2_replace  r+  z$ModelPatcher.set_model_attn2_replacec                 C  r  )Nattn1_output_patchr!  r"  r   r   r   set_model_attn1_output_patch  r   z)ModelPatcher.set_model_attn1_output_patchc                 C  r  )Nattn2_output_patchr!  r"  r   r   r   set_model_attn2_output_patch  r   z)ModelPatcher.set_model_attn2_output_patchc                 C  r  )Ninput_block_patchr!  r"  r   r   r   set_model_input_block_patch  r   z(ModelPatcher.set_model_input_block_patchc                 C  r  )Ninput_block_patch_after_skipr!  r"  r   r   r   &set_model_input_block_patch_after_skip  r   z3ModelPatcher.set_model_input_block_patch_after_skipc                 C  r  )Noutput_block_patchr!  r"  r   r   r   set_model_output_block_patch  r   z)ModelPatcher.set_model_output_block_patchc                 C  r  )N	emb_patchr!  r"  r   r   r   set_model_emb_patch  r   z ModelPatcher.set_model_emb_patchc                 C  r  )Nforward_timestep_embed_patchr!  r"  r   r   r   &set_model_forward_timestep_embed_patch  r   z3ModelPatcher.set_model_forward_timestep_embed_patchc                 C  r  )Ndouble_blockr!  r"  r   r   r   set_model_double_block_patch  r   z)ModelPatcher.set_model_double_block_patchc                 C  r  )N
post_inputr!  r"  r   r   r   set_model_post_input_patch  r   z'ModelPatcher.set_model_post_input_patchc                 C  r  )Nnoise_refinerr!  r"  r   r   r   set_model_noise_refiner_patch  r   z*ModelPatcher.set_model_noise_refiner_patchc           	      K  sT   | j d di }||d< ||d< ||d< ||d< ||d< ||d< || j d d< d S )	Nr
   rope_optionsscale_xscale_yscale_tshift_xshift_yshift_tr  )	rH   rC  rF  rD  rG  rE  rH  r   rB  r   r   r   set_model_rope_options  s   z#ModelPatcher.set_model_rope_optionsc                 C     || j |< d S r&   )r   )rH   r   objr   r   r   add_object_patch
  r   zModelPatcher.add_object_patchc                 C  s(   |  d| |d urd| _t | _d S )NrW   T)rL  r   r   r   r   )rH   rO   r   r   r   set_model_compute_dtype  s   z$ModelPatcher.set_model_compute_dtypec                 C  s(   | j |g |g | j |< t | _d S r&   )r   r   r   r   r   )rH   r   functionr   r   r   add_weight_wrapper  s   zModelPatcher.add_weight_wrapperr   strreturntorch.nn.Modulec                 C  s8   || j v r
| j | S || jv r| j| S tj| j|S )a  Retrieves a nested attribute from an object using dot notation considering
        object patches.

        Args:
            name (str): The attribute path using dot notation (e.g. "model.layer.weight")

        Returns:
            The value of the requested attribute

        Example:
            patcher = ModelPatcher()
            weight = patcher.get_model_object("layer1.conv.weight")
        )r   r   r'   r@   rf   r_   )rH   r   r   r   r   get_model_object  s
   



zModelPatcher.get_model_objectc           	      C  s   | j d }d|v r/|d }|D ]}|| }tt|D ]}t|| dr-|| |||< qqd|v rU|d }|D ]}|| }|D ]}t|| drS|| |||< qAq9d| j v rn| j d }t|drp||| j d< d S d S d S )Nr
   rE   r   r   r  )r   rangere   r4   r   )	rH   r:   r   rE   r   
patch_listr   r/   	wrap_funcr   r   r   model_patches_to-  s2   



zModelPatcher.model_patches_toc           	      C  s   | j d }g }d|v r0|d }|D ]}|| }tt|D ]}t|| dr.|||  7 }qqd|v rU|d }|D ]}|| }|D ]}t|| drS|||  7 }qBq:d| j v rj| j d }t|drj|| 7 }|S )Nr
   rE   modelsr   r  )r   rT  re   r4   rX  )	rH   r   rX  rE   r   rU  r   r/   rV  r   r   r   model_patches_modelsB  s2   



z!ModelPatcher.model_patches_modelscleanupc           
      C  s   | j d }d|v r2|d }|D ]"}|| }tt|D ]}t|| |r0t|| |di | qqd|v r[|d }|D ]}|| }|D ]}t|| |rYt|| |di | qDq<d| j v rv| j d }	t|	|rxt|	|di | d S d S d S )Nr
   rE   r   r  r   )r   rT  re   r4   rY   )
rH   function_name	argumentsr   rE   r   rU  r   r/   rV  r   r   r   model_patches_call_functionZ  s2   



z(ModelPatcher.model_patches_call_functionc                 C  s   t | jdr| j S d S )N	get_dtype)r4   r_   r^  rv   r   r   r   r`   o  s   
zModelPatcher.model_dtype      ?c              	   C  s   |   ] t }| j }|D ]A}d }d }t|tr|}	n|d }|d }	t|dkr/|d }|	|v rP|| | j	|	g }
|

||| |||f |
| j|	< qt | _t|W  d    S 1 sdw   Y  d S Nrc   r   rV   )use_ejectedr   r_   
state_dict
isinstancerP  re   addrE   r   appendr   r   r   list)rH   rE   strength_patchstrength_modelpmodel_sdr/   offsetrN  rD   current_patchesr   r   r   add_patchess  s*   





$zModelPatcher.add_patchesc           
      C  s   |   }i }|D ]S}|d ur||sq| j|d }| j|d }t| j|\}}}	|d ur2|j}|d ur:|d }|	d u rBdd }	|| jv rT||	fg| j|  ||< q||	fg||< q|S )Nr   c                 [  s   | S r&   r   )ar   r   r   r   r    s    z.ModelPatcher.get_key_patches.<locals>.<lambda>)	model_state_dict
startswithr   r   r   rX   r_   rP   rE   )
rH   filter_prefixrj  ri  r/   bkhbkrP   rG   rF   r   r   r   get_key_patches  s&   

zModelPatcher.get_key_patchesc                 C  sl   |   ( | j }t| }|d ur#|D ]}||s"|| q|W  d    S 1 s/w   Y  d S r&   )ra  r_   rb  rf  r   rp  pop)rH   rq  sdr   r/   r   r   r   ro    s   



$zModelPatcher.model_state_dictc                 C  s6  t | j|\}}}|| jvr|S | jp|}|| jvr0|s0tdddg|j| j|d|| j|< t	j
|}|d urEt	j
j|||dd}	n|j|dd}	|d urV||	dd}	t	j| j| |	|}
|d u rt	jj|
|jt	j|d}
|rw|
S |rt	j| j||
 d S t	j| j||
 d S ||
|t	j||d	S )
N	DimensionrP   inplace_updater:   r   Tr   inplaceseed)rx  r}  r   )rX   r_   rE   r   r   collections
namedtupler   r   r'   r   lora_compute_dtypecast_to_devicerM   rN   floatstochastic_roundingrO   r@   rA   copy_to_paramset_attr_param)rH   rD   r   rx  r   rP   rG   rF   
temp_dtypetemp_weight
out_weightr   r   r   r     s*   

(z#ModelPatcher.patch_weight_to_devicec                 C  s2   t | j|\}}}tj|r| j| d S d S r&   )rX   r_   r'   r   
pin_memoryr   rd  rH   rD   rP   rG   rF   r   r   r   pin_weight_to_device  s   z!ModelPatcher.pin_weight_to_devicec                 C  s<   || j v rt| j|\}}}tj| | j | d S d S r&   )r   rX   r_   r'   r   unpin_memoryremover  r   r   r   unpin_weight  s
   
zModelPatcher.unpin_weightc                 C  s   t | jD ]}| | qd S r&   )rf  r   r  rH   rD   r   r   r   unpin_all_weights  s   zModelPatcher.unpin_all_weightsc                   s,  g } j  D ]\}}d}dd |jddD }|jddD ]\}}	||vr*d} nq|rI|d urI| D ]\}
}	|	jj|t||
d d d|	_q5|st|dsVt|d	krt	j
|}|}t|dr{ fd
d}||d|7 }||d|7 }|r|dk| f}n|f}||||||f  q|S )NFc                 S  s   i | ]\}}||qS r   r   )r   r   rk   r   r   r   
<dictcomp>  s    z+ModelPatcher._load_list.<locals>.<dictcomp>recurseT_comfy_model_dtype)r:   rO   r5   r   c                   sp   |  j v rt j| S t jdd }t j| \}}}|d u s#|d u r%dS |j|ks/t|tr6| |j	 S dS )NrW   r   )
rE   ra   r_   rY   rX   rO   rc  r   r\   r]   )rD   r`   rP   _rv   r   r   check_module_offload_mem  s   
z9ModelPatcher._load_list.<locals>.check_module_offload_mem	{}.weight{}.biasi   )r_   named_modulesnamed_parametersr   rB   r   rY   r4   re   r'   r   r   rg   re  )rH   for_dynamicdefault_deviceloadingr   r6   defaultparamsr   rk   
param_name
module_memmodule_offload_memr  sort_criteriar   rv   r   
_load_list  s2    

zModelPatcher._load_listc           !      C  s  |   1 |   d}d}d}d}|  }	g }
g }d}|	jdd t|	D ]\}}|\}}}}}d}t||tdd |	|d |d tjj	  D  }|| | |k }d
|}d	
|}|s{t|d
r{|s{|}d}|d7 }||7 }t|dr{q&| j}| j|_|rt|d
rg |_g |_|| jv r|r| | nt| j|\}}}t|| j||g|_|d7 }|| jv r|r| | nt| j|\}}}t|| j||g|_|d7 }d}|||||f nt|d
rt| |s|r||7 }|
||||f n|}|rt|d
r|j|_d|_|| jv r|j| j|  || jv r.|j| j|  |t||7 }q&|
jdd |
D ]L}|d }|d }|d }t|drZ|jdkrZq>|D ]}t||}| | | j||d q\tj|r}t j!"  t#$d
|| d|_q>|
D ]
}|d %| q|D ]}|d }|d }|D ]}| &t|| qq|dk rd
|d nd}|dkrt#'d
||d |d |d | d| j_(nt#'d
||d | d| j_(|r| j%| | ) }| j j*|7  _*|| j_+|| j_,|| j_-| j.| j_/| 0t1j2D ]} | | |||| q| j3| j4dd W d    d S 1 s:w   Y  d S )Nr   T)reverseFc                 S  s   g | ]}|d  qS )rc   r   )r   x1r   r   r   r     r   z%ModelPatcher.load.<locals>.<listcomp>rc   r  r  r5   r1   rV   r  comfy_patched_weightsr   z&lowvram: loaded module regularly {} {}nFz{:.2f} MB usable,    zjloaded partially; {} {:.2f} MB loaded, {:.2f} MB offloaded, {:.2f} MB buffer reserved, lowvram patches: {}z5loaded completely; {} {:.2f} MB loaded, full load: {}force_apply)5ra  unpatch_hooksr  sort	enumeratemaxsumr'   r   NUM_STREAMSrg   r4   r   comfy_force_cast_weightsr2   r3   rE   r   rX   r_   rC   re  r7   r5   r1   r   extendr=   r  rl   r  is_device_cudarZ   cudasynchronizer>   r   r   r  infor   r   r   r:   r   r   r   r   r   r   ON_LOADapply_hooksr   )!rH   r   lowvram_model_memoryforce_patch_weights	full_loadmem_counterpatch_counterlowvram_counterlowvram_mem_counterr  load_completely	offloadedoffload_bufferr   r   r  r  r   r6   r  lowvram_weightpotential_offloadlowvram_fits
weight_keybias_keycast_weightr  rG   rF   rk   rD   usable_statr   r   r   r   load  s   4











$

$zModelPatcher.loadTc                 C  s   |   8 | jD ]}tj| j|| j| }|| jvr || j|< q|dkr(d}nd}|r5| j||||d W d    n1 s?w   Y  |   | jS )Nr   TFr  r  r  )	ra  r   r'   r@   set_attrr_   r   r  rx   )rH   r   r  load_weightsr  r/   oldr  r   r   r   patch_model  s   



zModelPatcher.patch_modelc                 C  sB  |    |r|   |   | jjr+| j D ]}t|| t| qd| j_d| j_t	| j
 }|D ]}| j
| }|jrItj| j||j q4tj| j||j q4d | j_| j
  |d urk| j| || j_d| j_d| j_| j D ]	}t|dr|`qxt	| j }|D ]}tj| j|| j|  q| j  d S )NFr   r  )ru   r  r  r_   r   modulesr=   r7   r   rf  r   r   rx  r'   r@   r  rP   r  r   clearr   r:   r   r   r4   r  r   r  )rH   r   unpatch_weightsr6   r   r/   rr  r   r   r   unpatch_model  s>   




zModelPatcher.unpatch_modelc              	   C  s"  |    d}d}d}|  }|  | jj}t|dkr2tjj}	t	||	d  |d d g|	 }
|D ]}|| | jj |k rD n|\}}}}}|t
|
 }t|d}t|drO|jdkrOd}|D ]>}t||}| j|d }|d ur|s~d} n'|s|   d}|jrtj| j||j n
tj| j||j | j| qfd|}d|}|rO| j}|| |t||7 }|r|| jv r|r| | nt| j|\}}}|jt || j|| |d7 }|| jv r|r| | nt| j|\}}}|j!t || j|| |d7 }d}|r#t|dr#|j"|_#d|_"d|_||7 }t$||}|
| |
d t%&d	| |D ]}| 't|| qCq4d| j_(| j j)|7  _)| j j*|8  _*|| j_t%+d
|d | jj*d |d | jj) |W  d    S 1 sw   Y  d S )NFr   rc   r5   r  Tr  r  zfreed {}zmUnloaded partially: {:.2f} MB freed, {:.2f} MB remains loaded, {:.2f} MB buffer reserved, lowvram patches: {}r  ),ra  r  r  r_   r   re   r'   r   r  minr  r4   r  rl   r   r   r  rx  r@   r  rP   r  ru  rg   r   r   r=   rE   r   rX   r2   re  rC   r3   r5   r1   r  r>   r   r  r   r   r   r  )rH   r   memory_to_freer  hooks_unpatchedmemory_freedr  unload_listr  NSoffload_weight_factorunloadr  r  r   r6   r  r  lowvram_possiblemove_weightrk   rD   rr  r  r  r  r  rG   rF   r   r   r   partially_unload  s    









*&zModelPatcher.partially_unloadc           	      C  sb  | j dd | jjd uo| jj| jkp|}| jj}| j| j|d |r,||| jj 7 }| jdd |dk rK|sK| j| j| |d 	 W d    dS d}| jj	dkrj| jjdkrj| j
| jdd 	 W d    dS | jj| |  krvd}| jj}z| j||| ||d	 W n ty } z|   |d }~ww | jj| W  d    S 1 sw   Y  d S )
NTrr   r  Fr  r   )r  r  r  )ra  r_   r   r   r   r  r   r  r  r   r  r   r   r  	Exceptiondetach)	rH   r   extra_memoryr  r  r   r  current_useder   r   r   partially_load  s8   
$zModelPatcher.partially_loadc                 C  r   r   r   rv   r   r   r   pinned_memory_size*  r   zModelPatcher.pinned_memory_sizec                 C     d S r&   r   )rH   ram_to_unloadr   r   r   partially_unload_ram.  r   z!ModelPatcher.partially_unload_ramc                 C  sJ   |    | | j |r| j| j|d | tjD ]}|| | q| jS )Nr  )ru   rW  r   r  r   r   	ON_DETACHr_   )rH   unpatch_allr   r   r   r   r  1  s   zModelPatcher.detachc                 C  r   r&   )r_   r:   rv   r   r   r   current_loaded_device:  r   z"ModelPatcher.current_loaded_devicec                 C  s   t d tjj||||dS )NziThe ModelPatcher.calculate_weight function is deprecated, please use: comfy.lora.calculate_weight insteadrK   )r>   r?   r'   rM   rN   )rH   rE   rP   rD   rL   r   r   r   rN   =  s   
zModelPatcher.calculate_weightc                 C  sF   | j dd |   t| jdrd | j_| tjD ]}||  qd S )NrZ  )r[  current_patcher)r]  clean_hooksr4   r_   r  r   r   
ON_CLEANUPrH   r   r   r   r   rZ  A  s   
zModelPatcher.cleanup	call_typer   r   c                 C     |  |d | d S r&   )add_callback_with_key)rH   r  r   r   r   r   add_callbackI  r   zModelPatcher.add_callbackrD   c                 C  $   | j |i |g }|| d S r&   )r   
setdefaultre  )rH   r  rD   r   r   r   r   r   r  L     z"ModelPatcher.add_callback_with_keyc                 C  (   | j |i }||v r|| d S d S r&   )r   r   ru  )rH   r  rD   r   r   r   r   remove_callbacks_with_keyP     z&ModelPatcher.remove_callbacks_with_keyc                 C     | j |i |g S r&   )r   r   )rH   r  rD   r   r   r   get_callbacksU  r+  zModelPatcher.get_callbacksc                 C  *   g }| j |i  D ]}|| q|S r&   )r   r   valuesr  )rH   r  c_listr   r   r   r   r   X     zModelPatcher.get_all_callbackswrapper_typewrapperc                 C  r  r&   )add_wrapper_with_key)rH   r  r  r   r   r   add_wrapper^  r   zModelPatcher.add_wrapperc                 C  r  r&   )r   r  re  )rH   r  rD   r  r   r   r   r   r  a  r  z!ModelPatcher.add_wrapper_with_keyc                 C  r  r&   )r   r   ru  )rH   r  rD   r   r   r   r   remove_wrappers_with_keye  r  z%ModelPatcher.remove_wrappers_with_keyc                 C  r   r&   )r   r   )rH   r  rD   r   r   r   get_wrappersj  r+  zModelPatcher.get_wrappersc                 C  r  r&   )r   r   r  r  )rH   r  w_listr   r   r   r   get_all_wrappersm  r  zModelPatcher.get_all_wrappersc                 C  rJ  r&   )r   )rH   rD   
attachmentr   r   r   set_attachmentss  r   zModelPatcher.set_attachmentsc                 C     || j v r| j | d S d S r&   )r   ru  r  r   r   r   remove_attachmentsv     
zModelPatcher.remove_attachmentsc                 C     | j |d S r&   )r   r   r  r   r   r   get_attachmentz  r   zModelPatcher.get_attachmentr   list[PatcherInjection]c                 C  rJ  r&   )r   )rH   rD   r   r   r   r   set_injections}  r   zModelPatcher.set_injectionsc                 C  r  r&   )r   ru  r  r   r   r   remove_injections  r  zModelPatcher.remove_injectionsc                 C  r  r&   )r   r   r  r   r   r   get_injections  r   zModelPatcher.get_injectionsrX  list['ModelPatcher']c                 C  rJ  r&   )r   )rH   rD   rX  r   r   r   set_additional_models  r   z"ModelPatcher.set_additional_modelsc                 C  r  r&   )r   ru  r  r   r   r   remove_additional_models  r  z%ModelPatcher.remove_additional_modelsc                 C  s   | j |g S r&   )r   r   r  r   r   r   get_additional_models_with_key  r   z+ModelPatcher.get_additional_models_with_keyc                 C  s"   g }| j  D ]}|| q|S r&   )r   r  r  )rH   
all_modelsrX  r   r   r   get_additional_models  s   z"ModelPatcher.get_additional_modelsc                   s.   d fdd |   }t|} ||d}|S )	Nprev_modelslist[ModelPatcher]	cache_setset[ModelPatcher]c                   sZ   g }| D ]}|  }|D ]}||vr|| || qqt|dkr&| S |  || S )z>Make sure circular references do not cause infinite recursion.r   )r  re  rd  re   )r  r!  next_modelsr_   
candidatesr   _evaluate_sub_additional_modelsr   r   r&    s   

zRModelPatcher.get_nested_additional_models.<locals>._evaluate_sub_additional_models)r  r!  )r  r   r!  r"  )r  r   )rH   r  
models_setreal_all_modelsr   r%  r   get_nested_additional_models  s
   z)ModelPatcher.get_nested_additional_modelsc                 C  s   t | |dS )Nr  )rm   )rH   rr   r   r   r   ra    r+   zModelPatcher.use_ejectedc                 C  sb   | j s| jrd S | j D ]}|D ]
}||  d| _ qq| j r-| tjD ]}||  q&d S d S NT)rt   rs   r   r  injectr   r   ON_INJECT_MODELrH   r   injr   r   r   r   rx     s   

zModelPatcher.inject_modelc                 C  sR   | j sd S | j D ]}|D ]}||  qq
d| _ | tjD ]}||  q d S ro   )rt   r   r  ejectr   r   ON_EJECT_MODELr-  r   r   r   ru     s   
zModelPatcher.eject_modelc                 C  s2   t | jdr
| | j_| tjD ]}||  qd S )Nr  )r4   r_   r  r   r   
ON_PRE_RUNr  r   r   r   pre_run  s
   
zModelPatcher.pre_runc                 C  s    |  tjD ]}|| | qd S r&   )r   r   ON_PREPARE_STATE)rH   timestepr   r   r   r   prepare_state  s   zModelPatcher.prepare_statec                 C  s    | j d ur| j | _d | _ d S d S r&   )r   r   rv   r   r   r   restore_hook_patches  s   

z!ModelPatcher.restore_hook_patchesr   comfy.hooks.EnumHookModec                 C  s
   || _ d S r&   )r   )rH   r   r   r   r   set_hook_mode  s   
zModelPatcher.set_hook_modetr   
hook_groupcomfy.hooks.HookGroupr   	dict[str]c                 C  s   |d }d}| di }|jD ]5}|jj||d}|rD| jd ur/| jjD ]
}	|	|kr.d} nq$t| j D ]}
|
|rC| j	|
 q6q|rN| 
d  d S d S )Nr   Fr
   )curr_tr
   T)r   r   hook_keyframeprepare_current_keyframer   rf  r   r   containsru  patch_hooks)rH   r9  r:  r   r=  reset_current_hooksr
   hookchangedcurrent_hookcached_groupr   r   r   %prepare_hook_patches_current_keyframe  s&   


z2ModelPatcher.prepare_hook_patches_current_keyframer   target_dictr%   
registeredc                 C  s   |    |d u rtj }g }|tjjjD ]}|j| jvr%|	| q|
| qt|dkrDt| j| _|D ]
}|| ||| q9| tjD ]
}|| |||| qJ|S r   )r6  r'   r   	HookGroupget_typeEnumHookTypeWeightr.   r   re  rd  re   r0   r   add_hook_patchesr   r   ON_REGISTER_ALL_HOOK_PATCHES)rH   r   rH  r   rI  weight_hooks_to_registerrC  r   r   r   r   register_all_hook_patches  s   
z&ModelPatcher.register_all_hook_patchesrC  comfy.hooks.WeightHookc              	   C  s   |   i | j|ji }t }| j }|D ]?}d }	d }
t|tr%|}n|d }	|d }t	|dkr7|d }
||v rV|
| ||g }|||| ||	|
f |||< q|| j|j< t | _t|W  d    S 1 spw   Y  d S r`  )ra  r   r   r.   r   r_   rb  rc  rP  re   rd  re  r   r   r   rf  )rH   rC  rE   rg  rh  current_hook_patchesri  rj  r/   rk  rN  rD   rl  r   r   r   rN    s.   




$zModelPatcher.add_hook_patchesc           	      C  s   i }|d urO|j D ]E}| j|ji }| D ]6}||g }t|jdr.|||  n|| D ]}t	|}|d  |j9  < |
t| q2|||< qq	|S )Nr_  r   )r   r   r   r.   r   mathisclosestrengthr  rf  re  tuple)	rH   r   combined_patchesrC  r   rD   rl  r   	new_patchr   r   r   get_combined_hook_patches  s   

z&ModelPatcher.get_combined_hook_patchesr
   c                 C  sd   | j |kr|r| js|d u rtj| ||S | j|d | tjD ]}|| | q"tj| ||S )Nr   )	r   r   r'   r   %create_transformer_options_from_hooksrA  r   r   ON_APPLY_HOOKS)rH   r   r
   r  r   r   r   r   r  ,  s   zModelPatcher.apply_hooksc           	   	   C  sV  |    |d urt|   }d }| jtjjjkr+t	tj
| jtj
 d d}| j|d }|d ur_t|}|D ]}||vrKtd|  q<| j|||d || q<| | n7|   | j|d}d }t|dkru|  }|D ]}||vrtd|  qw| j|||||d qwn|   || _W d    d S 1 sw   Y  d S )	NrV   )r}   r   z:Cached hook could not patch. Key does not exist in model: )cached_weightsrD   memory_counterr[  r   z:Cached hook would not patch. Key does not exist in model: )r   rX  rD   original_weightsr_  )ra  rf  ro  r   r   r'   r   r   r   r|   r   r   r   minimum_inference_memoryr   r   r   r>   r?   patch_cached_hook_weightsr  r  rZ  re   rt  patch_hook_weight_to_devicer   )	rH   r   model_sd_keysr_  r^  model_sd_keys_setrD   relevant_patchesr`  r   r   r   rA  5  sD   
"zModelPatcher.patch_hooksr^  r_  r|   c                 C  s   || j vr/tj| j|}| j}| jtjjj	kr"|
|}|r"|j}|j|dd|jf| j |< tj| j||| d j|| d d d S )NTry  r   rc   r9   )r   r'   r@   rf   r_   r   r   r   r   r   r   r:   r   r  )rH   r^  rD   r_  rP   target_devicer   r   r   r   rb  Y  s   

.z&ModelPatcher.patch_cached_hook_weightsc                 C  s   | j   | d  d S r&   )r   r  rA  rv   r   r   r   clear_cached_hook_weightsd  s   
z&ModelPatcher.clear_cached_hook_weightsrX  r`  c                 C  sd  ||vrd S t | j|\}}}|| jvr6| j}	| jtjjjkr)|	|}
|
r)|j
}	|j|	dd|j
f| j|< tjj||j
tjdd}|d urL||dd}tjj|| |||d}||= |d u rwtjj||jtj|d}tj| j|| n||dtj|d | jtjjjkr| j}	|	|}
|
r|j
}	| j|i  |j|	dd|j
f| j| |< ~~~d S )	NTry  r   rz  )r`  r|  )rx  r}  F)rX   r_   r   r   r   r'   r   r   r   r   r:   r   r   r  rZ   r[   rM   rN   r  r  rO   r@   rA   r  r   r  )rH   r   rX  rD   r`  r_  rP   rG   rF   rg  r   r  r  r   r   r   rc  h  s@   


z(ModelPatcher.patch_hook_weight_to_devicewhitelist_keys_setset[str]Nonec              	   C  s  |   x t| jdkrd | _	 W d    d S t| j }|rH|D ]#}||v rFtj| j	|| j| d j
| j| d d | j| q#n,|D ]}tj| j	|| j| d j
| j| d d qJ| j  d | _W d    d S W d    d S 1 sw   Y  d S )Nr   rc   r9   )ra  re   r   r   rf  r   r'   r@   r  r_   r   ru  r  )rH   ri  r   r/   r   r   r   r    s(   
.0
"zModelPatcher.unpatch_hooksc                 C  s   |    |   d S r&   )r  rh  rv   r   r   r   r    s   zModelPatcher.clean_hooksc           
      C  s   | j j }| D ]N\}}|dd}t|dk s |d dvr!q
ztj| j j|d }W n   Y q
|rEt	|drEt	|drF|j
dkrFq
d	| }	t| |	tj| j |	||< q
| j j||||d
S )Nrb   rc   rV   )rP   biasr   r5   r  Tzdiffusion_model.)clip_state_dictvae_state_dictclip_vision_state_dict)r_   diffusion_modelrb  r   rd   re   r'   r@   rf   r4   r  r   state_dict_for_saving)
rH   rm  rn  ro  unet_state_dictr/   vri   rj   rD   r   r   r   rq    s"   
z"ModelPatcher.state_dict_for_savingc                 C  s   |    | jdd d S )NF)r  )r  r  rv   r   r   r   __del__  s   zModelPatcher.__del__r   Fr{   )FN)r   rn   )r  r   r&   )r   rP  rQ  rR  )r_  r_  )NFF)Nr   FFNr   TFr*  )T)r  rP  r   r   )r  rP  rD   rP  r   r   )r  rP  rD   rP  )r  rP  )r  rP  r  r   )r  rP  rD   rP  r  r   )r  rP  rD   rP  )r  rP  )rD   rP  )rD   rP  r   r  )rD   rP  rX  r  )r   r7  )r9  r   r:  r;  r   r<  rR   )r   r;  rH  r<  r   r%   rI  r;  )rC  rR  )r   r;  ro   )r   r;  r
   r%   r^  r%   rD   rP  r_  r|   
r   r;  rX  r%   rD   rP  r`  r%   r_  r|   ri  rj  rQ  rk  )NNN)mrS   rT   rU   rI   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r  r  r#  r%  r*  r-  r/  r1  r3  r5  r7  r9  r;  r=  r?  rA  rI  rL  rM  rO  rS  rW  rY  r]  r`   rm  rt  ro  r   r  r  r  r  r  r  r  r  r  r  r  r  r  rZ   r[   rN   rZ  r  r  r  r  r   r	  r  r
  r  r  r  r  r  r  r  r  r  r  r  r  r)  ra  rx   ru   r2  r5  r6  r8  rG  rQ  rN  rZ  r  rA  rb  rh  rc  r  r  rq  rt  r   r   r   r   r      s    :	G 
% )U	
	$'r   c                      s   e Zd Zd; fdd	Zd< fdd	Zdd	 Zd=d
dZdd Zdd Zdd Z	dd Z
 fddZd>ddZd<ddZdd Zdd Zd? fdd 	Zd@ fd!d"	Zd<d#d$ZdAd+d,ZdBd1d2ZdCdDd7d8Zd9d: Z  ZS )EModelPatcherDynamicNr   Fc                   s0   |d urt j|rt|||||S t | S r&   )r'   r   is_device_cpur   r   r   )r   r_   r   r   r   r   r   r   r   r     s   zModelPatcherDynamic.__new__c                   s>   t  ||||| t| jdsi | j_d | _|d usJ d S )Ndynamic_vbars)r   rI   r4   r_   r|  non_dynamic_delegate_modelr   r   r   r   rI     s
   zModelPatcherDynamic.__init__c                 C  r   r*  r   rv   r   r   r   r     r   zModelPatcherDynamic.is_dynamicc                 C  s^   | j tdkr
d S | jj| j d }|r-|d u r-tj| 	 d | j j
}|| jj| j < |S )Nr   
   )r   rZ   r:   r_   r|  r   r   r   	ModelVBARr   r   )rH   createvbarr   r   r   	_vbar_get  s   zModelPatcherDynamic._vbar_getc                 C  s$   |   }|d ur| nd| jj S r   )r  r   r_   r   )rH   r  r   r   r   r     s   zModelPatcherDynamic.loaded_sizec                 C     t d)Nz7pin_weight_to_device invalid for dymamic weight loadingr   r  r   r   r   r    r   z(ModelPatcherDynamic.pin_weight_to_devicec                 C  r  )Nz/unpin_weight invalid for dymamic weight loadingr  r  r   r   r   r    r   z ModelPatcherDynamic.unpin_weightc                 C  s   |  d d S )Nr  )r  rv   r   r   r   r    r   z%ModelPatcherDynamic.unpin_all_weightsc                   s   t  j|dd d S )Nr   g?i   @)r   r  r  r   r   r   r    s   z#ModelPatcherDynamic.memory_requiredc                    s^  |rJ |rJ || j ksJ dd}d| j_|   |   | jdd}|d ur/|  | jd|d}|  |D ]}	|	^ }
} }}dd }fdd} fd	d
}t	|drd|_
d|_ |_||| || | d\}}|| | d\}}|p~|}||7 }|rtd  d || d| || d| n`|d urt	|ds|||_||7 }nL|D ]I}t |}t| j|\}}
}
|| jvrtdddg|d| j|< t||d d }|j||d}tj| j|| | j j| |  7  _qt|| q<| jjddD ]@\}}|| jvr|| j|< tj | j|\}}t||d d }|j||d}tj!| j|| | j j| |  7  _qt"| jdkradt"| j d| jjd  dnd}td| jj#j$ d|d  d d |  || j_%| j&| j_'| (t)j*D ]}|| |||| q| j+| j,dd! W d    d S 1 sw   Y  d S )"Nr   T)r  r  r  c                 S  s   |st | dsd | _d S d S )N_v_signature)r4   r  )itemdirtyr   r   r   	set_dirty  s   
z+ModelPatcherDynamic.load.<locals>.set_dirtyc           
        s   t ||}g }t| j|\}}}|d u rdS || jv r<tj| j| |||jkr+dS t||d t	|| j  d7  nt||d d  || j
v rQ|| j
|  t||d | |}t|tswt||d d pj|j}	|	|_tjj|j|	d}dtj|fS )	N)Fr   )Tr   _lowvram_functionrc   	_functionr  )shaperO   F)rl   rX   r_   rE   r'   rM   calculate_shaper  setattrrC   r   r  rc  r   rY   rO   _model_dtyper   TensorGeometryvram_aligned_size)
rH   r6   r   	param_keyrD   r2   rP   r  geometryr`   )num_patchesr   r   setup_param  s(   




z-ModelPatcherDynamic.load.<locals>.setup_paramc                   sz   t  |}|| jv rtj| j|| j| j | j||d t| j|\}}}|d ur;| j j	|
 |  7  _	d S d S )Nr  )rl   r   r'   r@   r  r_   rP   r   rX   r   r\   r   )rH   r  r   rD   rP   r  )r   r   r   force_load_param+  s   

 z2ModelPatcherDynamic.load.<locals>.force_load_paramr5   FrP   rl  zModule z" has resizing Lora - force loading_vrw  rx  r  )rO   r:   r  z Force pre-loaded z
 weights: i   z KB.r  zModel z$ prepared for dynamic VRAM loading. r  zMB Staged. z patches attached.r  )-r   r_   r   ra  r  r  
prioritizer  r  r4   r5   
pin_failedseed_keyr>   r  allocr  rl   rX   r   r~  r  rY   r   r'   r@   r  r\   r   r=   named_buffersr   resolve_attrset_attr_bufferre   r   rS   r:   r   r   r   r   r  r  r   ) rH   r   r  r  r  r  allocated_sizer  r  r   r  r  r6   r  r  r  r  
force_loadv_weight_sizeforce_load_biasv_weight_biasrk   rD   rP   r`   casted_weightbufmodulebuf_name
casted_bufforce_load_statr   r   )r   r  r   r    sx   
	




 4,
$zModelPatcherDynamic.loadc                 C  s   |rJ | j tdksJ |  }|d u rdn||}||k r\t| j D ]}| j|}t	j
| j||j q(t| j D ]}t	j
| j|| j| qB|| jj7 }d| j_|S )Nr   r   )r   rZ   r:   r  free_memoryrf  r   r   ru  r'   r@   r  r_   rP   r   r  r   )rH   r   r  r  r  freedrD   rr  r   r   r   r  j  s   z$ModelPatcherDynamic.partially_unloadc                 C  sV   d}| j dd}|D ]}|\}}}}}}tj|}|d ur(|| |  7 }q
|S )Nr   T)r  )r  r'   pinned_memoryget_pinr\   r   )rH   totalr  r   r  r6   pinr   r   r   r  |  s   z&ModelPatcherDynamic.pinned_memory_sizec                 C  sH   | j d| jd}|D ]}|^ }}}|tj|8 }|dkr! d S q
d S )NTr  r   )r  r   r'   r  r  )rH   r  r  r   r  r6   r   r   r   r    s   z(ModelPatcherDynamic.partially_unload_ramTc                   s   |rJ t  j||dS )N)r  r  )r   r  )rH   r   r  r  r  r   r   r   r    s   zModelPatcherDynamic.patch_modelc                   sL   t  jd dd |r"| d | d d | j D ]	}t|| qd S d S )NF)r   r  r  )r   r  r  r  r_   r  r=   )rH   r   r  r6   r   r   r   r    s   
z!ModelPatcherDynamic.unpatch_modelc                 C  s   |rJ | j ddA | jjd uo| jj| jk}| j| jdd | jdd z	| j||d W n tyA } z| 	  |d }~ww 	 W d    d S 1 sNw   Y  d S )NTr  Fr  r  )r  )
ra  r_   r   r   r  r   r  r  r  r  )rH   r   r  r  r  r  r   r   r   r    s   $z"ModelPatcherDynamic.partially_loadr^  r%   rD   rP  r_  r|   c                 C  s   J r&   r   )rH   r^  rD   r_  r   r   r   rb    r   z-ModelPatcherDynamic.patch_cached_hook_weightsr   r;  rX  r`  c                 C  s   ||vrd S t d)NzaHooks not implemented in ModelPatcherDynamic. Please remove --fast arguments form ComfyUI startupr  )rH   r   rX  rD   r`  r_  r   r   r   rc    s   z/ModelPatcherDynamic.patch_hook_weight_to_deviceri  rj  rQ  rk  c                 C  r  r&   r   )rH   ri  r   r   r   r    r   z!ModelPatcherDynamic.unpatch_hooksc                 C  s   | j d| jd}| | _|S )NT)r   r   )r   r}  r   )rH   model_patcherr   r   r   get_non_dynamic_delegate  s   
z,ModelPatcherDynamic.get_non_dynamic_delegate)NNNr   Fru  r{   )Nr   FFFrv  r*  rw  rx  r&   ry  )rS   rT   rU   r   rI   r   r  r   r  r  r  r  r  r  r  r  r  r  r  rb  rc  r  r  r   r   r   r   r   rz    s*    


|

	

rz  r&   r{   )r$   r%   )3__doc__
__future__r   r~  r  r>   rT  r   typingr   r   rZ   comfy.floatr'   comfy.hooks
comfy.loracomfy.model_managementcomfy.patcher_extensioncomfy.utilscomfy.comfy_typesr   comfy.quant_opsr   r   r   r	   comfy_aimdo.model_vbarr   r   r   r#   r*   r0   r7   r=   rA   rC   r^   ra   rX   rl   rm   r|   r  r   nn	Parameterr   r   rz  CoreModelPatcherr   r   r   r   <module>   sd    





         [  