Spaces:
Runtime error
Runtime error
| # ββ 0. ZeroGPU decorator (must be first) βββββββββββββββββββββββββββ | |
| import spaces # <-- leave this as the very first import | |
| # ββ 1. Standard libs βββββββββββββββββββββββββββββββββββββββββββββββ | |
| import os, sys, gc, time, warnings, tempfile, subprocess, random | |
| import numpy as np, psutil | |
| # ββ 2. Torch stack (torch 2.1.0 / torchaudio 2.1.0 from requirements) β | |
| import torch, torchaudio | |
| # ββ 3. Misc deps ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| import gradio as gr | |
| from pydub import AudioSegment | |
| from huggingface_hub import login | |
| from torch.cuda.amp import autocast | |
| # ββ 4. Torch <2.3 shim (transformers 4.38 expects it) βββββββββββββ | |
| if not hasattr(torch, "get_default_device"): | |
| torch.get_default_device = lambda: torch.device( | |
| "cuda" if torch.cuda.is_available() else "cpu" | |
| ) | |
| warnings.filterwarnings("ignore") | |
| os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:128" | |
| # ββ 5. Install audiocraft 1.3.0 (no deps) at runtime ββββββββββββββ | |
| try: | |
| from audiocraft.models import MusicGen | |
| except ModuleNotFoundError: | |
| print("π§ Installing audiocraft 1.3.0 (no-deps)β¦") | |
| subprocess.check_call( | |
| [sys.executable, "-m", "pip", "install", "audiocraft==1.3.0", "--no-deps", "-q"] | |
| ) | |
| from audiocraft.models import MusicGen | |
| # ββ 6. Hugging Face authentication ββββββββββββββββββββββββββββββββ | |
| HF_TOKEN = os.getenv("HF_TOKEN") | |
| if not HF_TOKEN: | |
| sys.exit("ERROR: Add HF_TOKEN as a secret in your Space settings.") | |
| login(HF_TOKEN) | |
| # ββ 7. Load MusicGen model ββββββββββββββββββββββββββββββββββββββββ | |
| print("β¬ Loading facebook/musicgen-medium (first load β 6 GB)β¦") | |
| musicgen = MusicGen.get_pretrained("facebook/musicgen-medium") | |
| musicgen.to(torch.get_default_device()) | |
| musicgen.set_generation_params(duration=10, two_step_cfg=False) | |
| SR = musicgen.sample_rate | |
| # ββ 8. Prompt builders (add more as needed) βββββββββββββββββββββββ | |
| def _build(base,bpm,dr,syn,st,bass,gtr,def_bass,def_gtr,flow): | |
| step = f" with {st}" if st!="none" else flow.format(bpm=bpm) | |
| return (f"{base}" | |
| f"{def_bass if bass=='none' else ', '+bass}" | |
| f"{def_gtr if gtr=='none' else ', '+gtr+' guitar riffs'}" | |
| f"{'' if dr=='none' else ', '+dr+' drums'}" | |
| f"{'' if syn=='none' else ', '+syn+' accents'}" | |
| f"{step} at {bpm} BPM.") | |
| def set_rhcp(bpm,dr,syn,st,bass,gtr): | |
| return _build("Instrumental funk rock",bpm,dr,syn,st,bass,gtr, | |
| ", groovy basslines",", syncopated guitar riffs", | |
| "{bpm} BPM funky flow" if bpm>120 else "groovy rhythmic flow") | |
| def set_nirvana(bpm,dr,syn,st,bass,gtr): | |
| return _build("Instrumental grunge",bpm,dr,syn,st,bass,gtr, | |
| ", melodic basslines",", raw distorted guitar riffs", | |
| "{bpm} BPM grungy pulse" if bpm>120 else "grungy rhythmic pulse") | |
| # (β Add remaining genre prompt functions here the same way.) | |
| # ββ 9. Audio post-FX helpers ββββββββββββββββββββββββββββββββββββββ | |
| def apply_eq(seg): return seg.low_pass_filter(8000).high_pass_filter(80) | |
| def apply_fade(seg): return seg.fade_in(1000).fade_out(1000) | |
| def log(stage=""): | |
| if stage: print(f"ββ {stage} ββ") | |
| if torch.cuda.is_available(): | |
| a = torch.cuda.memory_allocated()/1024**3 | |
| r = torch.cuda.memory_reserved()/1024**3 | |
| print(f"GPU alloc {a:.2f} GB reserved {r:.2f} GB") | |
| print(f"CPU {psutil.virtual_memory().percent}%") | |
| # ββ 10. Core generator (ZeroGPU wrapper) ββββββββββββββββββββββββββ | |
| def generate(prompt,cfg,k,p,temp, | |
| total_len,chunk_len,xfade, | |
| bpm,dr,syn,step,bass,gtr): | |
| if not prompt.strip(): | |
| return None, "β οΈ Empty prompt." | |
| total_len = int(total_len) | |
| chunk_len = max(5, min(int(chunk_len), 15)) | |
| n_chunks = max(1, total_len // chunk_len) | |
| chunk_len = total_len / n_chunks | |
| overlap = min(1.0, xfade / 1000.0) | |
| render = chunk_len + overlap | |
| segments = [] | |
| torch.manual_seed(42); np.random.seed(42) | |
| for i in range(n_chunks): | |
| log(f"chunk {i+1}") | |
| musicgen.set_generation_params(duration=render,use_sampling=True, | |
| top_k=k,top_p=p,temperature=temp,cfg_coef=cfg) | |
| with torch.no_grad(), autocast(): | |
| audio = musicgen.generate([prompt], progress=False)[0] | |
| audio = audio.cpu().float() | |
| if audio.dim()==1 or audio.shape[0]==1: | |
| audio = audio.repeat(2,1) | |
| with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp: | |
| torchaudio.save(tmp.name, audio, SR) | |
| segments.append(AudioSegment.from_wav(tmp.name)) | |
| os.unlink(tmp.name) | |
| torch.cuda.empty_cache(); gc.collect() | |
| track = segments[0] | |
| for seg in segments[1:]: | |
| track = track.append(seg, crossfade=xfade) | |
| track = track[: total_len*1000] | |
| track = apply_fade(apply_eq(track).normalize(headroom=-9.0)) | |
| out_f = "output_cleaned.mp3" | |
| track.export(out_f, format="mp3", bitrate="128k", | |
| tags={"title":"GhostAI Track","artist":"GhostAI"}) | |
| return out_f, "β Done!" | |
| def clear_inputs(): | |
| return ("",3.0,250,0.9,1.0,30,10,1000, | |
| 120,"none","none","none","none","none") | |
| # ββ 11. Gradio UI βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with gr.Blocks(css="body{background:#0A0A0A;color:#E0E0E0;font-family:'Orbitron',sans-serif}") as demo: | |
| gr.Markdown("<h1 style='text-align:center'>π» GhostAI MusicGen</h1>") | |
| prompt = gr.Textbox(lines=4, label="Instrumental Prompt") | |
| with gr.Row(): | |
| gr.Button("RHCP πΆοΈ").click(set_rhcp, | |
| inputs=[gr.State(120),"none","none","none","none","none"], | |
| outputs=prompt) | |
| gr.Button("Nirvana πΈ").click(set_nirvana, | |
| inputs=[gr.State(120),"none","none","none","none","none"], | |
| outputs=prompt) | |
| # β add more genre buttons β¦ | |
| cfg = gr.Slider(1,10,3,label="CFG") | |
| k = gr.Slider(10,500,250,step=10,label="Top-K") | |
| p = gr.Slider(0,1,0.9,step=0.05,label="Top-P") | |
| temp = gr.Slider(0.1,2,1,label="Temp") | |
| length= gr.Radio([30,60,90,120],value=30,label="Length (s)") | |
| chunk = gr.Slider(5,15,10,label="Chunk (s)") | |
| xfade = gr.Slider(100,2000,1000,label="Cross-fade (ms)") | |
| bpm = gr.Slider(60,180,120,label="BPM") | |
| drum = gr.Dropdown(["none","standard rock","funk groove","techno kick","jazz swing"],"none","Drums") | |
| synth = gr.Dropdown(["none","analog synth","digital pad","arpeggiated synth"],"none","Synth") | |
| steps = gr.Dropdown(["none","syncopated steps","steady steps","complex steps"],"none","Steps") | |
| bass = gr.Dropdown(["none","slap bass","deep bass","melodic bass"],"none","Bass") | |
| gtr = gr.Dropdown(["none","distorted","clean","jangle"],"none","Guitar") | |
| gen = gr.Button("Generate π") | |
| clr = gr.Button("Clear π§Ή") | |
| audio = gr.Audio(type="filepath") | |
| status= gr.Textbox(interactive=False) | |
| gen.click(generate, | |
| [prompt,cfg,k,p,temp,length,chunk,xfade,bpm,drum,synth,steps,bass,gtr], | |
| [audio,status]) | |
| clr.click(clear_inputs, None, | |
| [prompt,cfg,k,p,temp,length,chunk,xfade,bpm,drum,synth,steps,bass,gtr]) | |
| demo.launch(share=False) | |