Spaces:
Running on Zero
Running on Zero
| """Teacher-latent dataset plus the shared flow-matching conventions.""" | |
| import glob | |
| import os | |
| import torch | |
| from torch.utils.data import Dataset | |
| class TeacherLatents(Dataset): | |
| """Teacher ODE samples: clean latents [16, F, H, W] + their prompt index.""" | |
| def __init__(self, root, prompts_path, frames=None): | |
| self.files = sorted(glob.glob(os.path.join(root, '*.pt'))) | |
| if not self.files: | |
| raise RuntimeError(f'no .pt latents under {root}') | |
| blob = torch.load(prompts_path, map_location='cpu') | |
| self.pos = blob['pos'] # [P, 512, 4096] fp16 | |
| self.neg = blob['neg'] # [1, 512, 4096] fp16 | |
| self.prompts = blob['prompts'] | |
| self.frames = frames | |
| def __len__(self): | |
| return len(self.files) | |
| def __getitem__(self, i): | |
| d = torch.load(self.files[i], map_location='cpu', weights_only=False) | |
| lat = d['latents'].float() | |
| if self.frames is not None: | |
| lat = lat[:, :self.frames] | |
| pi = int(d['prompt_idx']) | |
| return lat, self.pos[pi].float(), pi | |
| def shifted_uniform_t(n, shift=5.0, device='cpu', generator=None): | |
| """Flow fractions distributed as Wan's inference sigma schedule. | |
| Wan samples with shift=5, which concentrates steps near t=1. Training with | |
| plain U(0,1) would under-serve exactly the region the student spends most of | |
| its few steps in, so draw from the same reparameterisation the sampler uses: | |
| t = shift*u / (1 + (shift-1)*u), u ~ U(0,1). | |
| """ | |
| u = torch.rand(n, device=device, generator=generator) | |
| return shift * u / (1 + (shift - 1) * u) | |
| def add_noise(z0, t, noise=None): | |
| """Wan's rectified-flow convention, matching train_streaming.py: | |
| z_t = (1 - t) * z0 + t * noise | |
| target = noise - z0 (velocity the model predicts) | |
| t broadcasts over [B] or [B, F]; z0 is [B, C, F, H, W]. | |
| """ | |
| if noise is None: | |
| noise = torch.randn_like(z0) | |
| while t.dim() < z0.dim(): | |
| t = t.unsqueeze(-1) | |
| return (1 - t) * z0 + t * noise, noise - z0, noise | |
| def x0_from_velocity(z_t, v, t): | |
| """Invert the flow parameterisation: z0 = z_t - t * v.""" | |
| while t.dim() < z_t.dim(): | |
| t = t.unsqueeze(-1) | |
| return z_t - t * v | |