Mike0021 commited on
Commit
2b60549
·
verified ·
1 Parent(s): c201838

add beam search quality control

Browse files
Files changed (2) hide show
  1. README.md +1 -1
  2. app.py +33 -2
README.md CHANGED
@@ -22,4 +22,4 @@ The checkpoint is gated under CC BY-NC 4.0. This Space requires an `HF_TOKEN` se
22
 
23
  ## API
24
 
25
- The Gradio endpoint is `/transcribe`. It accepts an audio file, optional exact instrument group names, a sampling toggle, and temperature. It returns the combined MIDI, all isolated track files, the browser visualization payload, and a machine-readable manifest.
 
22
 
23
  ## API
24
 
25
+ The Gradio endpoint is `/transcribe`. It accepts an audio file, optional exact instrument group names, a sampling toggle, temperature, and a beam width from 1–4. It returns the combined MIDI, all isolated track files, the browser visualization payload, and a machine-readable manifest.
app.py CHANGED
@@ -140,12 +140,24 @@ def _audio_duration(path: str | None) -> float | None:
140
  return None
141
 
142
 
143
- def _estimate_gpu_duration(audio: Any, *args: Any, **kwargs: Any) -> int:
 
 
 
 
 
 
 
 
144
  """Estimate allocation from 5-second chunks; accepts Gradio extras."""
145
 
146
  duration = _audio_duration(_audio_path(audio))
147
  chunks = max(1, math.ceil((duration or 15.0) / 5.0))
148
- return min(GPU_DURATION_CAP, GPU_BASE_SECONDS + chunks * GPU_SECONDS_PER_CHUNK)
 
 
 
 
149
 
150
 
151
  def _display_name(name: str) -> str:
@@ -348,6 +360,7 @@ def transcribe_audio(
348
  instruments: list[str] | None,
349
  use_sampling: bool,
350
  temperature: float,
 
351
  ) -> Iterator[tuple[str | None, list[str] | None, str, dict[str, Any]]]:
352
  """Stream chunk progress, then return combined and isolated MIDI files."""
353
 
@@ -407,6 +420,7 @@ def transcribe_audio(
407
  return
408
 
409
  requested = list(dict.fromkeys(instruments or []))
 
410
  started = time.perf_counter()
411
  events: list[NoteStartEvent | NoteEndEvent | ProgressEvent] = []
412
  last_completed = -1
@@ -417,6 +431,7 @@ def transcribe_audio(
417
  instruments=requested or None,
418
  use_sampling=bool(use_sampling),
419
  temperature=float(temperature),
 
420
  batch_size=1,
421
  )
422
  for event in stream:
@@ -598,18 +613,21 @@ EXAMPLE_ROWS = [
598
  ["violin", "acoustic_piano"],
599
  False,
600
  1.0,
 
601
  ],
602
  [
603
  str(EXAMPLE_ROOT / "livery-stable-blues-jazz-band.mp3"),
604
  ["trumpet", "clarinet", "trombone", "drums"],
605
  False,
606
  1.0,
 
607
  ],
608
  [
609
  str(EXAMPLE_ROOT / "double-tracked-pop-rock.mp3"),
610
  [],
611
  False,
612
  1.0,
 
613
  ],
614
  ]
615
 
@@ -663,6 +681,17 @@ with gr.Blocks(title="MuScriptor — Audio to MIDI") as demo:
663
  step=0.1,
664
  label="Temperature",
665
  )
 
 
 
 
 
 
 
 
 
 
 
666
  transcribe_button = gr.Button(
667
  "Transcribe audio",
668
  variant="primary",
@@ -700,6 +729,7 @@ with gr.Blocks(title="MuScriptor — Audio to MIDI") as demo:
700
  instrument_input,
701
  use_sampling_input,
702
  temperature_input,
 
703
  ],
704
  outputs=[
705
  full_midi_output,
@@ -729,6 +759,7 @@ with gr.Blocks(title="MuScriptor — Audio to MIDI") as demo:
729
  instrument_input,
730
  use_sampling_input,
731
  temperature_input,
 
732
  ],
733
  outputs=[
734
  full_midi_output,
 
140
  return None
141
 
142
 
143
+ def _estimate_gpu_duration(
144
+ audio: Any,
145
+ instruments: list[str] | None = None,
146
+ use_sampling: bool = False,
147
+ temperature: float = 1.0,
148
+ beam_size: int = 1,
149
+ *args: Any,
150
+ **kwargs: Any,
151
+ ) -> int:
152
  """Estimate allocation from 5-second chunks; accepts Gradio extras."""
153
 
154
  duration = _audio_duration(_audio_path(audio))
155
  chunks = max(1, math.ceil((duration or 15.0) / 5.0))
156
+ beam = max(1, min(4, int(beam_size or 1)))
157
+ return min(
158
+ GPU_DURATION_CAP,
159
+ GPU_BASE_SECONDS + chunks * GPU_SECONDS_PER_CHUNK * beam,
160
+ )
161
 
162
 
163
  def _display_name(name: str) -> str:
 
360
  instruments: list[str] | None,
361
  use_sampling: bool,
362
  temperature: float,
363
+ beam_size: int,
364
  ) -> Iterator[tuple[str | None, list[str] | None, str, dict[str, Any]]]:
365
  """Stream chunk progress, then return combined and isolated MIDI files."""
366
 
 
420
  return
421
 
422
  requested = list(dict.fromkeys(instruments or []))
423
+ beam = max(1, min(4, int(beam_size or 1)))
424
  started = time.perf_counter()
425
  events: list[NoteStartEvent | NoteEndEvent | ProgressEvent] = []
426
  last_completed = -1
 
431
  instruments=requested or None,
432
  use_sampling=bool(use_sampling),
433
  temperature=float(temperature),
434
+ beam_size=beam,
435
  batch_size=1,
436
  )
437
  for event in stream:
 
613
  ["violin", "acoustic_piano"],
614
  False,
615
  1.0,
616
+ 1,
617
  ],
618
  [
619
  str(EXAMPLE_ROOT / "livery-stable-blues-jazz-band.mp3"),
620
  ["trumpet", "clarinet", "trombone", "drums"],
621
  False,
622
  1.0,
623
+ 1,
624
  ],
625
  [
626
  str(EXAMPLE_ROOT / "double-tracked-pop-rock.mp3"),
627
  [],
628
  False,
629
  1.0,
630
+ 1,
631
  ],
632
  ]
633
 
 
681
  step=0.1,
682
  label="Temperature",
683
  )
684
+ beam_size_input = gr.Slider(
685
+ minimum=1,
686
+ maximum=4,
687
+ value=1,
688
+ step=1,
689
+ label="Beam width",
690
+ info=(
691
+ "1 is faster. Widths 2–4 use slower deterministic "
692
+ "beam search; sampling and temperature apply only at 1."
693
+ ),
694
+ )
695
  transcribe_button = gr.Button(
696
  "Transcribe audio",
697
  variant="primary",
 
729
  instrument_input,
730
  use_sampling_input,
731
  temperature_input,
732
+ beam_size_input,
733
  ],
734
  outputs=[
735
  full_midi_output,
 
759
  instrument_input,
760
  use_sampling_input,
761
  temperature_input,
762
+ beam_size_input,
763
  ],
764
  outputs=[
765
  full_midi_output,