Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 57 additions & 10 deletions REPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,70 @@ Ten sam cel (predykcja następnego znaku), spektrum mechanizmów — od twardego
- **GPT** wygrywa ppl zmiennym, długim kontekstem (uwaga), kosztem ~800K param.
Prawdziwe osie spektrum to **pamięć i generalizacja**, nie sam ppl.

## 5. Co wiemy / czego nie

**Udowodnione (z liczbą):** mały char-LM uczy się struktury muzyki; czyszczenie danych obniża perplexity (3,88 → 3,80); mechanizm szwu bezstratny; ensemble bije pojedyncze modele; **niezależne maluchy mają wspólną geometrię** (CKA, po audycie); zmierzone **spektrum n-gram → NPLM → transformer** (ppl vs pamięć vs generalizacja).

**Jeszcze nie:** że łączenie reprezentacji **bije** ensemble — to wymaga ekspertów **komplementarnych** (różne, nakładające się domeny) i/lub wymuszonego wspólnego kontraktu; routing.

## 6. Następne kroki
## 5. Łuk trzeci: sędzia — mierzenie „czy to w ogóle muzyka" (E-JUDGE)

PPL ma dwie ślepe plamy: nie odpowiada, czy generacja *działa jako muzyka*, i nie porównuje
modeli z różnych korpusów. Zbudowaliśmy więc niezależnego sędziego: klasyfikator `JudgeGPT`
(trunk GPT verbatim + mean-pool + 3 głowy; 55 tys. melodii z thesession.org, split po
`tune_id`), który patrząc TYLKO na ciało melodii (nagłówki `M:`/`K:` wycinane — nie można
oszukiwać promptem) przewiduje **meter / mode / type**. Val acc: meter 0.92, mode 0.72,
type 0.82 — z pomyłkami muzycznie prawidłowymi (hornpipe↔reel to para najtrudniejsza nawet
dla ludzi; Bmin↔D to ten sam zbiór dźwięków — sufit informacyjny).

**Benchmark domenowy.** Każdego eksperta oceniamy wyłącznie na melodiach z jego własnej
domeny (pula walidacyjna ograniczona filtrem type+metrum z `domains.json`). Wynik (score) to
średnie prawdopodobieństwo, jakie sędzia przyznaje prawdziwym etykietom; każda porażka modelu
liczy się jako zero (brak zniekształcenia przez „przeżywających"), a punktem odniesienia
(sufitem) jest ocena przez tego samego sędziego **prawdziwych** melodii tej domeny. Wyniki:
jigi osiągają **80–86% sufitu**, walc 86% (sufit miękki — sędzia sam jest mało pewny na 3/4),
reele 69–72%. Ranking wyznaczony przez sędziego pokrywa się z rankingiem PPL — dwie
niezależne miary, jeden werdykt. Odnotujmy uczciwie: pierwsza wersja benchmarku, oceniająca
wszystkich ekspertów na jednej wspólnej puli melodii, pokazywała dokładnie odwrotnie
(najlepiej wypadały reele). To była wada pomiaru, nie właściwość modeli: niezbalansowane
klasy sprawiały, że ekspert 4/4 „wygrywał" tam, gdzie prawda o metrum była po prostu
najczęstsza. Dopiero pule domenowe dały uczciwy obraz — kolejny pomiar, który obalił nasze
pierwsze odczytanie.

**Macierz OOD** (ekspert × domena celu; prawda = to, o co prosimy):
- Diagonala dominuje wszędzie — **specjalizacja ekspertów jest realna**.
- **Nagłówki nie sterują poza domeną**: jig z promptem `M:4/4` generuje 6/8 z pewnością
0.94 (home-bias 0.9). Sterowanie promptem jest martwe.
- **Kontekst steruje w połowie**: z prawdziwym prefiksem melodii home-bias spada do ~0.5,
score rośnie do 40–63% sufitu. Modele czytają styl z nut, nie z nagłówków — w domenie też
(mode z `K:` słabo, z prefiksu lepiej).
- **Asymetria**: najlepsze komórki OOD to reele→jigi (≈60% sufitu, home-bias type 0.2) —
eksperci 4/4 są elastyczni, 6/8 to twardy nawyk.
- **Elastyczność siedzi w małych modelach**: e32 mają najniższy home-bias wszędzie
(najsłabiej „zapatrzone" w swoją domenę) przy najsłabszej diagonali; duże modele są
najsztywniejsze. Nowa hipoteza pod E1: **komplementarność może wolić małe, gibkie modele
mimo gorszego PPL**.
- Bach (chorały) jest uczciwie wyłączony: bez wspólnego słownika nie da się go nawet
zakodować w irlandzkich promptach — wspólny kontrakt słownikowy to warunek wstępny
dalszych testów.

Ograniczenia: sędzia ma fizyczny sufit na mode (tonacje względne są niedróżnialne z treści
dźwiękowej); macierz OOD policzona na n=30/komórkę — wersja pod paper wymaga pełnego
przebiegu i sufitu z całej puli.

## 6. Co wiemy / czego nie

**Udowodnione (z liczbą):** mały char-LM uczy się struktury muzyki; czyszczenie danych obniża perplexity (3,88 → 3,80); mechanizm szwu bezstratny; ensemble bije pojedyncze modele; **niezależne maluchy mają wspólną geometrię** (CKA, po audycie); zmierzone **spektrum n-gram → NPLM → transformer** (ppl vs pamięć vs generalizacja); **sędzia niezależny od PPL potwierdza ranking ekspertów** i mierzy nową oś (specjalizacja: jigi 80–86% sufitu, reele 69–72%); **nagłówki nie sterują ekspertem poza domeną, kontekst melodyczny tak (w połowie)**; **elastyczność OOD rośnie, gdy model jest mniejszy** (hipoteza pod E1, do potwierdzenia).

**Jeszcze nie:** że łączenie reprezentacji **bije** ensemble — to wymaga ekspertów **komplementarnych** (różne, nakładające się domeny) i/lub wymuszonego wspólnego kontraktu; routing; pełna (n=100) macierz OOD z sufitem z całej puli; wspólny słownik (warunek testów międzykorpusem, m.in. dla Bacha).

## 7. Następne kroki
1. Pre-check: czy rozbieżność (wariancja) między ekspertami koreluje z błędem — bramka przed routingiem.
2. Wymuszony wspólny kontrakt (zamrożony front + głowa) na stylach w **tym samym metrum** (różne metrum = model oszukuje po nagłówku — pułapka pomiaru) + ekspertach **komplementarnych**.
3. Bogatszy, nieliniowy łącznik — dopiero jeśli (2) pokaże sygnał.
3. **Wspólny słownik przy trenowaniu ekspertów** — usuwa klasę artefaktów OOD (dziś: pominięcia słownikowe, wyłączony Bach) i jest wstępem do stitcha między ekspertami.
4. E-JUDGE ensemble/stitch: te same melodie, ten sam sędzia — czy metoda kompozycji bije pojedynczych ekspertów w oś stylu, nie tylko w PPL.
5. Bogatszy, nieliniowy łącznik — dopiero jeśli (2) pokaże sygnał.
- Osobny kierunek: wiele modeli „grające razem" (polifonia, synchronizacja).

## 7. Po co to
## 8. Po co to
Dwa cele: (a) **budować know-how zespołu Slayer** — tani, jawny, reprodukowalny poligon; (b) **de-ryzykować metody** pod docelowy model budowlany (klasyfikacja / tworzenie / rozumienie `.ifc`), gdzie poprawność jest sprawdzalna kodem (walidator = weryfikowalna nagroda).

## Metoda w akcji (dlaczego to wiarygodne)
W trakcie tych prac **pomiar dwukrotnie obalił wewnętrzną hipotezę zespołu** i zostało to przyjęte, nie naciągnięte: (1) pierwszy E1 „bił ensemble" — okazał się artefaktem zbioru testowego; (2) E_CKA przeszedł **adwersarialny audyt własnego pomiaru**, który wycofał jedną z dwóch metryk (skażony baseline). To jest sedno tego labu: *najpierw mierz, potem twierdź — i audytuj własny pomiar.*
W trakcie tych prac **pomiar trzykrotnie obalił wewnętrzne przekonania zespołu** i zostało to przyjęte, nie naciągnięte: (1) pierwszy E1 „bił ensemble" — okazał się artefaktem zbioru testowego; (2) E_CKA przeszedł **adwersarialny audyt własnego pomiaru**, który wycofał jedną z dwóch metryk (skażony baseline); (3) pierwszy benchmark sędziego (wspólna pula dla wszystkich ekspertów) pokazał ranking odwrotny niż PPL — okazał się artefaktem niezbalansowanych klas; naprawa: pule domenowe. To jest sedno tego labu: *najpierw mierz, potem twierdź — i audytuj własny pomiar.*

---
*Pełne rozumowanie (teza ↔ antyteza → synteza, audyt, weryfikacja źródeł) i kod: `music-experts/docs/` oraz `music-experts/src/`.*
5 changes: 3 additions & 2 deletions music-experts/.gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# cache
__pycache__/
*.pyc

.venv
# Repo = kod + wagi + docs. Surowe dane i OUTPUTY (nagrania, korpusy, raporty robocze)
# są regenerowalne, więc NIE idą. Idą tylko wytrenowane MODELE (wagi).
data/*
!data/models
out/*
data/models
data/models/*
!data/models/*.pt
data/models/gpt_ckpt_v1_dirty.pt
37 changes: 36 additions & 1 deletion music-experts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,45 @@ context 128 chars, character-level. Trained on CPU in minutes.
- **Duet** (`src/compose/duet.py`) — two experts layered (piano + violin, simultaneous): multi-track, not model-level fusion.
- **Next — E1:** representation-level stitch (the actual hypothesis, meant to beat these baselines).

## Judge — automatic generation benchmark

Perplexity measures text fit, not whether a generated tune *works as music* (meter? key? dance
type?). The judge is an independent classifier that scores generated melodies like a human
would: seeing only the tune **body** (the `M:`/`K:` headers are stripped — the judge cannot
cheat off the prompt), it predicts **meter**, **mode** and **type** (jig/reel/hornpipe...).
Built from the same building blocks as the experts: `JudgeGPT` = `core/gpt.py` trunk (verbatim)
+ mean-pool + 3 linear heads, pure PyTorch; 55k tunes, leak-free split by `tune_id`.
`judge_v2` val acc: meter **0.92**, mode **0.72**, type **0.82** — with musically honest
confusions (hornpipe↔reel, Bmin↔D).

Two benchmarks built on top of it:

- **In-domain** (`benchmark_judge.py`): each expert is scored only on tunes from its own
domain (`data/models/domains.json`), failures count as 0 (no survivor bias), with a
real-melody ceiling for reference. Leaderboard: jigs hold **0.80–0.86** of ceiling,
waltz 0.86 (soft ceiling), reels 0.69–0.72. The judge's ranking agrees with PPL — two
independent metrics, one verdict.
- **OOD transfer matrix** (`benchmark_ood.py`): expert × target domain. Diagonal always
wins (specialization is real), but **headers don't steer off-domain** (home-bias 0.9 —
a jig expert told `M:4/4` still emits 6/8), while **melody context half-steers** (home-bias
~0.5). Reel experts are the most flexible donors; small (e32) models bend easiest,
big ones are most rigid.

```bash
./run_benchmarks.sh # in-domain sweep, all checkpoints
python src/tools/train_judge.py --iters 5000 --batch 64 --out data/models/judge_v2.pt
python src/tools/benchmark_judge.py --model data/models/jig_ckpt.pt --judge data/models/judge_v2.pt
python src/tools/benchmark_ood.py # expert × domain transfer matrix
```

Full WHY / HOW / WHAT, results and limitations (in Polish):
[docs/Badania/2026-09-05_posttraining-reverse-kl/Judge-Sedzia-Generacji.md](docs/Badania/2026-09-05_posttraining-reverse-kl/Judge-Sedzia-Generacji.md)

## Pipeline (`src/`)
`prepare_data.py` / `prepare_bach.py` (build ABC corpus) → `gpt.py` (architecture) → `train_gpt.py`
(train; optional shared vocab) → `make_midi.py` / `gen_samples.py` (generate + render) →
`e0_stitch.py` / `fuse.py` / `duet.py` (composition) · `ngram_model.py` (baseline) · `abc_to_midi.py` (render).
`e0_stitch.py` / `fuse.py` / `duet.py` (composition) · `ngram_model.py` (baseline) · `abc_to_midi.py` (render) ·
`train_judge.py` / `judge_tunes.py` / `benchmark_judge.py` / `benchmark_ood.py` (judge — generation benchmark).

## Usage
```bash
Expand Down
Binary file removed music-experts/data/models/bach_ckpt.pt
Binary file not shown.
31 changes: 31 additions & 0 deletions music-experts/data/models/domains.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"_author": "Adam Skrodzki",
"_comment": "Domena każdego checkpointu (co przeszło do korpusu przy prepare_data.py). Domena = filtr melodii z tunes.csv: 'type' to substring typu, 'meter' równość. null = model spoza zakresu benchmarku (brak dopasowanych melodii).",
"bach_ckpt.pt": {"type": null, "meter": null},
"jig_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_v2_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_e32_s1_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_e32_s2_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_e32_s3_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_e64_s3_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_e128_s3_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_e192_s3_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_l1_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_l2_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_s1_ckpt.pt": {"type": "jig", "meter": "6/8"},
"jig_s2_ckpt.pt": {"type": "jig", "meter": "6/8"},
"reel_ckpt.pt": {"type": "reel", "meter": "4/4"},
"reel_sv_ckpt.pt": {"type": "reel", "meter": "4/4"},
"waltz_ckpt.pt": {"type": "waltz", "meter": "3/4"},
"universalist_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "domena arbitralna: model trenowany na calym korpusie; type wplywa tylko na gwiazdke diag i glowe hb"},
"jig_sh_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "teacher RKL, wspolny slownik (VOCAB_FROM=universalist)"},
"reel_sh_ckpt.pt": {"type": "reel", "meter": "4/4", "_note": "teacher RKL, wspolny slownik (VOCAB_FROM=universalist)"},
"waltz_sh_ckpt.pt": {"type": "waltz", "meter": "3/4", "_note": "teacher RKL, wspolny slownik (VOCAB_FROM=universalist)"},
"student_rkl_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "domena arbitralna (student po RKL); j.w."},
"student_junk_rkl_sc_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "domena arbitralna (student po RKL); j.w."},
"student_rkl_last_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "domena arbitralna (student po RKL, last); j.w."},
"student_rkl_sc_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "domena arbitralna (student po RKL cont+scratch); j.w."},
"student_rkl_sc_last_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "domena arbitralna (student po RKL cont+scratch, last); j.w."},
"student_jigstart_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "ablation: start z jig_sh (bez widzenia reel/waltz), RKL cont+scratch; domena arbitralna"},
"student_jigstart_last_ckpt.pt": {"type": "jig", "meter": "6/8", "_note": "j.w., last"}
}
Binary file removed music-experts/data/models/jig_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_e128_s3_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_e192_s3_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_e32_s1_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_e32_s2_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_e32_s3_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_e64_s3_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_l1_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_l2_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_s1_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_s2_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/jig_v2_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/reel_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/reel_sv_ckpt.pt
Binary file not shown.
Binary file removed music-experts/data/models/waltz_ckpt.pt
Binary file not shown.
Loading