How can I do image-to-image batched inference with FLUX.2 Klein, with one-to-one input image-prompt pairing? #13431
Replies: 5 comments 1 reply
|
You can iterate through the prompt/image pairs like so: outputs = []
for image, prompt in zip(images, prompts):
output = pipe(
prompt=prompt,
image=image,
num_inference_steps=4,
guidance_scale=1.0
).images[0]
outputs.append(output) |
|
The issue you're hitting is fundamental to how Why this happensInternally, the pipeline stacks prompts and images into batch dimensions. When both are lists, the standard Solution 1: Manual one-to-one loop (simplest, slightly slower)The most robust approach today is to call the pipeline individually for each pair and collect results: outputs = []
for prompt, img in zip(prompts, images):
out = pipe(
prompt=prompt,
image=img,
num_inference_steps=4,
guidance_scale=1.0,
).images[0]
outputs.append(out)This guarantees 1:1 pairing. The overhead is usually negligible for Solution 2: Collapse into a single batched call with paired indicesIf you absolutely need one batched pipeline call (e.g. for VAE encode efficiency), you can duplicate prompts and images so each appears exactly once in the same batch order: # Flatten: [prompt_a, prompt_b, prompt_c] and [img_a, img_b, img_c]
# become batch items 0,1,2 with direct correspondence
outputs = pipe(
prompt=prompts, # length 3
image=images, # length 3
num_inference_steps=4,
guidance_scale=1.0,
).images # length 3Wait — this is exactly what you tried. The key detail is whether
For The real fixCheck if you're using a custom wrapper or a community pipeline that adds broadcasting. The base
Diagnostic stepAdd a debug print right before the print(f"Prompts: {len(prompts)}, Images: {len(images)}")
print(f"Prompt[0]: {prompts[0]}")
print(f"Image[0] size: {images[0].size}")Then inspect the output length. If you get 9 images from 3 prompts + 3 images, you confirmed Cartesian-product behavior. Recommended path forwardFor production use with FLUX.2 Klein, I'd go with Solution 1 (explicit loop) until you profile it. With 4 steps and a 9B model, the loop overhead is likely <2% of total latency. If you need true batching for throughput, use the If you can share:
…I can verify whether this is a known issue in that specific version or a custom pipeline behavior. |
|
This isn't a batching mistake on your side — it's just how this pipeline reads image. For Flux2KleinPipeline a list of So for genuinely one-to-one you call it once per pair, like the loop in the earlier reply. It's not batched in the One thing that might actually help you: the single batched call runs all N prompts in one pass, each against all M |
|
To perform 1-to-1 paired batched inference in Diffusers pipelines, ensure that:
Here is the clean implementation for batching FLUX / Diffusers image-to-image: import torch
from diffusers import Flux2KleinPipeline
from diffusers.utils import load_image
model_id = "black-forest-labs/FLUX.2-klein-9B"
pipe = Flux2KleinPipeline.from_pretrained(model_id, torch_dtype=torch.bfloat16).to("cuda")
prompts = [
"A futuristic cyberpunk city",
"A cozy wooden cabin in a snowy forest",
"A watercolor painting of a sunflower"
]
images = [
load_image("path/to/image_a.jpg").resize((1024, 1024)),
load_image("path/to/image_b.jpg").resize((1024, 1024)),
load_image("path/to/image_c.jpg").resize((1024, 1024))
]
# Pass lists directly; diffusers automatically batches item-by-item (batch_size = 3)
output_images = pipe(
prompt=prompts,
image=images,
num_inference_steps=4,
guidance_scale=1.0,
).images
# output_images[0] corresponds to prompts[0] + images[0], etc. |
|
Short answer: call it once per pair. A single call can't give each prompt its own image, so the zip loop from earlier in the thread is the correct way to get true one-to-one: outputs = [
pipe(prompt=p, image=img, num_inference_steps=4, guidance_scale=1.0).images[0]
for p, img in zip(prompts, images)
]Worth flagging that the answers saying equal-length lists pair item by item aren't right for this pipeline, which is exactly the cross-pairing you already saw. For FLUX.2 Klein a list of images is treated as shared reference context, so every prompt in the batch attends to all the images. That's useful when you want several prompts to share the same references, but it can't do per-prompt pairing. Quick way to confirm on your setup: run your original batched call and check how many images come back and whether each one reflects only its matching input. If you need throughput later, batch groups that share the same reference and loop across the groups. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I implemented something similar to the code below, but it appears that the model treats all provided images as shared context. As a result, each prompt is paired with all passed images (e.g., prompt_a is processed with image_a, image_b, and image_c).
What I am trying to achieve instead is batched inference with one-to-one pairing, so each prompt is processed only with its corresponding image (e.g., prompt_a with image_a, prompt_b with image_b, etc.).
What is the correct way to structure the inputs or batching logic to ensure this one-to-one mapping?
I would greatly appreciate any help with this. Thank you for your time.
All reactions