BiliSakura commited on
Commit
3765616
·
verified ·
1 Parent(s): ccbbabe

Update JiT-B-16-SIM/scheduler/scheduling_flow_match_fd.py

Browse files
JiT-B-16-SIM/scheduler/scheduling_flow_match_fd.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 The FD-Loss Authors. SPDX-License-Identifier: MIT
2
+ """Flow-matching scheduler for JiT, pMF, and iMF sampling."""
3
+
4
+ from dataclasses import dataclass
5
+ from typing import Optional
6
+
7
+ import numpy as np
8
+ import torch
9
+
10
+ from diffusers.configuration_utils import ConfigMixin, register_to_config
11
+ from diffusers.schedulers.scheduling_utils import SchedulerMixin
12
+ from diffusers.utils import BaseOutput
13
+
14
+
15
+ @dataclass
16
+ class FDLossFlowMatchSchedulerOutput(BaseOutput):
17
+ prev_sample: torch.FloatTensor
18
+
19
+
20
+ class FDLossFlowMatchScheduler(SchedulerMixin, ConfigMixin):
21
+ """
22
+ Euler / Heun flow-matching scheduler used by FD-Loss generators.
23
+
24
+ Timesteps run from 1 (noise) to 0 (data), matching the training convention in this repo.
25
+ """
26
+
27
+ config_name = "scheduler_config.json"
28
+ order = 1
29
+
30
+ @register_to_config
31
+ def __init__(self, num_train_timesteps: int = 1000):
32
+ self.num_train_timesteps = num_train_timesteps
33
+ self.timesteps = torch.from_numpy(np.linspace(1.0, 0.0, num_train_timesteps + 1))
34
+
35
+ def set_timesteps(self, num_inference_steps: int, device: Optional[torch.device] = None):
36
+ self.timesteps = torch.linspace(1.0, 0.0, num_inference_steps + 1, device=device)
37
+ return self.timesteps
38
+
39
+ def step(
40
+ self,
41
+ model_output: torch.Tensor,
42
+ timestep: torch.Tensor,
43
+ sample: torch.Tensor,
44
+ next_timestep: torch.Tensor,
45
+ return_dict: bool = True,
46
+ ) -> FDLossFlowMatchSchedulerOutput:
47
+ dt = next_timestep.reshape(-1, *([1] * (sample.ndim - 1))) - timestep.reshape(
48
+ -1, *([1] * (sample.ndim - 1))
49
+ )
50
+ prev_sample = sample + dt * model_output
51
+ if not return_dict:
52
+ return (prev_sample,)
53
+ return FDLossFlowMatchSchedulerOutput(prev_sample=prev_sample)
54
+
55
+ def step_heun(
56
+ self,
57
+ model_output: torch.Tensor,
58
+ next_model_output: torch.Tensor,
59
+ timestep: torch.Tensor,
60
+ sample: torch.Tensor,
61
+ next_timestep: torch.Tensor,
62
+ return_dict: bool = True,
63
+ ) -> FDLossFlowMatchSchedulerOutput:
64
+ dt = next_timestep.reshape(-1, *([1] * (sample.ndim - 1))) - timestep.reshape(
65
+ -1, *([1] * (sample.ndim - 1))
66
+ )
67
+ prev_sample = sample + dt * 0.5 * (model_output + next_model_output)
68
+ if not return_dict:
69
+ return (prev_sample,)
70
+ return FDLossFlowMatchSchedulerOutput(prev_sample=prev_sample)