Spaces:
Running on Zero
Running on Zero
Upload folder using huggingface_hub
Browse files- __pycache__/armazenamento.cpython-311.pyc +0 -0
- __pycache__/nucleo.cpython-311.pyc +0 -0
- app.py +6 -1
- modelos/__pycache__/__init__.cpython-311.pyc +0 -0
- modelos/__pycache__/ace_step.cpython-311.pyc +0 -0
- modelos/__pycache__/base.cpython-311.pyc +0 -0
- modelos/__pycache__/qwen3_tts.cpython-311.pyc +0 -0
- modelos/__pycache__/wan22.cpython-311.pyc +0 -0
- modelos/__pycache__/z_image.cpython-311.pyc +0 -0
- modelos/ace_step.py +56 -21
- requirements.txt +11 -14
__pycache__/armazenamento.cpython-311.pyc
CHANGED
|
Binary files a/__pycache__/armazenamento.cpython-311.pyc and b/__pycache__/armazenamento.cpython-311.pyc differ
|
|
|
__pycache__/nucleo.cpython-311.pyc
CHANGED
|
Binary files a/__pycache__/nucleo.cpython-311.pyc and b/__pycache__/nucleo.cpython-311.pyc differ
|
|
|
app.py
CHANGED
|
@@ -56,7 +56,12 @@ def _fazer_endpoint(tipo: str):
|
|
| 56 |
yield {"etapa": "Baixando o modelo…", "progress": None}
|
| 57 |
falha = nucleo.preparar(tipo)
|
| 58 |
if falha:
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
return
|
| 61 |
# O try daqui não é redundância do try do nucleo: a ALOCAÇÃO do
|
| 62 |
# @spaces.GPU acontece ANTES de o corpo rodar, e é ali que nascem os
|
|
|
|
| 56 |
yield {"etapa": "Baixando o modelo…", "progress": None}
|
| 57 |
falha = nucleo.preparar(tipo)
|
| 58 |
if falha:
|
| 59 |
+
# erro_gpu, e não erro: download que falhou (repo errado, rede,
|
| 60 |
+
# Hub fora) é ESTE runtime não conseguindo atender agora — o
|
| 61 |
+
# backend degrada para o gerador local em vez de devolver a
|
| 62 |
+
# falha à pessoa. Medido: o 404 de um id de modelo errado saía
|
| 63 |
+
# como erro do pedido e a música morria sem o fallback.
|
| 64 |
+
yield {"erro_gpu": falha}
|
| 65 |
return
|
| 66 |
# O try daqui não é redundância do try do nucleo: a ALOCAÇÃO do
|
| 67 |
# @spaces.GPU acontece ANTES de o corpo rodar, e é ali que nascem os
|
modelos/__pycache__/__init__.cpython-311.pyc
CHANGED
|
Binary files a/modelos/__pycache__/__init__.cpython-311.pyc and b/modelos/__pycache__/__init__.cpython-311.pyc differ
|
|
|
modelos/__pycache__/ace_step.cpython-311.pyc
CHANGED
|
Binary files a/modelos/__pycache__/ace_step.cpython-311.pyc and b/modelos/__pycache__/ace_step.cpython-311.pyc differ
|
|
|
modelos/__pycache__/base.cpython-311.pyc
CHANGED
|
Binary files a/modelos/__pycache__/base.cpython-311.pyc and b/modelos/__pycache__/base.cpython-311.pyc differ
|
|
|
modelos/__pycache__/qwen3_tts.cpython-311.pyc
CHANGED
|
Binary files a/modelos/__pycache__/qwen3_tts.cpython-311.pyc and b/modelos/__pycache__/qwen3_tts.cpython-311.pyc differ
|
|
|
modelos/__pycache__/wan22.cpython-311.pyc
CHANGED
|
Binary files a/modelos/__pycache__/wan22.cpython-311.pyc and b/modelos/__pycache__/wan22.cpython-311.pyc differ
|
|
|
modelos/__pycache__/z_image.cpython-311.pyc
CHANGED
|
Binary files a/modelos/__pycache__/z_image.cpython-311.pyc and b/modelos/__pycache__/z_image.cpython-311.pyc differ
|
|
|
modelos/ace_step.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
# -*- coding: utf-8 -*-
|
| 2 |
"""
|
| 3 |
-
MÚSICA — ACE-Step 1.5
|
| 4 |
|
| 5 |
É a primeira vez que este app tem MÚSICA de verdade sem provedor pago: a
|
| 6 |
trilha do `midia_livre` é síntese de acordes (e a tela sempre disse isso);
|
|
@@ -8,38 +8,43 @@ o ACE-Step compõe — com letra, inclusive. Quando o worker está de pé, é el
|
|
| 8 |
quem responde "music"; quando dorme, a trilha sintetizada volta a valer, e a
|
| 9 |
diferença de qualidade é o preço anunciado da GPU gratuita.
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
`lyrics` aceita o formato de seções do projeto ([Verse]/[Chorus]); sem letra
|
| 12 |
vai "[instrumental]" — mandar string vazia faz alguns checkpoints alucinarem
|
| 13 |
-
voz.
|
| 14 |
-
TTS, a chamada exata deve ser conferida no primeiro deploy com GPU (o
|
| 15 |
-
MODELS.md marca), porque este ambiente não alcança os pesos.
|
| 16 |
"""
|
| 17 |
from __future__ import annotations
|
| 18 |
|
|
|
|
| 19 |
import logging
|
| 20 |
import os
|
| 21 |
-
import tempfile
|
| 22 |
from typing import Dict, Optional
|
| 23 |
|
| 24 |
from . import base
|
| 25 |
|
| 26 |
logger = logging.getLogger("worker.ace_step")
|
| 27 |
|
| 28 |
-
VRAM_MINIMA_GB =
|
| 29 |
|
| 30 |
_pipe = None
|
| 31 |
_modelo_carregado = ""
|
| 32 |
|
| 33 |
|
| 34 |
def _modelo() -> str:
|
| 35 |
-
return os.getenv("MUSIC_MODEL",
|
|
|
|
| 36 |
|
| 37 |
|
| 38 |
def baixar(progresso: base.Progresso) -> None:
|
| 39 |
-
# Aquecer o cache do Hub com o repo dos pesos. O ACEStepPipeline tem um
|
| 40 |
-
# baixador próprio; se ele buscar por fora do cache, o pior caso é o
|
| 41 |
-
# download acontecer dentro da GPU como antes — melhor um aquecimento
|
| 42 |
-
# imperfeito que nenhum.
|
| 43 |
base.baixar_repo(_modelo(), progresso)
|
| 44 |
|
| 45 |
|
|
@@ -51,9 +56,19 @@ def carregar(progresso: base.Progresso) -> None:
|
|
| 51 |
if _pipe is not None and _modelo_carregado == _modelo():
|
| 52 |
return
|
| 53 |
progresso(None, "Carregando o modelo de música…")
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
_modelo_carregado = _modelo()
|
| 58 |
|
| 59 |
|
|
@@ -72,13 +87,13 @@ def gerar(params: Dict, progresso: base.Progresso) -> base.Saida:
|
|
| 72 |
int(os.getenv("MUSIC_MAX_SEGUNDOS", "240"))))
|
| 73 |
|
| 74 |
progresso(5, "Compondo…")
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
|
| 83 |
|
| 84 |
def descarregar() -> None:
|
|
@@ -94,3 +109,23 @@ def config_menor(params: Dict) -> Optional[Dict]:
|
|
| 94 |
p["duration"] = 30
|
| 95 |
return p
|
| 96 |
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
# -*- coding: utf-8 -*-
|
| 2 |
"""
|
| 3 |
+
MÚSICA — ACE-Step 1.5 XL Turbo, no formato DIFFUSERS.
|
| 4 |
|
| 5 |
É a primeira vez que este app tem MÚSICA de verdade sem provedor pago: a
|
| 6 |
trilha do `midia_livre` é síntese de acordes (e a tela sempre disse isso);
|
|
|
|
| 8 |
quem responde "music"; quando dorme, a trilha sintetizada volta a valer, e a
|
| 9 |
diferença de qualidade é o preço anunciado da GPU gratuita.
|
| 10 |
|
| 11 |
+
POR QUE DIFFUSERS E NÃO O PACOTE `acestep`, decidido na primeira validação
|
| 12 |
+
real: o pacote do projeto crava `transformers==4.50.0`, e o Z-Image/Qwen3-TTS
|
| 13 |
+
exigem >=4.51 — no mesmo processo os dois não se resolvem (pip cai em
|
| 14 |
+
ResolutionImpossible). O projeto publica o checkpoint OFICIAL em formato
|
| 15 |
+
diffusers (`acestep-v15-xl-turbo-diffusers`), carregável pelo
|
| 16 |
+
`AceStepPipeline` que entrou no diffusers 0.38 — e o text_encoder dele é
|
| 17 |
+
justamente um Qwen3Model, o mesmo stack dos outros modelos. Um requirements
|
| 18 |
+
só, os quatro tipos juntos. (O id antigo `ACE-Step/ACE-Step-v1.5` nem existe
|
| 19 |
+
no Hub — 404 medido.)
|
| 20 |
+
|
| 21 |
`lyrics` aceita o formato de seções do projeto ([Verse]/[Chorus]); sem letra
|
| 22 |
vai "[instrumental]" — mandar string vazia faz alguns checkpoints alucinarem
|
| 23 |
+
voz. O turbo é destilado: 8 passos, sem CFG para ajustar.
|
|
|
|
|
|
|
| 24 |
"""
|
| 25 |
from __future__ import annotations
|
| 26 |
|
| 27 |
+
import io
|
| 28 |
import logging
|
| 29 |
import os
|
|
|
|
| 30 |
from typing import Dict, Optional
|
| 31 |
|
| 32 |
from . import base
|
| 33 |
|
| 34 |
logger = logging.getLogger("worker.ace_step")
|
| 35 |
|
| 36 |
+
VRAM_MINIMA_GB = 12
|
| 37 |
|
| 38 |
_pipe = None
|
| 39 |
_modelo_carregado = ""
|
| 40 |
|
| 41 |
|
| 42 |
def _modelo() -> str:
|
| 43 |
+
return os.getenv("MUSIC_MODEL",
|
| 44 |
+
"ACE-Step/acestep-v15-xl-turbo-diffusers").strip()
|
| 45 |
|
| 46 |
|
| 47 |
def baixar(progresso: base.Progresso) -> None:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
base.baixar_repo(_modelo(), progresso)
|
| 49 |
|
| 50 |
|
|
|
|
| 56 |
if _pipe is not None and _modelo_carregado == _modelo():
|
| 57 |
return
|
| 58 |
progresso(None, "Carregando o modelo de música…")
|
| 59 |
+
import torch
|
| 60 |
+
from diffusers import AceStepPipeline
|
| 61 |
+
_pipe = AceStepPipeline.from_pretrained(
|
| 62 |
+
_modelo(), torch_dtype=torch.bfloat16,
|
| 63 |
+
token=os.getenv("HF_TOKEN") or None)
|
| 64 |
+
# Tiling no VAE: decodificar minutos de áudio 48 kHz de uma vez é o pico
|
| 65 |
+
# de memória do pipeline — o card do modelo recomenda para áudio longo.
|
| 66 |
+
_pipe.vae.enable_tiling()
|
| 67 |
+
livre = base.vram_livre_gb()
|
| 68 |
+
if livre is not None and livre < 16:
|
| 69 |
+
_pipe.enable_model_cpu_offload()
|
| 70 |
+
else:
|
| 71 |
+
_pipe.to(base.dispositivo())
|
| 72 |
_modelo_carregado = _modelo()
|
| 73 |
|
| 74 |
|
|
|
|
| 87 |
int(os.getenv("MUSIC_MAX_SEGUNDOS", "240"))))
|
| 88 |
|
| 89 |
progresso(5, "Compondo…")
|
| 90 |
+
saida = _pipe(prompt=prompt, lyrics=letra,
|
| 91 |
+
audio_duration=float(duracao),
|
| 92 |
+
generator=base.semente(params))
|
| 93 |
+
progresso(95, "Finalizando…")
|
| 94 |
+
# audios[0] é (canais, amostras) em 48 kHz; o WAV sai estéreo.
|
| 95 |
+
return _wav_estereo(saida.audios[0],
|
| 96 |
+
getattr(_pipe, "sample_rate", 48000)), "audio/wav"
|
| 97 |
|
| 98 |
|
| 99 |
def descarregar() -> None:
|
|
|
|
| 109 |
p["duration"] = 30
|
| 110 |
return p
|
| 111 |
return None
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def _wav_estereo(onda, taxa: int) -> bytes:
|
| 115 |
+
"""Tensor (canais, amostras) → WAV 16-bit. struct, sem soundfile —
|
| 116 |
+
uma dependência a menos, como no TTS."""
|
| 117 |
+
import struct
|
| 118 |
+
try:
|
| 119 |
+
dados = onda.detach().float().cpu().numpy()
|
| 120 |
+
except AttributeError:
|
| 121 |
+
dados = onda
|
| 122 |
+
if dados.ndim == 1:
|
| 123 |
+
dados = dados.reshape(1, -1)
|
| 124 |
+
canais = dados.shape[0]
|
| 125 |
+
# Intercala os canais (LRLR…), que é como o WAV guarda estéreo.
|
| 126 |
+
inteiros = (dados.T.clip(-1, 1) * 32767).astype("<i2").tobytes()
|
| 127 |
+
bloco = canais * 2
|
| 128 |
+
return (b"RIFF" + struct.pack("<I", 36 + len(inteiros)) + b"WAVEfmt "
|
| 129 |
+
+ struct.pack("<IHHIIHH", 16, 1, canais, int(taxa),
|
| 130 |
+
int(taxa) * bloco, bloco, 16)
|
| 131 |
+
+ b"data" + struct.pack("<I", len(inteiros)) + inteiros)
|
requirements.txt
CHANGED
|
@@ -6,10 +6,11 @@
|
|
| 6 |
# O resto é a MESMA camada de inferência do worker CUDA
|
| 7 |
# (services/gpu-worker/requirements.txt) — mesmos modelos, mesmas versões,
|
| 8 |
# de propósito: dois pares de versões seriam dois comportamentos.
|
| 9 |
-
# `>=0.
|
| 10 |
-
#
|
| 11 |
-
#
|
| 12 |
-
|
|
|
|
| 13 |
# `>=4.51` é MEDIDO, não gosto: o Z-Image usa encoder Qwen3, e a classe
|
| 14 |
# Qwen3Model só existe do 4.51 em diante — com 4.50 a primeira geração real
|
| 15 |
# caiu com "module transformers has no attribute Qwen3Model".
|
|
@@ -24,15 +25,11 @@ qwen-tts>=0.1.1
|
|
| 24 |
Pillow==11.1.0
|
| 25 |
imageio==2.36.1
|
| 26 |
imageio-ffmpeg==0.6.0
|
| 27 |
-
# O
|
| 28 |
-
# transformers==4.50.0
|
| 29 |
-
#
|
| 30 |
-
#
|
| 31 |
-
#
|
| 32 |
-
#
|
| 33 |
-
# DEGRADA para o gerador local — comportamento honesto, nunca 500.
|
| 34 |
-
# Quando o ACE-Step soltar o pino (ou houver um Space só de música),
|
| 35 |
-
# devolva a linha:
|
| 36 |
-
# git+https://github.com/ace-step/ACE-Step.git
|
| 37 |
boto3==1.35.90
|
| 38 |
requests>=2.32
|
|
|
|
| 6 |
# O resto é a MESMA camada de inferência do worker CUDA
|
| 7 |
# (services/gpu-worker/requirements.txt) — mesmos modelos, mesmas versões,
|
| 8 |
# de propósito: dois pares de versões seriam dois comportamentos.
|
| 9 |
+
# `>=0.38` é MEDIDO: é a versão em que o AceStepPipeline entrou no diffusers
|
| 10 |
+
# — a música daqui carrega o checkpoint oficial em formato diffusers
|
| 11 |
+
# (acestep-v15-xl-turbo-diffusers), sem o pacote do projeto. Fixe a versão
|
| 12 |
+
# exata que o primeiro build verde escolher.
|
| 13 |
+
diffusers>=0.38
|
| 14 |
# `>=4.51` é MEDIDO, não gosto: o Z-Image usa encoder Qwen3, e a classe
|
| 15 |
# Qwen3Model só existe do 4.51 em diante — com 4.50 a primeira geração real
|
| 16 |
# caiu com "module transformers has no attribute Qwen3Model".
|
|
|
|
| 25 |
Pillow==11.1.0
|
| 26 |
imageio==2.36.1
|
| 27 |
imageio-ffmpeg==0.6.0
|
| 28 |
+
# O PACOTE `acestep` NÃO ENTRA AQUI, E NÃO FOI ESQUECIMENTO. Ele crava
|
| 29 |
+
# transformers==4.50.0, e o Z-Image/Qwen3-TTS exigem >=4.51: no MESMO
|
| 30 |
+
# processo os dois não se resolvem (pip cai em ResolutionImpossible). A
|
| 31 |
+
# música usa o checkpoint OFICIAL em formato diffusers, pelo AceStepPipeline
|
| 32 |
+
# do próprio diffusers >=0.38 — mesmo stack dos outros modelos, zero
|
| 33 |
+
# dependência extra.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
boto3==1.35.90
|
| 35 |
requests>=2.32
|