Skip to content

feat: add Euler CFG++ and Euler-A CFG++ samplers#1354

Open
daniandtheweb wants to merge 1 commit intoleejet:masterfrom
daniandtheweb:euler_cfg_pp
Open

feat: add Euler CFG++ and Euler-A CFG++ samplers#1354
daniandtheweb wants to merge 1 commit intoleejet:masterfrom
daniandtheweb:euler_cfg_pp

Conversation

@daniandtheweb
Copy link
Contributor

@daniandtheweb daniandtheweb commented Mar 17, 2026

This PR adds support for the Euler CFG++ and Euler Ancestral CFG++ samplers: CFG++.

The logic from the code has been adapted from their repository and checked against ComfyUI's implementation and I tried to keep the sampler style as close as possible to the existing ones.
Some changes were needed in src/stable-diffusion.cpp as this specific sampler requires the unconditioned output in order to work.
This currently doesn't work with Spectrum cache.

As any CFG++ sampler you must use very low CFG values (for SDXL often less than 2).

I'd be very grateful if anyone could review this, as it's the first sampler I implement that requires this kind of changes.

@Green-Sky
Copy link
Contributor

Green-Sky commented Mar 19, 2026

I wonder whats the best way to integrate this here is. Binding this to samplers feels wrong.


Short test, trying to find the value for cfg++ that matches the image the closest.

euler_a 5cfg euler_a_cfg_pp 1.1cfg
cyber_sd1_eulera_cfg5 output

@daniandtheweb
Copy link
Contributor Author

I still think it's a good addition to the samplers. I tend to see more coherent generations at relatively higher CFGs, however I may be biased, this requires more testing.
When I'll have some time I'll try to create a grid showing the differences in CFGs between the sampler variants to have a better idea whether this is worth adding as a sampler or not.

@daniandtheweb
Copy link
Contributor Author

daniandtheweb commented Mar 23, 2026

From some initial testing with a SDXL model (cyberrealisticXL_V90, positive prompt: "a cute cat, best quality,", negative prompt: "worst quality,", 20 steps, seed 42, discrete scheduler) the biggest image similarity between Euler and Euler CFG++ is at 4.5 and 1.1 CFG (91.62% SSIM 61.07 MSE).

screenshot-2026-03-23_20-28-23

There's also a high similarity between CFG 1.4 and 5.5 (90%).


Other than that, as the CFG++ paper specifies this method allows for a smoother trajectory of generation:

Positive prompt: "a cute cat, best quality, black background",
Negative prompt: "worst quality, photo,",
Seed: 42, Scheduler: discrete

5 steps Euler CFG++ 5 steps Euler Target Image (20 steps Euler)
1765151440 1765151441 1765151439

Next I'll also try on more complex prompts.

@daniandtheweb
Copy link
Contributor Author

I did some more testing, on a more complex generation there appears to be an increase in difference in the generated images.
On the same test model (cyberrealisticXL_V90), 20 steps with positive prompt: "dog jumping towards a door, outdoors, grass, house, best quality, photography" and negative prompt: "worst quality," here's what I get:

CFG 4.0 4.5 5.0 5.5 6.0
Euler 1765151471 1765151472 1765151473 1765151474 1765151475
CFG 1.1 1.2 1.3 1.4
Euler CFG++ 1765151476 1765151477 1765151478 1765151479
CFG 1.5 1.6 1.7 1.8
Euler CFG++ 1765151480 1765151481 1765151482 1765151483

The highest similarity in this case comes from 5.5 and 1.3 and it's still just 78%:
screenshot-2026-03-24_02-55-15

I can't really say if it's better or not, however given the smooth generation trajectory I think that this method may introduce less artifacts in certain kind of images (I just managed to get it to happen on very few samples, but I'm not that good at writing prompts so I can't really test that aspect so well).

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.

2 participants