Diffusers documentation

Usando Blocos Personalizados com Mellon

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Usando Blocos Personalizados com Mellon

Mellon é uma interface de fluxo de trabalho visual que se integra ao Modular Diffusers e foi projetada para fluxos de trabalho baseados em nós.

Mellon está em desenvolvimento inicial e ainda não está pronto para uso em produção. Considere isso um vislumbre de como a integração funciona!

Blocos personalizados funcionam no Mellon sem necessidade de configuração adicional - basta adicionar um mellon_pipeline_config.json ao seu repositório. Este arquivo de configuração informa ao Mellon como renderizar os parâmetros do seu bloco como componentes de interface.

É assim que ele aparece em ação com o bloco Gemini Prompt Expander:

Mellon custom block demo

Para usar um bloco personalizado modular de diffusers no Mellon:

  1. Arraste um Dynamic Block Node da seção ModularDiffusers
  2. Insira o repo_id (por exemplo, diffusers/gemini-prompt-expander-mellon)
  3. Clique em Carregar Bloco Personalizado
  4. O nó se transforma para mostrar as entradas e saídas do seu bloco

Agora, vamos ver como criar essa configuração para o seu próprio bloco personalizado.

Etapas para criar uma configuração do Mellon

  1. Especifique os tipos Mellon para seus parâmetros - Cada InputParam/OutputParam precisa de um tipo que informe ao Mellon qual componente de interface a renderizar (por exemplo, "textbox", "dropdown", "image").
  2. Gerar mellon_pipeline_config.json - Use nossa utilidade para gerar um modelo de configuração e enviá-lo para seu repositório no Hub.
  3. (Opcional) Ajustar manualmente a configuração - Ajuste fino da configuração gerada para suas necessidades específicas.

Especifique os tipos Mellon para os parâmetros

Os tipos Mellon determinam como cada parâmetro é renderizado na interface. Se você não especificar um tipo para um parâmetro, ele usará o padrão "custom", que é renderizado como um ponto de conexão simples. Você pode ajustar isso a qualquer momento na configuração gerada.

TipoEntrada/SaídaDescrição
imageAmbosImagem (PIL Image)
videoAmbosVídeo
textAmbosExibição de texto
textboxEntradaEntrada de texto
dropdownEntradaMenu de seleção em lista suspensa
sliderEntradaSlider para valores numéricos
numberEntradaEntrada numérica
checkboxEntradaAlternância booleana

Para parâmetros que exigem mais configuração (como menus suspensos com opções ou controles deslizantes com valores mín/máx), passe uma instância de MellonParam diretamente em vez de uma string. Você pode usar um dos métodos de classe abaixo ou criar um totalmente personalizado com MellonParam(name, label, type, ...).

MétodoDescrição
MellonParam.Input.image(name)Entrada de imagem
MellonParam.Input.textbox(name, default)Entrada de texto como textarea
MellonParam.Input.dropdown(name, options, default)Seleção em menu suspenso
MellonParam.Input.slider(name, default, min, max, step)Slider para valores numéricos
MellonParam.Input.number(name, default, min, max, step)Entrada numérica (sem controle deslizante)
MellonParam.Input.seed(name, default)Entrada de semente com botão de aleatorização
MellonParam.Input.checkbox(name, default)Caixa de seleção booleana
MellonParam.Input.model(name)Entrada do modelo para componentes do diffusers
MellonParam.Output.image(name)Saída de imagem
MellonParam.Output.video(name)Saída de vídeo
MellonParam.Output.text(name)Saída de texto
MellonParam.Output.model(name)Saída do modelo para componentes do diffusers

Escolha um dos métodos abaixo para especificar um tipo Mellon.

Usando metadados em definições de bloco

Se você está definindo um bloco personalizado do zero, adicione metadata={"mellon": "<type>"} diretamente às suas definições de InputParam e OutputParam. Se você está editando um bloco personalizado existente do Hub, consulte Editando blocos personalizados para saber como baixá-lo localmente.

class GeminiPromptExpander(ModularPipelineBlocks):
    
    @property
    def inputs(self) -> List[InputParam]:
        return [
            InputParam(
                "prompt",
                type_hint=str,
                required=True,
                description="Prompt to use",
                metadata={"mellon": "textbox"},  # Text input
            )
        ]
    
    @property
    def intermediate_outputs(self) -> List[OutputParam]:
        return [
            OutputParam(
                "prompt",
                type_hint=str,
                description="Expanded prompt by the LLM",
                metadata={"mellon": "text"},  # Text output
            ),
            OutputParam(
                "old_prompt",
                type_hint=str,
                description="Old prompt provided by the user",
<CopyLLMTxtMenu containerStyle="float: inline-end; margin-inline-start: 10px; display: inline-flex; position: relative; z-index: 10;"></CopyLLMTxtMenu>

                # No metadata - we don't want to render this in UI
            )
        ]

Para ter controle total sobre a configuração da interface, passe uma instância de MellonParam diretamente:

from diffusers.modular_pipelines.mellon_node_utils import MellonParam

InputParam(
    "mode",
    type_hint=str,
    default="balanced",
    metadata={"mellon": MellonParam.Input.dropdown("mode", options=["fast", "balanced", "quality"])},
)

Usando input_types e output_types ao gerar Config

Se você está trabalhando com um pipeline existente ou prefere manter as definições de seus blocos limpas, especifique os tipos ao gerar a configuração usando o argumento input_types/output_types:

from diffusers.modular_pipelines.mellon_node_utils import MellonPipelineConfig

mellon_config = MellonPipelineConfig.from_custom_block(
    blocks,
    input_types={"prompt": "textbox"},
    output_types={"prompt": "text"}
)

Quando metadata e input_types/output_types são especificados, os argumentos substituem metadata.

Gere e envie a configuração do Mellon

Depois de adicionar metadados ao seu bloco, gere o modelo de configuração padrão do Mellon e envie-o para o Hub:

from diffusers import ModularPipelineBlocks
from diffusers.modular_pipelines.mellon_node_utils import MellonPipelineConfig

# load your custom blocks from your local dir
blocks = ModularPipelineBlocks.from_pretrained("/path/local/folder", trust_remote_code=True)

# Generate the default config template
mellon_config = MellonPipelineConfig.from_custom_block(blocks)
# push the default template to `repo_id`, you will need to pass the same local folder path so that it will save the config locally first
mellon_config.save(
    local_dir="/path/local/folder",
    repo_id= repo_id,
    push_to_hub=True
)

Isso cria um arquivo mellon_pipeline_config.json no seu repositório.

Revise e ajuste a configuração

O template gerado é um ponto de partida - você pode querer ajustá-lo para suas necessidades. Vamos analisar a configuração gerada para o Gemini Prompt Expander:

{
  "label": "Gemini Prompt Expander",
  "default_repo": "",
  "default_dtype": "",
  "node_params": {
    "custom": {
      "params": {
        "prompt": {
          "label": "Prompt",
          "type": "string",
          "display": "textarea",
          "default": ""
        },
        "out_prompt": {
          "label": "Prompt",
          "type": "string",
          "display": "output"
        },
        "old_prompt": {
          "label": "Old Prompt",
          "type": "custom",
          "display": "output"
        },
        "doc": {
          "label": "Doc",
          "type": "string",
          "display": "output"
        }
      },
      "input_names": ["prompt"],
      "model_input_names": [],
      "output_names": ["out_prompt", "old_prompt", "doc"],
      "block_name": "custom",
      "node_type": "custom"
    }
  }
}

Compreendendo a Estrutura

O dicionário params define como cada elemento de interface é renderizado. As listas input_names, model_input_names e output_names mapeiam esses elementos de interface para a interface de entrada/saída dos ModularPipelineBlocks subjacentes:

Configuração do MellonModularPipelineBlocks
input_namespropriedade inputs
model_input_namespropriedade expected_components
output_namespropriedade intermediate_outputs

Neste exemplo: prompt é a única entrada. Não há componentes de modelo, e as saídas incluem out_prompt, old_prompt e doc.

Agora, vamos examinar o dicionário params:

  • prompt: Um parâmetro de entrada com display: "textarea" (renderizado como uma caixa de entrada de texto), label: "Prompt" (exibido na interface) e default: "" (inicia vazio). O campo type: "string" é importante no Mellon porque determina quais nós podem ser conectados entre si - apenas tipos correspondentes podem ser vinculados com “noodles”.

  • out_prompt: A saída do prompt expandido. O prefixo out_ foi adicionado automaticamente porque a entrada e a saída compartilham o mesmo nome (prompt), evitando conflitos de nomenclatura na configuração. Ele possui display: "output", o que o renderiza como um soquete de saída.

  • old_prompt: Tem type: "custom" porque não especificamos metadados. Isso é renderizado como um ponto simples na interface. Como não queremos realmente expor isso na interface, podemos removê-lo.

  • doc: A saída da documentação, adicionada automaticamente a todos os blocos personalizados.

Fazendo Ajustes

Remova old_prompt de params e output_names, pois você não precisará usá-lo.

{
  "label": "Gemini Prompt Expander",
  "default_repo": "",
  "default_dtype": "",
  "node_params": {
    "custom": {
      "params": {
        "prompt": {
          "label": "Prompt",
          "type": "string",
          "display": "textarea",
          "default": ""
        },
        "out_prompt": {
          "label": "Prompt",
          "type": "string",
          "display": "output"
        },
        "doc": {
          "label": "Doc",
          "type": "string",
          "display": "output"
        }
      },
      "input_names": ["prompt"],
      "model_input_names": [],
      "output_names": ["out_prompt", "doc"],
      "block_name": "custom",
      "node_type": "custom"
    }
  }
}

Veja a configuração final em diffusers/gemini-prompt-expander-mellon.

Update on GitHub