Skip to content

[feat]Add strength in flux_fill pipeline (denoising strength for fluxfill) #10603

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Apr 4, 2025

Conversation

Suprhimp
Copy link
Contributor

What does this PR do?

allows the fluxfill pipeline to have a denoising strength (denoising strength).

Before submitting

Who can review?

@yiyixuxu and @asomoza

I use fluxfill pipeline to edit image or outpatin. Yes it works very well but I don't agree Flux Fill pipeline does not require strength as an input like regular inpainting pipelines this line in the docs.

When remove object in the image, We need denoising strength I guess. without denoising strength I can't get clean image that remove object that I want.
let me gives you an example I tested.

mask
original_image

this is mask and original image that I want to edit.

And this is the result with denoising strength (0.6 with revised pipeline) and none(default pipeline)

cbimage (51)
7fabf5e8-9d0d-47d8-af7b-0371b4f29f21

I did lama inpaint to remove more clearly in both case but output is different.

As you can see with denoising strength we can have more control with the image quality. So I think there is no reason to not use denoising strength in fluxfill pipeline

I changed the fluxfill pipeline code with reference sdxl inpaint pipeline.
So, I think there would be things that need to be fixed.

Thanks for reading :)

Copy link
Contributor

@hlky hlky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some comments. However, we should note that Flux Fill is intended to fill areas based on a text description and not for object removal.

self.mask_processor = VaeImageProcessor(
vae_scale_factor=self.vae_scale_factor * 2,
vae_latent_channels=latent_channels,
vae_latent_channels=self.vae.config.latent_channels,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to use latent_channels here not the config directly. This allows pipelines to be used without the component e.g. FluxFillPipeline(vae=None, ...).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know that, Thanks, I changed. :)

@@ -627,6 +659,8 @@ def disable_vae_tiling(self):
# Copied from diffusers.pipelines.flux.pipeline_flux.FluxPipeline.prepare_latents
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we copy from FluxImg2ImgPipeline.prepare_latents or FluxInpaintPipeline.prepare_latents?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure , That would be more clean. Thanks for the review :)

@@ -809,6 +866,10 @@ def __call__(
self._joint_attention_kwargs = joint_attention_kwargs
self._interrupt = False

original_image = image
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep :) Maby that came from sdxl inpaint pipeline, but it is not used in this pipeline

@@ -855,13 +952,13 @@ def __call__(
if masked_image_latents is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above # 6. Prepare mask and masked image latents.

@Suprhimp
Copy link
Contributor Author

Thankyou for the fast and kind review, I'll revise it and test :)

@Suprhimp
Copy link
Contributor Author

Suprhimp commented Jan 17, 2025

I've left some comments. However, we should note that Flux Fill is intended to fill areas based on a text description and not for object removal.

Hmm, Maby I missed the intention than ;)
Although I think we can use fluxfill with more controllable, with denosing strength:)

@hlky Thanks for the review again, I changed the code that you've reviewed.

@asomoza
Copy link
Member

asomoza commented Jan 17, 2025

Hi, you're saying you used lama to remove the object before doing this? If that's what you did, you're just essentially using this pipeline as an img2img one and the model as just a refiner.

The original fill model was trained to do this without the need of changing the strength and this is from the original implementation, I'm not saying that what you're doing is wrong though, people used redux in a more different and creative way and it works alright but I want to understand your use case since I haven't encountered the need to lower the strength to make it work.

Did you try what you're doing here with just the regular Flux model and the img2img pipeline?

@Suprhimp
Copy link
Contributor Author

Suprhimp commented Jan 17, 2025

Did you try what you're doing here with just the regular Flux model and the img2img pipeline?

Thanks for your response :)

I tried with sdxl model with img2img model. But not flux image2image.
And yep I understand what you said, Maby I'm just using the fluxfill pipeline as an refiner.

As I use this pipeline an image edit pipeline, I just want to use the single pipeline as an object adder or outpainter but also object remover.

If I have to use my case with flux img2img pipeline I can do that, but as you know flux model is quite large.
So I'd like to use it as refiner but also object adder or outpainter etc.

If I can use fluxfill pipeline with strength parameter, I don't need any other pipeline :)

@asomoza

@hlky
Copy link
Contributor

hlky commented Jan 17, 2025

@Suprhimp To confirm, you're using lama cleaner to remove the object first?

@Suprhimp
Copy link
Contributor Author

Suprhimp commented Jan 17, 2025

To confirm, you're using lama cleaner to remove the object first?

@hlky Yep I used lamacleaner before both case (my pipeline, and default pipeline)

@ukaprch
Copy link

ukaprch commented Jan 18, 2025

lama with the refiner is very good at removing objects. I thought the whole point of Flux fill was to replace or insert an object. Big difference there.

@Suprhimp
Copy link
Contributor Author

Hmm I think even we use fluxfill without lamainpainter to replace or insert an object, There will be certian point to need stength. Maby, keep the original color masked but change object, or change object but referenced based image in masked area.

You guys think it is unecessary to use strength referer to the orignal masked area in replace or insert an object?

@asomoza
Copy link
Member

asomoza commented Jan 22, 2025

There will be certian point to need stength. Maby, keep the original color masked but change object, or change object but referenced based image in masked area.

This are valid use cases but that it's again just a nasked img2img, in fact, if you want to preserve as much of the original image intact, you should always do it with img2img instead of this pipeline, and just replace the new part in the original image.

Still I think they're valid points and also the one that you don't want to switch models because they're really big, but this will make the pipeline more complex, @yiyixuxu WDYT?

Copy link
Contributor

This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the contributing guidelines are likely to be ignored.

@github-actions github-actions bot added the stale Issues that haven't received updates label Feb 16, 2025
@jonluca
Copy link

jonluca commented Mar 5, 2025

This would be a welcome addition, would be good to be able to use strength with flux fill

@github-actions github-actions bot removed the stale Issues that haven't received updates label Mar 5, 2025
@asomoza
Copy link
Member

asomoza commented Mar 6, 2025

This would be a welcome addition, would be good to be able to use strength with flux fill

@jonluca we're still waiting for @yiyixuxu feedback here, but in the meantime, do you have some demo images of using the strength with the vanilla flux fill pipeline? I mean without using it as a refiner only or with another inpainting model like lama cleaner.

@yiyixuxu
Copy link
Collaborator

yiyixuxu commented Mar 6, 2025

@asomoza I think it's ok to support if you think the use case is meaningful :)

@lvwilson
Copy link

lvwilson commented Apr 1, 2025

I +1 this use case.

@asomoza
Copy link
Member

asomoza commented Apr 2, 2025

sure, I think it's worth it because of the VRAM usage of Flux, I'll do some quick tests as soon as possible. In the meantime @Suprhimp would you mind resolving the conflicts or do you prefer if I take it over?

@Suprhimp
Copy link
Contributor Author

Suprhimp commented Apr 3, 2025

I'll try right away:) @asomoza

@Suprhimp
Copy link
Contributor Author

Suprhimp commented Apr 4, 2025

@asomoza I fixed conflict and I did test with my code, it seems work well to me

@HuggingFaceDocBuilderDev

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@asomoza
Copy link
Member

asomoza commented Apr 4, 2025

@bot /style

Copy link
Contributor

github-actions bot commented Apr 4, 2025

Style fixes have been applied. View the workflow run here.

Copy link
Member

@asomoza asomoza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took the liberty to fix the bad name in the prepare_latents copy, hope you don't mind, but now we have an issue with it.

Comment on lines 688 to 696
image = image.to(device=device, dtype=dtype)
image_latents = self._encode_vae_image(image=image, generator=generator)
if batch_size > image_latents.shape[0] and batch_size % image_latents.shape[0] == 0:
# expand init_latents for batch_size
additional_image_per_prompt = batch_size // image_latents.shape[0]
image_latents = torch.cat([image_latents] * additional_image_per_prompt, dim=0)
elif batch_size > image_latents.shape[0] and batch_size % image_latents.shape[0] != 0:
raise ValueError(
f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
f" size of {batch_size}. Make sure the batch size matches the length of the generators."
f"Cannot duplicate `image` of batch size {image_latents.shape[0]} to {batch_size} text prompts."
Copy link
Member

@asomoza asomoza Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part it's not the same as the prepare_latents in FluxImg2ImgPipeline but you're commenting that this function was copied from it.

Copy link
Contributor Author

@Suprhimp Suprhimp Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detail review, and yes, since FluxImg2ImgPipeline was updated 2 weeks ago, It has to be changed.
So I updated prepare_latents function as same with in FluxImg2ImgPipeline.

And also I tested with my code, it works well. (honestly, it works better than before i think, lol)

@asomoza
Copy link
Member

asomoza commented Apr 4, 2025

thanks a lot! Failing tests are not related to this PR

@asomoza asomoza merged commit 94f2c48 into huggingface:main Apr 4, 2025
10 of 12 checks passed
@Suprhimp
Copy link
Contributor Author

Suprhimp commented Apr 5, 2025

Thank you! I wanted to revise the last part as well, but I couldn't respond because I couldn't use the computer at that time. But I wanted to merge this PR quickly, so I asked for help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants