Spaces:
Running
Running
Emre Sarigöl commited on
Commit ·
ed8f8ab
1
Parent(s): a01358a
Deploy sync_pilot dashboard - 2026-06-10 16:54
Browse files
sync_pilot/dashboard/coverage.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
| 1 |
"""Maps taxonomy dimensions to current inference-pipeline coverage.
|
| 2 |
|
| 3 |
-
Answers: which of the 12 taxonomy dimensions
|
| 4 |
-
|
| 5 |
-
|
|
|
|
| 6 |
"""
|
| 7 |
|
| 8 |
from __future__ import annotations
|
|
@@ -23,13 +24,18 @@ class DimensionCoverage:
|
|
| 23 |
DIMENSION_COVERAGE: dict[int, DimensionCoverage] = {
|
| 24 |
1: DimensionCoverage(
|
| 25 |
"covered",
|
| 26 |
-
[
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
),
|
| 29 |
2: DimensionCoverage(
|
| 30 |
"covered",
|
| 31 |
-
["
|
| 32 |
-
"
|
| 33 |
),
|
| 34 |
3: DimensionCoverage(
|
| 35 |
"partial",
|
|
@@ -54,13 +60,13 @@ DIMENSION_COVERAGE: dict[int, DimensionCoverage] = {
|
|
| 54 |
),
|
| 55 |
6: DimensionCoverage(
|
| 56 |
"covered",
|
| 57 |
-
["
|
| 58 |
-
"
|
| 59 |
),
|
| 60 |
7: DimensionCoverage(
|
| 61 |
"covered",
|
| 62 |
-
["
|
| 63 |
-
"
|
| 64 |
),
|
| 65 |
8: DimensionCoverage(
|
| 66 |
"covered",
|
|
@@ -69,8 +75,8 @@ DIMENSION_COVERAGE: dict[int, DimensionCoverage] = {
|
|
| 69 |
),
|
| 70 |
9: DimensionCoverage(
|
| 71 |
"partial",
|
| 72 |
-
["
|
| 73 |
-
"
|
| 74 |
),
|
| 75 |
10: DimensionCoverage(
|
| 76 |
"partial",
|
|
|
|
| 1 |
"""Maps taxonomy dimensions to current inference-pipeline coverage.
|
| 2 |
|
| 3 |
+
Answers: which of the 12 taxonomy dimensions the current MAEST, MuQ, PaSST,
|
| 4 |
+
taxonomy-adapter, lyrics, rhythm, and GT-review layers produce tags for, and
|
| 5 |
+
how completely. Static map because the answer depends on the pipeline
|
| 6 |
+
architecture, not the per-track data.
|
| 7 |
"""
|
| 8 |
|
| 9 |
from __future__ import annotations
|
|
|
|
| 24 |
DIMENSION_COVERAGE: dict[int, DimensionCoverage] = {
|
| 25 |
1: DimensionCoverage(
|
| 26 |
"covered",
|
| 27 |
+
[
|
| 28 |
+
"maest/genre",
|
| 29 |
+
"muq-probe/genre",
|
| 30 |
+
"passt-probe/genre",
|
| 31 |
+
"taxonomy-adapter/genre",
|
| 32 |
+
],
|
| 33 |
+
"MAEST keeps a Discogs baseline while MuQ, PaSST, and the taxonomy adapter now provide the Turkish taxonomy-facing genre families used in the track explorer.",
|
| 34 |
),
|
| 35 |
2: DimensionCoverage(
|
| 36 |
"covered",
|
| 37 |
+
["muq-probe/genre", "passt-probe/genre", "taxonomy-adapter/genre"],
|
| 38 |
+
"Expanded MuQ/PaSST probes and the taxonomy adapter provide the subtype-oriented Turkish genre terms surfaced for review.",
|
| 39 |
),
|
| 40 |
3: DimensionCoverage(
|
| 41 |
"partial",
|
|
|
|
| 60 |
),
|
| 61 |
6: DimensionCoverage(
|
| 62 |
"covered",
|
| 63 |
+
["muq-probe/instrument", "passt-probe/instrument", "taxonomy-adapter/instrument"],
|
| 64 |
+
"Instrumentation is now grounded primarily by promoted MuQ/PaSST probe heads plus the taxonomy adapter. GT review can override these into source-verified instrumentation.",
|
| 65 |
),
|
| 66 |
7: DimensionCoverage(
|
| 67 |
"covered",
|
| 68 |
+
["muq-probe/vocal", "taxonomy-adapter/vocal", "review-sidecar/vocal"],
|
| 69 |
+
"Vocal configuration and technique candidates come from MuQ probes and the taxonomy adapter, with reviewer selections persisted in the GT-review sidecar.",
|
| 70 |
),
|
| 71 |
8: DimensionCoverage(
|
| 72 |
"covered",
|
|
|
|
| 75 |
),
|
| 76 |
9: DimensionCoverage(
|
| 77 |
"partial",
|
| 78 |
+
["muq-probe/mood", "review-sidecar/mood"],
|
| 79 |
+
"Mood candidates are currently MuQ-probe driven and can be accepted or corrected in GT review. Coverage is useful but still needs human review because mood vocabulary is subjective.",
|
| 80 |
),
|
| 81 |
10: DimensionCoverage(
|
| 82 |
"partial",
|
sync_pilot/dashboard/plots.py
CHANGED
|
@@ -15,17 +15,53 @@ from typing import Any, Iterable
|
|
| 15 |
import plotly.graph_objects as go
|
| 16 |
|
| 17 |
from sync_pilot.dashboard.styles import (
|
|
|
|
| 18 |
CLAP_COLOR,
|
| 19 |
MAEST_COLOR,
|
| 20 |
MUQ_COLOR,
|
| 21 |
MUQ_REVIEW_COLOR,
|
|
|
|
| 22 |
STEM_COLOR,
|
|
|
|
| 23 |
THEME_COLOR,
|
| 24 |
)
|
| 25 |
|
| 26 |
_MAEST_DISPLAY_MIN_SCORE = 0.15
|
| 27 |
_CLAP_DISPLAY_TOP_K = 3
|
| 28 |
_CLAP_MOOD_DISPLAY_TOP_K = 2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
|
| 31 |
def _empty_figure(message: str) -> go.Figure:
|
|
@@ -53,17 +89,8 @@ def _empty_figure(message: str) -> go.Figure:
|
|
| 53 |
|
| 54 |
def _source_color(source: str) -> str:
|
| 55 |
"""Map a tag source to its canonical color."""
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
if source.startswith("muq-probe-review"):
|
| 59 |
-
return MUQ_REVIEW_COLOR
|
| 60 |
-
if source.startswith("muq"):
|
| 61 |
-
return MUQ_COLOR
|
| 62 |
-
if source.startswith("stem-window"):
|
| 63 |
-
return STEM_COLOR
|
| 64 |
-
if source.startswith("lyrics"):
|
| 65 |
-
return THEME_COLOR
|
| 66 |
-
return MAEST_COLOR
|
| 67 |
|
| 68 |
|
| 69 |
def _source_bucket(source: str) -> str | None:
|
|
@@ -73,6 +100,16 @@ def _source_bucket(source: str) -> str | None:
|
|
| 73 |
return "maest"
|
| 74 |
if source.startswith("muq-probe-review"):
|
| 75 |
return "muq-probe-review-v1"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
if source.startswith("muq"):
|
| 77 |
return "muq-mulan-zs"
|
| 78 |
if source.startswith("stem-window"):
|
|
@@ -80,6 +117,10 @@ def _source_bucket(source: str) -> str | None:
|
|
| 80 |
return None
|
| 81 |
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
def _catalog_display_tags(tags: list[dict[str, Any]], category: str) -> list[dict[str, Any]]:
|
| 84 |
rows = [t for t in tags if t.get("category") == category]
|
| 85 |
filtered: list[dict[str, Any]] = []
|
|
@@ -223,10 +264,7 @@ def catalog_top_tags_chart(
|
|
| 223 |
thereof) without forcing same-axis alignment of disagreeing terms.
|
| 224 |
"""
|
| 225 |
per_source: dict[str, Counter[str]] = {
|
| 226 |
-
|
| 227 |
-
"clap-zs": Counter(),
|
| 228 |
-
"muq-mulan-zs": Counter(),
|
| 229 |
-
"stem-window-v1": Counter(),
|
| 230 |
}
|
| 231 |
for tr in tracks:
|
| 232 |
for tag in _catalog_display_tags(tr.get("tags", []) or [], category):
|
|
@@ -234,6 +272,8 @@ def catalog_top_tags_chart(
|
|
| 234 |
name = tag.get("name", "")
|
| 235 |
bucket = _source_bucket(str(src))
|
| 236 |
if bucket and name:
|
|
|
|
|
|
|
| 237 |
per_source[bucket][name] += 1
|
| 238 |
|
| 239 |
# Build a single combined list of (count, name, source) and keep the
|
|
@@ -253,7 +293,7 @@ def catalog_top_tags_chart(
|
|
| 253 |
fig.add_trace(
|
| 254 |
go.Bar(
|
| 255 |
x=[c for c, _, _ in combined],
|
| 256 |
-
y=[f"{n} · {s}" for _, n, s in combined],
|
| 257 |
orientation="h",
|
| 258 |
marker={"color": [_source_color(s) for _, _, s in combined]},
|
| 259 |
text=[str(c) for c, _, _ in combined],
|
|
|
|
| 15 |
import plotly.graph_objects as go
|
| 16 |
|
| 17 |
from sync_pilot.dashboard.styles import (
|
| 18 |
+
CATEGORY_COLORS,
|
| 19 |
CLAP_COLOR,
|
| 20 |
MAEST_COLOR,
|
| 21 |
MUQ_COLOR,
|
| 22 |
MUQ_REVIEW_COLOR,
|
| 23 |
+
PASST_COLOR,
|
| 24 |
STEM_COLOR,
|
| 25 |
+
TAXONOMY_ADAPTER_COLOR,
|
| 26 |
THEME_COLOR,
|
| 27 |
)
|
| 28 |
|
| 29 |
_MAEST_DISPLAY_MIN_SCORE = 0.15
|
| 30 |
_CLAP_DISPLAY_TOP_K = 3
|
| 31 |
_CLAP_MOOD_DISPLAY_TOP_K = 2
|
| 32 |
+
_SOURCE_BUCKET_ORDER = [
|
| 33 |
+
"maest",
|
| 34 |
+
"clap-zs",
|
| 35 |
+
"muq-probe-v1",
|
| 36 |
+
"muq-probe-expanded-v1",
|
| 37 |
+
"passt-probe-expanded-v1",
|
| 38 |
+
"taxonomy-adapter-v1",
|
| 39 |
+
"muq-probe-review-v1",
|
| 40 |
+
"lyrics-llm",
|
| 41 |
+
"stem-window-v1",
|
| 42 |
+
]
|
| 43 |
+
_SOURCE_LABELS = {
|
| 44 |
+
"maest": "MAEST",
|
| 45 |
+
"clap-zs": "CLAP",
|
| 46 |
+
"muq-probe-v1": "MuQ probe",
|
| 47 |
+
"muq-probe-expanded-v1": "MuQ expanded",
|
| 48 |
+
"passt-probe-expanded-v1": "PaSST expanded",
|
| 49 |
+
"taxonomy-adapter-v1": "taxonomy adapter",
|
| 50 |
+
"muq-probe-review-v1": "review probe",
|
| 51 |
+
"lyrics-llm": "lyrics LLM",
|
| 52 |
+
"stem-window-v1": "stem windows",
|
| 53 |
+
}
|
| 54 |
+
_SOURCE_COLORS = {
|
| 55 |
+
"maest": MAEST_COLOR,
|
| 56 |
+
"clap-zs": CLAP_COLOR,
|
| 57 |
+
"muq-probe-v1": MUQ_COLOR,
|
| 58 |
+
"muq-probe-expanded-v1": MUQ_COLOR,
|
| 59 |
+
"passt-probe-expanded-v1": PASST_COLOR,
|
| 60 |
+
"taxonomy-adapter-v1": TAXONOMY_ADAPTER_COLOR,
|
| 61 |
+
"muq-probe-review-v1": MUQ_REVIEW_COLOR,
|
| 62 |
+
"lyrics-llm": THEME_COLOR,
|
| 63 |
+
"stem-window-v1": STEM_COLOR,
|
| 64 |
+
}
|
| 65 |
|
| 66 |
|
| 67 |
def _empty_figure(message: str) -> go.Figure:
|
|
|
|
| 89 |
|
| 90 |
def _source_color(source: str) -> str:
|
| 91 |
"""Map a tag source to its canonical color."""
|
| 92 |
+
bucket = _source_bucket(source) or source
|
| 93 |
+
return _SOURCE_COLORS.get(bucket, CATEGORY_COLORS["other"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
|
| 95 |
|
| 96 |
def _source_bucket(source: str) -> str | None:
|
|
|
|
| 100 |
return "maest"
|
| 101 |
if source.startswith("muq-probe-review"):
|
| 102 |
return "muq-probe-review-v1"
|
| 103 |
+
if source.startswith("muq-probe-expanded"):
|
| 104 |
+
return "muq-probe-expanded-v1"
|
| 105 |
+
if source.startswith("muq-probe"):
|
| 106 |
+
return "muq-probe-v1"
|
| 107 |
+
if source.startswith("passt-probe-expanded"):
|
| 108 |
+
return "passt-probe-expanded-v1"
|
| 109 |
+
if source.startswith("taxonomy-adapter"):
|
| 110 |
+
return "taxonomy-adapter-v1"
|
| 111 |
+
if source.startswith("lyrics"):
|
| 112 |
+
return "lyrics-llm"
|
| 113 |
if source.startswith("muq"):
|
| 114 |
return "muq-mulan-zs"
|
| 115 |
if source.startswith("stem-window"):
|
|
|
|
| 117 |
return None
|
| 118 |
|
| 119 |
|
| 120 |
+
def _source_label(source: str) -> str:
|
| 121 |
+
return _SOURCE_LABELS.get(source, source)
|
| 122 |
+
|
| 123 |
+
|
| 124 |
def _catalog_display_tags(tags: list[dict[str, Any]], category: str) -> list[dict[str, Any]]:
|
| 125 |
rows = [t for t in tags if t.get("category") == category]
|
| 126 |
filtered: list[dict[str, Any]] = []
|
|
|
|
| 264 |
thereof) without forcing same-axis alignment of disagreeing terms.
|
| 265 |
"""
|
| 266 |
per_source: dict[str, Counter[str]] = {
|
| 267 |
+
source: Counter() for source in _SOURCE_BUCKET_ORDER
|
|
|
|
|
|
|
|
|
|
| 268 |
}
|
| 269 |
for tr in tracks:
|
| 270 |
for tag in _catalog_display_tags(tr.get("tags", []) or [], category):
|
|
|
|
| 272 |
name = tag.get("name", "")
|
| 273 |
bucket = _source_bucket(str(src))
|
| 274 |
if bucket and name:
|
| 275 |
+
if bucket not in per_source:
|
| 276 |
+
per_source[bucket] = Counter()
|
| 277 |
per_source[bucket][name] += 1
|
| 278 |
|
| 279 |
# Build a single combined list of (count, name, source) and keep the
|
|
|
|
| 293 |
fig.add_trace(
|
| 294 |
go.Bar(
|
| 295 |
x=[c for c, _, _ in combined],
|
| 296 |
+
y=[f"{n} · {_source_label(s)}" for _, n, s in combined],
|
| 297 |
orientation="h",
|
| 298 |
marker={"color": [_source_color(s) for _, _, s in combined]},
|
| 299 |
text=[str(c) for c, _, _ in combined],
|
sync_pilot/dashboard/styles.py
CHANGED
|
@@ -15,6 +15,8 @@ MAEST_COLOR = "#5B5EA6"
|
|
| 15 |
CLAP_COLOR = "#1FB3A5"
|
| 16 |
MUQ_COLOR = "#9B5DE5"
|
| 17 |
MUQ_REVIEW_COLOR = "#C77DFF"
|
|
|
|
|
|
|
| 18 |
LYRICS_COLOR = "#E07B39"
|
| 19 |
STEM_COLOR = "#E07B39"
|
| 20 |
# Theme tags from the lyrics-llm extractor (Tier 2). Sage green deliberately
|
|
|
|
| 15 |
CLAP_COLOR = "#1FB3A5"
|
| 16 |
MUQ_COLOR = "#9B5DE5"
|
| 17 |
MUQ_REVIEW_COLOR = "#C77DFF"
|
| 18 |
+
PASST_COLOR = "#F59E0B"
|
| 19 |
+
TAXONOMY_ADAPTER_COLOR = "#2563EB"
|
| 20 |
LYRICS_COLOR = "#E07B39"
|
| 21 |
STEM_COLOR = "#E07B39"
|
| 22 |
# Theme tags from the lyrics-llm extractor (Tier 2). Sage green deliberately
|
sync_pilot/dashboard/views/overview.py
CHANGED
|
@@ -183,9 +183,9 @@ def render() -> None:
|
|
| 183 |
st.subheader("What the catalog looks like")
|
| 184 |
st.caption(
|
| 185 |
f"Top tags across all {n_tracks} tracks, split by source after the "
|
| 186 |
-
"same display precision policy used on track pages. Indigo = MAEST "
|
| 187 |
-
"
|
| 188 |
-
"
|
| 189 |
)
|
| 190 |
|
| 191 |
grid_rows = st.columns(2)
|
|
|
|
| 183 |
st.subheader("What the catalog looks like")
|
| 184 |
st.caption(
|
| 185 |
f"Top tags across all {n_tracks} tracks, split by source after the "
|
| 186 |
+
"same display precision policy used on track pages. Indigo = MAEST, "
|
| 187 |
+
"purple = MuQ probes, amber = PaSST promoted probes, blue = taxonomy "
|
| 188 |
+
"adapter, violet = human-review probe tags, sage = lyrics themes."
|
| 189 |
)
|
| 190 |
|
| 191 |
grid_rows = st.columns(2)
|
sync_pilot/dashboard/views/taxonomy.py
CHANGED
|
@@ -111,7 +111,8 @@ def render() -> None:
|
|
| 111 |
|
| 112 |
st.markdown("### Inference coverage at a glance")
|
| 113 |
st.caption(
|
| 114 |
-
"Which dimensions
|
|
|
|
| 115 |
)
|
| 116 |
st.dataframe(
|
| 117 |
_coverage_table(spec.dimensions),
|
|
|
|
| 111 |
|
| 112 |
st.markdown("### Inference coverage at a glance")
|
| 113 |
st.caption(
|
| 114 |
+
"Which dimensions the current MAEST, MuQ/PaSST probe, taxonomy-adapter, "
|
| 115 |
+
"lyrics, rhythm, and GT-review layers currently produce signals for."
|
| 116 |
)
|
| 117 |
st.dataframe(
|
| 118 |
_coverage_table(spec.dimensions),
|