Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
CHANGED
|
@@ -1,15 +1,13 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import zipfile
|
| 3 |
-
import tempfile
|
| 4 |
import shutil
|
| 5 |
from pathlib import Path
|
| 6 |
-
import pandas as pd
|
| 7 |
import json
|
| 8 |
import os
|
| 9 |
import traceback
|
| 10 |
import gc
|
| 11 |
import torch
|
| 12 |
-
import spaces
|
| 13 |
|
| 14 |
# Import your modules
|
| 15 |
from engine import compute_mapss_measures
|
|
@@ -17,146 +15,125 @@ from models import get_model_config, cleanup_all_models
|
|
| 17 |
from config import DEFAULT_ALPHA
|
| 18 |
from utils import clear_gpu_memory
|
| 19 |
|
| 20 |
-
@spaces.GPU(duration=300)
|
| 21 |
def process_audio_files(zip_file, model_name, layer, alpha):
|
| 22 |
-
"""
|
| 23 |
-
Process uploaded ZIP file containing audio mixtures.
|
| 24 |
-
|
| 25 |
-
Expected ZIP structure:
|
| 26 |
-
- references/: Contains N reference audio files
|
| 27 |
-
- outputs/: Contains N output audio files
|
| 28 |
-
"""
|
| 29 |
|
| 30 |
if zip_file is None:
|
| 31 |
return None, "Please upload a ZIP file"
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
for item in extract_path.iterdir():
|
| 51 |
if item.is_dir():
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
max_gpus
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
add_ci=False # Disable CI for faster processing
|
| 117 |
-
)
|
| 118 |
-
|
| 119 |
-
# Create output ZIP with results
|
| 120 |
-
output_zip = temp_path / "results.zip"
|
| 121 |
-
|
| 122 |
-
with zipfile.ZipFile(output_zip, 'w') as zipf:
|
| 123 |
-
# Add all CSV files from results
|
| 124 |
-
results_path = Path(results_dir)
|
| 125 |
-
for csv_file in results_path.rglob("*.csv"):
|
| 126 |
-
arcname = str(csv_file.relative_to(results_path.parent))
|
| 127 |
-
zipf.write(csv_file, arcname)
|
| 128 |
-
|
| 129 |
-
# Add params.json
|
| 130 |
-
params_file = results_path / "params.json"
|
| 131 |
-
if params_file.exists():
|
| 132 |
-
zipf.write(params_file, str(params_file.relative_to(results_path.parent)))
|
| 133 |
-
|
| 134 |
-
# Add manifest
|
| 135 |
-
manifest_file = results_path / "manifest_canonical.json"
|
| 136 |
-
if manifest_file.exists():
|
| 137 |
-
zipf.write(manifest_file, str(manifest_file.relative_to(results_path.parent)))
|
| 138 |
-
|
| 139 |
-
# Read the ZIP file to return
|
| 140 |
-
with open(output_zip, 'rb') as f:
|
| 141 |
-
output_data = f.read()
|
| 142 |
-
|
| 143 |
-
# Create a proper file object for Gradio
|
| 144 |
-
output_file_path = temp_path / "download_results.zip"
|
| 145 |
-
with open(output_file_path, 'wb') as f:
|
| 146 |
-
f.write(output_data)
|
| 147 |
|
| 148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
|
| 159 |
-
# Create Gradio interface
|
| 160 |
def create_interface():
|
| 161 |
with gr.Blocks(title="MAPSS - Multi-source Audio Perceptual Separation Scores") as demo:
|
| 162 |
gr.Markdown("""
|
|
@@ -278,7 +255,6 @@ def create_interface():
|
|
| 278 |
label="Diffusion maps alpha parameter"
|
| 279 |
)
|
| 280 |
|
| 281 |
-
# Define model layer configurations
|
| 282 |
def update_layer_slider(model_name):
|
| 283 |
"""Update layer slider based on selected model"""
|
| 284 |
model_configs = {
|
|
@@ -303,7 +279,6 @@ def create_interface():
|
|
| 303 |
interactive=config["interactive"]
|
| 304 |
)
|
| 305 |
|
| 306 |
-
# Connect the model dropdown to update the layer slider
|
| 307 |
model_dropdown.change(
|
| 308 |
fn=update_layer_slider,
|
| 309 |
inputs=[model_dropdown],
|
|
@@ -323,24 +298,14 @@ def create_interface():
|
|
| 323 |
max_lines=10
|
| 324 |
)
|
| 325 |
|
| 326 |
-
# Set up the processing
|
| 327 |
process_btn.click(
|
| 328 |
fn=process_audio_files,
|
| 329 |
inputs=[file_input, model_dropdown, layer_slider, alpha_slider],
|
| 330 |
outputs=[output_file, status_text]
|
| 331 |
)
|
| 332 |
-
|
| 333 |
-
# Add examples if you want
|
| 334 |
-
gr.Examples(
|
| 335 |
-
examples=[
|
| 336 |
-
# You can add example ZIP files here if you have them
|
| 337 |
-
],
|
| 338 |
-
inputs=[file_input]
|
| 339 |
-
)
|
| 340 |
|
| 341 |
return demo
|
| 342 |
|
| 343 |
-
# Create and launch the app
|
| 344 |
if __name__ == "__main__":
|
| 345 |
demo = create_interface()
|
| 346 |
demo.launch()
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import zipfile
|
|
|
|
| 3 |
import shutil
|
| 4 |
from pathlib import Path
|
|
|
|
| 5 |
import json
|
| 6 |
import os
|
| 7 |
import traceback
|
| 8 |
import gc
|
| 9 |
import torch
|
| 10 |
+
import spaces
|
| 11 |
|
| 12 |
# Import your modules
|
| 13 |
from engine import compute_mapss_measures
|
|
|
|
| 15 |
from config import DEFAULT_ALPHA
|
| 16 |
from utils import clear_gpu_memory
|
| 17 |
|
| 18 |
+
@spaces.GPU(duration=300)
|
| 19 |
def process_audio_files(zip_file, model_name, layer, alpha):
|
| 20 |
+
"""Process uploaded ZIP file containing audio mixtures."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
if zip_file is None:
|
| 23 |
return None, "Please upload a ZIP file"
|
| 24 |
|
| 25 |
+
try:
|
| 26 |
+
# Use a fixed extraction path
|
| 27 |
+
extract_path = Path("/tmp/mapss_extract")
|
| 28 |
+
if extract_path.exists():
|
| 29 |
+
shutil.rmtree(extract_path)
|
| 30 |
+
extract_path.mkdir(parents=True)
|
| 31 |
+
|
| 32 |
+
# Extract ZIP
|
| 33 |
+
with zipfile.ZipFile(zip_file.name, 'r') as zip_ref:
|
| 34 |
+
zip_ref.extractall(extract_path)
|
| 35 |
+
|
| 36 |
+
# Find references and outputs directories
|
| 37 |
+
refs_dir = None
|
| 38 |
+
outs_dir = None
|
| 39 |
+
|
| 40 |
+
for item in extract_path.iterdir():
|
| 41 |
+
if item.is_dir():
|
| 42 |
+
if item.name.lower() in ['references', 'refs', 'reference']:
|
| 43 |
+
refs_dir = item
|
| 44 |
+
elif item.name.lower() in ['outputs', 'outs', 'output', 'separated']:
|
| 45 |
+
outs_dir = item
|
| 46 |
+
|
| 47 |
+
# Check one level deeper if not found
|
| 48 |
+
if refs_dir is None or outs_dir is None:
|
| 49 |
for item in extract_path.iterdir():
|
| 50 |
if item.is_dir():
|
| 51 |
+
for subitem in item.iterdir():
|
| 52 |
+
if subitem.is_dir():
|
| 53 |
+
if subitem.name.lower() in ['references', 'refs', 'reference']:
|
| 54 |
+
refs_dir = subitem
|
| 55 |
+
elif subitem.name.lower() in ['outputs', 'outs', 'output', 'separated']:
|
| 56 |
+
outs_dir = subitem
|
| 57 |
+
|
| 58 |
+
if refs_dir is None or outs_dir is None:
|
| 59 |
+
return None, "Could not find 'references' and 'outputs' directories in the ZIP file"
|
| 60 |
+
|
| 61 |
+
# Get audio files
|
| 62 |
+
ref_files = sorted([f for f in refs_dir.glob("*.wav")])
|
| 63 |
+
out_files = sorted([f for f in outs_dir.glob("*.wav")])
|
| 64 |
+
|
| 65 |
+
if len(ref_files) == 0:
|
| 66 |
+
return None, "No reference WAV files found"
|
| 67 |
+
if len(out_files) == 0:
|
| 68 |
+
return None, "No output WAV files found"
|
| 69 |
+
|
| 70 |
+
# Create manifest
|
| 71 |
+
manifest = [{
|
| 72 |
+
"mixture_id": "uploaded_mixture",
|
| 73 |
+
"references": [str(f) for f in ref_files],
|
| 74 |
+
"systems": {
|
| 75 |
+
"uploaded_system": [str(f) for f in out_files]
|
| 76 |
+
}
|
| 77 |
+
}]
|
| 78 |
+
|
| 79 |
+
# Validate model
|
| 80 |
+
allowed_models = set(get_model_config(0).keys())
|
| 81 |
+
if model_name not in allowed_models:
|
| 82 |
+
return None, f"Invalid model. Allowed: {', '.join(sorted(allowed_models))}"
|
| 83 |
+
|
| 84 |
+
# Set layer
|
| 85 |
+
if model_name == "raw":
|
| 86 |
+
layer_final = 0
|
| 87 |
+
else:
|
| 88 |
+
model_defaults = {
|
| 89 |
+
"wavlm": 24, "wav2vec2": 24, "hubert": 24,
|
| 90 |
+
"wavlm_base": 12, "wav2vec2_base": 12, "hubert_base": 12,
|
| 91 |
+
"wav2vec2_xlsr": 24, "ast": 12
|
| 92 |
+
}
|
| 93 |
+
layer_final = layer if layer is not None else model_defaults.get(model_name, 12)
|
| 94 |
+
|
| 95 |
+
# Check GPU availability
|
| 96 |
+
max_gpus = 1 if torch.cuda.is_available() else 0
|
| 97 |
+
|
| 98 |
+
# Run experiment
|
| 99 |
+
results_dir = compute_mapss_measures(
|
| 100 |
+
models=[model_name],
|
| 101 |
+
mixtures=manifest,
|
| 102 |
+
layer=layer_final,
|
| 103 |
+
alpha=alpha,
|
| 104 |
+
verbose=True,
|
| 105 |
+
max_gpus=max_gpus,
|
| 106 |
+
add_ci=False
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
# Create output ZIP at a fixed location
|
| 110 |
+
output_zip = Path("/tmp/mapss_results.zip")
|
| 111 |
+
|
| 112 |
+
with zipfile.ZipFile(output_zip, 'w') as zipf:
|
| 113 |
+
results_path = Path(results_dir)
|
| 114 |
+
files_added = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
+
# Add all files from results
|
| 117 |
+
for file_path in results_path.rglob("*"):
|
| 118 |
+
if file_path.is_file():
|
| 119 |
+
arcname = str(file_path.relative_to(results_path.parent))
|
| 120 |
+
zipf.write(file_path, arcname)
|
| 121 |
+
files_added += 1
|
| 122 |
+
|
| 123 |
+
if output_zip.exists() and files_added > 0:
|
| 124 |
+
return str(output_zip), f"Processing completed! Created ZIP with {files_added} files."
|
| 125 |
+
else:
|
| 126 |
+
return None, f"Processing completed but no output files were generated. Check if embeddings were computed."
|
| 127 |
|
| 128 |
+
except Exception as e:
|
| 129 |
+
error_msg = f"Error: {str(e)}\n{traceback.format_exc()}"
|
| 130 |
+
return None, error_msg
|
| 131 |
+
|
| 132 |
+
finally:
|
| 133 |
+
cleanup_all_models()
|
| 134 |
+
clear_gpu_memory()
|
| 135 |
+
gc.collect()
|
| 136 |
|
|
|
|
| 137 |
def create_interface():
|
| 138 |
with gr.Blocks(title="MAPSS - Multi-source Audio Perceptual Separation Scores") as demo:
|
| 139 |
gr.Markdown("""
|
|
|
|
| 255 |
label="Diffusion maps alpha parameter"
|
| 256 |
)
|
| 257 |
|
|
|
|
| 258 |
def update_layer_slider(model_name):
|
| 259 |
"""Update layer slider based on selected model"""
|
| 260 |
model_configs = {
|
|
|
|
| 279 |
interactive=config["interactive"]
|
| 280 |
)
|
| 281 |
|
|
|
|
| 282 |
model_dropdown.change(
|
| 283 |
fn=update_layer_slider,
|
| 284 |
inputs=[model_dropdown],
|
|
|
|
| 298 |
max_lines=10
|
| 299 |
)
|
| 300 |
|
|
|
|
| 301 |
process_btn.click(
|
| 302 |
fn=process_audio_files,
|
| 303 |
inputs=[file_input, model_dropdown, layer_slider, alpha_slider],
|
| 304 |
outputs=[output_file, status_text]
|
| 305 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 306 |
|
| 307 |
return demo
|
| 308 |
|
|
|
|
| 309 |
if __name__ == "__main__":
|
| 310 |
demo = create_interface()
|
| 311 |
demo.launch()
|