Diffusers documentation
AutoPipelineBlocks
AutoPipelineBlocks
AutoPipelineBlocks は、異なるワークフローをサポートするブロックを含むマルチブロック型です。実行時に提供される入力に基づいて、実行するサブブロックを自動的に選択します。通常、テキストから画像への変換、画像から画像への変換、インペイントといった複数のワークフローを、利便性のため単一のパイプラインにパッケージ化する際に使用されます。
このガイドでは、AutoPipelineBlocksの作成方法を示します。
テキストから画像への変換、画像から画像への変換、インペインティングの3つのModularPipelineBlocksを作成します。これらは、パイプラインで利用可能な異なるワークフローを表しています。
import torch
from diffusers.modular_pipelines import ModularPipelineBlocks, InputParam, OutputParam
class TextToImageBlock(ModularPipelineBlocks):
model_name = "text2img"
@property
def inputs(self):
return [InputParam(name="prompt")]
@property
def intermediate_outputs(self):
return []
@property
def description(self):
return "I'm a text-to-image workflow!"
def __call__(self, components, state):
block_state = self.get_block_state(state)
print("running the text-to-image workflow")
# Add your text-to-image logic here
# For example: generate image from prompt
self.set_block_state(state, block_state)
return components, stateclass ImageToImageBlock(ModularPipelineBlocks):
model_name = "img2img"
@property
def inputs(self):
return [InputParam(name="prompt"), InputParam(name="image")]
@property
def intermediate_outputs(self):
return []
@property
def description(self):
return "I'm an image-to-image workflow!"
def __call__(self, components, state):
block_state = self.get_block_state(state)
print("running the image-to-image workflow")
# Add your image-to-image logic here
# For example: transform input image based on prompt
self.set_block_state(state, block_state)
return components, stateclass InpaintBlock(ModularPipelineBlocks):
model_name = "inpaint"
@property
def inputs(self):
return [InputParam(name="prompt"), InputParam(name="image"), InputParam(name="mask")]
@property
def intermediate_outputs(self):
return []
@property
def description(self):
return "I'm an inpaint workflow!"
def __call__(self, components, state):
block_state = self.get_block_state(state)
print("running the inpaint workflow")
# Add your inpainting logic here
# For example: fill masked areas based on prompt
self.set_block_state(state, block_state)
return components, stateサブブロックのクラスとその対応するブロック名のリストを含むAutoPipelineBlocksクラスを作成します。
また、対応するブロックをトリガーする入力名のリストであるblock_trigger_inputsを含める必要があります。実行時にトリガー入力が提供された場合、そのブロックが実行対象として選択されます。トリガー入力が検出されない場合に実行するデフォルトのブロックを指定するには、Noneを使用します。
最後に、どの入力がどのワークフローをトリガーするかを明確に説明するdescriptionを含めることが重要です。これにより、ユーザーは特定のワークフローの実行方法を理解しやすくなります。
from diffusers.modular_pipelines import AutoPipelineBlocks
class AutoImageBlocks(AutoPipelineBlocks):
# List of sub-block classes to choose from
block_classes = [InpaintBlock, ImageToImageBlock, TextToImageBlock]
# Names for each block in the same order
block_names = ["inpaint", "img2img", "text2img"]
# Trigger inputs that determine which block to run
# - "mask" triggers inpaint workflow
# - "image" triggers img2img workflow (but only if mask is not provided)
# - if none of above, runs the text2img workflow (default)
block_trigger_inputs = ["mask", "image", None]
@property
def description(self):
return (
"Pipeline generates images given different types of conditions!\n"
+ "This is an auto pipeline block that works for text2img, img2img and inpainting tasks.\n"
+ " - inpaint workflow is run when `mask` is provided.\n"
+ " - img2img workflow is run when `image` is provided (but only when `mask` is not provided).\n"
+ " - text2img workflow is run when neither `image` nor `mask` is provided.\n"
)ブロックの実行方法や必要な入力について混乱を避けるため、description を含めることは非常に重要です。AutoPipelineBlocks は便利ですが、適切に説明されていない場合、その条件分岐ロジックを理解するのが困難になる可能性があります。
AutoImageBlocksのインスタンスを作成します。
auto_blocks = AutoImageBlocks()
ネストされたAutoPipelineBlocksブロックがより大きなパイプライン内でサブブロックとして使用される場合など、より複雑な構成については、get_execution_blocks()メソッドを使用して、入力に基づいて実際に実行されるブロックを抽出してください。
auto_blocks.get_execution_blocks(mask=True)ConditionalPipelineBlocks
AutoPipelineBlocks は ConditionalPipelineBlocks の特殊なケースです。AutoPipelineBlocks はトリガー入力が提供されているかどうかに基づいてブロックを選択するのに対し、ConditionalPipelineBlocks は select_block メソッドで提供されるカスタムな選択ロジックに基づいてブロックを選択できます。
ConditionalPipelineBlocks を直接使用して記述した同じ例を以下に示します。
from diffusers.modular_pipelines import ConditionalPipelineBlocks
class AutoImageBlocks(ConditionalPipelineBlocks):
block_classes = [InpaintBlock, ImageToImageBlock, TextToImageBlock]
block_names = ["inpaint", "img2img", "text2img"]
block_trigger_inputs = ["mask", "image"]
default_block_name = "text2img"
@property
def description(self):
return (
"Pipeline generates images given different types of conditions!\n"
+ "This is an auto pipeline block that works for text2img, img2img and inpainting tasks.\n"
+ " - inpaint workflow is run when `mask` is provided.\n"
+ " - img2img workflow is run when `image` is provided (but only when `mask` is not provided).\n"
+ " - text2img workflow is run when neither `image` nor `mask` is provided.\n"
)
def select_block(self, mask=None, image=None) -> str | None:
if mask is not None:
return "inpaint"
if image is not None:
return "img2img"
return None # falls back to default_block_name ("text2img")block_trigger_inputs に列挙された入力は、select_block() へのキーワード引数として渡されます。select_block が None を返す場合、default_block_name にフォールバックします。default_block_name も None の場合、条件付きブロック全体がスキップされます。これは、特定の入力が提供された場合のみ実行されるべき任意の処理ステップに有用です。
ワークフロー
条件ブロック(AutoPipelineBlocksまたはConditionalPipelineBlocks)を含むパイプラインは、複数のワークフローをサポートできます。例えば、当社のSDXLモジュラーパイプラインでは、1つのパイプラインで12ものワークフローに対応しています。しかし、その一方で、ユーザーにとってサポートされているワークフローやその実行方法が分かりにくくなるという問題も生じます。パイプラインの構築者にとって、特定のワークフローに関連するブロックのみを抽出できることは有用です。
各ワークフローに名前を付け、必要な入力を明示的に列挙するために、_workflow_map を定義することをお勧めします。
from diffusers.modular_pipelines import SequentialPipelineBlocks
class MyPipelineBlocks(SequentialPipelineBlocks):
block_classes = [TextEncoderBlock, AutoImageBlocks, DecodeBlock]
block_names = ["text_encoder", "auto_image", "decode"]
_workflow_map = {
"text2image": {"prompt": True},
"image2image": {"image": True, "prompt": True},
"inpaint": {"mask": True, "image": True, "prompt": True},
}組み込みのモジュラーパイプラインにはすべて、事前定義されたワークフローが用意されています。available_workflowsプロパティは、サポートされているすべてのワークフローをリストします。
pipeline_blocks = MyPipelineBlocks()
pipeline_blocks.available_workflows
# ['text2image', 'image2image', 'inpaint']get_workflow を使用して特定のワークフローを取得し、そのワークフローを実行する特定のブロックを調査・デバッグします。
pipeline_blocks.get_workflow("inpaint")