Spaces:
Running
on
Zero
Running
on
Zero
workaround for gradio file permission -attempt
Browse files
main.py
CHANGED
|
@@ -14,7 +14,10 @@ from audiocraft.data.audio_utils import f32_pcm, normalize_audio
|
|
| 14 |
from audiocraft.data.audio import audio_write
|
| 15 |
from audiocraft.models import JASCO
|
| 16 |
import os
|
|
|
|
| 17 |
from huggingface_hub import login
|
|
|
|
|
|
|
| 18 |
|
| 19 |
title = """# 🙋🏻♂️Welcome to 🌟Tonic's 🎼Jasco🎶AudioCraft Demo"""
|
| 20 |
description = """Facebook presents JASCO, a temporally controlled text-to-music generation model utilizing both symbolic and audio-based conditions. JASCO can generate high-quality music samples conditioned on global text descriptions along with fine-grained local controls. JASCO is based on the Flow Matching modeling paradigm together with a novel conditioning method, allowing for music generation controlled both locally (e.g., chords) and globally (text description). [run this demo locally](https://huggingface.co/spaces/Tonic/audiocraft?docker=true) or [embed this space](https://huggingface.co/spaces/Tonic/audiocraft?embed=true) or [duplicate this space](https://huggingface.co/spaces/Tonic/audiocraft?duplicate=true) to run it privately . you can also use this demo via API by clicking the link at the bottom of the page."""
|
|
@@ -187,15 +190,37 @@ Model: facebook/jasco-chords-drums-1B
|
|
| 187 |
- Melody-enabled models may be slower
|
| 188 |
"""
|
| 189 |
|
|
|
|
|
|
|
|
|
|
| 190 |
hf_token = os.environ.get('HFTOKEN')
|
| 191 |
if hf_token:
|
| 192 |
login(token=hf_token)
|
| 193 |
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
|
| 198 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
|
| 200 |
def generate_chord_mappings():
|
| 201 |
# Define basic chord mappings
|
|
@@ -308,41 +333,87 @@ def chords_string_to_list(chords: str):
|
|
| 308 |
chrd_times = [x.split(',') for x in chords[1:-1].split('),(')]
|
| 309 |
return [(x[0], float(x[1])) for x in chrd_times]
|
| 310 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
# Create necessary directories
|
| 312 |
os.makedirs("models", exist_ok=True)
|
| 313 |
|
| 314 |
@spaces.GPU
|
| 315 |
-
def load_model(version='facebook/jasco-chords-drums-400M'):
|
| 316 |
global MODEL
|
| 317 |
print("Loading model", version)
|
| 318 |
if MODEL is None or MODEL.name != version:
|
| 319 |
MODEL = None
|
| 320 |
-
|
| 321 |
-
# Setup model directory
|
| 322 |
-
model_dir = os.path.join(os.path.dirname(__file__), "models")
|
| 323 |
-
os.makedirs(model_dir, exist_ok=True)
|
| 324 |
-
|
| 325 |
-
# Generate and save chord mappings
|
| 326 |
-
chord_mapping_path = os.path.join(model_dir, "chord_to_index_mapping.pkl")
|
| 327 |
-
if not os.path.exists(chord_mapping_path):
|
| 328 |
-
chord_mapping_path = generate_chord_mappings()
|
| 329 |
-
|
| 330 |
try:
|
| 331 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
MODEL = JASCO.get_pretrained(
|
| 333 |
version,
|
| 334 |
device='cuda',
|
| 335 |
-
|
|
|
|
| 336 |
)
|
| 337 |
MODEL.name = version
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 338 |
except Exception as e:
|
| 339 |
raise gr.Error(f"Error loading model: {str(e)}")
|
| 340 |
|
| 341 |
if MODEL is None:
|
| 342 |
raise gr.Error("Failed to load model")
|
| 343 |
-
|
| 344 |
return MODEL
|
| 345 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 346 |
@spaces.GPU
|
| 347 |
def _do_predictions(texts, chords, melody_matrix, drum_prompt, progress=False, gradio_progress=None, **gen_kwargs):
|
| 348 |
MODEL.set_generation_params(**gen_kwargs)
|
|
@@ -516,4 +587,13 @@ with gr.Blocks() as demo:
|
|
| 516 |
outputs=[audio_output_0, audio_output_1]
|
| 517 |
)
|
| 518 |
|
| 519 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
from audiocraft.data.audio import audio_write
|
| 15 |
from audiocraft.models import JASCO
|
| 16 |
import os
|
| 17 |
+
import tempfile
|
| 18 |
from huggingface_hub import login
|
| 19 |
+
from pathlib import Path
|
| 20 |
+
|
| 21 |
|
| 22 |
title = """# 🙋🏻♂️Welcome to 🌟Tonic's 🎼Jasco🎶AudioCraft Demo"""
|
| 23 |
description = """Facebook presents JASCO, a temporally controlled text-to-music generation model utilizing both symbolic and audio-based conditions. JASCO can generate high-quality music samples conditioned on global text descriptions along with fine-grained local controls. JASCO is based on the Flow Matching modeling paradigm together with a novel conditioning method, allowing for music generation controlled both locally (e.g., chords) and globally (text description). [run this demo locally](https://huggingface.co/spaces/Tonic/audiocraft?docker=true) or [embed this space](https://huggingface.co/spaces/Tonic/audiocraft?embed=true) or [duplicate this space](https://huggingface.co/spaces/Tonic/audiocraft?duplicate=true) to run it privately . you can also use this demo via API by clicking the link at the bottom of the page."""
|
|
|
|
| 190 |
- Melody-enabled models may be slower
|
| 191 |
"""
|
| 192 |
|
| 193 |
+
MODEL = None
|
| 194 |
+
INTERRUPTING = False
|
| 195 |
+
|
| 196 |
hf_token = os.environ.get('HFTOKEN')
|
| 197 |
if hf_token:
|
| 198 |
login(token=hf_token)
|
| 199 |
|
| 200 |
+
# Set up cache directory
|
| 201 |
+
CACHE_DIR = os.path.join(tempfile.gettempdir(), 'audiocraft_cache')
|
| 202 |
+
os.makedirs(CACHE_DIR, exist_ok=True)
|
| 203 |
+
|
| 204 |
+
# Set environment variables
|
| 205 |
+
os.environ['AUDIOCRAFT_CACHE_DIR'] = CACHE_DIR
|
| 206 |
+
os.environ['TORCH_HOME'] = CACHE_DIR
|
| 207 |
+
os.environ['HF_HOME'] = os.path.join(CACHE_DIR, 'huggingface')
|
| 208 |
+
os.environ['TRANSFORMERS_CACHE'] = os.path.join(CACHE_DIR, 'transformers')
|
| 209 |
+
os.environ['XDG_CACHE_HOME'] = CACHE_DIR
|
| 210 |
+
|
| 211 |
+
# Create necessary subdirectories
|
| 212 |
+
for subdir in ['models', 'cache', 'huggingface', 'drum_cache', 'transformers']:
|
| 213 |
+
os.makedirs(os.path.join(CACHE_DIR, subdir), exist_ok=True)
|
| 214 |
|
| 215 |
+
def cleanup_cache():
|
| 216 |
+
"""Clean up temporary cache files"""
|
| 217 |
+
try:
|
| 218 |
+
import shutil
|
| 219 |
+
if os.path.exists(CACHE_DIR):
|
| 220 |
+
shutil.rmtree(CACHE_DIR)
|
| 221 |
+
os.makedirs(CACHE_DIR, exist_ok=True)
|
| 222 |
+
except Exception as e:
|
| 223 |
+
print(f"Error cleaning cache: {e}")
|
| 224 |
|
| 225 |
def generate_chord_mappings():
|
| 226 |
# Define basic chord mappings
|
|
|
|
| 333 |
chrd_times = [x.split(',') for x in chords[1:-1].split('),(')]
|
| 334 |
return [(x[0], float(x[1])) for x in chrd_times]
|
| 335 |
|
| 336 |
+
# Add this before model loading
|
| 337 |
+
def patch_jasco_cache():
|
| 338 |
+
"""Monkey patch JASCO cache initialization"""
|
| 339 |
+
from audiocraft.modules import jasco_conditioners
|
| 340 |
+
|
| 341 |
+
original_init = jasco_conditioners.DrumConditioner.__init__
|
| 342 |
+
|
| 343 |
+
def new_init(self, *args, **kwargs):
|
| 344 |
+
if 'cache_path' in kwargs:
|
| 345 |
+
kwargs['cache_path'] = os.path.join(CACHE_DIR, 'drum_cache')
|
| 346 |
+
return original_init(self, *args, **kwargs)
|
| 347 |
+
|
| 348 |
+
jasco_conditioners.DrumConditioner.__init__ = new_init
|
| 349 |
+
|
| 350 |
+
# Apply the patch
|
| 351 |
+
patch_jasco_cache()
|
| 352 |
+
|
| 353 |
# Create necessary directories
|
| 354 |
os.makedirs("models", exist_ok=True)
|
| 355 |
|
| 356 |
@spaces.GPU
|
| 357 |
+
def load_model(version='facebook/jasco-chords-drums-melody-400M'):
|
| 358 |
global MODEL
|
| 359 |
print("Loading model", version)
|
| 360 |
if MODEL is None or MODEL.name != version:
|
| 361 |
MODEL = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 362 |
try:
|
| 363 |
+
# Set up custom cache paths
|
| 364 |
+
cache_path = os.path.join(CACHE_DIR, version.replace('/', '_'))
|
| 365 |
+
os.makedirs(cache_path, exist_ok=True)
|
| 366 |
+
|
| 367 |
+
# Set additional environment variables
|
| 368 |
+
os.environ['AUDIOCRAFT_CACHE_DIR'] = cache_path
|
| 369 |
+
os.environ['TRANSFORMERS_CACHE'] = os.path.join(cache_path, 'transformers')
|
| 370 |
+
|
| 371 |
+
# Initialize model with custom cache configuration
|
| 372 |
+
model_kwargs = {
|
| 373 |
+
'device': 'cuda',
|
| 374 |
+
'cache_dir': cache_path,
|
| 375 |
+
'model_cache_dir': cache_path
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
# Initialize chord mapping
|
| 379 |
+
mapping_file = initialize_chord_mapping()
|
| 380 |
+
os.environ['AUDIOCRAFT_CHORD_MAPPING'] = mapping_file
|
| 381 |
+
|
| 382 |
+
# Load the model with specific cache paths
|
| 383 |
MODEL = JASCO.get_pretrained(
|
| 384 |
version,
|
| 385 |
device='cuda',
|
| 386 |
+
cache_dir=cache_path,
|
| 387 |
+
local_files_only=False
|
| 388 |
)
|
| 389 |
MODEL.name = version
|
| 390 |
+
|
| 391 |
+
# Configure model paths
|
| 392 |
+
MODEL._cache_dir = cache_path
|
| 393 |
+
|
| 394 |
+
# Load the chord mapping
|
| 395 |
+
with open(mapping_file, 'rb') as f:
|
| 396 |
+
MODEL.chord_to_index = pickle.load(f)
|
| 397 |
+
|
| 398 |
except Exception as e:
|
| 399 |
raise gr.Error(f"Error loading model: {str(e)}")
|
| 400 |
|
| 401 |
if MODEL is None:
|
| 402 |
raise gr.Error("Failed to load model")
|
|
|
|
| 403 |
return MODEL
|
| 404 |
|
| 405 |
+
class ModelLoadingError(Exception):
|
| 406 |
+
pass
|
| 407 |
+
|
| 408 |
+
def handle_model_error(func):
|
| 409 |
+
def wrapper(*args, **kwargs):
|
| 410 |
+
try:
|
| 411 |
+
return func(*args, **kwargs)
|
| 412 |
+
except Exception as e:
|
| 413 |
+
print(f"Error in {func.__name__}: {str(e)}")
|
| 414 |
+
raise ModelLoadingError(f"Failed to load model: {str(e)}")
|
| 415 |
+
return wrapper
|
| 416 |
+
|
| 417 |
@spaces.GPU
|
| 418 |
def _do_predictions(texts, chords, melody_matrix, drum_prompt, progress=False, gradio_progress=None, **gen_kwargs):
|
| 419 |
MODEL.set_generation_params(**gen_kwargs)
|
|
|
|
| 587 |
outputs=[audio_output_0, audio_output_1]
|
| 588 |
)
|
| 589 |
|
| 590 |
+
# Add cleanup on close
|
| 591 |
+
demo.load(lambda: None, [], [], _js="() => { window.addEventListener('beforeunload', () => { cleanup_cache(); }); }")
|
| 592 |
+
# Launch with cleanup and error handling
|
| 593 |
+
try:
|
| 594 |
+
demo.queue().launch(ssr_mode=False
|
| 595 |
+
)
|
| 596 |
+
except Exception as e:
|
| 597 |
+
print(f"Error launching demo: {str(e)}")
|
| 598 |
+
finally:
|
| 599 |
+
cleanup_cache()
|