SeedVR2 / app.py
aducsdr's picture
Update app.py
0c56f63 verified
raw
history blame
6.65 kB
import gradio as gr
import subprocess
import os
import sys
import time
from threading import Thread
from queue import Queue, Empty
# --- 1. CONFIGURAÇÃO E INSTALAÇÃO AUTOMÁTICA ---
# Esta parte do código é executada apenas uma vez quando o Space inicia.
INSTALLATION_FLAG = ".installation_complete"
SEEDVR_REPO_DIR = "SeedVR"
def run_subprocess(command, cwd=None):
"""Executa um comando de subprocesso e imprime a saída em tempo real."""
print(f"Executando comando: {' '.join(command)}")
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=cwd)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
rc = process.poll()
if rc != 0:
raise RuntimeError(f"Comando falhou com código de saída {rc}: {' '.join(command)}")
def setup_environment():
"""
Traduz os comandos do manual do SeedVR para o ambiente do Hugging Face Spaces.
1. Clona o repositório.
2. Instala dependências especiais.
3. Cria um "flag" para não repetir a instalação.
"""
print("--- Verificando o ambiente de instalação ---")
# Se a instalação já foi feita, não faz nada.
if os.path.exists(INSTALLATION_FLAG):
print("Ambiente já configurado. Pulando a instalação.")
return
print("--- Iniciando configuração pela primeira vez ---")
# Comando 1: git clone ...
if not os.path.exists(SEEDVR_REPO_DIR):
run_subprocess(["git", "clone", "https://github.com/bytedance-seed/SeedVR.git"])
else:
print("Repositório SeedVR já existe.")
# Comandos 2 e 3: conda create/activate (substituído pelo `python_version: 3.10` no README.md)
print("Versão do Python já definida pelo Hugging Face Spaces.")
# Comando 4: pip install -r requirements.txt (já foi executado pelo Hugging Face)
print("Dependências do requirements.txt já instaladas.")
# Comando 5: pip install flash_attn... (instalação especial)
print("Instalando flash_attn com flags especiais...")
# Usamos sys.executable para garantir que estamos usando o pip do ambiente correto
flash_attn_command = [
sys.executable, "-m", "pip", "install",
"flash_attn==2.5.9.post1", "--no-build-isolation"
]
run_subprocess(flash_attn_command)
print("--- Configuração do ambiente concluída com sucesso! ---")
# Cria o arquivo de flag para indicar que a instalação foi concluída
with open(INSTALLATION_FLAG, "w") as f:
f.write("OK")
# Executa a função de configuração
setup_environment()
# O restante do código do app (interface Gradio, download do modelo, inferência)
# continuaria aqui, como na resposta anterior.
from huggingface_hub import snapshot_download
# --- 2. LÓGICA DA APLICAÇÃO (DOWNLOAD DO MODELO E INFERÊNCIA) ---
# Baixar o modelo (fora da função de inferência para não baixar toda vez)
CKPTS_DIR = os.path.join(SEEDVR_REPO_DIR, "ckpts")
if not os.path.exists(os.path.join(CKPTS_DIR, "README.md")):
print("Baixando o modelo SeedVR2-3B...")
snapshot_download(
repo_id="ByteDance-Seed/SeedVR2-3B",
local_dir=CKPTS_DIR,
local_dir_use_symlinks=False,
resume_download=True,
allow_patterns=["*.json", "*.safetensors", "*.pth", "*.bin", "*.py", "*.md", "*.txt"],
)
else:
print("Modelo já foi baixado.")
def run_inference_app(video_file, seed_num):
if video_file is None:
return None, "Por favor, envie um arquivo de vídeo."
# Salva o arquivo de entrada em uma pasta temporária
input_folder = "inputs"
os.makedirs(input_folder, exist_ok=True)
input_video_path = os.path.join(input_folder, os.path.basename(video_file.name))
with open(input_video_path, "wb") as f_out, open(video_file.name, "rb") as f_in:
f_out.write(f_in.read())
output_folder = "outputs"
os.makedirs(output_folder, exist_ok=True)
# Comando de inferência do SeedVR
# Usando 4 GPUs, como especificado no hardware 4xL40s
command = [
"torchrun", "--nproc-per-node=4",
"projects/inference_seedvr2_3b.py",
"--video_path", f"../{input_folder}",
"--output_dir", f"../{output_folder}",
"--seed", str(seed_num),
"--res_h", "320",
"--res_w", "512",
"--sp_size", "1"
]
log_output = "Iniciando a inferência...\n" + ' '.join(command) + "\n\n"
try:
process = subprocess.Popen(
command,
cwd=SEEDVR_REPO_DIR, # Executa o comando de dentro do diretório do repositório
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
encoding='utf-8'
)
while True:
line = process.stdout.readline()
if not line:
break
log_output += line
print(line.strip()) # Imprime no console do Space para debug
yield None, log_output
process.wait()
if process.returncode != 0:
raise RuntimeError("O script de inferência falhou.")
# Encontra o vídeo gerado
result_files = [os.path.join(output_folder, f) for f in os.listdir(output_folder) if f.endswith('.mp4')]
if not result_files:
return None, log_output + "\nERRO: Nenhum vídeo foi gerado."
return result_files, log_output + "\n\nInferência concluída com sucesso!"
except Exception as e:
error_message = f"{log_output}\n\nOcorreu um erro: {str(e)}"
print(error_message)
return None, error_message
# --- 3. INTERFACE GRÁFICA (GRADIO) ---
with gr.Blocks() as demo:
gr.Markdown("# 🚀 Automação de Inferência para SeedVR2")
gr.Markdown("Envie um vídeo, clique em 'Gerar' e o processo de instalação e inferência será executado.")
with gr.Row():
with gr.Column(scale=1):
video_input = gr.File(label="Vídeo de Entrada")
seed_input = gr.Number(label="Seed", value=42)
run_button = gr.Button("Gerar Vídeo", variant="primary")
with gr.Column(scale=2):
gallery_output = gr.Gallery(label="Vídeo de Saída", show_label=True)
log_display = gr.Textbox(label="Logs de Execução", lines=15, interactive=False, autoscroll=True)
run_button.click(
fn=run_inference_app,
inputs=[video_input, seed_input],
outputs=[gallery_output, log_display]
)
demo.launch()