hum / sheet_worker.py
batoon's picture
Generate melody and drum variants together
6b1f7f2 verified
Raw History Blame Contribute Delete
2.45 kB
"""One isolated SheetSage2 CUDA transcription per request."""
from __future__ import annotations
import importlib
import json
from pathlib import Path
import shutil
import sys
import numpy as np
import soundfile as sf
import torch
from transformers import AutoModel
SHEETSAGE_REV = "eab522a8168e8b8b8c4856bf8609cd86198f01fe"
def run(source: Path, output: Path) -> None:
if not torch.cuda.is_available():
raise RuntimeError("SheetSage2 requires the configured NVIDIA GPU")
waveform, rate = sf.read(source, dtype="float32", always_2d=True)
if rate != 24000 or waveform.shape[1] != 1 or not np.isfinite(waveform).all():
raise ValueError("Expected finite mono 24 kHz PCM")
torch.manual_seed(1024)
np.random.seed(1024)
model = AutoModel.from_pretrained(
"m-a-p/SheetSage2", revision=SHEETSAGE_REV, trust_remote_code=True,
torch_dtype=torch.float32, attn_implementation="sdpa",
).eval().to("cuda")
native = output / "native"
result = model.transcribe(waveform[:, 0], sampling_rate=24000,
output_dir=native, dtype="fp32", preset="default",
melody_only=False)
if result.get("abc_error") or not (native / "score.abc").is_file():
raise RuntimeError(f"SheetSage2 could not export ABC: {result.get('abc_error')}")
package = model.__class__.__module__.rsplit(".", 1)[0]
exporter = importlib.import_module(package + ".exports_sheetsage2").export_result
events = json.loads((native / "events.json").read_text())
melody = exporter(events, model.tokenizer, output / "melody-only",
duration=result["duration_seconds"], melody_only=True)
if melody.get("abc_error") or not (output / "melody-only/score.abc").is_file():
raise RuntimeError(f"SheetSage2 could not export melody ABC: {melody.get('abc_error')}")
shutil.copy2(native / "score.abc", output / "full.abc")
shutil.copy2(output / "melody-only/score.abc", output / "melody.abc")
shutil.copy2(native / "melody_vocal.mid", output / "notes.mid")
shutil.copy2(native / "beat.lab", output / "beat.lab")
(output / "sheet.json").write_text(json.dumps({
"model": "m-a-p/SheetSage2", "revision": SHEETSAGE_REV,
"duration_s": result["duration_seconds"],
"source_timeline": True,
}, indent=2) + "\n")
if __name__ == "__main__":
run(Path(sys.argv[1]), Path(sys.argv[2]))