File size: 2,457 Bytes
f4ef5e0
 
 
cb19f94
 
 
 
 
f4ef5e0
 
cb19f94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---
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.