Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -80,10 +80,14 @@ os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")
|
|
| 80 |
os.environ.setdefault("HF_HUB_DISABLE_TELEMETRY", "1")
|
| 81 |
os.environ.setdefault("TRANSFORMERS_NO_ADVISORY_WARNINGS", "1")
|
| 82 |
|
|
|
|
| 83 |
os.environ["CUDA_VISIBLE_DEVICES"] = ""
|
| 84 |
os.environ["ACCELERATE_USE_CPU"] = "true"
|
| 85 |
os.environ["TRANSFORMERS_ATTN_IMPLEMENTATION"] = "eager"
|
|
|
|
|
|
|
| 86 |
os.environ.setdefault("ACESTEP_LM_BACKEND", "pt")
|
|
|
|
| 87 |
|
| 88 |
_cgroup_quota = _cgroup_cpu_quota()
|
| 89 |
print(
|
|
@@ -108,8 +112,11 @@ import spaces # noqa: F401
|
|
| 108 |
|
| 109 |
import torch
|
| 110 |
|
|
|
|
|
|
|
|
|
|
| 111 |
# =========================================================================== #
|
| 112 |
-
# Force CPU
|
| 113 |
# =========================================================================== #
|
| 114 |
torch.cuda.is_available = lambda: False # type: ignore[assignment]
|
| 115 |
torch.cuda.device_count = lambda: 0 # type: ignore[assignment]
|
|
@@ -205,7 +212,6 @@ def _zerogpu_startup_probe():
|
|
| 205 |
# --------------------------------------
|
| 206 |
|
| 207 |
|
| 208 |
-
# Патч spaces.GPU → no-op для acestep (CPU). Не влияет на probe выше.
|
| 209 |
def _patch_spaces_gpu_noop():
|
| 210 |
if getattr(spaces.GPU, "_acestep_noop", False):
|
| 211 |
return
|
|
@@ -231,7 +237,7 @@ except Exception as _e: # pragma: no cover
|
|
| 231 |
|
| 232 |
|
| 233 |
# =========================================================================== #
|
| 234 |
-
# SHARED: N-GAN
|
| 235 |
# =========================================================================== #
|
| 236 |
_NGAN_AVAILABLE = False
|
| 237 |
_ngan_model = None
|
|
@@ -298,7 +304,7 @@ def enhance_to_48k(audio, sr: int):
|
|
| 298 |
|
| 299 |
|
| 300 |
# =========================================================================== #
|
| 301 |
-
# SHARED: Whisper large-v3-turbo
|
| 302 |
# =========================================================================== #
|
| 303 |
ASR_MODEL = "openai/whisper-large-v3-turbo"
|
| 304 |
_asr_pipe = None
|
|
@@ -353,7 +359,7 @@ def transcribe_reference(audio_path):
|
|
| 353 |
|
| 354 |
|
| 355 |
# =========================================================================== #
|
| 356 |
-
# TAB 1: HIGGS AUDIO V3
|
| 357 |
# =========================================================================== #
|
| 358 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 359 |
|
|
@@ -438,7 +444,7 @@ def synthesize_higgs(
|
|
| 438 |
|
| 439 |
|
| 440 |
# =========================================================================== #
|
| 441 |
-
# TAB 2: FIREREDTTS3
|
| 442 |
# =========================================================================== #
|
| 443 |
from transformers.modeling_utils import PreTrainedModel
|
| 444 |
|
|
@@ -768,7 +774,7 @@ def voice_clone_firered(
|
|
| 768 |
|
| 769 |
|
| 770 |
# =========================================================================== #
|
| 771 |
-
# TAB 3: ACE-STEP 1.5 XL-TURBO
|
| 772 |
# =========================================================================== #
|
| 773 |
ACESTEP_DIT_MODEL = os.environ.get("ACESTEP_DIT_MODEL", "acestep-v15-turbo")
|
| 774 |
ACESTEP_LM_MODEL = os.environ.get("ACESTEP_LM_MODEL", "acestep-5Hz-lm-1.7B")
|
|
@@ -781,12 +787,8 @@ _acestep_status = {"available": True, "error": None}
|
|
| 781 |
|
| 782 |
@contextlib.contextmanager
|
| 783 |
def _no_meta_init():
|
| 784 |
-
"""Убирает meta-устройство из контекста инициализации transformers 5.x.
|
| 785 |
-
|
| 786 |
-
Иначе ResidualFSQ внутри ACE-Step вызывает .item() на мета-тензоре
|
| 787 |
-
и падает с RuntimeError('Tensor.item() cannot be called on meta tensors').
|
| 788 |
-
"""
|
| 789 |
-
orig = PreTrainedModel.get_init_context.__func__ # unwrap classmethod
|
| 790 |
|
| 791 |
def patched(cls, *args, **kwargs):
|
| 792 |
return [
|
|
@@ -818,7 +820,6 @@ def _get_acestep_handlers():
|
|
| 818 |
if not _acestep_status["available"]:
|
| 819 |
raise gr.Error(f"ACE-Step недоступен: {_acestep_status['error']}")
|
| 820 |
|
| 821 |
-
# ВАЖНО: до импорта acestep — патч spaces.GPU
|
| 822 |
_patch_spaces_gpu_noop()
|
| 823 |
|
| 824 |
try:
|
|
@@ -872,13 +873,62 @@ def _acestep_lyrics(verse: str, chorus: str, bridge: str, instrumental: bool) ->
|
|
| 872 |
return "\n".join(parts) if parts else "[inst]"
|
| 873 |
|
| 874 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 875 |
def acestep_text2music(
|
| 876 |
caption, verse, chorus, bridge, instrumental,
|
| 877 |
-
duration, steps, guidance, seed,
|
| 878 |
):
|
| 879 |
_patch_spaces_gpu_noop()
|
| 880 |
-
from acestep.inference import GenerationParams, GenerationConfig
|
| 881 |
-
|
| 882 |
lyrics = _acestep_lyrics(verse, chorus, bridge, instrumental)
|
| 883 |
params = GenerationParams(
|
| 884 |
caption=caption or "",
|
|
@@ -887,6 +937,7 @@ def acestep_text2music(
|
|
| 887 |
inference_steps=int(max(1, int(steps))),
|
| 888 |
guidance_scale=float(guidance),
|
| 889 |
seed=int(seed) if (seed is not None and int(seed) >= 0) else -1,
|
|
|
|
| 890 |
)
|
| 891 |
config = GenerationConfig(
|
| 892 |
batch_size=1,
|
|
@@ -896,25 +947,10 @@ def acestep_text2music(
|
|
| 896 |
save_dir = tempfile.mkdtemp(prefix="acestep_")
|
| 897 |
print(
|
| 898 |
f"[acestep] gen: steps={steps} guidance={guidance} "
|
| 899 |
-
f"dur={duration}s → {save_dir}",
|
| 900 |
flush=True,
|
| 901 |
)
|
| 902 |
-
|
| 903 |
-
with torch.inference_mode():
|
| 904 |
-
result = generate_music(
|
| 905 |
-
dit_handler=dit,
|
| 906 |
-
llm_handler=llm,
|
| 907 |
-
params=params,
|
| 908 |
-
config=config,
|
| 909 |
-
save_dir=save_dir,
|
| 910 |
-
)
|
| 911 |
-
except Exception as exc:
|
| 912 |
-
raise gr.Error(f"Ошибка генерации ACE-Step: {exc}")
|
| 913 |
-
if not result.success:
|
| 914 |
-
raise gr.Error(f"ACE-Step вернул ошибку: {result.error}")
|
| 915 |
-
if not result.audios:
|
| 916 |
-
raise gr.Error("ACE-Step не вернул аудио.")
|
| 917 |
-
return result.audios[0]["path"]
|
| 918 |
|
| 919 |
|
| 920 |
def acestep_create_sample(query, instrumental, vocal_language):
|
|
@@ -967,7 +1003,7 @@ def acestep_format_sample(caption, lyrics, user_bpm, user_keyscale):
|
|
| 967 |
|
| 968 |
|
| 969 |
# =========================================================================== #
|
| 970 |
-
# UI
|
| 971 |
# =========================================================================== #
|
| 972 |
EN_PROMPT = os.path.join(HERE, "examples", "en_prompt.wav")
|
| 973 |
ZH_PROMPT = os.path.join(HERE, "examples", "zh_prompt.wav")
|
|
@@ -1197,8 +1233,9 @@ with gr.Blocks(title="Higgs Audio v3 + FireRedTTS3 + ACE-Step (CPU)", fill_width
|
|
| 1197 |
gr.Markdown(
|
| 1198 |
"Генерация **музыки** по описанию + куплет/припев на "
|
| 1199 |
"**ACE-Step 1.5 XL-Turbo**, принудительно на CPU. "
|
| 1200 |
-
"⚠️ Первый запуск скачивает ~18 ГБ весов
|
| 1201 |
-
"
|
|
|
|
| 1202 |
)
|
| 1203 |
with gr.Tabs():
|
| 1204 |
with gr.Tab("Text → Music"):
|
|
@@ -1245,7 +1282,12 @@ with gr.Blocks(title="Higgs Audio v3 + FireRedTTS3 + ACE-Step (CPU)", fill_width
|
|
| 1245 |
)
|
| 1246 |
as_guidance = gr.Slider(
|
| 1247 |
0.0, 20.0, value=7.0, step=0.5,
|
| 1248 |
-
label="Guidance scale",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1249 |
)
|
| 1250 |
as_seed = gr.Number(
|
| 1251 |
value=-1, precision=0, label="Seed (-1 = random)",
|
|
@@ -1255,7 +1297,7 @@ with gr.Blocks(title="Higgs Audio v3 + FireRedTTS3 + ACE-Step (CPU)", fill_width
|
|
| 1255 |
inputs=[
|
| 1256 |
as_caption, as_verse, as_chorus, as_bridge,
|
| 1257 |
as_instrumental, as_duration,
|
| 1258 |
-
as_steps, as_guidance, as_seed,
|
| 1259 |
],
|
| 1260 |
outputs=[as_out],
|
| 1261 |
api_name="acestep_text2music",
|
|
|
|
| 80 |
os.environ.setdefault("HF_HUB_DISABLE_TELEMETRY", "1")
|
| 81 |
os.environ.setdefault("TRANSFORMERS_NO_ADVISORY_WARNINGS", "1")
|
| 82 |
|
| 83 |
+
# --- Force CPU ---
|
| 84 |
os.environ["CUDA_VISIBLE_DEVICES"] = ""
|
| 85 |
os.environ["ACCELERATE_USE_CPU"] = "true"
|
| 86 |
os.environ["TRANSFORMERS_ATTN_IMPLEMENTATION"] = "eager"
|
| 87 |
+
|
| 88 |
+
# --- ACE-Step: обход NaN на CPU ---
|
| 89 |
os.environ.setdefault("ACESTEP_LM_BACKEND", "pt")
|
| 90 |
+
os.environ.setdefault("ACESTEP_DTYPE", "float32")
|
| 91 |
|
| 92 |
_cgroup_quota = _cgroup_cpu_quota()
|
| 93 |
print(
|
|
|
|
| 112 |
|
| 113 |
import torch
|
| 114 |
|
| 115 |
+
# --- Ключевой фикс против NaN в DiT на CPU ---
|
| 116 |
+
torch.set_default_dtype(torch.float32)
|
| 117 |
+
|
| 118 |
# =========================================================================== #
|
| 119 |
+
# Force CPU
|
| 120 |
# =========================================================================== #
|
| 121 |
torch.cuda.is_available = lambda: False # type: ignore[assignment]
|
| 122 |
torch.cuda.device_count = lambda: 0 # type: ignore[assignment]
|
|
|
|
| 212 |
# --------------------------------------
|
| 213 |
|
| 214 |
|
|
|
|
| 215 |
def _patch_spaces_gpu_noop():
|
| 216 |
if getattr(spaces.GPU, "_acestep_noop", False):
|
| 217 |
return
|
|
|
|
| 237 |
|
| 238 |
|
| 239 |
# =========================================================================== #
|
| 240 |
+
# SHARED: N-GAN
|
| 241 |
# =========================================================================== #
|
| 242 |
_NGAN_AVAILABLE = False
|
| 243 |
_ngan_model = None
|
|
|
|
| 304 |
|
| 305 |
|
| 306 |
# =========================================================================== #
|
| 307 |
+
# SHARED: Whisper large-v3-turbo
|
| 308 |
# =========================================================================== #
|
| 309 |
ASR_MODEL = "openai/whisper-large-v3-turbo"
|
| 310 |
_asr_pipe = None
|
|
|
|
| 359 |
|
| 360 |
|
| 361 |
# =========================================================================== #
|
| 362 |
+
# TAB 1: HIGGS AUDIO V3
|
| 363 |
# =========================================================================== #
|
| 364 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 365 |
|
|
|
|
| 444 |
|
| 445 |
|
| 446 |
# =========================================================================== #
|
| 447 |
+
# TAB 2: FIREREDTTS3
|
| 448 |
# =========================================================================== #
|
| 449 |
from transformers.modeling_utils import PreTrainedModel
|
| 450 |
|
|
|
|
| 774 |
|
| 775 |
|
| 776 |
# =========================================================================== #
|
| 777 |
+
# TAB 3: ACE-STEP 1.5 XL-TURBO
|
| 778 |
# =========================================================================== #
|
| 779 |
ACESTEP_DIT_MODEL = os.environ.get("ACESTEP_DIT_MODEL", "acestep-v15-turbo")
|
| 780 |
ACESTEP_LM_MODEL = os.environ.get("ACESTEP_LM_MODEL", "acestep-5Hz-lm-1.7B")
|
|
|
|
| 787 |
|
| 788 |
@contextlib.contextmanager
|
| 789 |
def _no_meta_init():
|
| 790 |
+
"""Убирает meta-устройство из контекста инициализации transformers 5.x."""
|
| 791 |
+
orig = PreTrainedModel.get_init_context.__func__
|
|
|
|
|
|
|
|
|
|
|
|
|
| 792 |
|
| 793 |
def patched(cls, *args, **kwargs):
|
| 794 |
return [
|
|
|
|
| 820 |
if not _acestep_status["available"]:
|
| 821 |
raise gr.Error(f"ACE-Step недоступен: {_acestep_status['error']}")
|
| 822 |
|
|
|
|
| 823 |
_patch_spaces_gpu_noop()
|
| 824 |
|
| 825 |
try:
|
|
|
|
| 873 |
return "\n".join(parts) if parts else "[inst]"
|
| 874 |
|
| 875 |
|
| 876 |
+
def _run_acestep_generate(params, config, save_dir):
|
| 877 |
+
"""Обёртка с защитой от NaN: retry при NaN с другим shift."""
|
| 878 |
+
from acestep.inference import generate_music
|
| 879 |
+
|
| 880 |
+
dit, llm = _get_acestep_handlers()
|
| 881 |
+
|
| 882 |
+
try:
|
| 883 |
+
with torch.inference_mode():
|
| 884 |
+
result = generate_music(
|
| 885 |
+
dit_handler=dit,
|
| 886 |
+
llm_handler=llm,
|
| 887 |
+
params=params,
|
| 888 |
+
config=config,
|
| 889 |
+
save_dir=save_dir,
|
| 890 |
+
)
|
| 891 |
+
except Exception as exc:
|
| 892 |
+
raise gr.Error(f"Ошибка генерации ACE-Step: {exc}")
|
| 893 |
+
|
| 894 |
+
if not result.success:
|
| 895 |
+
err = str(getattr(result, "error", "unknown"))
|
| 896 |
+
# NaN → retry с другим shift
|
| 897 |
+
if "NaN" in err or "NaN" in err.lower():
|
| 898 |
+
print(f"[acestep] NaN detected → retry with shift=1.0", flush=True)
|
| 899 |
+
try:
|
| 900 |
+
params.shift = 1.0
|
| 901 |
+
except Exception:
|
| 902 |
+
pass
|
| 903 |
+
save_dir2 = tempfile.mkdtemp(prefix="acestep_retry_")
|
| 904 |
+
try:
|
| 905 |
+
with torch.inference_mode():
|
| 906 |
+
result = generate_music(
|
| 907 |
+
dit_handler=dit,
|
| 908 |
+
llm_handler=llm,
|
| 909 |
+
params=params,
|
| 910 |
+
config=config,
|
| 911 |
+
save_dir=save_dir2,
|
| 912 |
+
)
|
| 913 |
+
except Exception as exc:
|
| 914 |
+
raise gr.Error(f"Повторная генерация тоже упала: {exc}")
|
| 915 |
+
if not result.success:
|
| 916 |
+
raise gr.Error(f"ACE-Step вернул ошибку: {result.error}")
|
| 917 |
+
else:
|
| 918 |
+
raise gr.Error(f"ACE-Step вернул ошибку: {err}")
|
| 919 |
+
|
| 920 |
+
if not result.audios:
|
| 921 |
+
raise gr.Error("ACE-Step не вернул аудио.")
|
| 922 |
+
return result.audios[0]["path"]
|
| 923 |
+
|
| 924 |
+
|
| 925 |
def acestep_text2music(
|
| 926 |
caption, verse, chorus, bridge, instrumental,
|
| 927 |
+
duration, steps, guidance, seed, shift,
|
| 928 |
):
|
| 929 |
_patch_spaces_gpu_noop()
|
| 930 |
+
from acestep.inference import GenerationParams, GenerationConfig
|
| 931 |
+
|
| 932 |
lyrics = _acestep_lyrics(verse, chorus, bridge, instrumental)
|
| 933 |
params = GenerationParams(
|
| 934 |
caption=caption or "",
|
|
|
|
| 937 |
inference_steps=int(max(1, int(steps))),
|
| 938 |
guidance_scale=float(guidance),
|
| 939 |
seed=int(seed) if (seed is not None and int(seed) >= 0) else -1,
|
| 940 |
+
shift=float(shift) if shift is not None else 3.0,
|
| 941 |
)
|
| 942 |
config = GenerationConfig(
|
| 943 |
batch_size=1,
|
|
|
|
| 947 |
save_dir = tempfile.mkdtemp(prefix="acestep_")
|
| 948 |
print(
|
| 949 |
f"[acestep] gen: steps={steps} guidance={guidance} "
|
| 950 |
+
f"shift={shift} dur={duration}s → {save_dir}",
|
| 951 |
flush=True,
|
| 952 |
)
|
| 953 |
+
return _run_acestep_generate(params, config, save_dir)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 954 |
|
| 955 |
|
| 956 |
def acestep_create_sample(query, instrumental, vocal_language):
|
|
|
|
| 1003 |
|
| 1004 |
|
| 1005 |
# =========================================================================== #
|
| 1006 |
+
# UI
|
| 1007 |
# =========================================================================== #
|
| 1008 |
EN_PROMPT = os.path.join(HERE, "examples", "en_prompt.wav")
|
| 1009 |
ZH_PROMPT = os.path.join(HERE, "examples", "zh_prompt.wav")
|
|
|
|
| 1233 |
gr.Markdown(
|
| 1234 |
"Генерация **музыки** по описанию + куплет/припев на "
|
| 1235 |
"**ACE-Step 1.5 XL-Turbo**, принудительно на CPU. "
|
| 1236 |
+
"⚠️ Первый запуск скачивает ~18 ГБ весов; генерация на CPU идёт "
|
| 1237 |
+
"медленно — начинайте с 20–30 секунд. При ошибке NaN автоматически "
|
| 1238 |
+
"перезапускается с `shift=1.0`."
|
| 1239 |
)
|
| 1240 |
with gr.Tabs():
|
| 1241 |
with gr.Tab("Text → Music"):
|
|
|
|
| 1282 |
)
|
| 1283 |
as_guidance = gr.Slider(
|
| 1284 |
0.0, 20.0, value=7.0, step=0.5,
|
| 1285 |
+
label="Guidance scale (Turbo ignores → 1.0)",
|
| 1286 |
+
)
|
| 1287 |
+
as_shift = gr.Slider(
|
| 1288 |
+
1.0, 5.0, value=3.0, step=0.1,
|
| 1289 |
+
label="Shift (Timestep shift)",
|
| 1290 |
+
info="3.0 — стабильный старт; меньше = быстрее, больше = стабильнее",
|
| 1291 |
)
|
| 1292 |
as_seed = gr.Number(
|
| 1293 |
value=-1, precision=0, label="Seed (-1 = random)",
|
|
|
|
| 1297 |
inputs=[
|
| 1298 |
as_caption, as_verse, as_chorus, as_bridge,
|
| 1299 |
as_instrumental, as_duration,
|
| 1300 |
+
as_steps, as_guidance, as_seed, as_shift,
|
| 1301 |
],
|
| 1302 |
outputs=[as_out],
|
| 1303 |
api_name="acestep_text2music",
|