
    bi2:                         d dl Z d dlmZ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 ddlmZ ddlmZmZ erddlmZ d	Z ee      Z G d
 dee      ZddZy)    N)TYPE_CHECKINGAnyDictListOptionalTupleUnion)validate_hf_hub_args)Self   )ConfigMixin)PushToHubMixin
get_logger
BlockStatezguider_config.jsonc                   L   e Zd ZdZeZdZdZd%dedefdZ	d Z
d Zd	ed
edej                  ddfdZdeeeeeeef   f   f   ddfdZdej*                  j,                  ddfdZdej*                  j,                  ddfdZddded   fdZded   defdZdefdZedefd       Z edefd       Z!edefd       Z"e#deeeeeeef   f   f   dddededdf
d       Z$e#e%	 	 	 d&de&eee'jP                  f      d e&e   de)fd!              Z*d'd"eee'jP                  f   d#efd$Z+y)(BaseGuidancezGBase class providing the skeleton for implementing guidance techniques.N__guidance_identifier__startstopc                 L   || _         || _        d | _        d | _        d | _        d| _        d | _        d| _        d|cxk  rdk  sn t        d| d      ||cxk  rdk  sn t        d| d| d      | j                  t        | j                  t              st        d	      y )
Nr   T              ?z4Expected `start` to be between 0.0 and 1.0, but got .zExpected `stop` to be between z and 1.0, but got z\`_input_predictions` must be a list of required prediction names for the guidance technique.)_start_stop_step_num_inference_steps	_timestep_count_prepared_input_fields_enabled
ValueError_input_predictions
isinstancelist)selfr   r   s      Y/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/guiders/guider_utils.py__init__zBaseGuidance.__init__+   s    

)-!+/ EIu"s"STYSZZ[\]]$$=eWDVW[V\\]^__""**T=T=TVZ2[n  3\    c                     d| _         y )NFr"   r'   s    r(   disablezBaseGuidance.disable?   s	    r*   c                     d| _         y )NTr,   r-   s    r(   enablezBaseGuidance.enableB   s	    r*   stepnum_inference_stepstimestepreturnc                 <    || _         || _        || _        d| _        y )Nr   )r   r   r   r    )r'   r1   r2   r3   s       r(   	set_statezBaseGuidance.set_stateE   s     
$7!! r*   kwargsc                 
   |j                         D ]i  \  }}t        |t              }t        |t              xr" t	        |      dk(  xr t        d |D              }|rM|rPt        dt        |       d| d       || _        y)a  
        Set the input fields for the guidance technique. The input fields are used to specify the names of the returned
        attributes containing the prepared data after `prepare_inputs` is called. The prepared data is obtained from
        the values of the provided keyword arguments to this method.

        Args:
            **kwargs (`Dict[str, Union[str, Tuple[str, str]]]`):
                A dictionary where the keys are the names of the fields that will be used to store the data once it is
                prepared with `prepare_inputs`. The values can be either a string or a tuple of length 2, which is used
                to look up the required data provided for preparation.

                If a string is provided, it will be used as the conditional data (or unconditional if used with a
                guidance method that requires it). If a tuple of length 2 is provided, the first element must be the
                conditional data identifier and the second element must be the unconditional data identifier or None.

                Example:
                ```
                data = {"prompt_embeds": <some tensor>, "negative_prompt_embeds": <some tensor>, "latents": <some tensor>}

                BaseGuidance.set_input_fields(
                    latents="latents",
                    prompt_embeds=("prompt_embeds", "negative_prompt_embeds"),
                )
                ```
        r   c              3   <   K   | ]  }t        |t                y wN)r%   str).0vs     r(   	<genexpr>z0BaseGuidance.set_input_fields.<locals>.<genexpr>h   s     Dg\]ZPQSVEWDgs   zcExpected `set_input_fields` to be called with a string or a tuple of string with length 2, but got z	 for key r   N)	itemsr%   r;   tuplelenallr#   typer!   )r'   r7   keyvalue	is_stringis_tuple_of_str_with_len_2s         r(   set_input_fieldszBaseGuidance.set_input_fieldsK   s    4 !,,. 	JC"5#.I5%(gSZ1_gDgafDgAg ' !; yz~  @E  {F  zG  GP  QT  PU  UV  W 	 $r*   denoiserc                 .    | xj                   dz  c_         y)z
        Prepares the models for the guidance technique on a given batch of data. This method should be overridden in
        subclasses to implement specific model preparation logic.
           N)r    r'   rI   s     r(   prepare_modelszBaseGuidance.prepare_modelsp   s    
 	!r*   c                      y)a*  
        Cleans up the models for the guidance technique after a given batch of data. This method should be overridden
        in subclasses to implement specific model cleanup logic. It is useful for removing any hooks or other stateful
        modifications made during `prepare_models`.
        N rL   s     r(   cleanup_modelszBaseGuidance.cleanup_modelsw   s     	r*   datar   c                     t        d      )Nz?BaseGuidance::prepare_inputs must be implemented in subclasses.NotImplementedError)r'   rQ   s     r(   prepare_inputszBaseGuidance.prepare_inputs   s    !"cddr*   c                 @   t        d |D              st        d      t        |      | j                  k7  r%t        d| j                   dt        |       d      |D ci c]#  }t	        || j
                        |j                  % }} | j                  di |S c c}w )Nc              3   4   K   | ]  }t        |d         yw)
noise_predN)hasattr)r<   ds     r(   r>   z(BaseGuidance.__call__.<locals>.<genexpr>   s     :71l+:s   z1Expected all data to have `noise_pred` attribute.z	Expected z data items, but got z. Please check the input data.rO   )rB   r#   rA   num_conditionsgetattr_identifier_keyrX   forward)r'   rQ   rZ   forward_inputss       r(   __call__zBaseGuidance.__call__   s    :T::PQQt9+++D//00Ec$i[Pno  SWWQ'!T%9%9:ALLHWWt||-n-- Xs   (Bc                     t        d      )Nz8BaseGuidance::forward must be implemented in subclasses.rS   )r'   argsr7   s      r(   r^   zBaseGuidance.forward   s    !"\]]r*   c                     t        d      )Nz?BaseGuidance::is_conditional must be implemented in subclasses.rS   r-   s    r(   is_conditionalzBaseGuidance.is_conditional       !"cddr*   c                     | j                    S r:   )rd   r-   s    r(   is_unconditionalzBaseGuidance.is_unconditional   s    &&&&r*   c                     t        d      )Nz?BaseGuidance::num_conditions must be implemented in subclasses.rS   r-   s    r(   r[   zBaseGuidance.num_conditions   re   r*   input_fieldstuple_index
identifierc                 d   ddl m} |t        d      i }|j                         D ]J  \  }}	 t	        |t
              rt        ||      ||<   n$t	        |t              rt        |||         ||<   n	 L ||| j                  <    |di |S # t        $ r t        j                  d| d       Y w xY w)a  
        Prepares a batch of data for the guidance technique. This method is used in the `prepare_inputs` method of the
        `BaseGuidance` class. It prepares the batch based on the provided tuple index.

        Args:
            input_fields (`Dict[str, Union[str, Tuple[str, str]]]`):
                A dictionary where the keys are the names of the fields that will be used to store the data once it is
                prepared with `prepare_inputs`. The values can be either a string or a tuple of length 2, which is used
                to look up the required data provided for preparation. If a string is provided, it will be used as the
                conditional data (or unconditional if used with a guidance method that requires it). If a tuple of
                length 2 is provided, the first element must be the conditional data identifier and the second element
                must be the unconditional data identifier or None.
            data (`BlockState`):
                The input data to be prepared.
            tuple_index (`int`):
                The index to use when accessing input fields that are tuples.

        Returns:
            `BlockState`: The prepared batch of data.
        r   r   zInput fields cannot be None. Please pass `input_fields` to `prepare_inputs` or call `set_input_fields` before preparing inputs.z"`data` does not have attribute(s) z, skipping.rO   )"modular_pipelines.modular_pipeliner   r#   r?   r%   r;   r\   r@   AttributeErrorloggerdebugr]   )	clsri   rQ   rj   rk   r   
data_batchrD   rE   s	            r(   _prepare_batchzBaseGuidance._prepare_batch   s    8 	D R  
&,,. 
	VJC	VeS)&-dE&:JsOu-&-dE+4F&GJsO 
	V +5
3&&''J'' " VA%TUVs   AB

"B/.B/pretrained_model_name_or_path	subfolderc                 b     | j                   d||ddd|\  }}} | j                  |fd|i|S )a4  
        Instantiate a guider from a pre-defined JSON configuration file in a local directory or Hub repository.

        Parameters:
            pretrained_model_name_or_path (`str` or `os.PathLike`, *optional*):
                Can be either:

                    - A string, the *model id* (for example `google/ddpm-celebahq-256`) of a pretrained model hosted on
                      the Hub.
                    - A path to a *directory* (for example `./my_model_directory`) containing the guider configuration
                      saved with [`~BaseGuidance.save_pretrained`].
            subfolder (`str`, *optional*):
                The subfolder location of a model file within a larger model repository on the Hub or locally.
            return_unused_kwargs (`bool`, *optional*, defaults to `False`):
                Whether kwargs that are not consumed by the Python class should be returned or not.
            cache_dir (`Union[str, os.PathLike]`, *optional*):
                Path to a directory where a downloaded pretrained model configuration is cached if the standard cache
                is not used.
            force_download (`bool`, *optional*, defaults to `False`):
                Whether or not to force the (re-)download of the model weights and configuration files, overriding the
                cached versions if they exist.

            proxies (`Dict[str, str]`, *optional*):
                A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128',
                'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
            output_loading_info(`bool`, *optional*, defaults to `False`):
                Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
            local_files_only(`bool`, *optional*, defaults to `False`):
                Whether to only load local model weights and configuration files or not. If set to `True`, the model
                won't be downloaded from the Hub.
            token (`str` or *bool*, *optional*):
                The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from
                `diffusers-cli login` (stored in `~/.huggingface`) is used.
            revision (`str`, *optional*, defaults to `"main"`):
                The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
                allowed by Git.

        <Tip>

        To use private or [gated models](https://huggingface.co/docs/hub/models-gated#gated-models), log-in with `hf
        auth login`. You can also activate the special
        ["offline-mode"](https://huggingface.co/diffusers/installation.html#offline-mode) to use this method in a
        firewalled environment.

        </Tip>

        T)rt   ru   return_unused_kwargsreturn_commit_hashrw   rO   )load_configfrom_config)rq   rt   ru   rw   r7   configcommit_hashs          r(   from_pretrainedzBaseGuidance.from_pretrained   sV    p '6coo '
*G!%#	'

 '
# sv[<P[TZ[[r*   save_directorypush_to_hubc                 .     | j                   d||d| y)a:  
        Save a guider configuration object to a directory so that it can be reloaded using the
        [`~BaseGuidance.from_pretrained`] class method.

        Args:
            save_directory (`str` or `os.PathLike`):
                Directory where the configuration JSON file will be saved (will be created if it does not exist).
            push_to_hub (`bool`, *optional*, defaults to `False`):
                Whether or not to push your model to the Hugging Face Hub after saving it. You can specify the
                repository you want to push to with `repo_id` (will default to the name of `save_directory` in your
                namespace).
            kwargs (`Dict[str, Any]`, *optional*):
                Additional keyword arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method.
        )r~   r   NrO   )save_config)r'   r~   r   r7   s       r(   save_pretrainedzBaseGuidance.save_pretrained  s     	ZKZSYZr*   )r   r   )NNF)F),__name__
__module____qualname____doc__GUIDER_CONFIG_NAMEconfig_namer$   r]   floatr)   r.   r0   inttorch
LongTensorr6   r   r;   r	   r   rH   nnModulerM   rP   r   rU   r   r`   r^   propertyboolrd   rg   r[   classmethodrs   r
   r   osPathLiker   r}   r   rO   r*   r(   r   r   $   sA   R$K/Oe  (!c ! !uGWGW !\` !#$c5eCHo9M3N.N)O #$TX #$J"uxx "4 "uxx 4 e< eD4F e.T,/ .C .^# ^ e e e '$ ' ' e e e .(3c5c?&: ;;<.( .( 	.(
 .( 
.( .(`  LP#'"	=\'/c2;;6F0G'H=\ C==\ 
=\  =\~[eC4D.E [TX [r*   r   c                     |j                  t        t        d|j                              d      }| j                  t        t        d| j                              d      }| ||z  z  }||z  d|z
  | z  z   } | S )a  
    Rescales `noise_cfg` tensor based on `guidance_rescale` to improve image quality and fix overexposure. Based on
    Section 3.4 from [Common Diffusion Noise Schedules and Sample Steps are
    Flawed](https://arxiv.org/pdf/2305.08891.pdf).

    Args:
        noise_cfg (`torch.Tensor`):
            The predicted noise tensor for the guided diffusion process.
        noise_pred_text (`torch.Tensor`):
            The predicted noise tensor for the text-guided diffusion process.
        guidance_rescale (`float`, *optional*, defaults to 0.0):
            A rescale factor applied to the noise predictions.
    Returns:
        noise_cfg (`torch.Tensor`): The rescaled noise prediction tensor.
    rK   T)dimkeepdim)stdr&   rangendim)	noise_cfgnoise_pred_textguidance_rescalestd_textstd_cfgnoise_pred_rescaleds         r(   rescale_noise_cfgr     s      ""tE!_5I5I,J'KUY"ZHmmU1inn%= >mMG#x''9: #66!>N:NR[9[[Ir*   )r   )r   typingr   r   r   r   r   r   r	   r   huggingface_hub.utilsr
   typing_extensionsr   configuration_utilsr   utilsr   r   rm   r   r   r   ro   r   r   rO   r*   r(   <module>r      sV    
 I I I  6 " - . ? *  
H	x[; x[vr*   