(
order,
model_output: torch.Tensor,
sample: torch.Tensor,
step_index: int,
timesteps: list,
sigmas: torch.Tensor,
dpm_state: DPMState = None,
)
| 205 | |
| 206 | |
| 207 | def dpm_step( |
| 208 | order, |
| 209 | model_output: torch.Tensor, |
| 210 | sample: torch.Tensor, |
| 211 | step_index: int, |
| 212 | timesteps: list, |
| 213 | sigmas: torch.Tensor, |
| 214 | dpm_state: DPMState = None, |
| 215 | ) -> torch.Tensor: |
| 216 | |
| 217 | # Improve numerical stability for small number of steps |
| 218 | lower_order_final = step_index == len(timesteps) - 1 |
| 219 | lower_order_second = (step_index == len(timesteps) - 2) and len(timesteps) < 15 |
| 220 | |
| 221 | model_output = convert_model_output(model_output, sample, sigmas, step_index=step_index) |
| 222 | |
| 223 | assert dpm_state is not None |
| 224 | dpm_state.update(model_output) |
| 225 | |
| 226 | # Upcast to avoid precision issues when computing prev_sample |
| 227 | sample = sample.to(torch.float32) |
| 228 | |
| 229 | if order == 1 or dpm_state.lower_order_nums < 1 or lower_order_final: |
| 230 | if step_index == 0 or lower_order_final: |
| 231 | prev_sample, _, _, _ = ddim_update( |
| 232 | model_output, |
| 233 | sigmas.to(torch.float64), |
| 234 | step_index, |
| 235 | sample, |
| 236 | eta=0.0, |
| 237 | ) |
| 238 | else: |
| 239 | prev_sample = dpm_solver_first_order_update( |
| 240 | model_output, |
| 241 | sigmas.to(torch.float64), |
| 242 | step_index, |
| 243 | sample, |
| 244 | ) |
| 245 | elif order == 2 or dpm_state.lower_order_nums < 2 or lower_order_second: |
| 246 | prev_sample = multistep_dpm_solver_second_order_update( |
| 247 | dpm_state.model_outputs, |
| 248 | sigmas.to(torch.float64), |
| 249 | step_index, |
| 250 | sample, |
| 251 | ) |
| 252 | else: |
| 253 | assert False |
| 254 | |
| 255 | dpm_state.update_lower_order() |
| 256 | |
| 257 | # Cast sample back to expected dtype |
| 258 | prev_sample = prev_sample.to(model_output.dtype) |
| 259 | |
| 260 | return prev_sample, model_output, None |
| 261 | |
| 262 | |
| 263 | def convert_model_output( |
no test coverage detected