MolecularDiffusion.modules.models.reactot.schedule¶
The Schrodinger-bridge schedule React-OT replaces DDPM’s noise with.
Vendored from reactot/diffusion/_schedule.py and
reactot/diffusion/_utils.py of
https://github.com/deepprinciple/react-ot at commit 6dfccd0.
SBSchedule is a plain Python class, not an nn.Module. It
holds no buffers and nothing of it reaches a state dict – which is exactly
why React-OT’s released checkpoint has 246 tensors where OA-ReactDiff’s has
248 (OA carries two gamma buffers of 5001 + 151 values, and
10,651,063 - 10,645,911 = 5,152).
A load-bearing degeneracy in the released settings¶
At timesteps=3000 / beta_max=0.3 / power=0.5 the schedule is
constant:
linear_end = beta_max / timesteps = 1e-4 = make_beta_schedule's own
hardcoded linear_start, so the linspace is degenerate; ** 0.5 keeps it
constant; the mirror-concatenate keeps it constant; and the final
renormalisation lands every entry on 5e-5.
ode_sampling()
asserts that constancy (en_sb.py:411 upstream). Changing timesteps
or beta_max therefore breaks the ODE solver with an assertion, and
changes the DDPM solver’s meaning silently. Both must stay at 3000 / 0.3;
see the plan’s Hyperparameter Provenance table.
Classes¶
The bridge's variance schedule. |
Functions¶
|
Coefficients of the product of two Gaussians. |
|
Betas for the bridge, as upstream builds them. |
|
|
|
Append |
Module Contents¶
- class MolecularDiffusion.modules.models.reactot.schedule.SBSchedule(timesteps: int = 1000, beta_max: float = 0.3, power: float = 1.0, inv_power: float = 1.0)¶
The bridge’s variance schedule.
Not an
nn.Module: see the module docstring. Everything is derived frombetas, so a task rebuilds it from four numbers at construction and the checkpoint carries none of it.- timesteps¶
grid length, taken from the built array rather than the argument (the mirror-concatenate makes them equal for even
timesteps, which 3000 is).
- betas¶
(T,)per-step variance increments.
- std_fwd¶
sqrt(cumsum(betas)).
- std_bwd¶
sqrt(reverse cumsum(betas)).
- std_sb¶
sqrt(var)of the bridge marginal.
- mu_x0¶
weight on the endpoint
x0inq(x_t | x_0, x_1).
- mu_x1¶
weight on the endpoint
x1.
Build the schedule.
- Parameters:
timesteps – grid length. 3000 for the released weights.
beta_max – total variance. 0.3 for the released weights.
power – exponent on the linspace.
inv_power – exponent on its endpoints.
- get_std_fwd(step: torch.Tensor, xdim: Any = None) torch.Tensor¶
std_fwdatstep, optionally broadcast toxdim.- Parameters:
step – integer index tensor.
xdim – trailing shape to broadcast against;
None=> none.
- Returns:
The looked-up standard deviations.
- static inflate_batch_array(array: torch.Tensor, target: torch.Tensor) torch.Tensor¶
Reshape a per-node vector to broadcast against
target.- Parameters:
array –
(n,)(or(n, 1, ..., 1)).target – the tensor whose rank it must match.
- Returns:
arrayviewed as(n, 1, ..., 1).
- betas¶
- mu_x0¶
- mu_x1¶
- std_bwd¶
- std_fwd¶
- std_sb¶
- timesteps¶
- MolecularDiffusion.modules.models.reactot.schedule.compute_gaussian_product_coef(sigma1: Any, sigma2: Any) Tuple[Any, Any, Any]¶
Coefficients of the product of two Gaussians.
Given
p1 = N(x_t | x_0, sigma1**2)andp2 = N(x_t | x_1, sigma2**2), return(coef1, coef2, var)such thatp1 * p2 = N(x_t | coef1 * x0 + coef2 * x1, var).Deliberately untyped in its operands: it is called both with numpy arrays (schedule construction) and with torch tensors (
EnSB.p_posterior()), and does nothing either cannot do.- Parameters:
sigma1 – first standard deviation.
sigma2 – second standard deviation.
- Returns:
(coef1, coef2, var).
- MolecularDiffusion.modules.models.reactot.schedule.make_beta_schedule(n_timestep: int = 1000, linear_start: float = 0.0001, linear_end: float = 0.02, power: float = 1.0, inv_power: float = 1.0) numpy.ndarray¶
Betas for the bridge, as upstream builds them.
- Parameters:
n_timestep – length of the grid.
linear_start – first endpoint, before
inv_power/power.linear_end – last endpoint; the caller passes
beta_max/timesteps.power – exponent applied to the whole linspace.
inv_power – exponent applied to each endpoint first.
- Returns:
(n_timestep,)float64 array.
- MolecularDiffusion.modules.models.reactot.schedule.space_indices(num_steps: int, count: int) List[int]¶
countindices spread evenly overrange(num_steps).This is what turns React-OT’s 3000-step grid into an
nfe-step sampling schedule:space_indices(3000, nfe + 1)picks thenfe + 1grid points the sampler walks backwards through, so the number of network evaluations isnfe.- Parameters:
num_steps – size of the grid to sample from.
count – how many indices to take.
- Returns:
Ascending list of
countindices, starting at 0.
- MolecularDiffusion.modules.models.reactot.schedule.unsqueeze_xdim(z: torch.Tensor, xdim: Sequence[int]) torch.Tensor¶
Append
len(xdim)trailing singleton axes toz.- Parameters:
z – tensor to broadcast.
xdim – the trailing shape it must broadcast against.
- Returns:
zviewed with the extra axes.