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) | |