Buckets:

download
raw
15.5 kB
import"../chunks/DsnmJJEf.js";import{i as m,h as j,C as f,H as l,a,E as U,s as I}from"../chunks/BLbO27j4.js";import{p as g,o as G,s,f as Z,a as h,b as k,d as w,n as B}from"../chunks/jDjavuwI.js";const C='{"title":"Pipeline callbacks","local":"pipeline-callbacks","sections":[{"title":"Early stopping","local":"early-stopping","sections":[],"depth":2},{"title":"Display intermediate images","local":"display-intermediate-images","sections":[],"depth":2}],"depth":1}';var W=w('<meta name="hf:doc:metadata"/>'),_=w('<p></p> <!> <!> <p>A callback runs at the end of a denoising step and can change pipeline state or tensors for later steps. Use it to adjust attributes or tensor variables for new behavior without rewriting the pipeline.</p> <p>These callbacks apply to classic <a href="/docs/diffusers/pr_14921/en/api/pipelines/overview#diffusers.DiffusionPipeline">DiffusionPipeline</a> loops. In <a href="../modular_diffusers/overview">Modular Diffusers</a>, you can build and add custom pipeline blocks instead of <code>callback_on_step_end</code>.</p> <p>Diffusers provides several callbacks in the pipeline <a href="../api/pipelines/overview#diffusers.callbacks.PipelineCallback">overview</a>.</p> <p>To enable a callback, configure when the callback is executed after a certain number of denoising steps with one of the following arguments.</p> <ul><li><code>cutoff_step_ratio</code> specifies when a callback is activated as a percentage of the total denoising steps. Use when the cutoff should scale with <code>num_inference_steps</code> (for example, drop CFG after 40% of run).</li> <li><code>cutoff_step_index</code> specifies the exact step number a callback is activated. Use when you care about an absolute step (for example, step <code>10</code> on a fixed 25-step schedule).</li></ul> <p>The example below uses <code>cutoff_step_ratio=0.4</code>, which means the callback is activated once denoising reaches 40% of the total inference steps. <a href="/docs/diffusers/pr_14921/en/api/pipelines/overview#diffusers.callbacks.SDXLCFGCutoffCallback">SDXLCFGCutoffCallback</a> disables classifier-free guidance (CFG) after a certain number of steps, which can help save compute without significantly affecting performance.</p> <p>Define a callback with one of the <code>cutoff</code> arguments and pass it to the <code>callback_on_step_end</code> parameter in the pipeline.</p> <!> <p>Official callbacks set their own tensor inputs. For a custom function, pass <code>callback_on_step_end_tensor_inputs</code> as in <a href="#display-intermediate-images">Display intermediate images</a>.</p> <p>If you want to add a new official callback, feel free to open a <a href="https://github.com/huggingface/diffusers/issues/new/choose" rel="nofollow">feature request</a> or <a href="https://huggingface.co/docs/diffusers/main/en/conceptual/contribution#how-to-open-a-pr" rel="nofollow">submit a PR</a>. Otherwise, you can also create your own callback as shown below.</p> <!> <p>Early stopping is useful if you aren’t happy with the intermediate results during generation. This callback sets a hardcoded stop point by setting the <code>_interrupt</code> attribute to <code>True</code>, which makes the denoising loop skip the remaining steps.</p> <!> <!> <p>Visualizing intermediate images is useful for progress monitoring. The preview below is SDXL-only. It maps SDXL latents to RGB with a linear transform for a quick look during denoising. Those weights do not transfer to other models. For Qwen-Image and similar checkpoints, decode with the model VAE instead of this helper.</p> <p><a href="https://huggingface.co/blog/TimothyAlexisVass/explaining-the-sdxl-latent-space" rel="nofollow">Convert</a> Stable Diffusion XL latents (4 channels) to RGB tensors (3 channels).</p> <!> <p>Extract the latents and convert the first image in the batch to RGB. Save the image as a PNG file with the step number.</p> <!> <p>Use <code>callback_on_step_end_tensor_inputs</code> to choose which tensors the callback receives, which in this case, are the latents.</p> <!> <!> <p></p>',1);function Y(y,T){g(T,!1),G(()=>{new URLSearchParams(window.location.search).get("fw")}),m();var e=_();j("apt59n",d=>{var u=W();I(u,"content",C),h(d,u)});var n=s(Z(e),2);f(n,{containerStyle:"float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"});var t=s(n,2);l(t,{title:"Pipeline callbacks",local:"pipeline-callbacks",headingTag:"h1"});var p=s(t,16);a(p,{code:"aW1wb3J0JTIwdG9yY2glMEFmcm9tJTIwZGlmZnVzZXJzJTIwaW1wb3J0JTIwRFBNU29sdmVyTXVsdGlzdGVwU2NoZWR1bGVyJTJDJTIwU3RhYmxlRGlmZnVzaW9uWExQaXBlbGluZSUwQWZyb20lMjBkaWZmdXNlcnMuY2FsbGJhY2tzJTIwaW1wb3J0JTIwU0RYTENGR0N1dG9mZkNhbGxiYWNrJTBBJTBBY2FsbGJhY2slMjAlM0QlMjBTRFhMQ0ZHQ3V0b2ZmQ2FsbGJhY2soY3V0b2ZmX3N0ZXBfcmF0aW8lM0QwLjQpJTBBJTIzJTIwaWYlMjB1c2luZyUyMGN1dG9mZl9zdGVwX2luZGV4JTBBJTIzJTIwY2FsbGJhY2slMjAlM0QlMjBTRFhMQ0ZHQ3V0b2ZmQ2FsbGJhY2soY3V0b2ZmX3N0ZXBfcmF0aW8lM0ROb25lJTJDJTIwY3V0b2ZmX3N0ZXBfaW5kZXglM0QxMCklMEElMEFwaXBlbGluZSUyMCUzRCUyMFN0YWJsZURpZmZ1c2lvblhMUGlwZWxpbmUuZnJvbV9wcmV0cmFpbmVkKCUwQSUyMCUyMCUyMCUyMCUyMnN0YWJpbGl0eWFpJTJGc3RhYmxlLWRpZmZ1c2lvbi14bC1iYXNlLTEuMCUyMiUyQyUwQSUyMCUyMCUyMCUyMGR0eXBlJTNEdG9yY2guZmxvYXQxNiUyQyUwQSUyMCUyMCUyMCUyMGRldmljZV9tYXAlM0QlMjJjdWRhJTIyJTIwJTIwJTIzJTIwb3IlMjAlMjJtcHMlMjIlMkMlMjAlMjJ4cHUlMjIlMkMlMjAlMjJjcHUlMjIlMEEpJTBBcGlwZWxpbmUuc2NoZWR1bGVyJTIwJTNEJTIwRFBNU29sdmVyTXVsdGlzdGVwU2NoZWR1bGVyLmZyb21fY29uZmlnKHBpcGVsaW5lLnNjaGVkdWxlci5jb25maWclMkMlMjB1c2Vfa2FycmFzX3NpZ21hcyUzRFRydWUpJTBBJTBBcHJvbXB0JTIwJTNEJTIwJTIyYSUyMHNwb3J0cyUyMGNhciUyMG9uJTIwdGhlJTIwcm9hZCUyQyUyMGJlc3QlMjBxdWFsaXR5JTJDJTIwaGlnaCUyMHF1YWxpdHklMkMlMjBoaWdoJTIwZGV0YWlsJTJDJTIwOGslMjByZXNvbHV0aW9uJTIyJTBBb3V0cHV0JTIwJTNEJTIwcGlwZWxpbmUoJTBBJTIwJTIwJTIwJTIwcHJvbXB0JTNEcHJvbXB0JTJDJTBBJTIwJTIwJTIwJTIwbmVnYXRpdmVfcHJvbXB0JTNEJTIyJTIyJTJDJTBBJTIwJTIwJTIwJTIwZ3VpZGFuY2Vfc2NhbGUlM0Q2LjUlMkMlMEElMjAlMjAlMjAlMjBudW1faW5mZXJlbmNlX3N0ZXBzJTNEMjUlMkMlMEElMjAlMjAlMjAlMjBjYWxsYmFja19vbl9zdGVwX2VuZCUzRGNhbGxiYWNrJTJDJTBBKQ==",highlighted:`<span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> DPMSolverMultistepScheduler, StableDiffusionXLPipeline
<span class="hljs-keyword">from</span> diffusers.callbacks <span class="hljs-keyword">import</span> SDXLCFGCutoffCallback
callback = SDXLCFGCutoffCallback(cutoff_step_ratio=<span class="hljs-number">0.4</span>)
<span class="hljs-comment"># if using cutoff_step_index</span>
<span class="hljs-comment"># callback = SDXLCFGCutoffCallback(cutoff_step_ratio=None, cutoff_step_index=10)</span>
pipeline = StableDiffusionXLPipeline.from_pretrained(
<span class="hljs-string">&quot;stabilityai/stable-diffusion-xl-base-1.0&quot;</span>,
dtype=torch.float16,
device_map=<span class="hljs-string">&quot;cuda&quot;</span> <span class="hljs-comment"># or &quot;mps&quot;, &quot;xpu&quot;, &quot;cpu&quot;</span>
)
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config, use_karras_sigmas=<span class="hljs-literal">True</span>)
prompt = <span class="hljs-string">&quot;a sports car on the road, best quality, high quality, high detail, 8k resolution&quot;</span>
output = pipeline(
prompt=prompt,
negative_prompt=<span class="hljs-string">&quot;&quot;</span>,
guidance_scale=<span class="hljs-number">6.5</span>,
num_inference_steps=<span class="hljs-number">25</span>,
callback_on_step_end=callback,
)`,lang:"py",wrap:!1});var o=s(p,6);l(o,{title:"Early stopping",local:"early-stopping",headingTag:"h2"});var c=s(o,4);a(c,{code:"aW1wb3J0JTIwdG9yY2glMEFmcm9tJTIwZGlmZnVzZXJzJTIwaW1wb3J0JTIwRGlmZnVzaW9uUGlwZWxpbmUlMEElMEFkZWYlMjBpbnRlcnJ1cHRfY2FsbGJhY2socGlwZWxpbmUlMkMlMjBpJTJDJTIwdCUyQyUyMGNhbGxiYWNrX2t3YXJncyklM0ElMEElMjAlMjAlMjAlMjBzdG9wX2lkeCUyMCUzRCUyMDEwJTBBJTIwJTIwJTIwJTIwaWYlMjBpJTIwJTNEJTNEJTIwc3RvcF9pZHglM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBwaXBlbGluZS5faW50ZXJydXB0JTIwJTNEJTIwVHJ1ZSUwQSUyMCUyMCUyMCUyMHJldHVybiUyMGNhbGxiYWNrX2t3YXJncyUwQSUwQXBpcGVsaW5lJTIwJTNEJTIwRGlmZnVzaW9uUGlwZWxpbmUuZnJvbV9wcmV0cmFpbmVkKCUwQSUyMCUyMCUyMCUyMCUyMlF3ZW4lMkZRd2VuLUltYWdlJTIyJTJDJTBBJTIwJTIwJTIwJTIwZHR5cGUlM0R0b3JjaC5iZmxvYXQxNiUyQyUwQSUyMCUyMCUyMCUyMGRldmljZV9tYXAlM0QlMjJjdWRhJTIyJTJDJTIwJTIwJTIzJTIwb3IlMjAlMjJtcHMlMjIlMkMlMjAlMjJ4cHUlMjIlMkMlMjAlMjJjcHUlMjIlMEEpJTBBcGlwZWxpbmUoJTBBJTIwJTIwJTIwJTIwcHJvbXB0JTNEJTIyQSUyMHBob3RvJTIwb2YlMjBhJTIwY2F0JTIyJTJDJTBBJTIwJTIwJTIwJTIwbnVtX2luZmVyZW5jZV9zdGVwcyUzRDUwJTJDJTBBJTIwJTIwJTIwJTIwY2FsbGJhY2tfb25fc3RlcF9lbmQlM0RpbnRlcnJ1cHRfY2FsbGJhY2slMkMlMEEp",highlighted:`<span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> DiffusionPipeline
<span class="hljs-keyword">def</span> <span class="hljs-title function_">interrupt_callback</span>(<span class="hljs-params">pipeline, i, t, callback_kwargs</span>):
stop_idx = <span class="hljs-number">10</span>
<span class="hljs-keyword">if</span> i == stop_idx:
pipeline._interrupt = <span class="hljs-literal">True</span>
<span class="hljs-keyword">return</span> callback_kwargs
pipeline = DiffusionPipeline.from_pretrained(
<span class="hljs-string">&quot;Qwen/Qwen-Image&quot;</span>,
dtype=torch.bfloat16,
device_map=<span class="hljs-string">&quot;cuda&quot;</span>, <span class="hljs-comment"># or &quot;mps&quot;, &quot;xpu&quot;, &quot;cpu&quot;</span>
)
pipeline(
prompt=<span class="hljs-string">&quot;A photo of a cat&quot;</span>,
num_inference_steps=<span class="hljs-number">50</span>,
callback_on_step_end=interrupt_callback,
)`,lang:"py",wrap:!1});var i=s(c,2);l(i,{title:"Display intermediate images",local:"display-intermediate-images",headingTag:"h2"});var r=s(i,6);a(r,{code:"aW1wb3J0JTIwdG9yY2glMEFmcm9tJTIwUElMJTIwaW1wb3J0JTIwSW1hZ2UlMEFmcm9tJTIwZGlmZnVzZXJzJTIwaW1wb3J0JTIwQXV0b1BpcGVsaW5lRm9yVGV4dDJJbWFnZSUwQSUwQWRlZiUyMGxhdGVudHNfdG9fcmdiKGxhdGVudHMpJTNBJTBBJTIwJTIwJTIwJTIwd2VpZ2h0cyUyMCUzRCUyMCglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoNjAlMkMlMjAtNjAlMkMlMjAyNSUyQyUyMC03MCklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoNjAlMkMlMjAlMjAtNSUyQyUyMDE1JTJDJTIwLTUwKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCg2MCUyQyUyMCUyMDEwJTJDJTIwLTUlMkMlMjAtMzUpJTJDJTBBJTIwJTIwJTIwJTIwKSUwQSUwQSUyMCUyMCUyMCUyMHdlaWdodHNfdGVuc29yJTIwJTNEJTIwdG9yY2gudCh0b3JjaC50ZW5zb3Iod2VpZ2h0cyUyQyUyMGR0eXBlJTNEbGF0ZW50cy5kdHlwZSkudG8obGF0ZW50cy5kZXZpY2UpKSUwQSUyMCUyMCUyMCUyMGJpYXNlc190ZW5zb3IlMjAlM0QlMjB0b3JjaC50ZW5zb3IoKDE1MCUyQyUyMDE0MCUyQyUyMDEzMCklMkMlMjBkdHlwZSUzRGxhdGVudHMuZHR5cGUpLnRvKGxhdGVudHMuZGV2aWNlKSUwQSUyMCUyMCUyMCUyMHJnYl90ZW5zb3IlMjAlM0QlMjB0b3JjaC5laW5zdW0oJTIyLi4ubHh5JTJDbHIlMjAtJTNFJTIwLi4ucnh5JTIyJTJDJTIwbGF0ZW50cyUyQyUyMHdlaWdodHNfdGVuc29yKSUyMCUyQiUyMGJpYXNlc190ZW5zb3IudW5zcXVlZXplKC0xKS51bnNxdWVlemUoLTEpJTBBJTIwJTIwJTIwJTIwaW1hZ2VfYXJyYXklMjAlM0QlMjByZ2JfdGVuc29yLmNsYW1wKDAlMkMlMjAyNTUpLmJ5dGUoKS5jcHUoKS5udW1weSgpLnRyYW5zcG9zZSgxJTJDJTIwMiUyQyUyMDApJTBBJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwSW1hZ2UuZnJvbWFycmF5KGltYWdlX2FycmF5KQ==",highlighted:`<span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">from</span> PIL <span class="hljs-keyword">import</span> Image
<span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> AutoPipelineForText2Image
<span class="hljs-keyword">def</span> <span class="hljs-title function_">latents_to_rgb</span>(<span class="hljs-params">latents</span>):
weights = (
(<span class="hljs-number">60</span>, -<span class="hljs-number">60</span>, <span class="hljs-number">25</span>, -<span class="hljs-number">70</span>),
(<span class="hljs-number">60</span>, -<span class="hljs-number">5</span>, <span class="hljs-number">15</span>, -<span class="hljs-number">50</span>),
(<span class="hljs-number">60</span>, <span class="hljs-number">10</span>, -<span class="hljs-number">5</span>, -<span class="hljs-number">35</span>),
)
weights_tensor = torch.t(torch.tensor(weights, dtype=latents.dtype).to(latents.device))
biases_tensor = torch.tensor((<span class="hljs-number">150</span>, <span class="hljs-number">140</span>, <span class="hljs-number">130</span>), dtype=latents.dtype).to(latents.device)
rgb_tensor = torch.einsum(<span class="hljs-string">&quot;...lxy,lr -&gt; ...rxy&quot;</span>, latents, weights_tensor) + biases_tensor.unsqueeze(-<span class="hljs-number">1</span>).unsqueeze(-<span class="hljs-number">1</span>)
image_array = rgb_tensor.clamp(<span class="hljs-number">0</span>, <span class="hljs-number">255</span>).byte().cpu().numpy().transpose(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>)
<span class="hljs-keyword">return</span> Image.fromarray(image_array)`,lang:"py",wrap:!1});var J=s(r,4);a(J,{code:"ZGVmJTIwZGVjb2RlX3RlbnNvcnMocGlwZSUyQyUyMHN0ZXAlMkMlMjB0aW1lc3RlcCUyQyUyMGNhbGxiYWNrX2t3YXJncyklM0ElMEElMjAlMjAlMjAlMjBsYXRlbnRzJTIwJTNEJTIwY2FsbGJhY2tfa3dhcmdzJTVCJTIybGF0ZW50cyUyMiU1RCUwQSUwQSUyMCUyMCUyMCUyMGltYWdlJTIwJTNEJTIwbGF0ZW50c190b19yZ2IobGF0ZW50cyU1QjAlNUQpJTBBJTIwJTIwJTIwJTIwaW1hZ2Uuc2F2ZShmJTIyJTdCc3RlcCU3RC5wbmclMjIpJTBBJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwY2FsbGJhY2tfa3dhcmdz",highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">decode_tensors</span>(<span class="hljs-params">pipe, step, timestep, callback_kwargs</span>):
latents = callback_kwargs[<span class="hljs-string">&quot;latents&quot;</span>]
image = latents_to_rgb(latents[<span class="hljs-number">0</span>])
image.save(<span class="hljs-string">f&quot;<span class="hljs-subst">{step}</span>.png&quot;</span>)
<span class="hljs-keyword">return</span> callback_kwargs`,lang:"py",wrap:!1});var M=s(J,4);a(M,{code:"cGlwZWxpbmUlMjAlM0QlMjBBdXRvUGlwZWxpbmVGb3JUZXh0MkltYWdlLmZyb21fcHJldHJhaW5lZCglMEElMjAlMjAlMjAlMjAlMjJzdGFiaWxpdHlhaSUyRnN0YWJsZS1kaWZmdXNpb24teGwtYmFzZS0xLjAlMjIlMkMlMEElMjAlMjAlMjAlMjBkdHlwZSUzRHRvcmNoLmZsb2F0MTYlMkMlMEElMjAlMjAlMjAlMjBkZXZpY2VfbWFwJTNEJTIyY3VkYSUyMiUyMCUyMCUyMyUyMG9yJTIwJTIybXBzJTIyJTJDJTIwJTIyeHB1JTIyJTJDJTIwJTIyY3B1JTIyJTBBKSUwQSUwQWltYWdlJTIwJTNEJTIwcGlwZWxpbmUoJTBBJTIwJTIwJTIwJTIwcHJvbXB0JTNEJTIyQSUyMGNyb2lzc2FudCUyMHNoYXBlZCUyMGxpa2UlMjBhJTIwY3V0ZSUyMGJlYXIuJTIyJTJDJTBBJTIwJTIwJTIwJTIwbmVnYXRpdmVfcHJvbXB0JTNEJTIyRGVmb3JtZWQlMkMlMjB1Z2x5JTJDJTIwYmFkJTIwYW5hdG9teSUyMiUyQyUwQSUyMCUyMCUyMCUyMGNhbGxiYWNrX29uX3N0ZXBfZW5kJTNEZGVjb2RlX3RlbnNvcnMlMkMlMEElMjAlMjAlMjAlMjBjYWxsYmFja19vbl9zdGVwX2VuZF90ZW5zb3JfaW5wdXRzJTNEJTVCJTIybGF0ZW50cyUyMiU1RCUyQyUwQSkuaW1hZ2VzJTVCMCU1RA==",highlighted:`pipeline = AutoPipelineForText2Image.from_pretrained(
<span class="hljs-string">&quot;stabilityai/stable-diffusion-xl-base-1.0&quot;</span>,
dtype=torch.float16,
device_map=<span class="hljs-string">&quot;cuda&quot;</span> <span class="hljs-comment"># or &quot;mps&quot;, &quot;xpu&quot;, &quot;cpu&quot;</span>
)
image = pipeline(
prompt=<span class="hljs-string">&quot;A croissant shaped like a cute bear.&quot;</span>,
negative_prompt=<span class="hljs-string">&quot;Deformed, ugly, bad anatomy&quot;</span>,
callback_on_step_end=decode_tensors,
callback_on_step_end_tensor_inputs=[<span class="hljs-string">&quot;latents&quot;</span>],
).images[<span class="hljs-number">0</span>]`,lang:"py",wrap:!1});var b=s(M,2);U(b,{source:"https://github.com/huggingface/diffusers/blob/main/docs/source/en/using-diffusers/callback.md"}),B(2),h(y,e),k()}export{Y as component};

Xet Storage Details

Size:
15.5 kB
·
Xet hash:
c56bd9a3dcc4ad524d71ce96b41db87e39599f6d5ae3ff1e9d5a2d0f47401c0f

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