@@ -2582,27 +2582,49 @@ static sd::Tensor<float> sample_lms(denoise_cb_t model,
25822582 sd::Tensor<float > x,
25832583 const std::vector<float >& sigmas,
25842584 const SamplerExtraArgs& extra_sample_args) {
2585- // Linear Multi-Step from https://github.com/crowsonkb/k-diffusion
2586-
2585+ // Linear Multi-Step from https://github.com/crowsonkb/k-diffusion,
2586+ // modified with "history shift" value, which seemingly needs less steps
25872587 int divisions = 1000 ;
2588+ int max_order = 4 ;
2589+ int shift = 1 ; // 4, 0 - original; 4, 1 - PR #1843; 3, 1 - smoother image
25882590 for (const auto & [key, value] : extra_sample_args) {
25892591 int parsed = 0 ;
2592+ if (key == " lms_max_order" ) {
2593+ if (!parse_strict_int (value, parsed)) {
2594+ LOG_WARN (" ignoring invalid lms extra sample arg '%s=%s'" , key.c_str (), value.c_str ());
2595+ continue ;
2596+ }
2597+ max_order = std::max (1 , parsed);
2598+ // smaller values make the result softer, closer to Euler
2599+ // higher values need more steps
2600+ // values above 12 can produce NaNs, depending on steps and scheduler
2601+ }
2602+ if (key == " lms_shift" ) {
2603+ if (!parse_strict_int (value, parsed)) {
2604+ LOG_WARN (" ignoring invalid lms extra sample arg '%s=%s'" , key.c_str (), value.c_str ());
2605+ continue ;
2606+ }
2607+ shift = std::max (0 , parsed);
2608+ // for a low number of steps, the value 1 works best
2609+ }
25902610 if (key == " lms_divisions" ) {
25912611 if (!parse_strict_int (value, parsed)) {
25922612 LOG_WARN (" ignoring invalid lms extra sample arg '%s=%s'" , key.c_str (), value.c_str ());
25932613 continue ;
25942614 }
25952615 divisions = parsed; // std::max(1, parsed);
2596- // values above 35M produce noise, can be fixed by double precision
25972616 // values < 1 always produce noise
2617+ // values above 30M require double precision in the integrator
2618+ // (they are needless and just slow the integration down, but
2619+ // with single precision they softly produce noise
2620+ // near the 35M, it can be used for distorted generations)
25982621 }
25992622 }
2600- LOG_DEBUG (" linear multi-step sampler: integrating using %i division%s" , divisions, (divisions == 1 ) ? " " : " s" );
26012623
26022624 auto linear_multistep_coeff = [=](const int order, const int m, const int j) -> float {
26032625 if (!divisions)
26042626 return sigmas[m + 1 ] - sigmas[m]; // delta / 0 * 0
2605- #define LMS_PRECISION float // double
2627+ #define LMS_PRECISION float // when divisions > 30 millions, the double precision fixes noise
26062628 const LMS_PRECISION a = sigmas[m], dx = (sigmas[m + 1 ] - a) / divisions, s = sigmas[m - j];
26072629 const LMS_PRECISION b0 = a + 0 .5f * dx; // using Riemann middle integral
26082630 LMS_PRECISION sum = 0 .0f ;
@@ -2622,11 +2644,12 @@ static sd::Tensor<float> sample_lms(denoise_cb_t model,
26222644 return sum * dx;
26232645 };
26242646
2625- const int max_order = 4 ;
2626- float lms_coeff[max_order];
2647+ int steps = static_cast <int >(sigmas.size ()) - 1 ;
2648+ max_order = std::min (max_order, steps); // history can not be larger than steps
2649+ LOG_DEBUG (" linear multi-step sampler: lms_max_order = %i, lms_shift = %i, lms_divisions = %i" , max_order, shift, divisions);
2650+ std::vector<float > lms_coeff (max_order);
26272651 std::vector<sd::Tensor<float >> hist = {};
26282652
2629- int steps = static_cast <int >(sigmas.size ()) - 1 ;
26302653 for (int i = 0 ; i < steps; i++) {
26312654 const float sigma = sigmas[i];
26322655
@@ -2637,25 +2660,26 @@ static sd::Tensor<float> sample_lms(denoise_cb_t model,
26372660 sd::Tensor<float > denoised = std::move (denoised_opt.pred );
26382661
26392662 const int order = std::min (max_order, i + 1 );
2663+
26402664 for (int c = 0 ; c < order; c++) // computing coefficients
26412665 lms_coeff[c] = linear_multistep_coeff (order, i, c);
26422666
26432667 sd::Tensor<float > d_cur = (x - denoised) / sigma;
2644- switch (order) {
2645- case 4 : // derivative + 3 history points
2646- x += hist[hist.size () - 2 ] * lms_coeff[3 ];
2647- case 3 :
2648- x += hist[hist.size () - 1 ] * lms_coeff[2 ];
2649- case 2 :
2650- x += hist.back () * lms_coeff[1 ];
2651- case 1 :
2652- x += d_cur * lms_coeff[0 ];
2653- }
2654-
2655- if (hist.size () == static_cast <size_t >(max_order - 1 )) {
2656- hist.erase (hist.begin ());
2668+ x += d_cur * lms_coeff[0 ];
2669+ if (max_order > 1 ) { // if max_order == 1, the history is not used (order always < 2)
2670+ int hist_size_p1 = hist.size () + 1 ;
2671+ if (i) { // history does not exist at 1st step
2672+ int hist_max = hist.size () - 1 ;
2673+ for (int c = 2 ; c <= order; c++)
2674+ x += hist[std::min (hist_max, hist_size_p1 - c + shift)] * lms_coeff[c - 1 ];
2675+ // max_order == 4 => hist[] index = 2, 1, 0
2676+ // shift == 1 => hist[] index = 2, 2, 1
2677+ }
2678+ if (hist_size_p1 == max_order) {
2679+ hist.erase (hist.begin ());
2680+ }
2681+ hist.push_back (std::move (d_cur));
26572682 }
2658- hist.push_back (std::move (d_cur));
26592683 }
26602684 return x;
26612685}
0 commit comments