Buckets:

hf-doc-build/doc-dev / diffusers /pr_11986 /en /modular_diffusers /loop_sequential_pipeline_blocks.html
download
raw
27.9 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;LoopSequentialPipelineBlocks&quot;,&quot;local&quot;:&quot;loopsequentialpipelineblocks&quot;,&quot;sections&quot;:[],&quot;depth&quot;:1}">
<link href="/docs/diffusers/pr_11986/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/entry/start.e4c568fa.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/scheduler.8c3d61f6.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/singletons.59c211be.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/index.0997d446.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/paths.38f9cd8e.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/entry/app.29bdf47f.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/index.da70eac4.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/nodes/0.f8d125de.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/each.e59479a4.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/nodes/227.c794fdec.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/Tip.1d9b8c37.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/CodeBlock.a9c4becf.js">
<link rel="modulepreload" href="/docs/diffusers/pr_11986/en/_app/immutable/chunks/getInferenceSnippets.366c2c95.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;LoopSequentialPipelineBlocks&quot;,&quot;local&quot;:&quot;loopsequentialpipelineblocks&quot;,&quot;sections&quot;:[],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <h1 class="relative group"><a id="loopsequentialpipelineblocks" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#loopsequentialpipelineblocks"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>LoopSequentialPipelineBlocks</span></h1> <div class="course-tip course-tip-orange bg-gradient-to-br dark:bg-gradient-to-r before:border-orange-500 dark:before:border-orange-800 from-orange-50 dark:from-gray-900 to-white dark:to-gray-950 border border-orange-50 text-orange-700 dark:text-gray-400"><p data-svelte-h="svelte-11qh5l3">🧪 <strong>Experimental Feature</strong>: Modular Diffusers is an experimental feature we are actively developing. The API may be subject to breaking changes.</p></div> <p data-svelte-h="svelte-xl9zk8"><code>LoopSequentialPipelineBlocks</code> is a subclass of <code>ModularPipelineBlocks</code>. It is a multi-block that composes other blocks together in a loop, creating iterative workflows where blocks run multiple times with evolving state. It’s particularly useful for denoising loops requiring repeated execution of the same blocks.</p> <div class="course-tip bg-gradient-to-br dark:bg-gradient-to-r before:border-green-500 dark:before:border-green-800 from-green-50 dark:from-gray-900 to-white dark:to-gray-950 border border-green-50 text-green-700 dark:text-gray-400"><p data-svelte-h="svelte-z7v1cx">Other types of multi-blocks include <a href="./sequential_pipeline_blocks.md">SequentialPipelineBlocks</a> (for linear workflows) and <a href="./auto_pipeline_blocks.md">AutoPipelineBlocks</a> (for conditional block selection). For information on creating individual blocks, see the <a href="./pipeline_block.md">PipelineBlock guide</a>.</p> <p data-svelte-h="svelte-1hzjjr4">Additionally, like all <code>ModularPipelineBlocks</code>, <code>LoopSequentialPipelineBlocks</code> are definitions/specifications, not runnable pipelines. You need to convert them into a <code>ModularPipeline</code> to actually execute them. For information on creating and running pipelines, see the <a href="modular_pipeline.md">Modular Pipeline guide</a>.</p></div> <p data-svelte-h="svelte-1vaq9ea">You could create a loop using <code>PipelineBlock</code> like this:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">class</span> <span class="hljs-title class_">DenoiseLoop</span>(<span class="hljs-title class_ inherited__">PipelineBlock</span>):
<span class="hljs-keyword">def</span> <span class="hljs-title function_">__call__</span>(<span class="hljs-params">self, components, state</span>):
block_state = self.get_block_state(state)
<span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(block_state.num_inference_steps):
<span class="hljs-comment"># ... loop logic here</span>
<span class="hljs-keyword">pass</span>
self.set_block_state(state, block_state)
<span class="hljs-keyword">return</span> components, state<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1rdiz9k">But in this tutorial, we will focus on how to use <code>LoopSequentialPipelineBlocks</code> to create a “composable” denoising loop where you can add or remove blocks within the loop or reuse the same loop structure with different block combinations.</p> <p data-svelte-h="svelte-6557vk">It involves two parts: a <strong>loop wrapper</strong> and <strong>loop blocks</strong></p> <ul data-svelte-h="svelte-17nq7um"><li><p>The <strong>loop wrapper</strong> (<code>LoopSequentialPipelineBlocks</code>) defines the loop structure, e.g. it defines the iteration variables, and loop configurations such as progress bar.</p></li> <li><p>The <strong>loop blocks</strong> are basically standard pipeline blocks you add to the loop wrapper.</p> <ul><li>they run sequentially for each iteration of the loop</li> <li>they receive the current iteration index as an additional parameter</li> <li>they share the same block_state throughout the entire loop</li></ul></li></ul> <p data-svelte-h="svelte-rtau3w">Unlike regular <code>SequentialPipelineBlocks</code> where each block gets its own state, loop blocks share a single state that persists and evolves across iterations.</p> <p data-svelte-h="svelte-1qv8b">We will build a simple loop block to demonstrate these concepts. Creating a loop block involves three steps:</p> <ol data-svelte-h="svelte-1dhss6s"><li>defining the loop wrapper class</li> <li>creating the loop blocks</li> <li>adding the loop blocks to the loop wrapper class to create the loop wrapper instance</li></ol> <p data-svelte-h="svelte-ulnx8p"><strong>Step 1: Define the Loop Wrapper</strong></p> <p data-svelte-h="svelte-1en1jzl">To create a <code>LoopSequentialPipelineBlocks</code> class, you need to define:</p> <ul data-svelte-h="svelte-16l6cn8"><li><code>loop_inputs</code>: User input variables (equivalent to <code>PipelineBlock.inputs</code>)</li> <li><code>loop_intermediate_inputs</code>: Intermediate variables needed from the mutable pipeline state (equivalent to <code>PipelineBlock.intermediates_inputs</code>)</li> <li><code>loop_intermediate_outputs</code>: New intermediate variables this block will add to the mutable pipeline state (equivalent to <code>PipelineBlock.intermediates_outputs</code>)</li> <li><code>__call__</code> method: Defines the loop structure and iteration logic</li></ul> <p data-svelte-h="svelte-1xspfpu">Here is an example of a loop wrapper:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">from</span> diffusers.modular_pipelines <span class="hljs-keyword">import</span> LoopSequentialPipelineBlocks, PipelineBlock, InputParam, OutputParam
<span class="hljs-keyword">class</span> <span class="hljs-title class_">LoopWrapper</span>(<span class="hljs-title class_ inherited__">LoopSequentialPipelineBlocks</span>):
model_name = <span class="hljs-string">&quot;test&quot;</span>
<span class="hljs-meta"> @property</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">description</span>(<span class="hljs-params">self</span>):
<span class="hljs-keyword">return</span> <span class="hljs-string">&quot;I&#x27;m a loop!!&quot;</span>
<span class="hljs-meta"> @property</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">loop_inputs</span>(<span class="hljs-params">self</span>):
<span class="hljs-keyword">return</span> [InputParam(name=<span class="hljs-string">&quot;num_steps&quot;</span>)]
<span class="hljs-meta"> @torch.no_grad()</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">__call__</span>(<span class="hljs-params">self, components, state</span>):
block_state = self.get_block_state(state)
<span class="hljs-comment"># Loop structure - can be customized to your needs</span>
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(block_state.num_steps):
<span class="hljs-comment"># loop_step executes all registered blocks in sequence</span>
components, block_state = self.loop_step(components, block_state, i=i)
self.set_block_state(state, block_state)
<span class="hljs-keyword">return</span> components, state<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-15g49vj"><strong>Step 2: Create Loop Blocks</strong></p> <p data-svelte-h="svelte-e0yaqv">Loop blocks are standard <code>PipelineBlock</code>s, but their <code>__call__</code> method works differently:</p> <ul data-svelte-h="svelte-y66e4"><li>It receives the iteration variable (e.g., <code>i</code>) passed by the loop wrapper</li> <li>It works directly with <code>block_state</code> instead of pipeline state</li> <li>No need to call <code>self.get_block_state()</code> or <code>self.set_block_state()</code></li></ul> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">class</span> <span class="hljs-title class_">LoopBlock</span>(<span class="hljs-title class_ inherited__">PipelineBlock</span>):
<span class="hljs-comment"># this is used to identify the model family, we won&#x27;t worry about it in this example</span>
model_name = <span class="hljs-string">&quot;test&quot;</span>
<span class="hljs-meta"> @property</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">inputs</span>(<span class="hljs-params">self</span>):
<span class="hljs-keyword">return</span> [InputParam(name=<span class="hljs-string">&quot;x&quot;</span>)]
<span class="hljs-meta"> @property</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">intermediate_outputs</span>(<span class="hljs-params">self</span>):
<span class="hljs-comment"># outputs produced by this block</span>
<span class="hljs-keyword">return</span> [OutputParam(name=<span class="hljs-string">&quot;x&quot;</span>)]
<span class="hljs-meta"> @property</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">description</span>(<span class="hljs-params">self</span>):
<span class="hljs-keyword">return</span> <span class="hljs-string">&quot;I&#x27;m a block used inside the `LoopWrapper` class&quot;</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">__call__</span>(<span class="hljs-params">self, components, block_state, i: <span class="hljs-built_in">int</span></span>):
block_state.x += <span class="hljs-number">1</span>
<span class="hljs-keyword">return</span> components, block_state<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1c5cx58"><strong>Step 3: Combine Everything</strong></p> <p data-svelte-h="svelte-qvme9r">Finally, assemble your loop by adding the block(s) to the wrapper:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->loop = LoopWrapper.from_blocks_dict({<span class="hljs-string">&quot;block1&quot;</span>: LoopBlock})<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-gx44pi">Now you’ve created a loop with one step:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">&gt;&gt;&gt; </span>loop
LoopWrapper(
Class: LoopSequentialPipelineBlocks
Description: I<span class="hljs-string">&#x27;m a loop!!
Sub-Blocks:
[0] block1 (LoopBlock)
Description: I&#x27;</span>m a block used inside the `LoopWrapper` <span class="hljs-keyword">class</span>
)<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-bwerrz">It has two inputs: <code>x</code> (used at each step within the loop) and <code>num_steps</code> used to define the loop.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-built_in">print</span>(loop.doc)
<span class="hljs-keyword">class</span> <span class="hljs-title class_">LoopWrapper</span>
I<span class="hljs-string">&#x27;m a loop!!
Inputs:
x (`None`, *optional*):
num_steps (`None`, *optional*):
Outputs:
x (`None`):</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1ickhlt"><strong>Running the Loop:</strong></p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># run the loop</span>
loop_pipeline = loop.init_pipeline()
x = loop_pipeline(num_steps=<span class="hljs-number">10</span>, x=<span class="hljs-number">0</span>, output=<span class="hljs-string">&quot;x&quot;</span>)
<span class="hljs-keyword">assert</span> x == <span class="hljs-number">10</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-c9iaqy"><strong>Adding Multiple Blocks:</strong></p> <p data-svelte-h="svelte-y0dhln">We can add multiple blocks to run within each iteration. Let’s run the loop block twice within each iteration:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->loop = LoopWrapper.from_blocks_dict({<span class="hljs-string">&quot;block1&quot;</span>: LoopBlock(), <span class="hljs-string">&quot;block2&quot;</span>: LoopBlock})
loop_pipeline = loop.init_pipeline()
x = loop_pipeline(num_steps=<span class="hljs-number">10</span>, x=<span class="hljs-number">0</span>, output=<span class="hljs-string">&quot;x&quot;</span>)
<span class="hljs-keyword">assert</span> x == <span class="hljs-number">20</span> <span class="hljs-comment"># Each iteration runs 2 blocks, so 10 iterations * 2 = 20</span><!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-10vcc97"><strong>Key Differences from SequentialPipelineBlocks:</strong></p> <p data-svelte-h="svelte-1wopqg">The main difference is that loop blocks share the same <code>block_state</code> across all iterations, allowing values to accumulate and evolve throughout the loop. Loop blocks could receive additional arguments (like the current iteration index) depending on the loop wrapper’s implementation, since the wrapper defines how loop blocks are called. You can easily add, remove, or reorder blocks within the loop without changing the loop logic itself.</p> <p data-svelte-h="svelte-1f0i3fw">The officially supported denoising loops in Modular Diffusers are implemented using <code>LoopSequentialPipelineBlocks</code>. You can explore the actual implementation to see how these concepts work in practice:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> diffusers.modular_pipelines.stable_diffusion_xl.denoise <span class="hljs-keyword">import</span> StableDiffusionXLDenoiseStep
StableDiffusionXLDenoiseStep()<!-- HTML_TAG_END --></pre></div> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/diffusers/blob/main/docs/source/en/modular_diffusers/loop_sequential_pipeline_blocks.md" target="_blank"><span data-svelte-h="svelte-1kd6by1">&lt;</span> <span data-svelte-h="svelte-x0xyl0">&gt;</span> <span data-svelte-h="svelte-1dajgef"><span class="underline ml-1.5">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_u238jf = {
assets: "/docs/diffusers/pr_11986/en",
base: "/docs/diffusers/pr_11986/en",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/diffusers/pr_11986/en/_app/immutable/entry/start.e4c568fa.js"),
import("/docs/diffusers/pr_11986/en/_app/immutable/entry/app.29bdf47f.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 227],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
27.9 kB
·
Xet hash:
9f10a71aa10688975aa85d8e475010be7949bf952ab87810bc2ccfc0a6b43014

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