Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import gradio as gr | |
| try: | |
| import spaces | |
| except ImportError: # 'spaces' is only provided by Hugging Face Spaces | |
| import types as _types | |
| def _gpu(*args, **kwargs): | |
| if len(args) == 1 and callable(args[0]) and not kwargs: | |
| return args[0] | |
| def _decorator(func): | |
| return func | |
| return _decorator | |
| spaces = _types.SimpleNamespace(GPU=_gpu) | |
| from pyharp import * | |
| try: # torch>=2.6 flipped torch.load(weights_only) to True; legacy ckpts need False | |
| import torch as _torch | |
| if getattr(_torch.load, "__harp_compat__", False) is False: | |
| _torch_load_orig = _torch.load | |
| def _torch_load_compat(*args, **kwargs): | |
| kwargs.setdefault("weights_only", False) | |
| return _torch_load_orig(*args, **kwargs) | |
| _torch_load_compat.__harp_compat__ = True | |
| _torch.load = _torch_load_compat | |
| except Exception: # torch not installed / unexpected API -- nothing to patch | |
| pass | |
| import tempfile | |
| import torch | |
| import torchaudio | |
| from openunmix import utils, predict | |
| DEVICE = "cuda" if torch.cuda.is_available() else "cpu" | |
| _separators = {} | |
| def get_separator(model_name, niter, wiener_win_len): | |
| key = (model_name, niter, wiener_win_len) | |
| if key not in _separators: | |
| sep = utils.load_separator( | |
| model_str_or_path=model_name, | |
| niter=niter, | |
| wiener_win_len=wiener_win_len, | |
| device=DEVICE, | |
| pretrained=True, | |
| ) | |
| sep.freeze() | |
| sep.to(DEVICE) | |
| _separators[key] = sep | |
| return _separators[key] | |
| model_card = ModelCard( | |
| name="Open-Unmix", | |
| description="Music source separation into vocals, drums, bass, and other instruments using deep neural networks.", | |
| author="sigsep", | |
| tags=["audio-to-audio", "source-separation", "stems"], | |
| ) | |
| def process_fn(input_audio, model_name, niter, wiener_win_len): | |
| audio, rate = torchaudio.load(input_audio) | |
| if audio.shape[0] == 1: | |
| audio = audio.repeat(2, 1) | |
| separator = get_separator(model_name, int(niter), int(wiener_win_len)) | |
| estimates = predict.separate( | |
| audio=audio, | |
| rate=rate, | |
| model_str_or_path=model_name, | |
| separator=separator, | |
| device=DEVICE | |
| ) | |
| output_files = {} | |
| for target in ["vocals", "drums", "bass", "other"]: | |
| target_tensor = estimates[target][0].cpu() | |
| out_file = tempfile.NamedTemporaryFile(suffix=".wav", delete=False) | |
| out_file.close() | |
| torchaudio.save(out_file.name, target_tensor, int(separator.sample_rate)) | |
| output_files[target] = out_file.name | |
| return ( | |
| output_files["vocals"], | |
| output_files["drums"], | |
| output_files["bass"], | |
| output_files["other"] | |
| ) | |
| with gr.Blocks() as demo: | |
| input_components = [ | |
| gr.Audio(type="filepath", label="Input Audio").harp_required(True), | |
| gr.Dropdown(choices=["umxl", "umxhq", "umx"], value="umxl", label="Model", info="umxl is the largest and best performing model, trained on extra data."), | |
| gr.Slider(minimum=0, maximum=5, step=1, value=1, label="Wiener Filter Iterations", info="Number of iterations for Wiener filtering. 0 means softmask."), | |
| gr.Slider(minimum=100, maximum=500, step=50, value=300, label="Wiener Window Length", info="Number of frames on which to apply filtering independently."), | |
| ] | |
| output_components = [ | |
| gr.Audio(type="filepath", label="Vocals"), | |
| gr.Audio(type="filepath", label="Drums"), | |
| gr.Audio(type="filepath", label="Bass"), | |
| gr.Audio(type="filepath", label="Other"), | |
| ] | |
| build_endpoint( | |
| model_card=model_card, | |
| input_components=input_components, | |
| output_components=output_components, | |
| process_fn=process_fn, | |
| ) | |
| demo.queue().launch(share=True, show_error=False, pwa=True) | |