File size: 3,805 Bytes
cfbcb75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# tt_diffrhythm — Python reference

DiffRhythm 1.2 Full on one Tenstorrent Blackhole p100a. The CFM transformer and the stable-audio VAE
decoder run on the card; everything else stays on the CPU in DiffRhythm's own environment.

## Two processes

DiffRhythm's environment and the tt-metal runtime need different torch and numpy builds, so they run
as two processes talking over a Unix socket in a directory bind-mounted into both. Tensors cross as
raw little-endian bytes with a dtype and a shape (`wire.py`).

## Host side (inside the DiffRhythm environment)

### `TTWorker(checkpoint, image=None, log=None, reply_timeout_s=120.0, model="diffrhythm", vae=None)`

`checkpoint` is `cfm_model.pt` and `vae` is `vae_model.pt`; Hugging Face cache links are resolved.
`image` is the tt-metal / ttnn image the port was built against; it has no portable default, so set
it here or through `MUSIC_TT_IMAGE`. `.start()` starts the worker container on the card,
`.wait_ready(timeout_s)` blocks until the weights are on the device, `.close()` stops the container and
waits for it to exit, so the card is free only after that.

### `RemoteDiffRhythmDiT(worker, transformer)`

A drop-in for `cfm.transformer` in `CFM.sample` (batch 1): same call, same output. Assign it and the
upstream sampler runs unchanged.

### `RemoteVae(worker, upsample=2048)`

`[B, 64, T]` latents to `[B, 2, T * upsample]` float32 audio on the CPU. It picks the largest VAE
window from `shapes.VAE_WINDOWS` that fits the song.

## Worker side (inside the tt-metal image)

```bash
python -m tt_diffrhythm.worker --socket /ipc/worker.sock \
  --checkpoint /checkpoint/cfm_model.pt --vae /vae/vae_model.pt
```

Protocol (plain dicts, tensors via `wire`):

| | |
|---|---|
| `-> {"op": "ready", ...}` | once the weights are on the device |
| `<- {"op": "prepare", "text_embed": {drop_text: [T, 512]}, "cond": [T, 64]}` | `-> {"op": "prepared", ...}` |
| `<- {"op": "forward", "x": [T, 64], "drop_text": bool, "style": [512], "c": [512]}` | `-> {"op": "velocity", "v": [T, 64]}` |

## Direct use on the card

```python
from tt_diffrhythm import DiffRhythmDiT, DRPrecision, OobleckTT, open_device, close_device
from tt_diffrhythm.diffrhythm_host import Checkpoint

dev = open_device()
dit = DiffRhythmDiT(dev, Checkpoint("cfm_model.pt"))     # DRPrecision() by default
vae = OobleckTT(dev, "vae_model.pt")
...
close_device(dev)
```

### `DRPrecision`

Extends the shared `Precision` with the choices CFG forces. `pred + 4 (pred − null)` multiplies the
difference between the two branches by four, so the activations, the residual and the output stay in
fp32 and matmuls default to **HiFi4**. HiFi2 is about 14% faster and measurably worse
(final latent PCC 0.9931 against 0.9954).

## Kernel cache

```bash
python -m tt_diffrhythm.warm_cache
```

Compiles every sequence bucket of a 96–285 s song, both CFG branches, and the VAE windows in
`shapes.VAE_WINDOWS`. The first decode at a VAE shape costs 33.9 s against 0.33 s warm, so this is
worth running after any change to the code or the image.

## Modules

| Module | Role |
|---|---|
| `remote.py` | host side: `TTWorker`, `RemoteDiffRhythmDiT`, `RemoteVae`, the worker container |
| `worker.py` | worker side: loads the CFM transformer and the VAE and answers one host pipeline |
| `wire.py` | the tensor transport between the two torch builds |
| `shapes.py` | shapes both sides need, with no torch or ttnn import |
| `diffrhythm_dit.py` | the CFM transformer on the card, and `DRPrecision` |
| `diffrhythm_host.py` | checkpoint access, the torch reference and the sequence buckets |
| `oobleck_vae.py` | the audio VAE decoder on the card |
| `common.py` | device and host helpers shared with the tt-acestep port |
| `warm_cache.py` | ahead-of-time kernel compilation for every bucket |