| --- |
| license: mit |
| tags: |
| - taiko |
| - rhythm-game |
| - chart-generation |
| - music |
| - audio-to-symbolic |
| --- |
| |
| # π₯ SoftChart v1.5 β unified model |
|
|
| **One 7.94M-parameter model (bf16, ~16 MB) replacing three** (slot generator + |
| time generator + beat model, 24.5M / ~98 MB): β68% parameters, β84% disk, |
| with measured quality **parity or better** on every axis. |
|
|
| | axis | v1.5 (this model) | v1.0 dedicated | verdict | |
| |---|---|---|---| |
| | slot-mode F1 (12 songs) | 0.663 / oni **0.732** | 0.665 / 0.727 (slot12) | parity, oni better | |
| | time-mode F1 | **0.682** / oni 0.721 | 0.659 (pr12) | **better** | |
| | beat grid ok-rate (const) | **1.0** Β· p50 10.5 ms | 0.93 Β· 10.2 ms (beatd2) | better | |
| | beat grid (variable BPM) | 0.9 Β· p50 **3.2 ms** | 1.0 Β· 4.0 ms | parity | |
| | tuplet evenness (CV) | 0.0006 | 0.0006 | parity | |
|
|
| How the reduction was achieved (all measured, see repo REPORT): |
|
|
| 1. **Role folding** β dual-mode training (50% slot / 50% time windows, MODE |
| token) + a hi-res beat head. Beat supervision is **masked on slot |
| windows**: they carry grid-phase input channels, and an unmasked head |
| copies the channels instead of listening (measured collapse: 723 ms β |
| fixed: 10.5 ms). |
| 2. **Factorized embeddings** (ALBERT-style, E=64) β position tokens are 95% |
| of the table; 463K β 132K. |
| 3. **bf16 weights** β training ran bf16 autocast, so fp32 storage carried no |
| extra information (verified: F1/grid identical within noise). |
|
|
| Interesting side effect: the shared trunk **improved** both the time mode |
| (+2.3pp over the dedicated model) and the beat ok-rate β beat supervision |
| appears to act as a metrical regularizer for generation, and vice versa. |
|
|
| Usage (drop-in for all three v1.0 roles): |
|
|
| ```python |
| from softchart.generate import load_hf, generate_song_slot, generate_song |
| from softchart.grid import fit_grid_piecewise |
| from softchart.tja import write_tja_slots |
| |
| m = load_hf("JacobLinCool/softchart-v15") # one model, three roles |
| grid = fit_grid_piecewise(m, mel) # its own beat head drives the grid |
| g = generate_song_slot(m, mel, grid, "oni", level=9, density_bucket=7) |
| tja = write_tja_slots(g, grid, "Title", "oni", 9, "song.ogg") |
| # gridless fallback: generate_song(m, mel, "oni", level=9) (time mode) |
| ``` |
|
|
| MIT-licensed. Trained from scratch on community-made charts |
| ([taiko-1000-parsed](https://huggingface.co/datasets/JacobLinCool/taiko-1000-parsed)); |
| the official game never released chart data. |
|
|