Download src/diffusion/schedules.py from AnonMLuser/remdm-planner-minihack: direct link, hf CLI and curl.
- Browser
- Download file 3.46 kB
-
https://huggingface.co/AnonMLuser/remdm-planner-minihack/resolve/main/src/diffusion/schedules.py
- Command line
-
hf download hf://AnonMLuser/remdm-planner-minihack/src/diffusion/schedules.py
-
curl -L -o schedules.py https://huggingface.co/AnonMLuser/remdm-planner-minihack/resolve/main/src/diffusion/schedules.py
3.46 kB
| """Noise schedule functions for MDLM diffusion. | |
| All functions operate on PyTorch tensors and are pure (no global state). | |
| Convention: alpha(t) is the fraction of tokens that remain *unmasked*. | |
| - alpha(0) = 1.0 (fully clean) | |
| - alpha(1) = 0.0 (fully masked) | |
| """ | |
| from __future__ import annotations | |
| import math | |
| from collections.abc import Callable | |
| import torch | |
| from torch import Tensor | |
| def linear_schedule(t: Tensor) -> Tensor: | |
| """Linear noise schedule: alpha(t) = 1 - t. | |
| Args: | |
| t: Diffusion time in [0, 1]. Any shape. | |
| Returns: | |
| Retention probability alpha_t, same shape as *t*. | |
| """ | |
| return 1.0 - t | |
| def cosine_schedule(t: Tensor) -> Tensor: | |
| """Cosine noise schedule: alpha(t) = cos(pi/2 * t). | |
| MDLM Appendix E.1 eq (92) ("Cosine"); the same function the craftax | |
| repo names "cosine". | |
| Args: | |
| t: Diffusion time in [0, 1]. Any shape. | |
| Returns: | |
| Retention probability alpha_t, same shape as *t*. | |
| """ | |
| return torch.cos(t * (math.pi / 2.0)) | |
| def cosine_sq_schedule(t: Tensor) -> Tensor: | |
| """Cosine-squared noise schedule: alpha(t) = cos(pi/2 * t)^2. | |
| MDLM Appendix E.1 eq (91) ("Cosine Squared", after Nichol & Dhariwal). | |
| Previously registered under the name "cosine" in this repo; renamed so | |
| the label "cosine" denotes the same function in both repos. | |
| Args: | |
| t: Diffusion time in [0, 1]. Any shape. | |
| Returns: | |
| Retention probability alpha_t, same shape as *t*. | |
| """ | |
| return torch.cos(t * (math.pi / 2.0)) ** 2 | |
| def linear_schedule_deriv(t: Tensor) -> Tensor: | |
| """Analytic d(alpha)/dt for the linear schedule.""" | |
| return torch.full_like(t, -1.0) | |
| def cosine_schedule_deriv(t: Tensor) -> Tensor: | |
| """Analytic d(alpha)/dt for the cosine schedule.""" | |
| return -(math.pi / 2.0) * torch.sin(t * (math.pi / 2.0)) | |
| def cosine_sq_schedule_deriv(t: Tensor) -> Tensor: | |
| """Analytic d(alpha)/dt for the cosine-squared schedule.""" | |
| return -(math.pi / 2.0) * torch.sin(t * math.pi) | |
| _SCHEDULE_MAP: dict[str, Callable[[Tensor], Tensor]] = { | |
| "linear": linear_schedule, | |
| "cosine": cosine_schedule, | |
| "cosine_sq": cosine_sq_schedule, | |
| } | |
| _DERIV_BY_FN: dict[Callable[[Tensor], Tensor], Callable[[Tensor], Tensor]] = { | |
| linear_schedule: linear_schedule_deriv, | |
| cosine_schedule: cosine_schedule_deriv, | |
| cosine_sq_schedule: cosine_sq_schedule_deriv, | |
| } | |
| def get_schedule_deriv_for( | |
| schedule_fn: Callable[[Tensor], Tensor], | |
| ) -> Callable[[Tensor], Tensor]: | |
| """Analytic derivative for a registered schedule function. | |
| The NELBO weight uses the analytic d(alpha)/dt as stated in | |
| MDLM eq (10) / Shi eq (4). | |
| Raises: | |
| KeyError: If *schedule_fn* is not a registered schedule. | |
| """ | |
| if schedule_fn not in _DERIV_BY_FN: | |
| raise KeyError( | |
| "No analytic derivative registered for " | |
| f"{getattr(schedule_fn, '__name__', schedule_fn)!r}" | |
| ) | |
| return _DERIV_BY_FN[schedule_fn] | |
| def get_schedule(name: str) -> Callable[[Tensor], Tensor]: | |
| """Look up a noise schedule by name. | |
| Args: | |
| name: One of ``"linear"``, ``"cosine"``, ``"cosine_sq"``. | |
| Returns: | |
| The schedule function ``alpha(t)``. | |
| Raises: | |
| KeyError: If *name* is not registered. | |
| """ | |
| if name not in _SCHEDULE_MAP: | |
| raise KeyError( | |
| f"Unknown schedule '{name}'. Available: {list(_SCHEDULE_MAP.keys())}" | |
| ) | |
| return _SCHEDULE_MAP[name] | |