Buckets:

mishig's picture
|
download
raw
10.3 kB
## 使用 Mellon 搭配自定义块
[Mellon](https://github.com/cubiq/Mellon) 是一个可视化工作流界面,与 Modular Diffusers 集成,专为基于节点的工作流而设计。
> [!WARNING]
> Mellon 目前仍处于早期开发阶段,尚未准备好用于生产环境。请将其视为对集成方式的一次预览!
在 Mellon 中,自定义块开箱即用——只需在您的仓库中添加一个 `mellon_pipeline_config.json` 即可。该配置文件用于告知 Mellon 如何将您块的参数渲染为 UI 组件。
以下是使用 [Gemini Prompt Expander](https://huggingface.co/diffusers/gemini-prompt-expander-mellon) 块时的实际效果:
![Mellon custom block demo](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/modular_demo_dynamic.gif)
要在 Mellon 中使用模块化的 diffusers 自定义块:
1. 从 ModularDiffusers 部分拖入一个 **Dynamic Block Node**
2. 输入 `repo_id`(例如 `diffusers/gemini-prompt-expander-mellon`)
3. 点击 **加载自定义块**
4. 节点会变换以显示您块的输入和输出
现在,让我们逐步讲解如何为你自己的自定义块创建此配置。
## 创建 Mellon 配置的步骤
1. **为参数指定 Mellon 类型** - 每个 `InputParam`/`OutputParam` 都需要一个类型,用于告知 Mellon 应渲染哪个 UI 组件(例如 `"textbox"`、`"dropdown"`、`"image"`)。
2. **生成 `mellon_pipeline_config.json`** - 使用我们的工具生成配置模板并将其推送到您的 Hub 仓库。
3. **(可选)手动调整配置** - 根据您的具体需求微调生成的配置。
## 为参数指定 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`
如果您正在从头定义一个自定义块,请直接在 `InputParam` 和 `OutputParam` 定义中添加 `metadata={"mellon": "<type>"}`。如果您正在编辑 Hub 上现有的自定义块,请参阅 [编辑自定义块](./custom_blocks#editing-custom-blocks) 了解如何将其下载到本地。
```python
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` 实例:
```python
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` 参数指定类型:
```python
from diffusers.modular_pipelines.mellon_node_utils import MellonPipelineConfig
mellon_config = MellonPipelineConfig.from_custom_block(
blocks,
input_types={"prompt": "textbox"},
output_types={"prompt": "text"}
)
```
> [!NOTE]
> 当同时指定了 `metadata` 和 `input_types`/`output_types` 时,参数会覆盖 `metadata`。
## 生成并推送 Mellon 配置
向您的 block 添加元数据后,生成默认的 Mellon 配置模板并将其推送到 Hub:
```python
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 的生成配置:
```json
{
"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](/docs/diffusers/v0.43.0/zh/api/modular_diffusers/pipeline_blocks#diffusers.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` 中移除。
```json
{
"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](https://huggingface.co/diffusers/gemini-prompt-expander-mellon)。

Xet Storage Details

Size:
10.3 kB
·
Xet hash:
0de93199560175b3c53d1f4e16d5861885936177dc4c2d6686d6abde9b09f290

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.