r7 / app.py
RXTIME's picture
Update app.py
bb64571 verified
raw
history blame
4.86 kB
import gradio as gr
import os
import torch
import torchaudio
from transformers import (
WhisperProcessor, WhisperForConditionalGeneration,
MarianMTModel, MarianTokenizer,
SpeechT5Processor, SpeechT5ForTextToSpeech
)
import ffmpeg
import soundfile as sf
import numpy as np
# Configurações
UPLOAD_FOLDER = "uploads"
OUTPUT_FOLDER = "outputs"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
# Configurar dispositivo (GPU se disponível)
device = "cuda" if torch.cuda.is_available() else "cpu"
torch.backends.cudnn.benchmark = True # Acelera GPU NVIDIA
# Carregar modelos uma única vez (cache)
WHISPER_MODEL = "openai/whisper-tiny" # Modelo mais rápido
TRANSLATION_MODEL = "Helsinki-NLP/opus-mt-tc-big-en-pt" # Modelo alternativo
TTS_MODEL = "microsoft/speecht5_tts"
# Inicialização rápida dos modelos
print("Carregando modelos...")
whisper_processor = WhisperProcessor.from_pretrained(WHISPER_MODEL)
whisper_model = WhisperForConditionalGeneration.from_pretrained(WHISPER_MODEL).to(device)
translation_tokenizer = MarianTokenizer.from_pretrained(TRANSLATION_MODEL)
translation_model = MarianMTModel.from_pretrained(TRANSLATION_MODEL).to(device)
tts_processor = SpeechT5Processor.from_pretrained(TTS_MODEL)
tts_model = SpeechT5ForTextToSpeech.from_pretrained(TTS_MODEL).to(device)
# Funções otimizadas
def transcribe_audio(audio_path):
waveform, sample_rate = torchaudio.load(audio_path)
waveform = waveform.to(device)
# Processamento em chunks para áudios longos
inputs = whisper_processor(
waveform.squeeze().cpu().numpy(),
sampling_rate=sample_rate,
return_tensors="pt",
chunk_length_s=30 # Processar em chunks de 30 segundos
).to(device)
with torch.inference_mode():
predicted_ids = whisper_model.generate(**inputs)
return whisper_processor.batch_decode(predicted_ids, skip_special_tokens=True)[0]
def translate_text(text):
inputs = translation_tokenizer(text, return_tensors="pt", truncation=True).to(device)
with torch.inference_mode():
translated_ids = translation_model.generate(**inputs)
return translation_tokenizer.decode(translated_ids[0], skip_special_tokens=True)
def synthesize_speech(text, output_path):
inputs = tts_processor(text, return_tensors="pt").to(device)
with torch.inference_mode():
speech = tts_model.generate_speech(inputs["input_ids"], tts_model.speaker_embeddings)
# Converter para formato compatível com vídeo (44100 Hz, stereo)
sf.write(output_path, np.tile(speech.cpu().numpy(), (2, 1)).T, 44100, subtype='PCM_16')
def process_video(video_path, output_path):
# Processamento paralelizado com FFmpeg
(
ffmpeg
.input(video_path)
.output(output_path, vcodec='copy', acodec='aac', strict='experimental')
.global_args('-loglevel', 'error') # Reduzir logs
.run(overwrite_output=True, cmd='ffmpeg')
)
# Fluxo principal otimizado
def translate_video(video, progress=gr.Progress()):
try:
# Etapa 1: Extrair áudio
progress(0.1, "Extraindo áudio...")
audio_path = os.path.join(UPLOAD_FOLDER, "audio.wav")
(
ffmpeg
.input(video)
.output(audio_path, ac=1, ar=16000)
.global_args('-loglevel', 'error')
.run(overwrite_output=True)
)
# Etapa 2: Transcrição paralela
progress(0.3, "Transcrevendo...")
transcription = transcribe_audio(audio_path)
# Etapa 3: Tradução em lote
progress(0.5, "Traduzindo...")
translated_text = translate_text(transcription)
# Etapa 4: Síntese de voz acelerada
progress(0.7, "Sintetizando voz...")
synthesized_audio = os.path.join(UPLOAD_FOLDER, "synthesized_audio.wav")
synthesize_speech(translated_text, synthesized_audio)
# Etapa 5: Processamento final do vídeo
progress(0.9, "Montando vídeo...")
output_path = os.path.join(OUTPUT_FOLDER, "video_traduzido.mp4")
(
ffmpeg
.input(video)
.output(output_path, vcodec='copy', acodec='copy', map='0:v:0')
.input(synthesized_audio)
.global_args('-loglevel', 'error')
.run(overwrite_output=True)
)
return output_path
except Exception as e:
return f"Erro: {str(e)}"
# Interface otimizada
iface = gr.Interface(
fn=translate_video,
inputs=gr.Video(label="Vídeo de Entrada"),
outputs=gr.Video(label="Vídeo Traduzido"),
title="🚀 Tradutor de Vídeo Ultra-Rápido",
description="Carregue um vídeo e receba a versão em português com áudio traduzido!",
allow_flagging="never"
)
if __name__ == "__main__":
iface.launch(server_port=7860, show_error=True)