4242
4343import comfy_aimdo .model_vbar
4444
45+ def is_model_patcher_output (output ):
46+ return isinstance (output , ModelPatcher ) or isinstance (getattr (output , "patcher" , None ), ModelPatcher )
47+
48+ class PromptModelTracker :
49+ def __init__ (self ):
50+ self .models = {}
51+
52+ def start (self ):
53+ self .end ()
54+
55+ def add (self , outputs ):
56+ if isinstance (outputs , collections .abc .Mapping ):
57+ outputs = outputs .values ()
58+ elif not isinstance (outputs , (list , tuple )):
59+ outputs = (outputs ,)
60+
61+ for output in outputs :
62+ if isinstance (output , (collections .abc .Mapping , list , tuple )):
63+ self .add (output )
64+ continue
65+
66+ models = []
67+ if isinstance (output , ModelPatcher ):
68+ models .append (output )
69+ models .extend (output .model_patches_models ())
70+ models .extend (output .get_nested_additional_models ())
71+ else :
72+ patcher = getattr (output , "patcher" , None )
73+ if isinstance (patcher , ModelPatcher ):
74+ models .append (patcher )
75+ get_models = getattr (output , "get_models" , None )
76+ if callable (get_models ):
77+ models .extend (get_models ())
78+
79+ for model in models :
80+ if not isinstance (model , ModelPatcher ) or not model .is_dynamic ():
81+ continue
82+ key = (id (model .model ), model .load_device )
83+ self .models [key ] = model
84+ model .set_in_use_by_current_prompt (True )
85+
86+ def end (self ):
87+ for model in self .models .values ():
88+ model .set_in_use_by_current_prompt (False )
89+ self .models .clear ()
90+
4591def set_model_options_patch_replace (model_options , patch , name , block_name , number , transformer_index = None ):
4692 to = model_options ["transformer_options" ].copy ()
4793
@@ -1724,14 +1770,20 @@ def register_load_device(self, device):
17241770 self .model .dynamic_pins [device ] = {
17251771 "weights" : (comfy_aimdo .host_buffer .HostBuffer (0 , 0 , 0 ), [], [- 1 ], [0 ], [0 ], {}),
17261772 "patches" : (comfy_aimdo .host_buffer .HostBuffer (0 , 0 , 0 ), [], [- 1 ], [0 ], [0 ], {}),
1773+ "weights-loaded" : (comfy_aimdo .host_buffer .HostBuffer (0 , 0 , 0 ), [], [- 1 ], [0 ], [0 ], {}),
1774+ "patches-loaded" : (comfy_aimdo .host_buffer .HostBuffer (0 , 0 , 0 ), [], [- 1 ], [0 ], [0 ], {}),
17271775 "hostbufs_initialized" : False ,
17281776 "failed" : False ,
17291777 "active" : False ,
1778+ "current_prompt" : False ,
17301779 }
17311780
17321781 def is_dynamic (self ):
17331782 return True
17341783
1784+ def set_in_use_by_current_prompt (self , in_use ):
1785+ self .model .dynamic_pins [self .load_device ]["current_prompt" ] = in_use
1786+
17351787 def _vbar_get (self , create = False ):
17361788 if self .load_device == torch .device ("cpu" ):
17371789 return None
@@ -1802,6 +1854,8 @@ def load(self, device_to=None, lowvram_model_memory=0, force_patch_weights=False
18021854 hostbuf_size = comfy .model_management .pinned_hostbuf_size (self .model_size ())
18031855 pin_state ["weights" ] = (comfy_aimdo .host_buffer .HostBuffer (0 , 64 * 1024 * 1024 , hostbuf_size ), [], [- 1 ], [0 ], [0 ], {})
18041856 pin_state ["patches" ] = (comfy_aimdo .host_buffer .HostBuffer (0 , 8 * 1024 * 1024 , hostbuf_size ), [], [- 1 ], [0 ], [0 ], {})
1857+ pin_state ["weights-loaded" ] = (comfy_aimdo .host_buffer .HostBuffer (0 , 64 * 1024 * 1024 , hostbuf_size ), [], [- 1 ], [0 ], [0 ], {})
1858+ pin_state ["patches-loaded" ] = (comfy_aimdo .host_buffer .HostBuffer (0 , 8 * 1024 * 1024 , hostbuf_size ), [], [- 1 ], [0 ], [0 ], {})
18051859 pin_state ["hostbufs_initialized" ] = True
18061860 pin_state ["failed" ] = False
18071861 pin_state ["active" ] = True
@@ -1943,28 +1997,32 @@ def partially_unload(self, device_to, memory_to_free=0, force_patch_weights=Fals
19431997 return freed
19441998
19451999 def loaded_ram_size (self ):
1946- return (self .model .dynamic_pins [self .load_device ]["weights" ][0 ].size )
2000+ pin_state = self .model .dynamic_pins [self .load_device ]
2001+ return pin_state ["weights" ][0 ].size + pin_state ["weights-loaded" ][0 ].size
19472002
19482003 def pinned_memory_size (self ):
1949- return (self .model .dynamic_pins [self .load_device ]["weights" ][3 ][0 ])
2004+ pin_state = self .model .dynamic_pins [self .load_device ]
2005+ return pin_state ["weights" ][3 ][0 ] + pin_state ["weights-loaded" ][3 ][0 ]
19502006
1951- def unregister_inactive_pins (self , ram_to_unload , subsets = [ "weights" , "patches" ]):
2007+ def unregister_inactive_pins (self , ram_to_unload , subsets = [ "weights-loaded" , "patches-loaded" , "weights " , "patches" ]):
19522008 freed = 0
19532009 pin_state = self .model .dynamic_pins [self .load_device ]
19542010 for subset in subsets :
19552011 hostbuf , stack , stack_split , pinned_size , * _ = pin_state [subset ]
19562012 split = stack_split [0 ]
19572013 while split >= 0 :
19582014 module , offset = stack [split ]
2015+ module_pin = module ._pins [subset ]
19592016 split -= 1
19602017 stack_split [0 ] = split
1961- if not module . _pin_registered :
2018+ if not module_pin [ "registered" ] :
19622019 continue
1963- size = module ._pin .numel () * module ._pin .element_size ()
1964- if torch .cuda .cudart ().cudaHostUnregister (module ._pin .data_ptr ()) != 0 :
2020+ pin = module_pin ["pin" ]
2021+ size = pin .numel () * pin .element_size ()
2022+ if torch .cuda .cudart ().cudaHostUnregister (pin .data_ptr ()) != 0 :
19652023 comfy .model_management .discard_cuda_async_error ()
19662024 continue
1967- module . _pin_registered = False
2025+ module_pin [ "registered" ] = False
19682026 comfy .model_management .TOTAL_PINNED_MEMORY = max (0 , comfy .model_management .TOTAL_PINNED_MEMORY - size )
19692027 pinned_size [0 ] = max (0 , pinned_size [0 ] - size )
19702028 freed += size
@@ -1973,20 +2031,23 @@ def unregister_inactive_pins(self, ram_to_unload, subsets=[ "weights", "patches"
19732031 return freed
19742032 return freed
19752033
1976- def partially_unload_ram (self , ram_to_unload , subsets = [ "weights" , "patches" ]):
2034+ def partially_unload_ram (self , ram_to_unload , subsets = [ "weights-loaded" , "patches-loaded" , "weights " , "patches" ]):
19772035 freed = 0
19782036 pin_state = self .model .dynamic_pins [self .load_device ]
19792037 for subset in subsets :
19802038 hostbuf , stack , stack_split , pinned_size , * _ = pin_state [subset ]
19812039 while len (stack ) > 0 :
19822040 module , offset = stack .pop ()
1983- size = module ._pin .numel () * module ._pin .element_size ()
1984- module ._pin_balancer_entry [- 1 ] = None
1985- del module ._pin_balancer_entry
1986- del module ._pin
1987- hostbuf .truncate (offset , do_unregister = module ._pin_registered )
2041+ module_pin = module ._pins [subset ]
2042+ pin = module_pin ["pin" ]
2043+ size = pin .numel () * pin .element_size ()
2044+ module_pin ["balancer_entry" ][- 1 ] = None
2045+ del module_pin ["balancer_entry" ]
2046+ del module_pin ["pin" ]
2047+ registered = module_pin ["registered" ]
2048+ hostbuf .truncate (offset , do_unregister = registered )
19882049 stack_split [0 ] = min (stack_split [0 ], len (stack ) - 1 )
1989- if module . _pin_registered :
2050+ if registered :
19902051 comfy .model_management .TOTAL_PINNED_MEMORY = max (0 , comfy .model_management .TOTAL_PINNED_MEMORY - size )
19912052 pinned_size [0 ] = max (0 , pinned_size [0 ] - size )
19922053 freed += size
0 commit comments