Buckets:
| # Callback pipeline | |
| Callback dijalankan di akhir langkah denoising dan dapat mengubah status pipeline atau tensor untuk langkah-langkah berikutnya. Gunakan callback untuk menyesuaikan atribut atau variabel tensor demi perilaku baru tanpa menulis ulang pipeline. | |
| Callback ini berfungsi dengan loop [DiffusionPipeline](/docs/diffusers/main/id/api/pipelines/overview#diffusers.DiffusionPipeline) klasik secara bawaan. Mereka juga berfungsi dengan pipeline [Modular Diffusers](../modular_diffusers/overview) setelah blok yang menjalankannya disisipkan ke dalam loop denoising; lihat [Modular pipelines](#modular-pipelines). | |
| Diffusers menyediakan beberapa callback dalam [ringkasan](../api/pipelines/overview#diffusers.callbacks.PipelineCallback) pipeline. | |
| Untuk mengaktifkan callback, konfigurasikan kapan callback dieksekusi setelah sejumlah langkah denoising tertentu dengan salah satu argumen berikut. | |
| - `cutoff_step_ratio` menentukan kapan callback diaktifkan sebagai persentase dari total langkah denoising. Gunakan ketika cutoff harus berskala dengan `num_inference_steps` (misalnya, hapus CFG setelah 40% dari eksekusi). | |
| - `cutoff_step_index` menentukan nomor langkah persis di mana callback diaktifkan. Gunakan ini ketika Anda peduli pada langkah absolut (misalnya, langkah `10` pada jadwal tetap 25 langkah). | |
| Contoh di bawah menggunakan `cutoff_step_ratio=0.4`, yang berarti callback diaktifkan ketika denoising mencapai 40% dari total langkah inferensi. [SDXLCFGCutoffCallback](/docs/diffusers/main/id/api/pipelines/overview#diffusers.callbacks.SDXLCFGCutoffCallback) menonaktifkan classifier-free guidance (CFG) setelah sejumlah langkah tertentu, yang dapat membantu menghemat komputasi tanpa secara signifikan memengaruhi kinerja. | |
| Definisikan callback dengan salah satu argumen `cutoff` dan teruskan ke parameter `callback_on_step_end` di pipeline. | |
| ```py | |
| import torch | |
| from diffusers import DPMSolverMultistepScheduler, StableDiffusionXLPipeline | |
| from diffusers.callbacks import SDXLCFGCutoffCallback | |
| callback = SDXLCFGCutoffCallback(cutoff_step_ratio=0.4) | |
| # if using cutoff_step_index | |
| # callback = SDXLCFGCutoffCallback(cutoff_step_ratio=None, cutoff_step_index=10) | |
| pipeline = StableDiffusionXLPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| dtype=torch.float16, | |
| device_map="cuda" # or "mps", "xpu", "cpu" | |
| ) | |
| pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config, use_karras_sigmas=True) | |
| prompt = "a sports car on the road, best quality, high quality, high detail, 8k resolution" | |
| output = pipeline( | |
| prompt=prompt, | |
| negative_prompt="", | |
| guidance_scale=6.5, | |
| num_inference_steps=25, | |
| callback_on_step_end=callback, | |
| ) | |
| ``` | |
| Callback resmi mengatur input tensor mereka sendiri. Untuk fungsi kustom, berikan `callback_on_step_end_tensor_inputs` seperti pada [Tampilkan gambar antara](#display-intermediate-images). | |
| Jika Anda ingin menambahkan callback resmi baru, silakan buka [permintaan fitur](https://github.com/huggingface/diffusers/issues/new/choose) atau [kirim PR](../conceptual/contribution#how-to-open-a-pr). Selain itu, Anda juga dapat membuat callback Anda sendiri seperti yang ditunjukkan di bawah ini. | |
| ## Penghentian dini | |
| Early stopping berguna jika Anda tidak puas dengan hasil antara selama proses generasi. Callback ini menetapkan titik henti yang di-hardcode dengan mengatur atribut `_interrupt` menjadi `True`, yang membuat loop denoising melewati langkah-langkah yang tersisa. | |
| ```py | |
| import torch | |
| from diffusers import DiffusionPipeline | |
| def interrupt_callback(pipeline, i, t, callback_kwargs): | |
| stop_idx = 10 | |
| if i == stop_idx: | |
| pipeline._interrupt = True | |
| return callback_kwargs | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| "Qwen/Qwen-Image", | |
| dtype=torch.bfloat16, | |
| device_map="cuda", # or "mps", "xpu", "cpu" | |
| ) | |
| pipeline( | |
| prompt="A photo of a cat", | |
| num_inference_steps=50, | |
| callback_on_step_end=interrupt_callback, | |
| ) | |
| ``` | |
| ## Tampilkan gambar perantara | |
| Visualisasi gambar perantara berguna untuk memantau kemajuan. Pratinjau di bawah ini hanya untuk SDXL. Pratinjau ini memetakan latens SDXL ke RGB dengan transformasi linear untuk melihat cepat selama denoising. Bobot tersebut tidak dapat dipindahkan ke model lain. Untuk Qwen-Image dan checkpoint serupa, dekodekan dengan VAE model alih-alih helper ini. | |
| [Konversi](https://huggingface.co/blog/TimothyAlexisVass/explaining-the-sdxl-latent-space) latens Stable Diffusion XL (4 saluran) menjadi tensor RGB (3 saluran). | |
| ```py | |
| import torch | |
| from PIL import Image | |
| from diffusers import AutoPipelineForText2Image | |
| def latents_to_rgb(latents): | |
| weights = ( | |
| (60, -60, 25, -70), | |
| (60, -5, 15, -50), | |
| (60, 10, -5, -35), | |
| ) | |
| weights_tensor = torch.t(torch.tensor(weights, dtype=latents.dtype).to(latents.device)) | |
| biases_tensor = torch.tensor((150, 140, 130), dtype=latents.dtype).to(latents.device) | |
| rgb_tensor = torch.einsum("...lxy,lr -> ...rxy", latents, weights_tensor) + biases_tensor.unsqueeze(-1).unsqueeze(-1) | |
| image_array = rgb_tensor.clamp(0, 255).byte().cpu().numpy().transpose(1, 2, 0) | |
| return Image.fromarray(image_array) | |
| ``` | |
| Ekstrak latents dan konversi gambar pertama dalam batch ke RGB. Simpan gambar sebagai file PNG dengan nomor langkah. | |
| ```py | |
| def decode_tensors(pipe, step, timestep, callback_kwargs): | |
| latents = callback_kwargs["latents"] | |
| image = latents_to_rgb(latents[0]) | |
| image.save(f"{step}.png") | |
| return callback_kwargs | |
| ``` | |
| Gunakan `callback_on_step_end_tensor_inputs` untuk memilih tensor mana yang diterima oleh callback, yang dalam hal ini adalah latents. | |
| ```py | |
| pipeline = AutoPipelineForText2Image.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| dtype=torch.float16, | |
| device_map="cuda" # or "mps", "xpu", "cpu" | |
| ) | |
| image = pipeline( | |
| prompt="A croissant shaped like a cute bear.", | |
| negative_prompt="Deformed, ugly, bad anatomy", | |
| callback_on_step_end=decode_tensors, | |
| callback_on_step_end_tensor_inputs=["latents"], | |
| ).images[0] | |
| ``` | |
| ## Pipeline modular | |
| Pipeline modular tidak memiliki mekanisme `callback_on_step_end` dan `interrupt`. Sebagai gantinya, dukungan streaming kelas satu akan hadir: [huggingface/diffusers#14159](https://github.com/huggingface/diffusers/pull/14159), yang belum digabungkan, menambahkan `pipe.stream()`, yang menghasilkan status pipeline pada setiap langkah denoising dan mengakhiri eksekusi ketika Anda berhenti mengiterasi. Untuk saat ini, agar dapat menggunakan kembali fungsi callback Anda yang ada, sisipkan blok ke dalam loop denoising: blok ini menerima `BlockState` dari loop dengan indeks langkah dan timestep, serta dapat membaca atau mengedit `latents`. | |
| > [!TIP] | |
| > Edit blok *sebelum* [init_pipeline()](/docs/diffusers/main/id/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline): `pipe.blocks` mengembalikan salinan, sehingga mengubahnya setelah pipeline ada tidak akan berdampak apa pun. | |
| Blok di bawah ini mengambil callback sebagai input pipeline dan memanggilnya dengan tanda tangan yang sama seperti di atas: pipeline, indeks langkah, timestep, dan dict tensor, di mana nilai yang dikembalikan akan ditulis kembali. `walk_denoise_loops` menemukan setiap loop denoising di dalam blok, terlepas dari workflow apa pun yang dimilikinya, sehingga snippet yang sama dapat digunakan untuk pipeline modular apa pun. | |
| ```py | |
| from typing import Callable | |
| import torch | |
| from diffusers import ModularPipeline | |
| from diffusers.modular_pipelines import InputParam, LoopSequentialPipelineBlocks, ModularPipelineBlocks | |
| class CallbackOnStepEnd(ModularPipelineBlocks): | |
| @property | |
| def inputs(self): | |
| return [ | |
| InputParam( | |
| "callback_on_step_end", | |
| type_hint=Callable, | |
| description="Called after each scheduler step as `callback(pipe, i, t, {'latents': ...})`; the dict it returns is written back.", | |
| ), | |
| InputParam("latents", required=True), | |
| ] | |
| def __call__(self, components, block_state, i, t): | |
| if block_state.callback_on_step_end is not None: | |
| outputs = block_state.callback_on_step_end(components, i, t, {"latents": block_state.latents}) | |
| block_state.latents = outputs.get("latents", block_state.latents) | |
| return components, block_state | |
| def walk_denoise_loops(block): | |
| """Every denoising loop in the blocks, whichever workflow it belongs to.""" | |
| if isinstance(block, LoopSequentialPipelineBlocks) and "denoiser" in block.sub_blocks: | |
| yield block | |
| for sub in getattr(block, "sub_blocks", {}).values(): | |
| yield from walk_denoise_loops(sub) | |
| repo_id = "stabilityai/stable-diffusion-xl-base-1.0" | |
| blocks = ModularPipeline.from_pretrained(repo_id).blocks | |
| for loop in walk_denoise_loops(blocks): | |
| loop.sub_blocks["callback"] = CallbackOnStepEnd() # appended after the last step of the loop | |
| pipe = blocks.init_pipeline(repo_id) | |
| pipe.load_components(dtype=torch.float16) | |
| pipe.to("cuda") | |
| ``` | |
| `callback_on_step_end` kini menjadi input dari pipeline, dan callback yang ditulis untuk `DiffusionPipeline`, seperti `decode_tensors` di atas, berfungsi apa adanya: | |
| ```py | |
| image = pipe(prompt="A croissant shaped like a cute bear.", callback_on_step_end=decode_tensors, output="images")[0] | |
| ``` | |
| [Early stopping](#early-stopping) bekerja dengan cara berbeda: sebuah blok tidak dapat melewati loop tempatnya berjalan, sehingga pengaturan `_interrupt` tidak berpengaruh. Alih-alih, lempar pengecualian dari callback: pengecualian tersebut akan menyebar keluar dari `pipe(...)` (tidak ada gambar yang didekode), dan pipeline tetap dapat digunakan setelahnya. | |
| Ini berlaku untuk setiap pipeline modular kecuali loop internal dari loop bersarang (model video autoregresif seperti Helios dan Wan-Animate-2 melakukan denoising pada setiap chunk di dalam blok loop eksternal). Di sana, sisipkan blok ke dalam loop eksternal: blok ini berjalan sekali per chunk dan menerima indeks chunk `k` sebagai pengganti `i` dan `t`. | |
Xet Storage Details
- Size:
- 10.1 kB
- Xet hash:
- c3f35de6edadcd8f0edbb814eb1bb11582f006ca49c53eccb148d92822deedfe
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.