Download code/tt_diffrhythm/warm_cache.py from sunandbean/diffrhythm-1.2-p100a: direct link, hf CLI and curl.
- Browser
- Download file 3.03 kB
-
https://huggingface.co/sunandbean/diffrhythm-1.2-p100a/resolve/main/code/tt_diffrhythm/warm_cache.py
- Command line
-
hf download hf://sunandbean/diffrhythm-1.2-p100a/code/tt_diffrhythm/warm_cache.py
-
curl -L -o warm_cache.py https://huggingface.co/sunandbean/diffrhythm-1.2-p100a/resolve/main/code/tt_diffrhythm/warm_cache.py
3.03 kB
| #!/usr/bin/env python3 | |
| """Compile every P100a kernel shape this port can hit, ahead of the first songs. | |
| The card compiles kernels per shape and keeps them in TT_METAL_CACHE (data/tt-cache). Without this, the first song | |
| of each new length bucket pays that compilation (tens of seconds). Shapes, per model (--model): | |
| ENC_BUCKET), and both VAE windows (remote.py RemoteVae) | |
| diffrhythm: every DiT sequence bucket of a 96-285 s song (diffrhythm_host.seq_buckets), both CFG branches, and | |
| both VAE windows | |
| Random inputs: only the shapes matter. Run it again after changing this package or the TT image. | |
| """ | |
| import argparse | |
| import json | |
| import time | |
| import torch | |
| from . import diffrhythm_dit, diffrhythm_host as dhost, oobleck_vae | |
| from .shapes import VAE_WINDOWS | |
| def warm_vae(vae, report): | |
| for window in VAE_WINDOWS: # exactly as the worker does right after loading (worker.py) | |
| t0 = time.monotonic() | |
| audio = vae.decode(torch.zeros(64, window)) | |
| rec = {"vae_window": window, "s": round(time.monotonic() - t0, 2), "finite": bool(torch.isfinite(audio).all())} | |
| report["vae"].append(rec) | |
| print(json.dumps(rec), flush=True) | |
| def warm_diffrhythm(args): | |
| g = torch.Generator().manual_seed(0) | |
| started = time.monotonic() | |
| dev = diffrhythm_dit.open_device() | |
| report = {"seq_buckets": dhost.seq_buckets(), "dit": [], "vae": []} | |
| try: | |
| dit = diffrhythm_dit.DiffRhythmDiT(dev, dhost.Checkpoint(args.checkpoint or "/checkpoint/cfm_model.pt")) | |
| vae = oobleck_vae.OobleckTT(dev, args.vae or "/vae/vae_model.pt") | |
| report["load_s"] = round(time.monotonic() - started, 1) | |
| warm_vae(vae, report) | |
| for seq_pad in report["seq_buckets"]: | |
| frames = min(seq_pad, dhost.MAX_FRAMES) # any length in the bucket gives the same shapes | |
| t0 = time.monotonic() | |
| song = dit.prepare({null: torch.randn(frames, 512, generator=g) for null in (False, True)}, | |
| torch.randn(frames, 64, generator=g)) | |
| assert song.geo.seq_pad == seq_pad | |
| finite = True | |
| for null in (False, True): | |
| v = dit.forward(torch.randn(frames, 64, generator=g), null, torch.randn(512, generator=g), | |
| torch.randn(512, generator=g), song) | |
| finite &= bool(torch.isfinite(v).all()) | |
| dit.release(song) | |
| rec = {"seq_pad": seq_pad, "s": round(time.monotonic() - t0, 2), "finite": finite} | |
| report["dit"].append(rec) | |
| print(json.dumps(rec), flush=True) | |
| finally: | |
| diffrhythm_dit.close_device(dev) | |
| report["total_s"] = round(time.monotonic() - started, 1) | |
| print(json.dumps({k: report[k] for k in ("seq_buckets", "load_s", "total_s")}), flush=True) | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--checkpoint") | |
| parser.add_argument("--vae") | |
| args = parser.parse_args() | |
| return warm_diffrhythm(args) | |
| if __name__ == "__main__": | |
| main() | |