Spaces:
Running on Zero
Running on Zero
| from __future__ import annotations | |
| import uuid | |
| from pathlib import Path | |
| from tempfile import gettempdir | |
| import gradio as gr | |
| try: | |
| import spaces | |
| except ImportError: | |
| class spaces: | |
| class GPU: | |
| def __init__(self, func=None, duration=120): | |
| self.func = func | |
| def __call__(self, *args, **kwargs): | |
| if self.func is not None: | |
| return self.func(*args, **kwargs) | |
| return args[0] | |
| from pyharp import ModelCard, build_endpoint | |
| from midi_gpt_runtime import rewrite_bars | |
| OUTPUT_ROOT = Path(gettempdir()) / "midi_gpt_outputs" | |
| model_card = ModelCard( | |
| name="MIDI-GPT", | |
| description=( | |
| "Rewrite selected bars in a multitrack MIDI arrangement while " | |
| "preserving the rest of the composition." | |
| ), | |
| author="Metacreation Lab", | |
| tags=[ | |
| "music-generation", | |
| "symbolic-music", | |
| "midi", | |
| "music-editing", | |
| "multitrack", | |
| ], | |
| ) | |
| def process_fn( | |
| midi_path: str | None, | |
| track_index: float, | |
| start_bar: float, | |
| bar_count: str, | |
| temperature: float, | |
| top_p: float, | |
| seed: float, | |
| polyphony_limit: float, | |
| ) -> tuple[str, dict]: | |
| if not midi_path: | |
| raise gr.Error("Please upload a MIDI file.") | |
| source = Path(midi_path) | |
| if source.suffix.lower() not in {".mid", ".midi"}: | |
| raise gr.Error("The input must be a .mid or .midi file.") | |
| output_dir = OUTPUT_ROOT / uuid.uuid4().hex | |
| output_path = output_dir / f"{source.stem}-rewritten.mid" | |
| try: | |
| details = rewrite_bars( | |
| input_path=source, | |
| output_path=output_path, | |
| track_index=int(track_index), | |
| start_bar=int(start_bar), | |
| bar_count=int(bar_count), | |
| temperature=float(temperature), | |
| top_p=float(top_p), | |
| seed=int(seed), | |
| polyphony_limit=int(polyphony_limit), | |
| ) | |
| except Exception as exc: | |
| raise gr.Error(f"MIDI-GPT inference failed: {exc}") from exc | |
| return str(output_path), details | |
| with gr.Blocks(title="MIDI-GPT") as demo: | |
| input_components = [ | |
| gr.File( | |
| type="filepath", | |
| file_types=[".mid", ".midi"], | |
| label="Input MIDI", | |
| ) | |
| .harp_required(True) | |
| .set_info("A multitrack MIDI file containing at least four bars."), | |
| gr.Number( | |
| value=0, | |
| minimum=0, | |
| precision=0, | |
| label="Track Index", | |
| info="Zero-based index of the track to rewrite.", | |
| ), | |
| gr.Number( | |
| value=0, | |
| minimum=0, | |
| precision=0, | |
| label="Start Bar", | |
| info="Zero-based index of the first bar to rewrite.", | |
| ), | |
| gr.Dropdown( | |
| choices=["1", "2", "4"], | |
| value="2", | |
| label="Number of Bars", | |
| info="Number of consecutive bars to rewrite.", | |
| ), | |
| gr.Slider( | |
| minimum=0.5, | |
| maximum=1.5, | |
| step=0.1, | |
| value=1.0, | |
| label="Temperature", | |
| info="Higher values produce more varied results.", | |
| ), | |
| gr.Slider( | |
| minimum=0.5, | |
| maximum=1.0, | |
| step=0.05, | |
| value=0.95, | |
| label="Top-p", | |
| info="Nucleus sampling threshold.", | |
| ), | |
| gr.Number( | |
| value=0, | |
| minimum=0, | |
| maximum=2_147_483_647, | |
| precision=0, | |
| label="Seed", | |
| info="Use the same seed and controls to reproduce a result.", | |
| ), | |
| gr.Slider( | |
| minimum=0, | |
| maximum=12, | |
| step=1, | |
| value=0, | |
| label="Maximum Polyphony", | |
| info="Maximum simultaneous notes; 0 leaves it unrestricted.", | |
| ), | |
| ] | |
| output_components = [ | |
| gr.File( | |
| type="filepath", | |
| file_types=[".mid", ".midi"], | |
| label="Rewritten MIDI", | |
| ).set_info("Editable multitrack MIDI with the selected bars replaced."), | |
| gr.JSON(label="Generation Details"), | |
| ] | |
| build_endpoint( | |
| model_card=model_card, | |
| input_components=input_components, | |
| output_components=output_components, | |
| process_fn=process_fn, | |
| ) | |
| if __name__ == "__main__": | |
| demo.queue(default_concurrency_limit=1).launch( | |
| show_error=True, | |
| pwa=True, | |
| ) | |