Cartik's picture
Update app.py
0eff681 verified
Raw
History Blame Contribute Delete
7.12 kB
import os
# Отключаем SSR до импорта Gradio
os.environ["GRADIO_SSR_MODE"] = "false"
import gc
import tempfile
import gradio as gr
import soundfile as sf
import torch
import spaces
from diffusers import ModularPipeline
MODEL_ID = "Cartik/Sonexa-Music-v0.1-Beta"
# ============================================================
# CONFIG
# ============================================================
print("=" * 60)
print("Sonexa Music Generation")
print("=" * 60)
print(f"Model: {MODEL_ID}")
print(f"CUDA available: {torch.cuda.is_available()}")
print("=" * 60)
# ============================================================
# LOAD MODEL
# ============================================================
print("Loading music model on CPU...")
pipe = ModularPipeline.from_pretrained(
MODEL_ID,
)
pipe.load_components(
dtype=torch.float32,
)
# Модель постоянно находится в RAM.
# ZeroGPU выдаёт GPU только при вызове @spaces.GPU.
pipe.to("cpu")
print("Music model loaded successfully!")
# ============================================================
# MUSIC GENERATION
# ============================================================
@spaces.GPU(duration=120)
def generate_music(prompt, lyrics, duration):
prompt = (prompt or "").strip()
lyrics = (lyrics or "").strip()
if not prompt:
raise gr.Error(
"Опиши, какую музыку нужно создать."
)
try:
duration = float(duration)
duration = max(10, min(duration, 120))
print("=" * 60)
print("GPU GENERATION START")
print(f"Prompt: {prompt}")
print(f"Lyrics: {lyrics[:200]}")
print(f"Duration: {duration}s")
print("=" * 60)
# ZeroGPU выделяет CUDA перед входом сюда.
if not torch.cuda.is_available():
raise RuntimeError(
"ZeroGPU не выделил CUDA для генерации."
)
device = "cuda"
print("Moving music model to GPU...")
pipe.to(device)
print("Model moved to GPU.")
generator = torch.Generator(
device=device
).manual_seed(
int.from_bytes(
os.urandom(4),
"little",
)
)
print("Starting inference...")
with torch.inference_mode():
result = pipe(
prompt=prompt,
lyrics=lyrics,
audio_duration=duration,
generator=generator,
output="audios",
)
print("Inference finished.")
audio = result[0]
# ====================================================
# SAVE AUDIO
# ====================================================
output_file = tempfile.NamedTemporaryFile(
suffix=".wav",
delete=False,
)
output_path = output_file.name
output_file.close()
# Модель возвращает channel-first audio.
audio_array = (
audio
.T
.float()
.cpu()
.numpy()
)
sf.write(
output_path,
audio_array,
pipe.sampling_rate,
)
print(
f"Music saved: {output_path}"
)
# Возвращаем модель в RAM.
print("Moving model back to CPU...")
pipe.to("cpu")
print("Model returned to CPU.")
return output_path
except Exception as e:
print("=" * 60)
print("MUSIC GENERATION ERROR")
print("=" * 60)
print(repr(e))
print("=" * 60)
# Пытаемся вернуть модель в RAM,
# даже если генерация упала.
try:
pipe.to("cpu")
except Exception as cpu_error:
print(
f"Could not move model to CPU: {cpu_error}"
)
raise gr.Error(
f"Ошибка генерации: {e}"
)
finally:
gc.collect()
if torch.cuda.is_available():
try:
torch.cuda.empty_cache()
except Exception:
pass
print("Generation cleanup finished.")
# ============================================================
# UI
# ============================================================
with gr.Blocks(
title="Sonexa Music"
) as demo:
gr.Markdown(
"# Sonexa Music Generation"
)
gr.Markdown(
"Создавайте музыку по описанию и тексту песни."
)
with gr.Row():
# ====================================================
# INPUT
# ====================================================
with gr.Column():
prompt = gr.Textbox(
label="Описание музыки",
placeholder=(
"Energetic electronic music, "
"powerful drums, deep bass, "
"bright synths and an intense drop"
),
lines=5,
)
lyrics = gr.Textbox(
label="Текст песни",
placeholder=(
"[Verse]\n"
"Morning light is falling...\n\n"
"[Chorus]\n"
"We keep moving through the night..."
),
lines=8,
)
duration = gr.Slider(
minimum=10,
maximum=120,
value=60,
step=10,
label="Длительность (секунды)",
)
button = gr.Button(
"Создать музыку",
variant="primary",
)
# ====================================================
# OUTPUT
# ====================================================
with gr.Column():
output = gr.Audio(
label="Результат",
type="filepath",
)
# ========================================================
# API
# ========================================================
button.click(
fn=generate_music,
inputs=[
prompt,
lyrics,
duration,
],
outputs=output,
api_name="predict",
)
# ============================================================
# QUEUE
# ============================================================
demo.queue(
max_size=8,
default_concurrency_limit=1,
)
# ============================================================
# START
# ============================================================
print("=" * 60)
print("Starting Gradio...")
print("SSR disabled through environment.")
print("=" * 60)
demo.launch(
server_name="0.0.0.0",
server_port=7860,
show_api=True,
)