Right now we are adding the schedulers, but it is difficult to work with since swapping the scheduler doesn't work well. This also slows down testing and evaluation of the schedulers, as a separate script needs to be made each time to test the samplers. I also was implementing these into an application and swapping the schedulers wasn't working (due to different types at runtime).
I experimented some in adding a trait, so we can use impl Scheduler. Came up with the following, but causes some points of contention.
- steps need a
&mut self for some schedulers
- steps needs a timestep of different number types (
f64 and usize) currently
- add_noise doesn't have a noise input on each one
- timesteps returns a slice of
usize or f64 (or maybe other ones?)
pub trait Scheduler {
fn step<T: SomeTraitThatWouldTakef64AndUsize>(&mut self, model_output: &Tensor, timestep: T, sample: &Tensor) -> Tensor;
fn timesteps(&self) -> &[usize];
fn add_noise(&self, original_samples: &Tensor, noise: Tensor, timestep: usize) -> Tensor;
fn init_noise_sigma(&self) -> f64;
fn scale_model_input(&self, sample: Tensor, timestep: usize) -> Tensor;
}
And then I could do the following (I'm still learning traits):
sample<T: Scheduler>(
...,
mut scheduler: T
)
And/or we could also do a Scheduler enum.
enum SamplerScheduler {
Dpmpp2m(dpmsolver_multistep::DPMSolverMultistepScheduler),
Dpmpp2s(dpmsolver_singlestep::DPMSolverSinglestepScheduler),
Ddim(ddim::DDIMScheduler),
Ddpm(ddpm::DDPMScheduler),
EulerDiscrete(euler_discrete::EulerDiscreteScheduler),
}
I'm not 100% sure what's the best approach.
Right now we are adding the schedulers, but it is difficult to work with since swapping the scheduler doesn't work well. This also slows down testing and evaluation of the schedulers, as a separate script needs to be made each time to test the samplers. I also was implementing these into an application and swapping the schedulers wasn't working (due to different types at runtime).
I experimented some in adding a trait, so we can use
impl Scheduler. Came up with the following, but causes some points of contention.&mut selffor some schedulersf64andusize) currentlyusizeorf64(or maybe other ones?)And then I could do the following (I'm still learning traits):
And/or we could also do a Scheduler enum.
I'm not 100% sure what's the best approach.