gap-urgenet / app.py
multimodalart's picture
multimodalart HF Staff
Upload app.py with huggingface_hub
43c4638 verified
Raw
History Blame Contribute Delete
4.1 kB
import os
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
import spaces
import torch
import numpy as np
import soundfile as sf
import tempfile
import time
from huggingface_hub import hf_hub_download
from models.gap_urgenet import GAP_URGENet
REPO_ID = "Xiaobin-Rong/gap-urgenet"
def _download_checkpoints():
"""Download all 5 checkpoints from HuggingFace Hub."""
ckpts = {}
for fname in ["DeWavLM-Omni.pt", "Adapter.pt", "Vocoder.pt",
"Predictor.pt", "PostNet.pt"]:
ckpts[fname] = hf_hub_download(repo_id=REPO_ID, filename=fname)
return ckpts
print("[*] Downloading checkpoints from HuggingFace Hub...")
_ckpt_paths = _download_checkpoints()
print("[*] All checkpoints downloaded.")
print("[*] Loading GAP-URGENet model...")
# Monkey-patch torch.load to avoid weights_only default issue in torch 2.6+
_orig_load = torch.load
torch.load = lambda *a, **k: _orig_load(*a, **{**k, "weights_only": k.get("weights_only", False)})
model = GAP_URGENet(
dewavlm_ckpt_path=_ckpt_paths["DeWavLM-Omni.pt"],
adapter_ckpt_path=_ckpt_paths["Adapter.pt"],
vocoder_ckpt_path=_ckpt_paths["Vocoder.pt"],
predictor_ckpt_path=_ckpt_paths["Predictor.pt"],
postnet_ckpt_path=_ckpt_paths["PostNet.pt"],
).to("cuda").eval()
# Restore original torch.load
torch.load = _orig_load
print("[*] Model loaded and moved to CUDA.")
@spaces.GPU(duration=60)
def enhance_audio(audio_path: str, enable_plc: bool = True) -> str:
"""Enhance noisy speech audio using GAP-URGENet.
Args:
audio_path: Path to the noisy audio file (wav, flac, etc.).
enable_plc: Whether to perform packet loss concealment (PLC).
Returns:
Path to the enhanced audio file (WAV format).
"""
t0 = time.perf_counter()
audio, fs = sf.read(audio_path, dtype='float32')
# Handle mono / stereo
if audio.ndim > 1:
audio = audio[:, 0] # take first channel
input_tensor = torch.FloatTensor(audio).unsqueeze(0).to("cuda")
with torch.inference_mode():
output = model(input_tensor, sr_in=fs, sr_out=fs, enable_plc=enable_plc)
enhanced = output.cpu().detach().numpy().squeeze()
# Normalize to preserve original scale
scale = np.max(np.abs(audio))
if scale > 0:
enhanced = enhanced / (np.max(np.abs(enhanced)) + 1e-8) * scale
# Save to temp file
out_path = tempfile.NamedTemporaryFile(suffix=".wav", delete=False).name
sf.write(out_path, enhanced, fs)
elapsed = time.perf_counter() - t0
print(f"[*] Inference completed in {elapsed:.2f}s")
return out_path
import gradio as gr
CSS = """
#col-container { max-width: 1100px; margin: 0 auto; }
.dark .gradio-container { color: var(--body-text-color); }
"""
with gr.Blocks(theme=gr.themes.Citrus(), css=CSS) as demo:
gr.Markdown(
"# GAP-URGENet: Universal Speech Enhancement\n"
"1st place in the ICASSP 2026 URGENT Challenge objective evaluation. "
"Upload noisy speech audio and get enhanced output."
)
with gr.Column(elem_id="col-container"):
with gr.Row():
audio_input = gr.Audio(
label="Noisy Audio",
type="filepath",
)
audio_output = gr.Audio(
label="Enhanced Audio",
type="filepath",
)
with gr.Row():
plc_checkbox = gr.Checkbox(label="Enable Packet Loss Concealment (PLC)", value=True)
run_btn = gr.Button("Enhance Audio", variant="primary")
run_btn.click(
fn=enhance_audio,
inputs=[audio_input, plc_checkbox],
outputs=audio_output,
api_name="enhance",
)
gr.Examples(
examples=[
["examples/noisy_sample_1.wav", True],
["examples/noisy_sample_2.flac", True],
["examples/noisy_sample_3.flac", True],
],
inputs=[audio_input, plc_checkbox],
outputs=audio_output,
fn=enhance_audio,
cache_examples=True,
cache_mode="lazy",
)
demo.launch(mcp_server=True)