240703 - ComfyUI Advanced KSampler
Spis Treści #
- Odrobina teorii - KSampler (Advancer)
- KSampler, Advanced KSampler i steps
- Sampler
- Scheduler
- Add Noise, Return with Leftover Noise
- Denoise
- Nie dość dużo stepów (steps 30, end at 20)
- Latent Image shenanigans
- Kiepski substrat + prompt = dobry kierunek
- Kiepski substrat + ZERO CONDITIONING = katastrofa
- Odpowiednio Chory Eksperyment - integrujemy wszystko
- Linki powiązane

1. Odrobina teorii - KSampler (Advancer) #
1.1. KSampler, Advanced KSampler i steps #
Mamy dwa węzły: KSampler i KSampler (Advanced). Działają podobnie, ale ten drugi daje nam więcej kontroli (jako, że pracujemy z KSamplerami i potencjalnym denoise, używam niezerowego latent space). CZARNY kolor to "zwykły" KSampler, NIEBIESKI to KSampler "Advanced".
W tym dokumencie zapoznamy się z różnicą między nimi i dojdziemy do tego jak działa KSampler.

Zacznijmy od parametru 'steps'.
- Jeśli mamy '20 steps', dla schedulera typu NORMAL on usuwa 5% szumu per step.
- Jeśli mamy '40 steps', dla schedulera typu NORMAL on usuwa 2.5% szumu per step.
Czyli próbuje zrobić to jednym ruchem dla 1 step, lub w dwóch dla 2 steps...:

Dlatego od PEWNEGO MOMENTU dla 'convergent samplers' (patrz jeden z poprzednich dokumentów) zaczyna się różnić przede wszystkim ilością detali; poniższy rysunek to różnica 50 do 20 steps:

1.2. Sampler #
Jak (w uproszczeniu) uczy się modele (za filmikiem)?

- Podajemy pliki tekstowe z obrazkami
- To jest zmienione w szum na podstawie plików tekstowych i "zrozumienia"
- Widać jak "szum zmienia się w obrazek" i vice versa przy użyciu różnych algorytmów
KSampler odwraca ten proces. Zmienia szum w obrazek.
Pole 'Sampler' reprezentuje matematyczny algorytm transformacji szumu w wynikowy rysunek.
- Wpierw sampler patrzy na ilość stepów
- Potem odpowiednio denoisuje
- Seed to naprawdę 'noise seed' - generacja szumu dodanego do Latent Image.
- I na podstawie szumu analizowany jest prompt i jest próba zbudowania rysunku pasującego do prompta, po wypaleniu / odbudowaniu szumu.
Te, które są 'convergent' - "wymuszają" kontekst obrazka pochodzący z prompta a te, które są 'non-convergent' patrzą bardziej na szum niż na kontekst obrazka (prompt).
Dlatego 'non-convergent' dla większej ilości iteracji idą w inny sposób (wszystkie 'ancestral') są non-convergent:

1.3. Scheduler #
Do tej pory mówiliśmy, że dla 20 stepów scheduler typu NORMAL usuwa 5% szumu per iterację (czyli dzieli przez ilość stepów). Do tego właśnie służy scheduler - w jaki sposób ma usuwać stepy?
- scheduler NORMAL: usuwa liniowo. 20 steps? -> 5% szumu. 40 steps? 2.5% szumu.
- scheduler EXPONENTIAL: usuwa wykładniczo. Wpierw usuwa mniej szumu, potem więcej. Więc wynik będzie bardziej inny, zwłaszcza dla samplera typu Ancestral:

Te rzeczy stają się ważne gdy kaskadujemy ze sobą KSamplery.
1.4. Add Noise, Return with Leftover Noise #
Parametry:
- Add Noise
- Return with Leftover Noise
"Prosty" KSampler zawsze dodaje szum do generacji i nie daje tu opcji.
Ale KSampler (Advanced) ma inne możliwości działania - może szumu nie dodać. Możesz np. wyjść od KSamplera, przekazać mu szum (dla pierwszej iteracji ZAWSZE chcesz dodać szum; to się dzieje gdy tego 'leftover noise' nie ma):

Jeśli kaskadujemy ze sobą KSamplery, możemy np. zacząć z czegoś idącego mocniej za promptem a potem przekazać to do Ancestral:

- Pierwszy (lewy) zaczyna od iteracji 0, kończy na 20; używa dpmpp_2m+normal
- Drugi zaczyna od iteracji 20, kończy na 40; używa euler_ancestral+exponential
- Są chainowane ze sobą; (ale output #1 jest widoczny; #2 idzie po prostu dalej)
1.5. Denoise #
To jest bardziej skomplikowane. Parametr 'DENOISE' nie występuje dla KSampler (Advanced). Ale wreszcie rozumiem o co chodzi. Wpierw spójrzmy na "identyczność"
- KSampler: denoise 0.8, steps 20 (euler, normal)
- KSampler Advanced: Steps 20, start at 4 (euler, normal)

Wynik:
- Oba rysunki są praktycznie identyczne (acz są pewne niewielkie różnice)
- (tak, przy denoise 1 / start at step 1 mamy to co wyżej)
I to prowadzi do tego czym jest parametr Denoise:
- Let’s say you start with a blank latent image.
- You feed it into a KSampler, where noise is generated as per the seed.
- KSampler then looks at the number of steps you want it take in denoising the image to come up with something. It uses the sampling method to determine the mathematics it will use in denoising each step.
- In this example you have 20 steps, so it will calculate the amount to de-noise in each step.
- It will start denoising at step 4, until 20.
Dzięki takiemu układowi mamy możliwość fajnego chainowania KSamplerów.

A dokładniej:
- simplifying, denoise = (steps - start_at_step) / steps
- You can do advanced denoising by selecting the starting and ending steps mid-schedule to pick out the specific amount and weight of the noise you want to manipulate.
- For rough understanding,
- big noise means big stuff and change of image composition
- small noise means finer stuff down to change of textures and surface.
- This is very model, sampler and schedule specific so you need to find out what step number changes what for your favorite setup.
- When you are familiar with picking specific noise by sampler schedule, next you can do is injecting noise at specific steps.
- For rough understanding,
- So far with my experimentation with SDXL in a 2x Advanced KSampler setup (one initial and then sends to Refiner) is a start_step 15, end_at_step 25, with total 30 steps is about equivalent to that 5 - 7 range denoise 'sweet spot' on the simple KSampler.
1.6. Nie dość dużo stepów (steps 30, end at 20) #
Z uwagi na to jak działa sampler i scheduler, możemy ustawić coś takiego:
- zacznij na step 1
- masz mieć 30 iteracji
- skończ na iteracji 20
W ten sposób nie usunęliśmy całego szumu. Zostaną pewne artefakty:
To dla dpm2pp_2m + uniform:

To dla dpm2pp_2m + exponential:

2. Latent Image shenanigans #
2.1. Kiepski substrat + prompt = dobry kierunek #
Zrobię prosty rysunek w paincie. Nic szczególnego:

Czyli dwie wektorowe grafiki na tle zdjęcia piramid. Zróbmy z tym coś.

A co gdybyśmy dali niski cfg (ważniejszy image niż prompt)?

Czyli kierowanie promptem zdecydowanie pomaga. Po aplikacji kilku ksamplerów, seeda, itp:

Czyli:

Oczywiście da się z tym pracować lepiej, ale na test wystarczy.
Gdybym chciał zrobić to dobrze, przeczytałbym dokument 1 jeszcze raz i zrobiłbym "dodawanie embeddingów" - osobno opisałbym promptem czołg, osobno smoka i by zadziałało. Bo tam zadziałało :-).
2.2. Kiepski substrat + ZERO CONDITIONING = katastrofa #
Tu wyzerowaliśmy prompt (czarny węzeł), dla denoise 83% (25/30):

A tu dla denoise 100% (1/30):
Seed X:

Seed X+1:

Czyli bez prompta, on 100% bazuje na tym jaki pojawi się szum.
3. Odpowiednio Chory Eksperyment - suma latent space #
Wiecie, to się nie może dobrze skończyć. Dodajmy do siebie latent space obu światów:
- smok-czołg-piramida
- obcy-grzyb-neony
Czyli:

Jako, że daję ZERO CONDITIONING, chcę dać euler-ancestral + exponential, 50 kroków.
Nie wiem CZEGO oczekiwałem, ale nie tego (rysunek samochodu sportowego to wynik innego seeda):

A jak zrobię denoise 5/50:

A jak opiszę co tam ma być (prompt: "illustration of a mushroom, tank and a dragon") i dam cfg 8:

...i na tym chyba najlepiej zakończyć ten dokument...