o
    ۷i`                     @   s  d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	 d dl
mZmZmZmZmZmZ d dlZd dlZd dlmZmZ ddlmZmZ dd	lmZ dd
lmZmZmZ ddl m!Z! e rb	 e"e#Z$dZ%G dd deZ&eG dd dZ'eG dd dZ(i de)dddde)ddde*dddde*ddd e*d!dd"e*d#d$dd%e*d&d'dd(ej+d)dd*e,e- d+dd,e-d-d.dd/ej.j.e,ej.j. B dd0dd1ej/d2dd3ej/d4dd5e)d6d7dd8e0e)ef d9dd:dd:d;d<d=ej.j.dd>de*d?dej.j.dd@de-dAdBde-dCdDde-dCdEde*dFdGdej/ddHdej/ddIdej/dJdej/dKdej/ddLde*d&dMdej1ej2dNddOZ3e,ej.j. dPde,ej.j. dQdej/dRdej/d:dSdTej/d:dUdTej/d:dVdTej/d:dWdTej/dXddYZ4eG dZd[ d[Z5eG d\d] d]Z6d^d_ Z7d`da Z8ddddeZ9ddfdgZ:ddhdiZ;ddkdlZ<ddmdnZ=ddodpZ>dqdr Z?	s			ddtduZ@dvdw ZAdxdy ZBdze,eCe)e,e5 f  d{e,e5 fd|d}ZDd~e,eCe)e,e6 f  d{e,e6 fddZEd{e0e)ef fddZFdS )    N)OrderedDict)	dataclassfield)	UnionType)AnyLiteralTypeUnionget_args
get_origin)InvalidSpecifierSpecifierSet   )ConfigMixin
FrozenDict)_is_single_file_path_or_url)DIFFUSERS_LOAD_ID_FIELDSis_torch_availablelogging)_is_package_availablea  {model_description}

## Example Usage

[TODO]

## Pipeline Architecture

This modular pipeline is composed of the following blocks:

{blocks_description} {trigger_inputs_section}

## Model Components

{components_description} {configs_section}

{io_specification_section}
c                   @   s   e Zd Zdd Zdd ZdS )InsertableDictc                    sD   t |  } fdd|D }|| |f |   | | | S )Nc                    s    g | ]\}}| kr||fqS  r   .0kvkeyr   h/home/ubuntu/vllm_env/lib/python3.10/site-packages/diffusers/modular_pipelines/modular_pipeline_utils.py
<listcomp>@        z)InsertableDict.insert.<locals>.<listcomp>)listitemsinsertclearupdate)selfr   valueindexr"   r   r   r   r#   <   s   
zInsertableDict.insertc              	   C   s   | sdS g }t |  D ]4\}\}}t|tr#d|j d|j d}nd|jj d|jj d}|| dt| d| d qd	d
	| d S )NzInsertableDict()z<class '.z'>z<obj 'z: (, )zInsertableDict([
  z,
  z
]))
	enumerater"   
isinstancetype
__module____name__	__class__appendreprjoin)r&   r"   ir   r'   obj_reprr   r   r   __repr__L   s   
"zInsertableDict.__repr__N)r0   r/   __qualname__r#   r7   r   r   r   r   r   ;   s    r   c                   @   s  e Zd ZU dZdZedB ed< dZedB ed< dZ	edB ed< dZ
edB ed< edddid	Zeee B dB ed
< edddid	ZedB ed< edddid	ZedB ed< edddid	ZedB ed< dZed ed< edddid	Zeee B dB ed< dd Zdd Zdd ZedededefddZedee fddZedefd d!Zed"edeeedB f fd#d$Zd)deeeef B dB defd%d&Z defd'd(Z!dS )*ComponentSpeca=  Specification for a pipeline component.

    A component can be created in two ways:
    1. From scratch using __init__ with a config dict
    2. using `from_pretrained`

    Attributes:
        name: Name of the component
        type_hint: Type of the component (e.g. UNet2DConditionModel)
        description: Optional description of the component
        config: Optional config dict for __init__ creation
        pretrained_model_name_or_path: Optional pretrained_model_name_or_path path for from_pretrained creation
        subfolder: Optional subfolder in pretrained_model_name_or_path
        variant: Optional variant in pretrained_model_name_or_path
        revision: Optional revision in pretrained_model_name_or_path
        default_creation_method: Preferred creation method - "from_config" or "from_pretrained"
    Nname	type_hintdescriptionconfigloadingT)defaultmetadatapretrained_model_name_or_path 	subfoldervariantrevisionfrom_pretrained)from_configrF   default_creation_methodFrepoc                 C   s2   | j }|d ur| jd u rt| d| d S d S d S )NrA   )rI   rA   object__setattr__)r&   
repo_valuer   r   r   __post_init__   s   zComponentSpec.__post_init__c                 C   s   t | j| j| jfS )z=Make ComponentSpec hashable, using load_id as the hash value.)hashr:   load_idrH   r&   r   r   r   __hash__   s   zComponentSpec.__hash__c                 C   s2   t |tsdS | j|jko| j|jko| j|jkS )z8Compare ComponentSpec objects based on name and load_id.F)r-   r9   r:   rO   rH   )r&   otherr   r   r   __eq__   s   


zComponentSpec.__eq__	componentreturnc                 C   s   t |dr|jdkrd}n*t|tjjrtdt|tr*t |ds't	d d}ntd| d|j
j d	|j
}t|trG|dkrG|j}nd
}t |drZ|jdkrZ| |j}ni }| d||||d|S )a  Create a ComponentSpec from a Component.

        Currently supports:
        - Components created with `ComponentSpec.load()` method
        - Components that are ConfigMixin subclasses but not nn.Modules (e.g. schedulers, guiders)

        Args:
            name: Name of the component
            component: Component object to create spec from

        Returns:
            ComponentSpec object

        Raises:
            ValueError: If component is not supported (e.g. nn.Module without load_id, non-ConfigMixin)
        _diffusers_load_idnullrF   zeCannot create ComponentSpec from a nn.Module that was not created with `ComponentSpec.load()` method.z\Component was not created using `ComponentSpec`, defaulting to `from_config` creation methodrG   z!Cannot create ComponentSpec from (z). Currently ComponentSpec.from_component() only supports:  - components created with `ComponentSpec.load()` method - components that are a subclass of ConfigMixin but not a nn.Module (e.g. guider, scheduler).N)r:   r;   r=   rH   r   )hasattrrV   r-   torchnnModule
ValueErrorr   loggerwarningr1   r0   r=   decode_load_id)clsr:   rT   rH   r;   r=   	load_specr   r   r   from_component   s6   

zComponentSpec.from_componentc                 C   s   t  S )ux   
        Return the names of all loading‐related fields (i.e. those whose field.metadata["loading"] is True).
        )r   copy)ra   r   r   r   loading_fields   s   zComponentSpec.loading_fieldsc                    s<    j dkrdS  fdd  D }dd |D }d|S )z
        Unique identifier for this spec's pretrained load, composed of
        pretrained_model_name_or_path|subfolder|variant|revision (no empty segments).
        rG   rW   c                    s   g | ]}t  |qS r   )getattr)r   r   rP   r   r   r          z)ComponentSpec.load_id.<locals>.<listcomp>c                 S   s   g | ]
}|d u r
dn|qS )NrW   r   r   pr   r   r   r          |)rH   re   r4   )r&   partsr   rP   r   rO      s
   

zComponentSpec.load_idrO   c                 C   sb   |   }t|}|dkr|S |d}t|D ]\}}|t|k r.|dkr(dn|||| < q|S )a  
        Decode a load_id string back into a dictionary of loading fields and values.

        Args:
            load_id: The load_id string to decode, format: "pretrained_model_name_or_path|subfolder|variant|revision"
                     where None values are represented as "null"

        Returns:
            Dict mapping loading field names to their values. e.g. {
                "pretrained_model_name_or_path": "path/to/repo", "subfolder": "subfolder", "variant": "variant",
                "revision": "revision"
            } If a segment value is "null", it's replaced with None. Returns None if load_id is "null" (indicating
            component not created with `load` method).
        rW   rk   N)re   dictfromkeyssplitr,   len)ra   rO   re   resultrl   r5   partr   r   r   r`      s   

zComponentSpec.decode_load_idc                 K   s   | j du st| j tstd|p| jpi }t| j tr'| j j|fi |}n4t	| j j
j}i }| D ]\}}||v rA|||< q5| D ]\}}||v rR|||< qF| j di |}d|_t|drg|j| _|S )z/Create component using from_config with config.Nz?`type_hint` is required when using from_config creation method.rW   r=   r   )r;   r-   r.   r]   r=   
issubclassr   rG   inspect	signature__init__
parametersr"   rV   rY   )r&   r=   kwargsrT   signature_paramsinit_kwargsr   r   r   r   r   create
  s(   
zComponentSpec.createc              
      s   fdd  D fdd  D }|dd}|du r%tdt|}|r8jdu r8tdj jdurKtjtjj	sK dd jdu rzd	d
l
m} |j|fi | }W n tyz } ztdj d| d}~ww |j_n@|rtjdntjd}tjtjj	s dd z||fi | }W n ty } ztdj d| d}~ww |_| D ]
\}	}
t|	|
 qǈj|_|S )z%Load component using from_pretrained.c                    s    i | ]}| v r|  |qS r   )popr   r   )rx   r   r   
<dictcomp>)  r    z&ComponentSpec.load.<locals>.<dictcomp>c              	      s    i | ]}|  |t|qS r   )getrf   r}   )passed_loading_kwargsr&   r   r   r~   +  r    rA   Nz`pretrained_model_name_or_path` info is required when using `load` method (you can directly set it in `pretrained_model_name_or_path` field of the ComponentSpec or pass it as an argument)zW`type_hint` is required when loading a single file model but is missing for component: torch_dtyper   )	AutoModelzUnable to load z without `type_hint`: from_single_filerF   z using load method: )re   r|   r]   r   r;   r:   rs   rZ   r[   r\   	diffusersr   rF   	Exceptionr1   rf   rA   r"   setattrrO   rV   )r&   rx   load_kwargsrA   is_single_filer   rT   eload_methodr   r   r   )rx   r   r&   r   load&  sP   



	zComponentSpec.loadN)"r0   r/   r8   __doc__r:   str__annotations__r;   r   r<   r=   r   r   rA   r!   rC   rD   rE   rH   r   rI   rM   rQ   rS   classmethodr   rc   re   propertyrO   rm   r`   r{   r   r   r   r   r   r9   `   s2   
 $$
; $&r9   c                   @   s2   e Zd ZU dZeed< eed< dZedB ed< dS )
ConfigSpecz5Specification for a pipeline configuration parameter.r:   r?   Nr<   )r0   r/   r8   r   r   r   r   r<   r   r   r   r   r   b  s
   
 r   promptTz0The prompt or prompts to guide image generation.)r;   requiredr<   negative_promptz8The prompt or prompts not to guide the image generation.)r;   r<   max_sequence_lengthi   z,Maximum sequence length for prompt encoding.)r;   r?   r<   heightz,The height in pixels of the generated image.widthz+The width in pixels of the generated image.num_inference_steps2   zThe number of denoising steps.num_images_per_prompt   z,The number of images to generate per prompt.	generatorz-Torch generator for deterministic generation.sigmasz(Custom sigmas for the denoising process.strengthg?z Strength for img2img/inpainting.imagezJReference image(s) for denoising. Can be a single image or list of images.latentsz1Pre-generated noisy latents for image generation.	timestepsz$Timesteps for the denoising process.output_typepilz!Output format: 'pil', 'np', 'pt'.attention_kwargsz+Additional kwargs for attention processors.denoiser_input_fieldsz[conditional model inputs for the denoiser: e.g. prompt_embeds, negative_prompt_embeds, etc.)r:   kwargs_typer<   
mask_imagezMask image for inpainting.z(Padding for mask cropping in inpainting.z*Control image for ControlNet conditioning.g        z"When to start applying ControlNet.g      ?z!When to stop applying ControlNet.z"Scale for ControlNet conditioning.   z*Number of layers to extract from the imagez\text embeddings used to guide the image generation. Can be generated from text_encoder step.zFmask for the text embeddings. Can be generated from text_encoder step.zenegative text embeddings used to guide the image generation. Can be generated from text_encoder step.zOmask for the negative text embeddings. Can be generated from text_encoder step.zYimage latents used to guide the image generation. Can be generated from vae_encoder step.zNumber of prompts, the final batch size of model inputs should be batch_size * num_images_per_prompt. Can be generated in input step.z>The dtype of the model inputs, can be generated in input step.)padding_mask_cropcontrol_imagecontrol_guidance_startcontrol_guidance_endcontrolnet_conditioning_scalelayersprompt_embedsprompt_embeds_masknegative_prompt_embedsnegative_prompt_embeds_maskimage_latents
batch_sizedtypezGenerated images.zThe generated videos.zDenoised latents.zThe prompt embeddings.)r;   r   r<   zThe encoder attention mask.zThe negative prompt embeddings.z$The negative prompt embeddings mask.z-The latent representation of the input image.)imagesvideosr   r   r   r   r   r   c                   @   s   e Zd ZU dZdZeed< dZeed< dZ	eed< dZ
eed< dZeed	< dZeed
< dZeeef ed< dd Zeddededd fddZdS )
InputParamz%Specification for an input parameter.Nr:   r;   r?   Fr   rB   r<   r   r@   c                 C   s&   d| j  d| jr
dnd d| j dS )N<: r   optionalz
, default=>)r:   r   r?   rP   r   r   r   r7   5  s   &zInputParam.__repr__template_namenoterU   c                 K   x   |t vrtd| dt |  }|d|d|}|r.d|v r.|d  d| d|d< || | dd|i|S )	<Get template for name if exists, otherwise raise ValueError.zInputParam template for 
 not foundr:   r<    (r+   Nr   )INPUT_PARAM_TEMPLATESr]   rd   r|   r%   ra   r   r   	overridestemplate_kwargsr:   r   r   r   template8     
zInputParam.templater   )r0   r/   r8   r   r:   r   r   r;   r   r?   r   boolr<   r   r@   rm   r7   r   r   r   r   r   r   r   )  s   
 r   c                   @   sv   e Zd ZU dZeed< dZeed< dZeed< dZ	eed< dZ
eeef ed< d	d
 Zeddededd fddZdS )OutputParamz&Specification for an output parameter.r:   Nr;   rB   r<   r   r@   c                 C   s4   d| j  dt| jdr| jj dS t| j dS )Nr   r   r0   r   )r:   rY   r;   r0   r   rP   r   r   r   r7   W  s   "zOutputParam.__repr__r   r   rU   c                 K   r   )	r   zOutputParam template for r   r:   r<   r   r+   Nr   )OUTPUT_PARAM_TEMPLATESr]   rd   r|   r%   r   r   r   r   r   \  r   zOutputParam.templater   )r0   r/   r8   r   r   r   r;   r   r<   r   r@   rm   r7   r   r   r   r   r   r   r   M  s   
 r   c                 C   sf   dd | D }dd | D }d dd |D }d dd |D }|}|r1|r/| d| n|}|S )a  
    Format input parameters into a string representation, with required params first followed by optional ones.

    Args:
        inputs: list of input parameters with 'required' and 'name' attributes, and 'default' for optional params

    Returns:
        str: Formatted string of input parameters

    Example:
        >>> inputs = [ ... InputParam(name="prompt", required=True), ... InputParam(name="image", required=True), ...
        InputParam(name="guidance_scale", required=False, default=7.5), ... InputParam(name="num_inference_steps",
        required=False, default=50) ... ] >>> format_inputs_short(inputs) 'prompt, image, guidance_scale=7.5,
        num_inference_steps=50'
    c                 S   s   g | ]}|j r|qS r   r   r   paramr   r   r   r     rg   z'format_inputs_short.<locals>.<listcomp>c                 S   s   g | ]}|j s|qS r   r   r   r   r   r   r     rg   r*   c                 s   s    | ]}|j V  qd S r   r:   r   r   r   r   	<genexpr>  s    z&format_inputs_short.<locals>.<genexpr>c                 s   s"    | ]}|j  d |j V  qdS )=N)r:   r?   r   r   r   r   r     s     )r4   )inputsrequired_inputsoptional_inputsrequired_stroptional_str
inputs_strr   r   r   format_inputs_shortq  s   r   c                 C   s  g }| D ]*}|j |v r|d|j  d q|j du r&|jdur&d|j }n|j }|| qdd | D }g }g }|D ]}	|	j |v rJ||	j  q<||	j  q<g }
|r`|
dd|  |rm|
d	d|  |rz|
d
d|  |
rd|
S dS )aI  
    Formats intermediate inputs and outputs of a block into a string representation.

    Args:
        intermediate_inputs: list of intermediate input parameters
        required_intermediate_inputs: list of required intermediate input names
        intermediate_outputs: list of intermediate output parameters

    Returns:
        str: Formatted string like:
            Intermediates:
                - inputs: Required(latents), dtype
                - modified: latents # variables that appear in both inputs and outputs
                - outputs: images # new outputs only
    z	Required(r+   N*_c                 S   s   h | ]}|j qS r   r   )r   inpr   r   r   	<setcomp>  s    z-format_intermediates_short.<locals>.<setcomp>z    - inputs: r*   z    - modified: z    - outputs: 
z
    (none))r:   r2   r   r4   )intermediate_inputsrequired_intermediate_inputsintermediate_outputsinput_partsr   inp_name
inputs_setmodified_partsnew_output_partsoutrq   r   r   r   format_intermediates_short  s.   

r   Argss   c                 C   s@  | sdS d| }d|d  }d|d  }g }dd }dd }	| | | d	 | D ]p}
|
jtkr6||
jnd}|
jd
u rH|
jd
urHd|
j n|
j}| | d| d}t|
drn|
jsn|d7 }|
jd
urn|d|
j 7 }|d7 }|
jrt	
dd|
j}|	|||}|d| | 7 }n|d| d7 }| | q*d|S )a  Format a list of InputParam or OutputParam objects into a readable string representation.

    Args:
        params: list of InputParam or OutputParam objects to format
        header: Header text to use (e.g. "Args" or "Returns")
        indent_level: Number of spaces to indent each parameter line (default: 4)
        max_line_length: Maximum length for each line before wrapping (default: 115)

    Returns:
        A formatted string representing all parameters
    rB    r      c                 S   J   t | tst| tu rdd t| D }d|S t| dr!| jS t| S )Nc                 S   $   g | ]}t |d r|jnt|qS r0   rY   r0   r   r   tr   r   r   r        $ z7format_params.<locals>.get_type_str.<locals>.<listcomp> | r0   	r-   r   r   r	   r
   r4   rY   r0   r   r;   	type_strsr   r   r   get_type_str     
z#format_params.<locals>.get_type_strc           	      S   s   |   }g }g }d}|D ]-}t||rdnd }|r0|| |kr0|d| |g}t|}q|| ||7 }q|rD|d| d| |S )zFWrap text while preserving markdown links and maintaining indentation.r   r   r   r   )ro   rp   r2   r4   )	textindent
max_lengthwordslinescurrent_linecurrent_lengthwordword_lengthr   r   r   	wrap_text  s   


z format_params.<locals>.wrap_text:N** (``r   , *optional*z, defaults to z):z \[(.*?)\]\((https?://[^\s\)]+)\)z[\1](\2)r   zTODO: Add description.)r2   r;   r   r:   r   rY   r   r?   r<   resubr4   )paramsheaderindent_levelmax_line_lengthbase_indentparam_indentdesc_indentformatted_paramsr   r  r   type_strr:   	param_strdescwrapped_descr   r   r   format_params  s4   &


r  c                 C      t | d||S )a  Format a list of InputParam objects into a readable string representation.

    Args:
        input_params: list of InputParam objects to format
        indent_level: Number of spaces to indent each parameter line (default: 4)
        max_line_length: Maximum length for each line before wrapping (default: 115)

    Returns:
        A formatted string representing all input parameters
    Inputsr  )input_paramsr  r  r   r   r   format_input_params     r  c                 C   r  )a  Format a list of OutputParam objects into a readable string representation.

    Args:
        output_params: list of OutputParam objects to format
        indent_level: Number of spaces to indent each parameter line (default: 4)
        max_line_length: Maximum length for each line before wrapping (default: 115)

    Returns:
        A formatted string representing all output parameters
    Outputsr  )output_paramsr  r  r   r   r   format_output_params  r  r  r  c           	      C   s   | sdS dd }|rd| dgng }| D ]\}|j tkr!||j nd}|jdu r3|jdur3d|j n|j}d| d| d	}t|d
rY|jsY|d7 }|jdurY|d|j d	7 }|d7 }|jrc|jnd}|d| 7 }|| qd	|S )as  Format a list of InputParam or OutputParam objects as a markdown bullet-point list.

    Suitable for model cards rendered on Hugging Face Hub.

    Args:
        params: list of InputParam or OutputParam objects to format
        header: Header text (e.g. "Inputs" or "Outputs")

    Returns:
        A formatted markdown string, or empty string if params is empty.
    rB   c                 S   r   )Nc                 S   r   r   r   r   r   r   r   r   =  r   z@format_params_markdown.<locals>.get_type_str.<locals>.<listcomp>r   r0   r   r   r   r   r   r   ;  r   z,format_params_markdown.<locals>.get_type_strr  z:**
Nz- `z` (`r  r   r  z, defaults to `r+   zNo description providedr   r   )
r;   r   r:   r   rY   r   r?   r<   r2   r4   )	r
  r  r   r   r   r  r:   r  r  r   r   r   format_params_markdown,  s"   &

r   c                 C   s  | sdS d| }d|d  }g }| | d |r| d t| D ]d\}}t|jdr1|jjnt|j}	| |j d|	 d}
|jrL|
d|j 7 }
g }| D ]}t	||}|re| | d	|  qR|rs|
d
d
| d7 }
| |
 |r|t| d k r| d q#d
|S )a  Format a list of ComponentSpec objects into a readable string representation.

    Args:
        components: list of ComponentSpec objects to format
        indent_level: Number of spaces to indent each component line (default: 4)
        max_line_length: Maximum length for each line before wrapping (default: 115)
        add_empty_lines: Whether to add empty lines between components (default: True)

    Returns:
        A formatted string representing all components
    rB   r   r   zComponents:r0   r  `)r   r   z [r*   ]r   r   )r2   r,   rY   r;   r0   r   r:   r<   re   rf   r4   rp   )
componentsr  r  add_empty_linesr  component_indentformatted_componentsr5   rT   	type_namecomponent_descloading_field_values
field_namefield_valuer   r   r   format_componentsT  s6   




r,  c           
      C   s   | sdS d| }d|d  }g }| | d |r| d t| D ]/\}}| |j d|j d}	|jr>|	d|j 7 }	| |	 |rR|t| d k rR| d q#d	|S )
a  Format a list of ConfigSpec objects into a readable string representation.

    Args:
        configs: list of ConfigSpec objects to format
        indent_level: Number of spaces to indent each config line (default: 4)
        max_line_length: Maximum length for each line before wrapping (default: 115)
        add_empty_lines: Whether to add empty lines between configs (default: True)

    Returns:
        A formatted string representing all configs
    rB   r   r   zConfigs:z (default: r+   r   r   r   )r2   r,   r:   r?   r<   rp   r4   )
configsr  r  r$  r  config_indentformatted_configsr5   r=   config_descr   r   r   format_configs  s"   



r1  c                 C   s   | du rdS dg}|   D ].\}}dd |  D }|r2ddd |D }|d	| d
|  q|d	| d qd|S )zFormat a workflow map into a readable string representation.

    Args:
        workflow_map: Dictionary mapping workflow names to trigger inputs

    Returns:
        A formatted string representing all workflows
    NrB   zSupported workflows:c                 S   s   g | ]\}}|r|qS r   r   r   r   r   r   r         z#format_workflow.<locals>.<listcomp>r*   c                 s       | ]	}d | d V  qdS r  Nr   r   r   r   r   r         z"format_workflow.<locals>.<genexpr>z  - `z`: requires z*`: default (no additional inputs required)r   )r"   r4   r2   )workflow_mapr   workflow_nametrigger_inputsr   r   r   r   r   format_workflow  s   	
r9  rB   c                 C   s   d}|r|d| d7 }|r%|  d}ddd |D }||d 7 }|r:t|dkr:t|dd	d
}	||	d 7 }|rOt|dkrOt|dd	d
}
||
d 7 }|t| dd7 }|d7 }|t|dd7 }|S )a	  
    Generates a formatted documentation string describing the pipeline block's parameters and structure.

    Args:
        inputs: list of input parameters
        intermediate_inputs: list of intermediate input parameters
        outputs: list of output parameters
        description (str, *optional*): Description of the block
        class_name (str, *optional*): Name of the class to include in the documentation
        expected_components (list[ComponentSpec], *optional*): list of expected components
        expected_configs (list[ConfigSpec], *optional*): list of expected configurations

    Returns:
        str: A formatted string containing information about components, configs, call parameters,
            intermediate inputs/outputs, and final outputs.
    rB   zclass 

r   c                 s   s    | ]	}d |   V  qdS )z  N)rstripr   liner   r   r   r     r5  z"make_doc_string.<locals>.<genexpr>r   r   Fr  r$  )r  )stripro   r4   rp   r,  r1  r  r  )r   outputsr<   
class_nameexpected_componentsexpected_configsoutput
desc_linesaligned_desccomponents_strconfigs_strr   r   r   make_doc_string  s"   rI  c           	      C   s   | d u ri }nt | tstdt| }|si S i }| D ]_\}}t|\}}|s2t| d |ryzt|}W n t	yR } ztd| d| d|d }~ww |dkrdtd| d| d	 n|j
|d
dsyt| d| d| d |||< q|S )NzZRequirements must be provided as a dictionary mapping package names to version specifiers.zO was specified in the requirements but wasn't found in the current environment.zRequirement specifier 'z' for z is invalid.zN/AzVersion of z2 could not be determined to validate requirement 'z '. Things might work unexpected.T)prereleasesz requirement 'z,' is not satisfied by the installed version z. Things might work unexpected.)r-   rm   r]   _normalize_requirementsr"   r   r^   r_   r   r   contains)	reqsnormalized_reqsfinalreqspecified_verreq_availablereq_actual_ver	specifiererrr   r   r   _validate_requirements  s>   

rV  c                    s6   | si S t  dtttf f fdd  |  S )Nmappingc                    s  |   D ]\}}t|tr | qt| }|std|d u r$dnt| }|r6|ds6d| }|}|d ur|sH|rH||< n8|r|r||krztd	t
d ||g}W n tyy   td| d| d| d	| d
	 Y nw t||< q||< qd S )Nz)Requirement package name cannot be empty.rB   )r   r   r   !~z==,zConflicting requirements for 'z' detected: 'z' vs 'z'. Keeping 'z'.)r"   r-   rm   r   r?  r]   
startswithr   r   r4   filterr   r^   r_   )rW  pkgspecpkg_namespec_strexisting_speccombined_spec_accumulate
normalizedr   r   rd  .  s4   




z,_normalize_requirements.<locals>._accumulate)r   rm   r   r   )rM  r   rc  r   rK  (  s   !rK  named_input_listsrU   c                  G   s   i }i }| D ]l\}}|D ]e}|j du r|jdurd|j }n|j }||v ri|| }|jdurV|jdurV|j|jkrVtd| d|j d||  d|j d| d|j d |jdu rh|jdurh|||< |||< q|||< |||< qqt| S )	a  
    Combines multiple lists of InputParam objects from different blocks. For duplicate inputs, updates only if current
    default value is None and new default value is not None. Warns if multiple non-None default values exist for the
    same input.

    Args:
        named_input_lists: List of tuples containing (block_name, input_param_list) pairs

    Returns:
        List[InputParam]: Combined list of unique InputParam objects
    Nr   z3Multiple different default values found for input 'z': z (from block 'z') and z
'). Using r)   )r:   r   r?   warningswarnr!   values)rf  combined_dictvalue_sources
block_namer   input_param
input_namecurrent_paramr   r   r   combine_inputsT  sB   


rp  named_output_listsc                  G   sV   i }| D ] \}}|D ]}|j |vs||j  jdu r#|jdur#|||j < q
qt| S )aV  
    Combines multiple lists of OutputParam objects from different blocks. For duplicate outputs, keeps the first
    occurrence of each output name.

    Args:
        named_output_lists: List of tuples containing (block_name, output_param_list) pairs

    Returns:
        List[OutputParam]: Combined list of unique OutputParam objects
    N)r:   r   r!   ri  )rq  rj  rl  r@  output_paramr   r   r   combine_outputs  s   

rs  c           0   	      s2  | j j}|dd}t| dd}g }t| ddpi }|rWt| D ]4\}\}}|j j}	t|ddr:|jdd	 nd}
||d
  d| d|	 d |
rV|d|
  q"|r^d	|nd}t| dg }|rt
|d	dd}|dd }|rdd |dD }dd t|D }d	|}nd}nd}t| dg }d}|rt|d	dd}|dd }|rd| }t| dddu}|r|| j}g }| j}t| dd}|dur||kr|nd}|d | D ]^\}}t|  z| |}W n ty   |d| d  |d! |d" Y qw |j} fd#d|D }|d| d  t|dd$} || r6| nd% |d |d" q| j}!|durN|n| j}"t|!d&} t|"d'}#| r`| nd(}$|#rg|#nd)}%|d*|$ d+|%  d	|}&d}'nO| j}(| j})t|(d&} t|)d'}#| r| nd(}$|#r|#nd)}%d,|$ d+|% }&d}'t| d-r| jrtd.d | jD }*|*rd/	d0d1 |*D }+d2|+ d}'d3d4g},t| d5r| jr|,| j |r&t| j }-td6d1 |-D r|,d7 td8d1 |-D r|,d9 td:d1 |-D r|,d; td<d1 |-D r%|,d= nWt| d-rx| jrx| jtfd>d1d?D rD|,d7 tfd@d1dAD rU|,d9 tfdBd1dCD rf|,d; tfdDd1dED sw|,d= n|,d= t| j}.dF| dG| dH|. dI}/||/||||&|'|,dJS )Ka  
    Generate model card content for a modular pipeline.

    This function creates a comprehensive model card with descriptions of the pipeline's architecture, components,
    configurations, inputs, and outputs.

    Args:
        blocks: The pipeline's blocks object containing all pipeline specifications

    Returns:
        Dict[str, Any]: A dictionary containing formatted content sections:
            - pipeline_name: Name of the pipeline
            - model_description: Overall description with pipeline type
            - blocks_description: Detailed architecture of blocks
            - components_description: List of required components
            - configs_section: Configuration parameters section
            - io_specification_section: Input/Output specification (per-workflow or unified)
            - trigger_inputs_section: Conditional execution information
            - tags: List of relevant tags for the model card
    Blocksz	 Pipeliner<   zA modular diffusion pipeline.
sub_blocksNrB   r   r   r   z. **z** (`r!  z   - zNo blocks defined.rB  Fr>  zComponents:
c                 S   s   g | ]
}|  r|  qS r   )r?  r<  r   r   r   r     rj   z7generate_modular_model_card_content.<locals>.<listcomp>c                 S   s"   g | ]\}}|d   d| qS )r   z. r   )r   r5   r=  r   r   r   r     s   " z No specific components required.zFNo specific components required. Components can be loaded dynamically.rC  z	Configs:
z

## Configuration Parameters

_workflow_mapr   z ## Workflow Input Specification
z<details>
<summary><strong>z</strong></summary>
z%*Could not resolve workflow blocks.*
z</details>
c                    s   g | ]	}|j  v r|qS r   r   rh   )trigger_input_namesr   r   r     s    )r  zNo additional inputs required.r  r  zNo specific inputs defined.zStandard pipeline outputs.z 
## Input/Output Specification

r:  z## Input/Output Specification

r8  c                 S   s   g | ]}|d ur|qS r   r   r   r   r   r   r     r2  r*   c                 s   r3  r4  r   r   r   r   r   r     r5  z6generate_modular_model_card_content.<locals>.<genexpr>z~
### Conditional Execution

This pipeline contains blocks that are selected at runtime based on inputs:
- **Trigger Inputs**: zmodular-diffusersr   
model_namec                 s       | ]}d |v V  qdS )
inpaintingNr   r   wfr   r   r   r   (      rz  c                 s   ry  )image2imageNr   r{  r   r   r   r   *  r}  zimage-to-imagec                 s   ry  )
controlnetNr   r{  r   r   r   r   ,  r}  r  c                 s   ry  )
text2imageNr   r{  r   r   r   r   .  r}  ztext-to-imagec                 3       | ]}| v V  qd S r   r   r   triggersr   r   r   2  r}  )maskr   c                 3   r  r   r   r   r  r   r   r   4  r}  )r   r   c                 3   r  r   r   r   r  r   r   r   6  r}  )r   controlnet_condc                 3   r  r   r   r   r  r   r   r   8  r}  )r   r  r   r   up   This is a modular diffusion pipeline built with 🧨 Diffusers' modular pipeline framework.

**Pipeline Type**: z

**Description**: z

This pipeline uses a z8-block architecture that can be customized and extended.)pipeline_namemodel_descriptionblocks_descriptioncomponents_descriptionconfigs_sectionio_specification_sectiontrigger_inputs_sectiontags)r1   r0   replacerf   r,   r"   r<   ro   r2   r4   r,  r?  r1  rv  r@  setkeysget_workflowr   r   r   rY   r8  sortedrx  anyrp   ru  )0blocksblocks_class_namer  r<   blocks_desc_partsru  r5   r:   blockblock_class
block_descr  r#  rG  r  r   enumerated_linesr-  r  rH  configs_descriptionhas_workflowsr6  rl   blocks_outputsblocks_intermediateshared_outputswf_namer8  workflow_blocks	wf_inputstrigger_paramsr   
all_inputsall_outputsoutputs_strinputs_descriptionoutputs_descriptionr  r  r   r@  trigger_inputs_listtrigger_inputs_strr  workflow_namesblock_countr  r   )rw  r  r   #generate_modular_model_card_content  s     



















	r  )r   r   r   )r   r   )r  )r   r   T)rB   NNN)Grt   r  rg  collectionsr   dataclassesr   r   typesr   typingr   r   r   r	   r
   r   	PIL.ImagePILrZ   packaging.specifiersr   r   configuration_utilsr   r   loaders.single_file_utilsr   utilsr   r   r   utils.import_utilsr   
get_loggerr0   r^   MODULAR_MODEL_CARD_TEMPLATEr   r9   r   r   int	Generatorr!   floatImageTensorrm   r   float32r   r   r   r   r   r   r  r  r  r   r,  r1  r9  rI  rV  rK  tuplerp  rs  r  r   r   r   r   <module>   s   
%  
!%).37;@
DJP  

)##
2
P


(
7&
8'&,&+