
    +h              
          S SK r S SKrS SKJr  S SKJr  S SKJrJrJ	r	J
r
Jr  S SKrSSKJr  SSKJrJr  \" 5       (       a   S SKJrJr  S S	KJr  S S
KJr  S SKJr  S SKJr  \R:                  " \5      r " S S\5      r  " S S5      r!  SS\"S\RF                  RH                  S\\"\%\RL                  4   S\
S   4S jjr' " S S5      r(S\\"\4   S\\"\4   4S jr) " S S5      r*g)    N)OrderedDict)combinations)AnyDictListOptionalUnion   )	ModelHook)is_accelerate_availablelogging)add_hook_to_moduleremove_hook_from_module)PartialState)send_to_device)clear_device_cache)convert_file_size_to_intc                       \ rS rSrSrSr   SS\\\\	\
R                  4      S\\S      S\S	   4S
 jjrSS jrSS jrS rS rSrg)CustomOffloadHook(   a  
A hook that offloads a model on the CPU until its forward pass is called. It ensures the model and its inputs are
on the given device. Optionally offloads other models to the CPU before the forward pass is called.

Args:
    execution_device(`str`, `int` or `torch.device`, *optional*):
        The device on which the model should be executed. Will default to the MPS device if it's available, then
        GPU 0 if there is a GPU, and finally to the CPU.
FNexecution_deviceother_hooksUserCustomOffloadHookoffload_strategyAutoOffloadStrategyc                 f    Ub  UO[        5       R                  U l        X l        X0l        S U l        g N)r   default_devicer   r   r   model_id)selfr   r   r   s       h/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/modular_pipelines/components_manager.py__init__CustomOffloadHook.__init__5   s2     5E4P 0VbVdVsVs& 0    c                     Xl         g r   r   )r    r   s     r!   set_strategyCustomOffloadHook.set_strategy@   s     0r$   c                 b    U R                   c  / U l         U R                   R                  U5        g)z=
Add a hook to the list of hooks to consider for offloading.
N)r   appendr    hooks     r!   add_other_hook CustomOffloadHook.add_other_hookC   s,     #!D%r$   c                 $    UR                  S5      $ )Ncpu)to)r    modules     r!   	init_hookCustomOffloadHook.init_hookK   s    yyr$   c           
      D   UR                   U R                  :w  GaW  U R                  Gb.  U R                   Vs/ s H*  oDR                  R                   U R                  :X  d  M(  UPM,     nn[        R
                  " 5       nU R                  b&  U R                  UU R                  UU R                  S9n[        R
                  " 5       n[        R                  SU R                   SXv-
  S S35        U HP  n[        R                  SU R                   SU R                   SUR                   S	35        UR                  5         MR     U(       a
  [        5         UR                  U R                  5        [        X R                  5      [        X0R                  5      4$ s  snf )
N)hooksr   modelr   z* time taken to apply offload strategy for : .2fz secondszmoving z to z, offloading z to cpu)devicer   r   r7   timeperf_counterr   r   loggerinfooffloadr   r1   r   )r    r2   argskwargsr,   hooks_to_offload
start_timeend_times           r!   pre_forwardCustomOffloadHook.pre_forwardN   sg   ==D111+595E5E#t5ETIZIZ^b^s^sIsD5E #t!..0
((4'+'<'<.!%$)-)>)>	 (= ($  ,,.@rS[ShjmQnnvw -DKK!$--T5J5J4K=Y]YfYfXggno LLN	 - $&(IId++,d$9$9:N6ShSh<iii1 $us   'F#F)r   r   r   r   )NNN)r   r   r,   r   )__name__
__module____qualname____firstlineno____doc__no_gradr   r	   strinttorchr:   r   r"   r'   r-   r3   rE   __static_attributes__ r$   r!   r   r   (   sw     G EI?C<@		"5c5<<)?#@A	 d#:;<	 ##89		1& jr$   r   c                   :    \ rS rSrSrS rS rS rS rS
S jr	Sr
g	)r   l   z
A simple hook grouping a model and a `CustomOffloadHook`, which provides easy APIs for to call the init method of
the hook or remove it entirely.
c                 (    Xl         X l        X0l        g r   r   r7   r,   )r    r   r7   r,   s       r!   r"   UserCustomOffloadHook.__init__r   s     
	r$   c                 N    U R                   R                  U R                  5        g r   )r,   r3   r7   r    s    r!   r?   UserCustomOffloadHook.offloadw   s    		DJJ'r$   c                 z    [        U R                  U R                  5        U R                  U R                  l        g r   )r   r7   r,   r   rY   s    r!   attachUserCustomOffloadHook.attachz   s$    4::tyy1!]]		r$   c                 P    [        U R                  5        S U R                  l        g r   )r   r7   r,   r   rY   s    r!   removeUserCustomOffloadHook.remove~   s    

+!		r$   c                 :    U R                   R                  U5        g r   )r,   r-   r+   s     r!   r-   $UserCustomOffloadHook.add_other_hook   s    		  &r$   )r,   r7   r   NrG   )rH   rI   rJ   rK   rL   r"   r?   r\   r_   r-   rQ   rR   r$   r!   r   r   l   s     

(+"'r$   r   r   r7   r   r   r   c                 L    [        X#S9n[        XUS9nUR                  5         U$ )N)r   r   rV   )r   r   r\   )r   r7   r   r   r,   	user_hooks         r!   custom_offload_with_hookre      s-     .>bD%x4PIr$   c                   (    \ rS rSrSrSS jrS rSrg)r      z
Offload strategy that should be used with `CustomOffloadHook` to automatically offload models to the CPU based on
the available memory on the device.
c                 $    [        U5      U l        g r   )r   memory_reserve_margin)r    ri   s     r!   r"   AutoOffloadStrategy.__init__   s    %=>S%T"r$   c           
      `   [        U5      S:X  a  / $ UR                  5       n[        R                  R	                  UR
                  5      S   nX`R                  -
  nXV:  a  / $ XV-
  n[        R                  SUS-  S S35        [        [        U Vs0 s H'  oR                  UR                  R                  5       _M)     snR                  5       S SS95      n	S	 n
U
" X5      nUc  [        R                  S
5        UnU$ U Vs/ s H  oR                  U;   d  M  UPM     nnU$ s  snf s  snf )Nr   z2 search for models to offload in order to free up    @r9   z
 GB memoryc                     U S   $ )N   rR   )xs    r!   <lambda>.AutoOffloadStrategy.__call__.<locals>.<lambda>   s    adr$   T)keyreversec                 
  ^  [        T R                  5       5      nSn[        S5      n[        S[	        U5      S-   5       H?  n[        X%5       H-  n[        U 4S jU 5       5      nXq:  a  M  Ub  Xt:  d  M)  UnUnM/     MA     U$ )z
search the optimal combination of models to offload to cpu, given a dictionary of module sizes and a
minimum memory offload size. the combination of models should add up to the smallest modulesize that is
larger than `min_memory_offload`
Ninfrn   c              3   .   >#    U  H
  nTU   v   M     g 7fr   rR   ).0candidate_model_idmodule_sizess     r!   	<genexpr>NAutoOffloadStrategy.__call__.<locals>.search_best_candidate.<locals>.<genexpr>   s      )Sf=O%78Sf   )listkeysfloatrangelenr   sum)ry   min_memory_offload	model_idsbest_candidate	best_sizercandidate_model_idscandidate_sizes   `       r!   search_best_candidate;AutoOffloadStrategy.__call__.<locals>.search_best_candidate   s     \..01I!NeI1c)nq01+7	+E'%( )Sf) &N &: )1^5O-@N(6I ,F 2 "!r$   zJno combination of models to offload to cpu is found, offloading all models)r   get_memory_footprintrP   cudamem_get_infoindexri   r=   r>   dictsortedr   r7   itemswarning)r    r6   r   r7   r   current_module_sizemem_on_devicer   r,   ry   r   best_offload_model_idsrB   s                r!   __call__AutoOffloadStrategy.__call__   s6   u:?I#88:

//0@0F0FGJ%(B(BB.I0@HI[^eIefiHjjtuv NSTed

 ? ? AAeTZZ\"
	". "7|!X!)NNgh$   27b--Ka:abO UJ  cs   .D&D+D+ri   N)3GB)rH   rI   rJ   rK   rL   r"   r   rQ   rR   r$   r!   r   r      s    U8 r$   dreturnc                    0 nU R                  5        HC  u  p#[        U[        5      (       a  [        U5      OUnXA;  a  / X'   X   R	                  U5        ME     S[
        [           S[        4S jn0 nUR                  5        HF  u  pGU" U5      nU(       a-  [        XS      [        5      (       a  [        U5      OUnX6U'   MA  WUS'   MH     U$ )a  Summarizes a dictionary by finding common prefixes that share the same value.

For a dictionary with dot-separated keys like: {
    'down_blocks.1.attentions.1.transformer_blocks.0.attn2.processor': [0.6],
    'down_blocks.1.attentions.1.transformer_blocks.1.attn2.processor': [0.6],
    'up_blocks.1.attentions.0.transformer_blocks.0.attn2.processor': [0.3],
}

Returns a dictionary where keys are the shortest common prefixes and values are their shared values: {
    'down_blocks': [0.6], 'up_blocks': [0.3]
}
r~   r   c                     U (       d  g[        U 5      S:X  a  U S   $ U  Vs/ s H  oR                  S5      PM     nnSn[        U6  H"  n[        [        U5      5      S:X  a  US-  nM"    O   US:X  a  gSR	                  US   SU 5      $ s  snf )zCFind the shortest common prefix among a list of dot-separated keys. rn   r   .N)r   splitzipsetjoin)r~   k	key_partscommon_lengthpartss        r!   find_common_prefix=summarize_dict_by_value_and_parts.<locals>.find_common_prefix   s    t9>7N ,004aWWS\4	0 )_E3u:!#"	 % A xx	!^m455 1s   Br   r   )r   
isinstancer}   tupler*   r   rN   )	r   value_to_keysrr   valuevalue_tupler   summaryr~   prefixs	            r!   !summarize_dict_by_value_and_partsr      s     Mggi
&0&=&=eEl5+)+M&"))#.	  6c 6s 62 G*002#D))3A1gJ)E)ED%;E#FOGBK 3 Nr$   c                   *   \ rS rSrSr/ SQrS r    S!S\\   S\\   S\\   S	\\	   4S
 jjr
\S\4S j5       rS"S\S\S\\   4S jjrS\S\4S jrS"S\4S jjr    S#S\\   S\\   S\\   S\4S jjrS$S\\\\R,                  4   4S jjrS r S"S\S\\\\\   4      S\\\\4      4S jjrS r    S!S\\   S\\   S\\   S\\   S\4
S jjrS%S\\\\   4   S\\   4S jjrS&S\\   S\\   4S jjrS"S\\   S\\   4S jjr S r!g)'ComponentsManageri  ai  
A central registry and management system for model components across multiple pipelines.

[`ComponentsManager`] provides a unified way to register, track, and reuse model components (like UNet, VAE, text
encoders, etc.) across different modular pipelines. It includes features for duplicate detection, memory
management, and component organization.

<Tip warning={true}>

    This is an experimental feature and is likely to change in the future.

</Tip>

Example:
    ```python
    from diffusers import ComponentsManager

    # Create a components manager
    cm = ComponentsManager()

    # Add components
    cm.add("unet", unet_model, collection="sdxl")
    cm.add("vae", vae_model, collection="sdxl")

    # Enable auto offloading
    cm.enable_auto_cpu_offload(device="cuda")

    # Retrieve components
    unet = cm.get_one(name="unet", collection="sdxl")
    ```
)	r   
added_time
collection
class_namesize_gbadaptershas_hookr   
ip_adapterc                 z    [        5       U l        [        5       U l        [        5       U l        S U l        SU l        g )NF)r   
componentsr   collectionsmodel_hooks_auto_offload_enabledrY   s    r!   r"   ComponentsManager.__init__C  s.    %-%-&=%*"r$   Nnamer   load_idr   c                    Uc  U R                   nU(       aM  [        5       nUR                  5        H.  u  pgU R                  U5      nX:X  d  M  UR	                  U5        M0     O[        UR                  5       5      nU(       aI  [        5       n	UR                  5        H*  u  pgX`R                  U   ;   d  M  U	R	                  U5        M,     O[        UR                  5       5      n	U(       aZ  [        5       n
UR                  5        H;  u  p[        US5      (       d  M  UR                  U:X  d  M*  U
R	                  U5        M=     O[        UR                  5       5      n
UR                  U	5      R                  U
5      nU$ )zy
Lookup component_ids by name, collection, or load_id. Does not support pattern matching. Returns a set of
component_ids
_diffusers_load_id)
r   r   r   _id_to_nameaddr~   r   hasattrr   intersection)r    r   r   r   r   ids_by_namecomponent_id	component	comp_nameids_by_collectionids_by_load_ididss               r!   _lookup_idsComponentsManager._lookup_idsK  s9    J%K+5+;+;+=' ,,\:	$OOL1 ,>
 joo/0K #+5+;+;+='#3#3J#??%)),7 ,> !$JOO$5 6 UN#-#3#3#59&:;;	@\@\`g@g"&&t, $6 !!23N&&'89FF~V
r$   r   c                 H    SR                  U R                  S5      S S 5      $ )N_)r   r   )r   s    r!   r   ComponentsManager._id_to_names  s#    xx**3/455r$   r   c           
         U S[        U5       3nSnU R                  R                  5        Hc  u  pgXr:X  d  M  U R                  U5      nX:X  a"  [        R                  SU SU S35        UnSn  O#[        R                  SU SU S	U S
35        Me     [        US5      (       a  UR                  S:w  as  U R                  UR                  S9n	U	 V
s/ s H  oU:w  d  M
  U
PM     n	n
U	(       a:  SR                  U	5      n[        R                  SU SUR                   SU S35        X R                  U'   [        R                  " 5       U R                  U'   U(       a  X0R                  ;  a  [        5       U R                  U'   X@R                  U   ;  a  U R                  XS9nU H2  n[        R                  SU SU SU 35        U R                  Xc5        M4     U R                  U   R                  U5        [        R!                  SU SU SU 35        O[        R!                  SU SU S35        U R"                  (       a"  U(       a  U R%                  U R&                  5        U$ s  sn
f )a{  
Add a component to the ComponentsManager.

Args:
    name (str): The name of the component
    component (Any): The component to add
    collection (Optional[str]): The collection to add the component to

Returns:
    str: The unique component ID, which is generated as "{name}_{id(component)}" where
         id(component) is Python's built-in unique identifier for the object
r   TzComponentsManager: component 'z' already exists as ''Fz%ComponentsManager: adding component 'z' as 'z', but it is duplicate of 'zK'To remove a duplicate, call `components_manager.remove('<component_id>')`.r   null)r   , z!', but it has duplicate load_id 'z' with existing components: zL. To remove a duplicate, call `components_manager.remove('<component_id>')`.r   r   z%ComponentsManager: removing existing z from collection '': z$ComponentsManager: added component 'z' in collection ')idr   r   r   r=   r   r   r   r   r   r;   r   r   r   remove_from_collectionr   r>   r   enable_auto_cpu_offload_auto_offload_device)r    r   r   r   r   is_new_componentcomp_idcompr   components_with_same_load_idr   existingcomp_ids_in_collections                r!   r   ComponentsManager.addw  s    qI0 "__224MG  ,,W5	$NN%CD6I^_f^ggh#ij#*L',$NN?vVL>Ytu|t} ~e f 5 9233	8T8TX^8^+/+;+;ID`D`+;+a(9U+l9U2_kYkB9U(+l+99%AB;L>Ijkt  lH  lH  kI  Ie  fn  eo oa b )2%(,		%!1!11/2u  ,#3#3J#??)-)9)9t)9)[&5GNN?vEWXbWccfgnfop //D  6   ,00>:4&@QR\Q]]`am`no KK>tfF<.XYZ[%%*:(()B)BCG ,ms   	I,I,c                    X R                   ;  a  [        R                  SU S35        gXR                   U   ;  a  [        R                  SU SU S35        gU R                   U   R                  U5        U R                   R	                  5        VVs/ s H  u  p4X;   d  M  UPM     nnnU(       d+  [        R                  SU S35        U R                  U5        ggs  snnf )	z'
Remove a component from a collection.
zCollection ' ' not found in ComponentsManagerNComponent 'z' not found in collection 'r   z'ComponentsManager: removing component 'z' from ComponentsManager)r   r=   r   r_   r   )r    r   r   collcomps
comp_collss         r!   r   (ComponentsManager.remove_from_collection  s     ---NN\*5UVW//
;;NN[6QR\Q]]^_`$++L9.2.>.>.D.D.F`.F{t,J_d.F
`NND\NRjklKK%  as   C#Cc                    XR                   ;  a  [        R                  SU S35        gU R                   R                  U5      nU R                  R                  U5        U R
                   H5  nXR
                  U   ;   d  M  U R
                  U   R                  U5        M7     U R                  (       a  U R                  U R                  5        g[        U[        R                  R                  5      (       a  UR                  S5        ASSKnUR!                  5         [        R"                  R%                  5       (       a  [        R"                  R'                  5         gg)zq
Remove a component from the ComponentsManager.

Args:
    component_id (str): The ID of the component to remove
r   r   Nr0   r   )r   r=   r   popr   r   r_   r   r   r   r   rP   nnModuler1   gccollectr   is_availableempty_cache)r    r   r   r   r   s        r!   r_   ComponentsManager.remove  s     .NN[6VWXOO''5	L)**J//
;;  ,33LA + %%(()B)BC)UXX__55U#JJLzz&&((

&&( )r$   namesreturn_dict_with_namesc                 
  ^ ^^	^^^ T R                  X#S9nU Vs0 s H  ofT R                  U   _M     nnU 4S jnTc  U" Xt5      $ [        T[        5      (       d  [	        S[        T5       S35      eUR                  5        V	s0 s H  oT R                  U	5      _M     sn	mS"U4S jjmTR                  S5      n
U
(       a  TSS mS	T;   a  TR                  S	5      n0 nUR                  5        HJ  u  m	n[        S
 U 5       5      m[        U	UU4S jU 5       5      nU
(       a  U(       + nU(       d  MF  XT	'   ML     U
(       a  SOSnT(       a  SOSn[        R                  SU U SU S[        UR                  5       5       35        GO=[        U4S jTR!                  5        5       5      (       a  UR                  5        V	Vs0 s H  u  pTU	   T:H  U
:w  d  M  X_M     nn	nU
(       a4  [        R                  ST S[        UR                  5       5       35        GO[        R                  ST S[        UR                  5       5       35        GOtTR#                  S5      (       a  TSS nUR                  5        V	Vs0 s H!  u  pTU	   R                  U5      U
:w  d  M  X_M#     nn	nU
(       a4  [        R                  SU S[        UR                  5       5       35        GO[        R                  SU S[        UR                  5       5       35        GOTR                  S5      (       a  TR#                  S5      (       a  TSS OTSS nUR                  5        V	Vs0 s H  u  pUTU	   ;   U
:w  d  M  X_M     nn	nU
(       a4  [        R                  SU S[        UR                  5       5       35        GO	[        R                  SU S[        UR                  5       5       35        O[        U4S jTR!                  5        5       5      (       a  UR                  5        V	Vs0 s H  u  pTTU	   ;   U
:w  d  M  X_M     nn	nU
(       a3  [        R                  ST S[        UR                  5       5       35        OB[        R                  ST S[        UR                  5       5       35        O[	        ST S35      eU(       d  [	        S T S!35      eU" X5      $ s  snf s  sn	f s  snn	f s  snn	f s  snn	f s  snn	f )#a  
Search components by name with simple pattern matching. Optionally filter by collection or load_id.

Args:
    names: Component name(s) or pattern(s)
        Patterns:
        - "unet" : match any component with base name "unet" (e.g., unet_123abc)
        - "!unet" : everything except components with base name "unet"
        - "unet*" : anything with base name starting with "unet"
        - "!unet*" : anything with base name NOT starting with "unet"
        - "*unet*" : anything with base name containing "unet"
        - "!*unet*" : anything with base name NOT containing "unet"
        - "refiner|vae|unet" : anything with base name exactly matching "refiner", "vae", or "unet"
        - "!refiner|vae|unet" : anything with base name NOT exactly matching "refiner", "vae", or "unet"
        - "unet*|vae*" : anything with base name starting with "unet" OR starting with "vae"
    collection: Optional collection to filter by
    load_id: Optional load_id to filter by
    return_dict_with_names:
                            If True, returns a dictionary with component names as keys, throw an error if
                            multiple components with the same name are found If False, returns a dictionary
                            with component IDs as keys

Returns:
    Dictionary mapping component names to components if return_dict_with_names=True, or a dictionary mapping
    component IDs to components if return_dict_with_names=False
)r   r   c                    > U(       aF  0 nU R                  5        H.  u  p4TR                  U5      nXR;   a  [        SU S35      eXBU'   M0     U$ U $ )a  
Create a dictionary mapping component names to components if return_dict_with_names=True, or a dictionary
mapping component IDs to components if return_dict_with_names=False, throw an error if duplicate component
names are found when return_dict_with_names=True
7Duplicate component names found in the search results: ], please set `return_dict_with_names=False` to return a dictionary with component IDs as keys)r   r   
ValueError)r   r   dict_to_returnr   r   r   r    s         r!   get_return_dict<ComponentsManager.search_components.<locals>.get_return_dict  ss     &!#%/%5%5%7MG $ 0 0 9I 2(UV_U`  a~    159- &8 &%!!r$   NzInvalid type for `names: z, only support stringc                    > TU    nU(       a  X:H  $ UR                  S5      (       a  USS nUR                  U5      $ UR                  S5      (       a$  UR                  S5      (       a  USS OUSS nXS;   $ X:H  $ )z
Helper function to check if a component matches a pattern based on its base name.

Args:
    component_id: The component ID to check
    pattern: The pattern to match against
    exact_match: If True, only exact matches to base_name are considered
*Nr   rn   )endswith
startswith)r   patternexact_match	base_namer   search
base_namess         r!   matches_pattern<ComponentsManager.search_components.<locals>.matches_pattern4  s     #<0I ++ !!#&& " ++F33 ##C((*1*:*:3*?*?2WQR[** ++r$   !rn   |c              3   |   #    U  H2  oR                  S 5      =(       d    UR                  S 5      (       + v   M4     g7f)r  N)r  r  )rw   terms     r!   rz   6ComponentsManager.search_components.<locals>.<genexpr>]  s.     !e_dW[s';'Qt}}S?Q"R"R_ds   :<c              3   8   >#    U  H  nT" TUT5      v   M     g 7fr   rR   )rw   r  r   r  r  s     r!   rz   r  `  s      $c]bUY_WdK%P%P]bs   zNOT r   zexactly matchingzmatching any of patternszGetting components  r8   c              3   .   >#    U  H
  nTU:H  v   M     g 7fr   rR   rw   r  r   s     r!   rz   r  n       I5H	)#5Hr|   z4Getting all components except those with base name 'r   z#Getting components with base name 'r  r   z&Getting components NOT starting with 'z"Getting components starting with 'z#Getting components NOT containing 'zGetting components containing 'c              3   .   >#    U  H
  nTU;   v   M     g 7fr   rR   r  s     r!   rz   r    r  r|   zComponent or pattern 'r   z&No components found matching pattern 'r   )F)r   r   r   rN   r   typer~   r   r  r   r   allanyr=   r>   r}   valuesr  )r    r   r   r   r   selected_idsr   r   r   r   is_not_patterntermsmatchesr   should_includelog_msg
match_typer   r	  r
  r  r  s   ``       `         @@@r!   search_components#ComponentsManager.search_components  s   F '':'O5AB\++\
B	"( =":FF E3''8eEZ[\\ ISHYZHYWt//88HYZ
	,< ))#.!"IE %<KK$EG!+!1!1!3!!e_d!ee "%$c]b$c!c ")7%7N!>'+G$ "4 !/fBG/:+@ZJKK-gYzl!E7"TRYR^R^R`MaLbcd IZ5F5F5HIII &0%5%5%7%7MGw'50^C %7   RSXRYY\]abibnbnbp]q\rstA%DQXQ]Q]Q_L`Kabc ^^C  3BZF &0%5%5%7%7MGg&11&9^K %7  
 DVHCPTU\UaUaUcPdOefg@DQXQ]Q]Q_L`Kabc c""$)NN3$7$7U1R[U12YF &0%5%5%7%7MGj11nD %7  
 A&TRYR^R^R`MaLbcd=fXSgllnI]H^_` IZ5F5F5HIII &0%5%5%7%7MGZ00^C %7  
 A%DQXQ]Q]Q_L`Kabc=eWCW\\^H\G]^_ 5eW<\]^^EeWANOOw??i C< [~s;   S)S.	S3S3S9'S9(S?>S?0TTr:   c                    [        5       (       d  [        S5      eU R                  R                  5        HM  u  p4[	        U[
        R                  R                  5      (       d  M0  [        US5      (       d  MC  [        USS9  MO     U R                  5         [        US9n[
        R                  " U5      nUR                  c%  [
        R                  " UR                   SS 35      n/ nU R                  R                  5        HK  u  p4[	        U[
        R                  R                  5      (       d  M0  [        X4XS	9nUR!                  U5        MM     U He  nU Vs/ s H  oULd  M	  UPM     n	nU	 HD  n
U
R"                  R$                  UR"                  R$                  :X  d  M3  UR'                  U
5        MF     Mg     X`l        SU l        Xl        gs  snf )
a}  
Enable automatic CPU offloading for all components.

The algorithm works as follows:
1. All models start on CPU by default
2. When a model's forward pass is called, it's moved to the execution device
3. If there's insufficient memory, other models on the device are moved back to CPU
4. The system tries to offload the smallest combination of models that frees enough memory
5. Models stay on the execution device until another model needs memory and forces them off

Args:
    device (Union[str, int, torch.device]): The execution device where models are moved for forward passes
    memory_reserve_margin (str): The memory reserve margin to use, default is 3GB. This is the amount of
                                memory to keep free on the device to avoid running out of memory during model
                                execution (e.g., for intermediate activations, gradients, etc.)
z7Make sure to install accelerate to use auto_cpu_offload_hf_hookT)recurser   N:r   r&   )r   ImportErrorr   r   r   rP   r   r   r   r   disable_auto_cpu_offloadr   r:   r   r  re   r*   r,   r   r-   r   r   r   )r    r:   ri   r   r   r   	all_hooksr,   hr   
other_hooks              r!   r   )ComponentsManager.enable_auto_cpu_offload  sm   " '((WXX#446OD)UXX__55')Z:X:X'	4@  7 	%%'.EZ[f%<<\\V[[M1#"67F	#446OD)UXX__55/k  &  7
 D&/AiD=1iKA)
??33tyy7Q7QQ''
3 *  %%)"$*! Bs   G'Gc                     U R                   c  SU l        gU R                    H#  nUR                  5         UR                  5         M%     U R                   (       a
  [	        5         SU l         SU l        g)z6
Disable automatic CPU offloading for all components.
NF)r   r   r?   r_   r   r+   s     r!   r*  *ComponentsManager.disable_auto_cpu_offload  s^     #).D&$$DLLNKKM %  %*"r$   fieldsr   c           
         XR                   ;  a  [        SU S35      eU R                   U   nUb?  [        U[        5      (       a  U/nU H!  nX@R                  ;  d  M  [        SU S35      e   UU R
                  U   SR                  U R                  R                  5        VVs/ s H  u  pVX;   d  M  UPM     snn5      =(       d    SS.n[        U[        R                  R                  5      (       Ga  [        US5      nSn	U(       a1  [        UR                  S	5      (       a  UR                  R                  n	UR                  UR                   R"                  UR%                  5       S
-  SUU	S.5        [        US5      (       a&  ['        UR(                  R+                  5       5      US'   [        US5      (       a  [        US5      (       a  [,        R.                  " UR0                  5      n
U
R3                  5        Vs/ s H  oR                   R"                  PM     nn[5        S U 5       5      (       ar  U
R                  5        VVs0 s H@  u  p[        US5      (       d  M  SUR                   R"                  ;   d  M4  XR6                  _MB     nnnU(       a  [9        U5      US'   Ub,  UR                  5        VVs0 s H  u  pX;   d  M  X_M     snn$ U$ s  snnf s  snf s  snnf s  snnf )a  Get comprehensive information about a component.

Args:
    component_id (str): Name of the component to get info for
    fields (Optional[Union[str, List[str]]]):
           Field(s) to return. Can be a string for single field or list of fields. If None, uses the
           available_info_fields setting.

Returns:
    Dictionary containing requested component metadata. If fields is specified, returns only those fields.
    Otherwise, returns all fields.
r   r   NzField 'z$' not found in available_info_fieldsr   )r   r   r   r&  r   rl   )r   r   r   r   r   peft_configr   _load_ip_adapter_weightsattn_processorsc              3   ,   #    U  H
  nS U;   v   M     g7f)	IPAdapterNrR   )rw   ptypes     r!   rz   3ComponentsManager.get_model_info.<locals>.<genexpr>(  s     I{e+s   scaler7  r   )r   r   r   rN   _available_info_fieldsr   r   r   r   rP   r   r   r   r&  r   update	__class__rH   r   r}   r3  r~   copydeepcopyr5  r  r  r:  r   )r    r   r1  r   fieldr   r   r>   r   r   
processorsvprocessor_typesr   scaless                  r!   get_model_info ComponentsManager.get_model_info  s   " .{<.8XYZZOOL1	 &#&&  ; ;;$wug5Y%Z[[   %//,7))T=M=M=S=S=U$o=UkdYeYnT=U$op 	
 i11y*5H#GI$6$68JKK#,#5#5#F#F KK"+"5"5">">(==?7K $ ((8 y-00#'	(=(=(B(B(D#EZ  y"<==')UfBgBg!]]9+D+DE
AKARARAT"UATA;;#7#7AT"UIIII %/$4$4$6$6DA"1g. #3>!++BVBV3V #77
$6  
 -Nv-V\* %)ZZ\A\TQQ[DAD\AAK[ %p< #V Bs0   'K!6K!K'K,,K,K,K2K2c                    U R                   (       d  gS nS nU R                   R                  5        Vs/ s HI  n[        U[        R                  R
                  5      (       d  M.  [        US5      (       d  MA  U" U5      PMK     nnU(       a2  [        S/U Vs/ s H  n[        [        U5      5      PM     sn-   5      OSn0 nU R                   R                  5        HT  n/ Xx'   U R                  R                  5        H  u  pX;   d  M  Xx   R                  U	5        M!     Xx   (       a  MO  S/Xx'   MV     UR                  5        VV	s/ s H  o  H  oPM     M     nnn	U(       a  [        S[        S U 5       5      5      OSn[        S[        S	 U R                   R                  5        5       5      5      [        S
[        S U R                   R                  5        5       5      5      SSSUUS.nS[        UR                  5       5      [        U5      S-  -   S-
  -  S-   nS[        UR                  5       5      [        U5      S-  -   S-
  -  S-   nSU-   nU R                   R                  5        VVs0 s H4  u  nn[        U[        R                  R
                  5      (       d  M1  UU_M6     nnnU R                   R                  5        VVs0 s H4  u  nn[        U[        R                  R
                  5      (       a  M1  UU_M6     nnnU(       Ga  USU-   -  nUSSUS    3 SSSUS    3 S3-  nUSSUS    3 SSSUS    3 S3-  nUSSUS     3 SS!SUS"    3 S#3-  nUU-  nUR                  5        GH*  u  pU R                  U5      nU" UU5      n[        US5      (       a  [        UR                   5      OSnU" U5      nXx   (       a  Xx   S$   OSnUUSUS    3 SUS%   SUS    3 S3-  nUUSUS    3 SUSUS    3 S3-  nUUS&   SUS     S'3 SUSUS"    3 SU S3-  n[#        S[        Xx   5      5       HX  nXx   U   nUS(SUS    3 SS(SUS    3 S3-  nUS(SUS    3 SS(SUS    3 S3-  nUS(SUS     3 SS(SUS"    3 SU S3-  nMZ     GM-     UU-  nU(       a  U(       a  US-  nUS)U-   -  nUS*SUS    3 SSSUS    3 S#3-  nUU-  nUR                  5        H  u  pU R                  U5      nXx   (       a  Xx   S$   OSnUUSUS    3 SUR$                  R&                  SUS    3 SU S3-  n[#        S[        Xx   5      5       H&  nXx   U   nUS(SUS    3 SS(SUS    3 SU S3-  nM(     M     UU-  nUS+-  nU R                    H  nU R                  U5      nUc  M  UR)                  S,5      c  UR)                  S-5      (       d  MC  USU S.3-  nUR)                  S,5      b  US/US,    S3-  nUR)                  S-5      (       d  M  US0-  nM     U$ s  snf s  snf s  sn	nf s  snnf s  snnf )1NzComponents:
==================================================
No components registered.
==================================================c                 >    [        U S5      (       a  U R                  $ g)Nr   N/A)r   r   )r   s    r!   get_load_id/ComponentsManager.__repr__.<locals>.get_load_id?  s    y"677 333r$   c                     US   (       d  [        [        U SS5      5      $ [        [        U SS5      5      n[        US   =(       d    S5      nU SU S3$ )Nr   r:   rI  r   ())rN   getattr)r   r>   r:   exec_devices       r!   format_device1ComponentsManager.__repr__.<locals>.format_deviceE  sY    
#79h>??WY%@A!$'9":"CeD ;-q11r$   r      rI  
   c              3   J   #    U  H  n[        [        U5      5      v   M     g 7fr   )r   rN   )rw   cs     r!   rz   -ComponentsManager.__repr__.<locals>.<genexpr>a  s     (NoSVos   !#c              3   8   #    U  H  n[        U5      v   M     g 7fr   )r   )rw   r   s     r!   rz   rW  d  s     K4JDc$ii4Js      c              3   `   #    U  H$  n[        UR                  R                  5      v   M&     g 7fr   )r   r=  rH   )rw   r   s     r!   rz   rW  e  s&      mTlyY%8%8%A%A!B!BTls   ,.   )r   classr:   dtypesizer   r   =   rn   
-zComponents:
zModels:
Name_ID<r   z | Classr\  zDevice: act(exec)r:   Dtyper]  z	Size (GB)r^  zLoad IDr   z | Collection
r   r   r   r9   r   zOther Components:
IDzO
Additional Component Info:
==================================================
r   r   z:
z  Adapters: z  IP-Adapter: Enabled
)r   r  r   rP   r   r   r   maxr   rN   r~   r   r   r*   r   rE  r]  r   r=  rH   get)r    rJ  rQ  r   load_idslidmax_load_id_lencomponent_collectionsr   r   r   collsall_collectionsmax_collection_len
col_widthssep_line	dash_lineoutputr   rB  modelsothersr>   
device_strr]  r   first_collectionir   s                                r!   __repr__ComponentsManager.__repr__9  s   Z		2 "__335
5	)UXX__5 #:A)Ma:b #K	"5 	 

 NV#rdx%Hxc#c(mx%HHI[] !#OO((*D*,!'#//557=)/66t<  8 )../4g%+ + .C-I-I-K^-KEX]PT4X]4-K^SbSS(No(N%NOhj b#KDOO4H4H4JKKLS mTXTcTcTjTjTl mmn&,

 #j//12S_q5HH1LMPTT3z0023c*o6IIAMNQUU	 8+ $(??#8#8#:]#:41ajEHHOO>\$!Q$#:]#'??#8#8#:a#:41a*QPUPXPXP_P_B`$!Q$#:a kI--F1Z%5$6"67s71ZPWEXDYBY:ZZ]^^F,Qz(/C.D,DESQRS]^eSfRgPgHhhkllFQz&'9&:$:;3y:V_K`JaHa>bbqrrFiF $*<<>**40*9d;
07	70K0KIOO,QV%i0 F[E`#8#>q#Afk T!Jt$4#5!56c$|:LQzZaObNcLc9ddghhZ*X*>)?'?@E!JW^L_K`I`CaadeeT)_Qz&/A.B#,EFc'RST^_hTiSjQjIkkno  oA  AC  D  D q#&;&A"BCA!6!<Q!?JAj&6%7#7 8BqGAT@U>U;VVYZZFAj&:%;#; <C1ZPWEXDYBY?ZZ]^^FAj&8%9#9 :#b:iCXBY@Y=ZZ]^h]iikllF	 D $2( iF $+i77Fa
4 0112#ga
7@S?T=T5UUdeeFiF $*<<>**40 F[E`#8#>q#Afk T!Jt$4#5!56c):M:M:V:VWXYcdkYlXmVm9nnq  sC  rD  DF  G  G q#&;&A"BCA!6!<Q!?JAj&6%7#7 8BqGAT@U>U;VVYZdYeeghhF D $2 iF 	DDOOD&&t,DTXXj%9%ER^I_I_BtfC.(88J'3T*-=,>bAAF88L))77F $ [

 &I _( ^as5   -X=&X=9X=Y
	Y70Y+Y0YYc           	         Ub  Uc  Uc  Ub  [        S5      eUb-  XR                  ;  a  [        SU S35      eU R                  U   $ U R                  X#U5      nU(       d  [        SU S35      e[        U5      S:  a(  [        SU S[	        UR                  5       5       35      e[        [        UR                  5       5      5      $ )	a   
Get a single component by either:
- searching name (pattern matching), collection, or load_id.
- passing in a component_id
Raises an error if multiple components match or none are found.

Args:
    component_id (Optional[str]): Optional component ID to get
    name (Optional[str]): Component name or pattern
    collection (Optional[str]): Optional collection to filter by
    load_id (Optional[str]): Optional load_id to filter by

Returns:
    A single component

Raises:
    ValueError: If no components match or multiple components match
zFIf searching by component_id, do not pass name, collection, or load_idr   r   zNo components found matching 'r   rn   z$Multiple components found matching 'r   )	r   r   r#  r   r}   r~   nextiterr  )r    r   r   r   r   resultss         r!   get_oneComponentsManager.get_one  s    4 #)9Z=SW^Wjeff #??2 ;|n<\!]^^??<00((7C=dV1EFFw<!CD6TRYR^R^R`MaLbcddD)*++r$   c                     [        5       n[        U[        5      (       d  U/nU H!  nUR                  U R	                  XBS95        M#     [        U5      $ )z
Get component IDs by a list of names, optionally filtered by collection.

Args:
    names (Union[str, List[str]]): List of component names
    collection (Optional[str]): Optional collection to filter by

Returns:
    List[str]: List of component IDs
r   )r   r   r}   r<  r   )r    r   r   r   r   s        r!   get_idsComponentsManager.get_ids  sM     e%&&GEDJJt''T'IJ Cyr$   r   c                     U Vs0 s H  o3U R                   U   _M     nnU(       aF  0 nUR                  5        H.  u  pgU R                  U5      nX;   a  [        SU S35      eXuU'   M0     U$ U$ s  snf )a  
Get components by a list of IDs.

Args:
    ids (List[str]):
        List of component IDs
    return_dict_with_names (Optional[bool]):
        Whether to return a dictionary with component names as keys:

Returns:
    Dict[str, Any]: Dictionary of components.
        - If return_dict_with_names=True, keys are component names.
        - If return_dict_with_names=False, keys are component IDs.

Raises:
    ValueError: If duplicate component names are found in the search results when return_dict_with_names=True
r   r   )r   r   r   r   )	r    r   r   r   r   r   r   r   r   s	            r!   get_components_by_ids'ComponentsManager.get_components_by_ids  s    $ 9<<"$//"--
<!N!+!1!1!3 ,,W5	.$QR[Q\  ]z  {  -1y) "4 "! =s   A/c                 F    U R                  X5      nU R                  U5      $ )ah  
Get components by a list of names, optionally filtered by collection.

Args:
    names (List[str]): List of component names
    collection (Optional[str]): Optional collection to filter by

Returns:
    Dict[str, Any]: Dictionary of components with component names as keys

Raises:
    ValueError: If duplicate component names are found in the search results
)r  r  )r    r   r   r   s       r!   get_components_by_names)ComponentsManager.get_components_by_names  s#     ll5-))#..r$   )r   r   r   r   r   r   )NNNNr   )NNNT)r   r   NN)T)"rH   rI   rJ   rK   rL   r;  r"   r   rN   r   r   staticmethodr   r   r   r   r_   boolr#  r	   rO   rP   r:   r   r*  r   r   rE  rz  r  r  r  r  rQ   rR   r$   r!   r   r     s7   @
+ #$(!%,0&sm& SM& #	&
 [)&P 6# 6 6E E E# EN&3 &C &$)3 )B  $$(!%'+x@}x@ SMx@ #	x@
 !%x@t++eCell4J.K ++Z+( 37OO sDI~./O 
$sCx.	!	OdBL '+"$(!%+,sm+, sm+, SM	+,
 #+, 
+,ZU3S	>2 xPS} $c HUYN B/T#Y /HSM / /r$   r   r  )+r>  r;   r   r   	itertoolsr   typingr   r   r   r   r	   rP   r6   r   utilsr   r   accelerate.hooksr   r   accelerate.stater   accelerate.utilsr   accelerate.utils.memoryr   accelerate.utils.modelingr   
get_loggerrH   r=   r   r   rN   r   r   rO   r:   re   r   r   r   rR   r$   r!   <module>r     s      # " 3 3   L-/:B			H	%Aj	 AjH' ': 7;8<			88??	 Cell23	 45		C  C P8c3h 8DcN 8vV/ V/r$   