
    bis                        d dl mZmZmZmZmZmZ d dlZd dlm	Z	 ddl
mZmZ ddlmZmZmZ ddlmZ ddlmZmZmZmZ ddlmZ dd	lmZ dd
lmZ  ej<                  e      Z  G d de	jB                        Z" G d d      Z#y)    )CallableDictListOptionalTupleUnionN   )BasicTransformerBlockFreeNoiseTransformerBlock)Downsample2DResnetBlock2D
Upsample2D)Transformer2DModel)AnimateDiffTransformer3DCrossAttnDownBlockMotionDownBlockMotionUpBlockMotion)DiffusionPipeline)logging)randn_tensorc                        e Zd ZdZdddgfdej
                  dededee   d	d
f
 fdZ	d	e
ej                  eej                     f   fdZ xZS )SplitInferenceModuleap  
    A wrapper module class that splits inputs along a specified dimension before performing a forward pass.

    This module is useful when you need to perform inference on large tensors in a memory-efficient way by breaking
    them into smaller chunks, processing each chunk separately, and then reassembling the results.

    Args:
        module (`nn.Module`):
            The underlying PyTorch module that will be applied to each chunk of split inputs.
        split_size (`int`, defaults to `1`):
            The size of each chunk after splitting the input tensor.
        split_dim (`int`, defaults to `0`):
            The dimension along which the input tensors are split.
        input_kwargs_to_split (`List[str]`, defaults to `["hidden_states"]`):
            A list of keyword arguments (strings) that represent the input tensors to be split.

    Workflow:
        1. The keyword arguments specified in `input_kwargs_to_split` are split into smaller chunks using
        `torch.split()` along the dimension `split_dim` and with a chunk size of `split_size`.
        2. The `module` is invoked once for each split with both the split inputs and any unchanged arguments
        that were passed.
        3. The output tensors from each split are concatenated back together along `split_dim` before returning.

    Example:
        ```python
        >>> import torch
        >>> import torch.nn as nn

        >>> model = nn.Linear(1000, 1000)
        >>> split_module = SplitInferenceModule(model, split_size=2, split_dim=0, input_kwargs_to_split=["input"])

        >>> input_tensor = torch.randn(42, 1000)
        >>> # Will split the tensor into 21 slices of shape [2, 1000].
        >>> output = split_module(input=input_tensor)
        ```

    It is also possible to nest `SplitInferenceModule` across different split dimensions for more complex
    multi-dimensional splitting.
       r   hidden_statesmodule
split_size	split_diminput_kwargs_to_splitreturnNc                 l    t         |           || _        || _        || _        t        |      | _        y )N)super__init__r   r   r   setr   )selfr   r   r   r   	__class__s        _/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/pipelines/free_noise_utils.pyr"   zSplitInferenceModule.__init__N   s3     	$"%()>%?"    c           	      :   i }t        |j                               D ]k  }|| j                  vst        j                  ||         s*t        j
                  ||   | j                  | j                        ||<   |j                  |       m g }t        |j                          D ]Y  }t        t        |j                         |            }|j                  |        | j                  |i |}|j                  |       [ t        |d   t        j                         r!t        j"                  || j                        S t        |d   t$              r>t%        t        | D 	cg c]#  }	t        j"                  |	| j                        % c}	      S t'        d      c c}	w )a  Forward method for the `SplitInferenceModule`.

        This method processes the input by splitting specified keyword arguments along a given dimension, running the
        underlying module on each split, and then concatenating the results. The splitting is controlled by the
        `split_size` and `split_dim` parameters specified during initialization.

        Args:
            *args (`Any`):
                Positional arguments that are passed directly to the `module` without modification.
            **kwargs (`Dict[str, torch.Tensor]`):
                Keyword arguments passed to the underlying `module`. Only keyword arguments whose names match the
                entries in `input_kwargs_to_split` and are of type `torch.Tensor` will be split. The remaining keyword
                arguments are passed unchanged.

        Returns:
            `Union[torch.Tensor, Tuple[torch.Tensor]]`:
                The outputs obtained from `SplitInferenceModule` are the same as if the underlying module was inferred
                without it.
                - If the underlying module returns a single tensor, the result will be a single concatenated tensor
                along the same `split_dim` after processing all splits.
                - If the underlying module returns a tuple of tensors, each element of the tuple will be concatenated
                along the `split_dim` across all splits, and the final result will be a tuple of concatenated tensors.
        r   dimzIn order to use the SplitInferenceModule, it is necessary for the underlying `module` to either return a torch.Tensor or a tuple of torch.Tensor's.)listkeysr   torch	is_tensorsplitr   r   popzipvaluesdictupdater   append
isinstanceTensorcattuple
ValueError)
r$   argskwargssplit_inputskeyresultssplit_inputinputs#intermediate_tensor_or_tensor_tuplexs
             r&   forwardzSplitInferenceModule.forward\   s\   0  & 	C$444EOOFSVK<X %F3K$.. YLJJsO		  3 3 56 	@K#l//1;?@FMM&!2=$++t2Nv2N/NN>?	@ gaj%,,/99W$..99
E*CMRq%))A4>>:RSS f  Ss   (F)__name__
__module____qualname____doc__nnModuleintr   strr"   r   r-   r7   r   rD   __classcell__)r%   s   @r&   r   r   %   s}    &V ,;+<@		@ @ 	@
  $Cy@ 
@2%eELL>Q0Q*R 2r'   r   c                   6   e Zd ZdZdeeeef   fdZdeeeef   fdZ		 	 d3dZ
	 	 	 	 	 d4deeeeef   f   d	ed
ej                  dededeeeeeef   f      deej$                     deej$                     dee   dee   dej$                  fdZ	 	 d5deded	edededej*                  d
ej                  deej,                     deej$                     fdZdededej$                  dej$                  dej$                  f
dZ	 	 	 	 	 d6d ee   d!ed"ed#ed$eeeeeej$                  ej$                  gej$                  f      ddfd%Zd3d&Zd'ee   d(eddfd)Zd*ee    d+eddfd,Z!d-ee"   d+eddfd.Z#d/eee$   ee%   f   d+eddfd0Z&d7d(ed+eddfd1Z'e(d2        Z)y)8AnimateDiffFreeNoiseMixinzFMixin class for [FreeNoise](https://huggingface.co/papers/2310.15169).blockc                    |j                   D ]  }t        |j                        }t        |      D ]  }t	        |j                  |   t
              r?|j                  |   j                  | j                  | j                  | j                         `t	        |j                  |   t              sJ |j                  |   }t        |j                  |j                  |j                  |j                  |j                  |j                   |j"                  |j$                  |j&                  |j(                  |j*                  | j                  | j                  | j                        j-                  | j.                  | j0                        |j                  |<   |j                  |   j3                  |j5                         d       |j                  |   j7                  |j8                  |j:                           y)z:Helper function to enable FreeNoise in transformer blocks.)r*   num_attention_headsattention_head_dimdropoutcross_attention_dimactivation_fnattention_biasonly_cross_attentiondouble_self_attentionpositional_embeddingsnum_positional_embeddingscontext_lengthcontext_strideweighting_schemedevicedtypeTstrictN)motion_moduleslentransformer_blocksranger6   r   set_free_noise_properties_free_noise_context_length_free_noise_context_stride_free_noise_weighting_schemer
   r*   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   tor`   ra   load_state_dict
state_dictset_chunk_feed_forward_chunk_size
_chunk_dim)r$   rP   motion_modulenum_transformer_blocksibasic_transfomer_blocks         r&   _enable_free_noise_in_blockz5AnimateDiffFreeNoiseMixin._enable_free_noise_in_block   s    #11 $	M%()I)I%J"12 !m>>qAC\]!44Q7QQ777799 &m&F&Fq&IK`aaa-:-M-Ma-P*:S266,B,V,V+A+T+T 6 > >,B,V,V&<&J&J'='L'L-C-X-X.D.Z.Z.D.Z.Z2H2b2b'+'F'F'+'F'F)-)J)J; b4::b> "44Q7" "44Q7GG.99;D H  "44Q7NN.::<R<]<]?!$	r'   c                     |j                   D ]n  }t        |j                        }t        |      D ]G  }t	        |j                  |   t
              s"|j                  |   }t        |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                   |j"                        j%                  | j&                  | j(                        |j                  |<   |j                  |   j+                  |j-                         d       |j                  |   j/                  |j0                  |j2                         J q y)z;Helper function to disable FreeNoise in transformer blocks.)r*   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r_   Trb   N)rd   re   rf   rg   r6   r   r
   r*   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   rl   r`   ra   rm   rn   ro   rp   rq   )r$   rP   rr   rs   rt   free_noise_transfomer_blocks         r&   _disable_free_noise_in_blockz6AnimateDiffFreeNoiseMixin._disable_free_noise_in_block   sV    #11 	M%()I)I%J"12 m>>qAC\]2?2R2RST2U/:O7;;,G,[,[+F+Y+Y ; C C,G,[,[&A&O&O'B'Q'Q-H-]-].I._._.I._._2M2g2g; b4::b> "44Q7 "44Q7GG3>>@ H  "44Q7NN3??A\AgAg+	r'   r   Nc                    t        |t        t        f      st        dt	        |            |-t        |t        t        f      st        dt	        |            ||t        d      |j                         D cg c]  }t        |t               }}|j                         D cg c]  }t        |t               }}t        t        |j                                     }	t        t        |j                                     }
t        |      st        d      t        |      st        d      |	dk7  rt        d      |
|k\  rt        d|d	      y c c}w c c}w )
NzFExpected `prompt` to have type `str` or `dict` but found type(prompt)=zXExpected `negative_prompt` to have type `str` or `dict` but found type(negative_prompt)=zO`prompt_embeds` and `negative_prompt_embeds` is not supported in FreeNoise yet.z5Expected integer keys in `prompt` dict for FreeNoise.z3Expected str values in `prompt` dict for FreeNoise.r   zUThe minimum frame index in `prompt` dict must be 0 as a starting prompt is necessary.zHThe maximum frame index in `prompt` dict must be lesser than num_frames=z and follow 0-based indexing.)r6   rL   r3   r:   typer,   rK   r2   minr+   maxall)r$   promptnegative_promptprompt_embedsnegative_prompt_embeds
num_framesrC   frame_indicesframe_prompts	min_frame	max_frames              r&   _check_inputs_free_noisez2AnimateDiffFreeNoiseMixin._check_inputs_free_noise   sP    &3+.fY]^dYeXghii&oT{; oY]^mYnXpq  $(>(Jnoo5;[[]CAs+CC5;]]_EAs+EEV[[]+,	V[[]+,	=!TUU=!RSS>tuu
"[PZ}\yz  # DEs   >E)Er   r   r`   num_videos_per_promptdo_classifier_free_guidancer   r   r   
lora_scale	clip_skipc                 f   |d}t        |t              rd|i}t        |t              rd|i}| j                  |||||       t        t	        |j                                     }t        t	        |j                                     }|t        |j                               d      ||dz
  <   |t        |j                               d      ||dz
  <   t        |j                               }t        |j                               }t        |j                               }t        |j                               }| j                  |||dd d d |	|
	      \  }}|g|j                  dd  }|j                  |      }t        t        |      dz
        D ]T  }||   }||dz      }||   j                  d      }||dz      j                  d      }| j                  ||||      |||dz    V d }d }|r| j                  dgt        |      z  ||d|d d |	|
	      \  }}|j                  |      }t        t        |      dz
        D ]T  }||   }||dz      }||   j                  d      }||dz      j                  d      }| j                  ||||      |||dz    V |}|}|rt!        j"                  ||g      }||fS )N r   r   F)	r   r`   num_images_per_promptr   r   r   r   r   r   T)r6   rL   r   r3   sorteditemsr+   r,   r2   encode_promptshape	new_zerosrg   re   	unsqueeze)_free_noise_prompt_interpolation_callbackr-   r8   )r$   r   r   r`   r   r   r   r   r   r   r   r   r   frame_negative_indicesframe_negative_prompts_r   prompt_interpolation_embedsrt   start_frame	end_framestart_tensor
end_tensor$negative_prompt_interpolation_embedss                           r&   _encode_prompt_free_noisez3AnimateDiffFreeNoiseMixin._encode_prompt_free_noise   s(    " O fc"[Fos+ /2O%%fo}Ndfpq fV\\^,-vo&;&;&=>? "(V[[](;B(?!@zA~*9$?S?S?U:VWY:Z*[
Q'V[[]+V]]_-!%o&:&:&<!=!%o&<&<&>!?  -- "7(- #'! . 

q 6m11!"56&3&=&=e&D#s=)A-. 	A'*K%a!e,I(+55a8L&q1u-77:JGKGuGuYjH'i!mD	 "&/3,&(,(:(:tc"899&;,0 6"'+%# ); 
)%A% 4J3S3STY3Z0356:; 4Q721q59	5a8BB1E3AE:DDQG
 BB;PY[gist 5[9q=Q 4!E&!II'=}&MNM444r'   
batch_sizenum_channels_latentsheightwidthra   	generatorlatentsc
           
         t        |t              r)t        |      |k7  rt        dt        |       d| d      | j                  dk(  r| j                  n|}
|||
|| j
                  z  || j
                  z  f}|	 t        ||||      }	| j                  dk(  rt|	S |	j                  d      |k(  r|	S |	j                  d      | j                  k7  r-t        d| d	| j                   d
|	j                  d             |	j                  |      }	| j                  dk(  rt        | j                  || j                        D ]  }t        d|| j                  z
        }t        ||| j                  z         }||z
  }|dk(  r nt        j                  t        t        ||                  }|t        j                   ||         }|}t        |||z         }|||z   k(  r|	d d d d |f   |	d d d d ||f<   ||z
  }|d | }|	d d d d |f   |	d d d d ||f<    nI| j                  dk(  r:|| j                  z   dz
  | j                  z  }t        j"                  |	g|z  d      }	|	d d d d d |f   }	|	S )Nz/You have passed a list of generators of length z+, but requested an effective batch size of z@. Make sure the batch size matches the length of the generators.repeat_context)r   r`   ra   randomr	   z_You have passed `latents` as a parameter to FreeNoise. The expected number of frames is either z or z, but found shuffle_contextr   )r   r   r)   )r6   r+   re   r:   ri   vae_scale_factorr   _free_noise_noise_typesizerl   rg   rj   r}   r|   r-   
LongTensorrandpermr8   )r$   r   r   r   r   r   ra   r`   r   r   context_num_framesr   rt   window_start
window_endwindow_lengthindicesshuffled_indicescurrent_startcurrent_endprefix_lengthnum_repeatss                         r&   _prepare_latents_free_noisez5AnimateDiffFreeNoiseMixin._prepare_latents_free_noised  s    i&3y>Z+GA#i.AQ R&<'gi  04/N/NRb/bD++hr 	
  d+++T***
 ?"5IfTYZG**h6||A*,aD$C$CC u  wA  vB  BF  GK  Gf  Gf  Fg  gs  t{  t@  t@  AB  tC  sD  E  jj(G&&*;;4::JHgHgh _"1a$*I*I&IJ \D<[<[-[\
 *\ 9 A%**4lJ0O+PQ#*5>>-S\+]#^  !!*mm.KL--"???Fq!M]G]?^GAq-";;< %0-$?M'7'G$?Fq!M]G]?^GAq-";;<+_. ((,<<%(G(GG!KPTPoPooKii	K 7Q?G!Q+,r'   start_index	end_indexr   r   c                     ||z
  dz   }g }t        |      D ])  }||dz
  z  }d|z
  |z  ||z  z   }	|j                  |	       + t        j                  |      }|S )Nr   )rg   r5   r-   r8   )
r$   r   r   r   r   num_indicesinterpolated_tensorsrt   alphainterpolated_tensors
             r&   _lerpzAnimateDiffFreeNoiseMixin._lerp  s{      +-1!{# 	=Aq)E#$u9"<uz?Q"Q ''(;<	=
  %yy)=>##r'   r\   r]   r^   
noise_typeprompt_interpolation_callbackc                    g d}g d}|| j                   j                  j                  kD  r:t        j	                  d|d| j                   j                  j                  d       ||vrt        d| d|      ||vrt        d| d	|      |xs  | j                   j                  j                  | _        || _        || _        || _	        |xs | j                  | _        t        | j                  j                  d
      rEg | j                  j                  | j                  j                  | j                  j                   }n.g | j                  j                  | j                  j                   }|D ]  }	| j#                  |	        y)ad	  
        Enable long video generation using FreeNoise.

        Args:
            context_length (`int`, defaults to `16`, *optional*):
                The number of video frames to process at once. It's recommended to set this to the maximum frames the
                Motion Adapter was trained with (usually 16/24/32). If `None`, the default value from the motion
                adapter config is used.
            context_stride (`int`, *optional*):
                Long videos are generated by processing many frames. FreeNoise processes these frames in sliding
                windows of size `context_length`. Context stride allows you to specify how many frames to skip between
                each window. For example, a context length of 16 and context stride of 4 would process 24 frames as:
                    [0, 15], [4, 19], [8, 23] (0-based indexing)
            weighting_scheme (`str`, defaults to `pyramid`):
                Weighting scheme for averaging latents after accumulation in FreeNoise blocks. The following weighting
                schemes are supported currently:
                    - "flat"
                       Performs weighting averaging with a flat weight pattern: [1, 1, 1, 1, 1].
                    - "pyramid"
                        Performs weighted averaging with a pyramid like weight pattern: [1, 2, 3, 2, 1].
                    - "delayed_reverse_sawtooth"
                        Performs weighted averaging with low weights for earlier frames and high-to-low weights for
                        later frames: [0.01, 0.01, 3, 2, 1].
            noise_type (`str`, defaults to "shuffle_context"):
                Must be one of ["shuffle_context", "repeat_context", "random"].
                    - "shuffle_context"
                        Shuffles a fixed batch of `context_length` latents to create a final latent of size
                        `num_frames`. This is usually the best setting for most generation scenarios. However, there
                        might be visible repetition noticeable in the kinds of motion/animation generated.
                    - "repeated_context"
                        Repeats a fixed batch of `context_length` latents to create a final latent of size
                        `num_frames`.
                    - "random"
                        The final latents are random without any repetition.
        )flatpyramiddelayed_reverse_sawtooth)r   r   r   zYou have set context_length=zH which is greater than self.motion_adapter.config.motion_max_seq_length=z*. This can lead to bad generation results.z0The parameter `weighting_scheme` must be one of z, but got weighting_scheme=z*The parameter `noise_type` must be one of z, but got noise_type=rd   N)motion_adapterconfigmotion_max_seq_lengthloggerwarningr:   ri   rj   rk   r   r   r   hasattrunet	mid_blockdown_blocks	up_blocksrv   )
r$   r\   r]   r^   r   r   allowed_weighting_schemeallowed_noise_typeblocksrP   s
             r&   enable_free_noisez+AnimateDiffFreeNoiseMixin.enable_free_noise  s   \ $S LD//66LLLNN/00yH[H[HbHbHxHxGz  {e  f #;;BC[B\\xgwfyz  //IJ\I]]shrgtuvv*8*lD<O<O<V<V<l<l'*8',<)&0#9V9dZ^ZdZd6499&&(89Xtyy,,Xdii.A.AXDIIDWDWXFCtyy,,Ctyy/B/BCF 	4E,,U3	4r'   c                    d| _         t        | j                  j                  d      rEg | j                  j                  | j                  j                  | j                  j
                  }n.g | j                  j                  | j                  j
                  }g | j                  j                  | j                  j                  | j                  j
                  }|D ]  }| j                  |        y)z)Disable the FreeNoise sampling mechanism.Nrd   )ri   r   r   r   r   r   ry   )r$   r   rP   s      r&   disable_free_noisez,AnimateDiffFreeNoiseMixin.disable_free_noise  s    *.'499&&(89Xtyy,,Xdii.A.AXDIIDWDWXFCtyy,,Ctyy/B/BCFT499((T$))*=*=T		@S@ST 	5E--e4	5r'   rd   spatial_split_sizec           	      $   |D ]  }t        |j                  |ddg      |_        t        t        |j                              D ],  }t        |j                  |   |dddg      |j                  |<   . t        |j
                  |ddg      |_         y )Nr   inputr   encoder_hidden_states)r   proj_inrg   re   rf   proj_out)r$   rd   r   rr   rt   s        r&   '_enable_split_inference_motion_modules_zAAnimateDiffFreeNoiseMixin._enable_split_inference_motion_modules_  s     , 	tM$89N9NPbdehogp$qM!3}??@A 6J!44Q7&$&=>	7003 &:-:P:PRdfgjqir%sM"	tr'   
attentionstemporal_split_sizec                 b    t        t        |            D ]  }t        ||   |dddg      ||<    y )Nr   r   r   rg   re   r   )r$   r   r   rt   s       r&   #_enable_split_inference_attentions_z=AnimateDiffFreeNoiseMixin._enable_split_inference_attentions_#  s>     s:' 	A012AI`7aJqM	r'   resnetsc                 b    t        t        |            D ]  }t        ||   |dddg      ||<    y )Nr   input_tensortembr   )r$   r   r   rt   s       r&    _enable_split_inference_resnets_z:AnimateDiffFreeNoiseMixin._enable_split_inference_resnets_+  s<    s7|$ 	lA-gaj:MqSaciRjkGAJ	lr'   samplersc                 `    t        t        |            D ]  }t        ||   |ddg      ||<    y )Nr   r   r   )r$   r   r   rt   s       r&   !_enable_split_inference_samplers_z;AnimateDiffFreeNoiseMixin._enable_split_inference_samplers_/  s<     s8}% 	gA.x{<OQRUdTefHQK	gr'   c                 6   g | j                   j                  | j                   j                  | j                   j                  }|D ]  }t	        |dd      | j                  |j                  |       t	        |dd      | j                  |j                  |       t	        |dd      | j                  |j                  |       t	        |dd      | j                  |j                  |       t	        |dd      | j                  |j                  |        y)az  
        Enable FreeNoise memory optimizations by utilizing
        [`~diffusers.pipelines.free_noise_utils.SplitInferenceModule`] across different intermediate modeling blocks.

        Args:
            spatial_split_size (`int`, defaults to `256`):
                The split size across spatial dimensions for internal blocks. This is used in facilitating split
                inference across the effective batch dimension (`[B x H x W, F, C]`) of intermediate tensors in motion
                modeling blocks.
            temporal_split_size (`int`, defaults to `16`):
                The split size across temporal dimensions for internal blocks. This is used in facilitating split
                inference across the effective batch dimension (`[B x F, H x W, C]`) of intermediate tensors in spatial
                attention, resnets, downsampling and upsampling blocks.
        rd   Nr   r   downsamplers
upsamplers)r   r   r   r   getattrr   rd   r   r   r   r   r   r   r   )r$   r   r   r   rP   s        r&   !enable_free_noise_split_inferencez;AnimateDiffFreeNoiseMixin.enable_free_noise_split_inference5  s     U499((T$))*=*=T		@S@ST 
	^Eu.5A<<U=Q=QSefulD1=889I9IK^_ui.:55emmEXYund3?66u7I7IK^_ulD1=66u7G7GI\]
	^r'   c                 :    t        | d      xr | j                  d uS )Nri   )r   ri   )r$   s    r&   free_noise_enabledz,AnimateDiffFreeNoiseMixin.free_noise_enabledR  s!    t9:jt?^?^fj?jjr'   )r   N)NNNNN)NN)      r   r   N)   r   )*rE   rF   rG   rH   r   r   r   r   rv   ry   r   rL   r   rK   r-   r`   boolr   r7   floatr   ra   	Generatorr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   propertyr    r'   r&   rO   rO      sW   Q'7OQ`bo7o1p 'R%8PRacp8p2q >" 
"V AE049=&*#'b5c4S>)*b5 b5 	b5
  #b5 &*b5 "%T#s(^(;"<=b5  -b5 !) 6b5 UOb5 C=b5 
b5Z 04*.HH "H 	H
 H H {{H H EOO,H %,,'HT$$+.$>Cll$X]XdXd$	$  )+ )+ H4 H4 H4 	H4
 H4 (0'c5<<NPUP\P\\](
H4 
H4T5t"#;<tRUt	t 12IL	l]8K lbe ljn lgd<0$z2BBCgZ]g	g^C ^dg ^qu ^: k kr'   rO   )$typingr   r   r   r   r   r   r-   torch.nnrI   models.attentionr
   r   models.resnetr   r   r   "models.transformers.transformer_2dr   models.unets.unet_motion_modelr   r   r   r   pipelines.pipeline_utilsr   utilsr   utils.torch_utilsr   
get_loggerrE   r   rJ   r   rO   r   r'   r&   <module>r     sj    @ ?   O C C C  9  , 
		H	%i299 iXCk Ckr'   