KSamplerAdvanced で denoise 量を指定する方法

KSamplerAdvancedKSampler の高機能版です。 KSampler で可能なことは機能的にはすべて可能な上に、サンプリングを途中で止めたり再開したりすることもできます。 ということで、KSampler で構築したワークフローの一部を KSamplerAdvanced で置き換えたい、という場合があります。 ここで問題になるのは、denoise の指定をどうするか、です。

このページでは、KSamplerdenoise とは一体何を指定する値なのか、 そして KSamplerAdvanceddenoise 相当の量をどのように指定すればよいのか、解説します。

結論 & 計算機

KSamplerAdvanced における denoise

KSamplerAdvanced: steps = , start_at_step =
=> denoise = 0.25
  • denoise = (steps - start_at_step) / steps = 1 - start_at_step / steps

置き換え (KSampler => KSamplerAdvanced)

KSampler: steps = , denoise =
=> KSamplerAdvanced: steps = 21, start_at_step = 1
  • KSamplerAdvanced.add_noise = enable
  • KSamplerAdvanced.steps = floor(KSampler.steps / KSampler.denoise)
  • KSamplerAdvanced.scheduler = KSampler.scheduler
  • KSamplerAdvanced.start_at_step = KSamplerAdvanced.steps - KSampler.steps
  • KSamplerAdvanced.end_at_step >= KSamplerAdvanced.steps

置き換え (KSamplerAdvanced => KSampler)

KSamplerAdvanced: steps = , start_at_step =
=> KSampler: steps = 5, denoise = 0.25
  • 前提: KSamplerAdvanced.add_noise = enable
  • 前提: KSamplerAdvanced.end_at_step >= KSamplerAdvanced.steps
  • KSampler.steps = KSamplerAdvanced.steps - KSamplerAdvanced.start_at_step
  • KSampler.scheduler = KSamplerAdvanced.scheduler
  • KSampler.denoise = KSampler.steps / KSamplerAdvanced.steps

目次

denoise = 1.0 の KSampler

KSampler は入力された画像 (もっとも単純な場合は EmptyLatentImage で作られた画像) を加工して出力するノードです。 加工の過程は、おおまかに言うと以下の 2段階からなります。

  1. まず denoise で指定された量のノイズを一気に加える。
  2. その後、少しずつノイズを除去する操作を、steps で指定された回数だけ繰り返す。

denoise が 1.0、steps が 20 の場合を見てみます。 (このページの図では schedulernormal の場合のみを示します。 他のスケジューラでは形が若干変わりますが、考え方は変わりません。)

denoise が 1.0 の場合は、最初に加えられるノイズの量は、U-Net の学習時に加えられた最大のノイズと同じ量になります。 各ステップ毎に取り除くノイズの量は、スケジューラが決定します。 ノイズスケジュールと呼ばれるものです。

denoise = 1.0 でない KSampler

denoise = 1.0 でない場合の動作は、おそらく皆さんが想像するであろうものとは大分違います。

実際に denoise を 0.6 に変更、steps は 20 のままにしてみると、以下のようになります。

33 ステップ分のノイズスケジュールから最後の 20 ステップ分だけを取り出して使う、ということになるのです。 20 / 33 は 0.606... で、これが denoise で指定した 0.6 に相当する値になります。

KSampler の中では、以下のような処理がされています。

  1. ステップ数が floor(steps / denoise) として、仮のノイズスケジュールを計算する (floor は少数点以下切り捨て操作)。
  2. 計算された仮のノイズスケジュールから最後の steps 数分だけを取り出して、このノードで使うノイズスケジュールの確定版とする。 残りは捨てる。
  3. 確定版に従ってノイズを加える。
  4. 確定版に従ってノイズを除去する。

denoise = 1.0 相当の KSamplerAdvanced に置き換える方法

これについては簡単です。

  • KSamplerAdvanced.add_noise = enable
  • KSamplerAdvanced.steps = KSampler.steps
  • KSamplerAdvanced.scheduler = KSampler.scheduler
  • KSamplerAdvanced.start_at_step = 0
  • KSamplerAdvanced.end_at_step >= KSamplerAdvanced.steps

まず KSampler から denoise 以外のパラメータをコピーします。 そして、ノイズは必ず加えるので add_noiseenable に、最大 denoise するので start_at_step0end_at_stepsteps 以上にする、以上です。 return_with_leftover_noise は有効でも無効でも変わりません。

denoise = 1.0 相当でない KSamplerAdvanced に置き換える方法

本題です。 KSampler に対して KSamplerAdvanced は、ステップ数に関しては直接指定できる一方で、denoise 割合については間接的に指定することになります。

denoise が 0.6、steps が 20 の KSampler に対応する KSamplerAdvanced は以下のようになります。

見ての通り、前掲の図と完全に同じ形です。

  • KSamplerAdvanced.add_noise = enable
  • KSamplerAdvanced.steps = floor(KSampler.steps / KSampler.denoise)
  • KSamplerAdvanced.scheduler = KSampler.scheduler
  • KSamplerAdvanced.start_at_step = KSamplerAdvanced.steps - KSampler.steps
  • KSamplerAdvanced.end_at_step >= KSamplerAdvanced.steps

return_with_leftover_noise は有効でも無効でも変わりません。

KSamplerAdvanced から KSampler への置き換え

場合によっては、逆方向の変換もできます。

  • 前提: KSamplerAdvanced.add_noise = enable
  • 前提: KSamplerAdvanced.end_at_step >= KSamplerAdvanced.steps
  • KSampler.steps = KSamplerAdvanced.steps - KSamplerAdvanced.start_at_step
  • KSampler.scheduler = KSamplerAdvanced.scheduler
  • KSampler.denoise = KSampler.steps / KSamplerAdvanced.steps

当然ながら、ノイズを加えない場合 (サンプリングを再開する場合)、end_at_stepsteps 未満の場合 (サンプリングを途中で止める場合) は、KSampler への置き換えはできません。