Spaces:
Running on Zero
Running on Zero
| """Rectified flow / flow matching objective (SD3 formulation), native PyTorch. | |
| Convention: predict velocity v = eps - x0 along the linear interpolant | |
| x_t = (1 - t) * x0 + t * eps , t in [0, 1] (t=0 data, t=1 noise). | |
| """ | |
| from __future__ import annotations | |
| import torch | |
| import torch.nn.functional as F | |
| from diffusers.training_utils import compute_density_for_timestep_sampling | |
| def repa_loss(proj_hidden: torch.Tensor, target_feats: torch.Tensor) -> torch.Tensor: | |
| """REPA (ICLR'25): cosine-align projected DiT hidden states to frozen-encoder features. | |
| Args: | |
| proj_hidden: Projected DiT hidden states, ``[B, D]`` or ``[B, N, D]``. | |
| target_feats: Frozen-encoder (DINOv3) features, same shape as ``proj_hidden``. | |
| Returns: | |
| Scalar alignment loss (lower is better fine structure). | |
| """ | |
| p = F.normalize(proj_hidden, dim=-1) | |
| t = F.normalize(target_feats, dim=-1) | |
| return (1.0 - (p * t).sum(dim=-1)).mean() | |
| def sample_timesteps(batch: int, device: torch.device, mean: float = 0.0, std: float = 1.0) -> torch.Tensor: | |
| """Logit-normal flow-matching timesteps ``[B]`` in ``[0, 1]`` (emphasizes the hard mid-range). | |
| Delegates to diffusers' own SD3 sampler instead of re-deriving the formula: with | |
| ``weighting_scheme="logit_normal"`` it returns ``sigmoid(N(mean, std))`` — identical to the | |
| hand-rolled ``sigmoid(randn*std + mean)`` it replaces. | |
| """ | |
| return compute_density_for_timestep_sampling( | |
| weighting_scheme="logit_normal", batch_size=batch, logit_mean=mean, logit_std=std, device=device | |
| ) | |
| def interpolate(x0: torch.Tensor, eps: torch.Tensor, t: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: | |
| """Linear interpolant ``x_t`` and its velocity target ``v = eps - x0``. | |
| Args: | |
| x0: Clean data latents ``[B, ...]`` (t=0 endpoint). | |
| eps: Gaussian noise of the same shape (t=1 endpoint). | |
| t: Per-sample timesteps ``[B]`` in ``[0, 1]``. | |
| Returns: | |
| ``(x_t, target_v)``, both shaped like ``x0``. | |
| """ | |
| t_ = t.view(-1, *([1] * (x0.dim() - 1))) | |
| x_t = (1 - t_) * x0 + t_ * eps | |
| target_v = eps - x0 | |
| return x_t, target_v | |
| def flow_loss( | |
| v_pred: torch.Tensor, target_v: torch.Tensor, weight: torch.Tensor | None = None | |
| ) -> torch.Tensor: | |
| """MSE on velocity. ``weight`` (broadcastable, e.g. ink-focal map) is applied as a weighted mean, | |
| normalized by the mean weight so the loss magnitude stays comparable to the unweighted case.""" | |
| se = (v_pred - target_v) ** 2 | |
| if weight is not None: | |
| return (se * weight).mean() / weight.mean().clamp_min(1e-6) | |
| return se.mean() | |