Diffusers documentation
使用 Mellon 搭配自定义块
使用 Mellon 搭配自定义块
Mellon 是一个可视化工作流界面,与 Modular Diffusers 集成,专为基于节点的工作流而设计。
Mellon 目前仍处于早期开发阶段,尚未准备好用于生产环境。请将其视为对集成方式的一次预览!
在 Mellon 中,自定义块开箱即用——只需在您的仓库中添加一个 mellon_pipeline_config.json 文件。该配置文件用于告知 Mellon 如何将您的块的参数渲染为 UI 组件。
以下是使用 Gemini Prompt Expander 块时的实际效果:

要在 Mellon 中使用模块化的 diffusers 自定义块:
- 从 ModularDiffusers 部分拖入一个 Dynamic Block Node
- 输入
repo_id(例如diffusers/gemini-prompt-expander-mellon) - 点击 加载自定义块
- 节点会变换以显示你方块的输入和输出
现在,让我们逐步了解如何为你自己的自定义块创建此配置。
创建 Mellon 配置的步骤
- 为参数指定 Mellon 类型 - 每个
InputParam/OutputParam都需要一个类型,用于告知 Mellon 应渲染哪个 UI 组件(例如"textbox"、"dropdown"、"image")。 - 生成
mellon_pipeline_config.json- 使用我们的工具生成配置模板并将其推送到您的 Hub 仓库。 - (可选)手动调整配置 - 根据您的具体需求微调生成的配置。
为参数指定 Mellon 类型
Mellon 类型决定了每个参数在 UI 中的渲染方式。如果未为某个参数指定类型,它将默认为 "custom",并渲染为一个简单的连接点。您始终可以在生成的配置中稍后调整此设置。
| 类型 | 输入/输出 | 描述 |
|---|---|---|
image | 两者 | 图像(PIL Image) |
video | 两者 | 视频 |
text | 两者 | 文本显示 |
textbox | 输入 | 文本输入 |
dropdown | 输入 | 下拉选择菜单 |
slider | 输入 | 用于数值的滑块 |
number | 输入 | 数值输入 |
checkbox | 输入 | 布尔切换 |
对于需要更多配置(例如带有选项的下拉菜单,或带有最小值/最大值的滑块)的参数,请直接传入 MellonParam 实例,而不是字符串。您可以使用下面的类方法之一,或者使用 MellonParam(name, label, type, ...) 创建一个完全自定义的实例。
| 方法 | 描述 |
|---|---|
MellonParam.Input.image(name) | 图像输入 |
MellonParam.Input.textbox(name, default) | 作为文本区域的文本输入 |
MellonParam.Input.dropdown(name, options, default) | 下拉选择 |
MellonParam.Input.slider(name, default, min, max, step) | 用于数值的滑块 |
MellonParam.Input.number(name, default, min, max, step) | 数值输入(无滑块) |
MellonParam.Input.seed(name, default) | 使用随机化按钮为输入设置随机种子 |
MellonParam.Input.checkbox(name, default) | 布尔复选框 |
MellonParam.Input.model(name) | diffusers 组件的模型输入 |
MellonParam.Output.image(name) | 图像输出 |
MellonParam.Output.video(name) | 视频输出 |
MellonParam.Output.text(name) | 文本输出 |
MellonParam.Output.model(name) | diffusers 组件的模型输出 |
选择以下方法之一来指定 Mellon 类型。
在块定义中使用元数据
如果您正在从头定义一个自定义块,请将 metadata={"mellon": "<type>"} 直接添加到您的 InputParam 和 OutputParam 定义中。如果您正在编辑 Hub 上现有的自定义块,请参阅 编辑自定义块 了解如何将其下载到本地。
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
)
]若要完全控制 UI 配置,请直接传入一个 MellonParam 实例:
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"])},
)在生成配置时使用 input_types 和 output_types
如果您正在使用现有的流水线,或者希望保持块定义简洁,可以在生成配置时使用 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"}
)当同时指定了
metadata和input_types/output_types时,参数会覆盖metadata。
生成并推送 Mellon 配置
向您的 block 添加元数据后,生成默认的 Mellon 配置模板并将其推送到 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
)这会在你的仓库中创建一个 mellon_pipeline_config.json 文件。
审查并调整配置
生成的模板是一个起点——您可能需要根据自身需求对其进行调整。下面我们来逐步了解 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"
}
}
}理解结构
params 字典定义了每个 UI 元素的渲染方式。input_names、model_input_names 和 output_names 列表将这些 UI 元素映射到底层 ModularPipelineBlocks 的 I/O 接口:
| Mellon 配置 | ModularPipelineBlocks |
|---|---|
input_names | inputs 属性 |
model_input_names | expected_components 属性 |
output_names | intermediate_outputs 属性 |
在此示例中:prompt 是唯一的输入。没有模型组件,输出包括 out_prompt、old_prompt 和 doc。
现在让我们来看看 params 字典:
prompt:一个输入参数,具有display: "textarea"(渲染为文本输入框)、label: "Prompt"(在 UI 中显示)以及default: ""(初始为空)。type: "string"字段在 Mellon 中非常重要,因为它决定了哪些节点可以连接在一起——只有类型匹配的节点才能通过“noodles”进行链接。out_prompt:扩展后的提示词输出。由于输入和输出共享相同的名称(prompt),系统自动添加了out_前缀,以避免配置中的命名冲突。它具有display: "output"属性,因此会渲染为输出插槽。old_prompt:由于我们未指定元数据,其类型为type: "custom"。在 UI 中,它会显示为一个简单的圆点。由于我们实际上并不希望在 UI 中暴露此项,因此可以将其移除。doc:文档输出,会自动添加到所有自定义块中。
进行调整
由于您不再需要使用 old_prompt,请将其从 params 和 output_names 中移除。
{
"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"
}
}
}最终配置请参见 diffusers/gemini-prompt-expander-mellon。
Update on GitHub