Serviços serverless de Inteligência Artificial para Áudio/Voz, Geração de Vídeo, Vídeo Avatar (Lip-Sync) e Serviços de Imagem (Geração, Edição e Remoção de Fundo) no Modal.com, gerenciados com UV e acessíveis diretamente via Modal Python SDK e CLI.
Todos os pesos dos modelos são embutidos diretamente no build das imagens (run_function(download_models)), eliminando a necessidade de volumes de cache e garantindo inicialização rápida dos containers sem cold-start de download em tempo de execução.
nvidia/parakeet-tdt-0.6b-v3 (ASR - GPU: T4)Qwen/Qwen3-TTS-12Hz-1.7B-Base (VoiceCloneTTS - GPU: A10G)Qwen/Qwen3-TTS-12Hz-1.7B-VoiceDesign (VoiceDesignTTS - GPU: A10G)FastVideo/FastVideo-FastH3-4-step-Preview-v1-VSA-DataFree (Video - GPU: B200)
16:9 (1344x768), 9:16 (768x1344), 1:1 (768x768), 4:3 (1024x768), 3:4 (768x1024)5s (124 frames), 10s (243 frames), 15s (345 frames)meituan-longcat/LongCat-Video-Avatar-1.5 (Avatar - GPU: H200)
480p (832x480) e 720p (1280x768)Qwen/Qwen-Image (QwenImage - GPU: A100-80GB)
Qwen/Qwen-Image-Edit-2511 (QwenImageEdit - GPU: A100-80GB)
ZhengPeng7/BiRefNet (BiRefNet - GPU: A10G)
curl -LsSf https://astral.sh/uv/install.sh | sh)uv run modal setup)uv sync
uv run modal deploy app.py
Após o deploy (modal deploy app.py), você pode chamar qualquer classe e método remotamente de qualquer script Python:
import modal
QwenImage = modal.Cls.lookup("modal-services", "QwenImage")
image_service = QwenImage()
img_bytes = image_service.generate.remote(
prompt="A futuristic city in cyberpunk neon style at night, highly detailed, 4k",
height=1024,
width=1024,
num_inference_steps=30,
guidance_scale=7.0,
)
with open("cyberpunk_city.png", "wb") as f:
f.write(img_bytes)
Suporta uma imagem ou uma lista de múltiplas imagens de referência:
import base64
import modal
QwenImageEdit = modal.Cls.lookup("modal-services", "QwenImageEdit")
# Edição com uma imagem de entrada
with open("input.png", "rb") as f:
orig_img_b64 = base64.b64encode(f.read()).decode("utf-8")
edit_service = QwenImageEdit()
edited_bytes = edit_service.edit.remote(
prompt="Transform the day scene into a snowstorm night",
image_base64=orig_img_b64,
true_cfg_scale=4.0,
num_inference_steps=40,
)
with open("edited_output.png", "wb") as f:
f.write(edited_bytes)
# Edição / Composição com múltiplas imagens de referência
with open("person.png", "rb") as f:
person_b64 = base64.b64encode(f.read()).decode("utf-8")
with open("background.png", "rb") as f:
bg_b64 = base64.b64encode(f.read()).decode("utf-8")
composite_bytes = edit_service.edit.remote(
prompt="Place the person from image 1 in the futuristic landscape of image 2",
image_base64=[person_b64, bg_b64],
true_cfg_scale=4.0,
)
with open("composite_output.png", "wb") as f:
f.write(composite_bytes)
import base64
import modal
BiRefNet = modal.Cls.lookup("modal-services", "BiRefNet")
with open("portrait.png", "rb") as f:
orig_img_b64 = base64.b64encode(f.read()).decode("utf-8")
bg_service = BiRefNet()
nobg_png_bytes = bg_service.remove_background.remote(
image_base64=orig_img_b64,
return_mask=False, # Retorna imagem RGBA com fundo transparente (PNG)
)
with open("portrait_nobg.png", "wb") as f:
f.write(nobg_png_bytes)
import base64
import modal
Avatar = modal.Cls.lookup("modal-services", "Avatar")
with open("portrait.png", "rb") as f:
img_b64 = base64.b64encode(f.read()).decode("utf-8")
with open("audio.wav", "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode("utf-8")
avatar_service = Avatar()
video_bytes = avatar_service.generate.remote(
image_base64=img_b64,
audio_base64=audio_b64,
resolution="480p", # "480p" ou "720p"
prompt="a person speaking to the camera with a serene expression, studio lighting, detailed",
)
with open("avatar_video.mp4", "wb") as f:
f.write(video_bytes)
import modal
Video = modal.Cls.lookup("modal-services", "Video")
video_service = Video()
video_bytes = video_service.generate.remote(
prompt="A sweeping wide shot of a wooden sailing ship navigating starlit oceans, warm lanterns, cinematic.",
aspect_ratio="16:9", # "16:9", "9:16", "1:1", "4:3", "3:4"
duration=5, # 5, 10 ou 15 segundos
steps=5,
seed=-1,
)
with open("generated_video.mp4", "wb") as f:
f.write(video_bytes)
import base64
import modal
ASR = modal.Cls.lookup("modal-services", "ASR")
with open("audio.wav", "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode("utf-8")
asr = ASR()
result = asr.transcribe.remote(audio_base64=audio_b64, language="pt")
print("Transcrição:", result["text"])
print("Timestamps:", result["timestamps"])
import base64
import modal
VoiceCloneTTS = modal.Cls.lookup("modal-services", "VoiceCloneTTS")
with open("sample_speaker.wav", "rb") as f:
ref_audio_b64 = base64.b64encode(f.read()).decode("utf-8")
tts_clone = VoiceCloneTTS()
wav_bytes = tts_clone.generate.remote(
text="Olá! Esta fala foi gerada com a minha voz clonada.",
ref_audio_base64=ref_audio_b64,
ref_text="Transcrição opcional do áudio de referência",
language="Portuguese",
)
with open("cloned_voice.wav", "wb") as f:
f.write(wav_bytes)
import modal
VoiceDesignTTS = modal.Cls.lookup("modal-services", "VoiceDesignTTS")
voice_design = VoiceDesignTTS()
wav_bytes = voice_design.generate.remote(
text="A imaginação é a chave para a inovação.",
instruct="Voz masculina madura, profunda, calma e acolhedora",
language="Portuguese",
)
with open("voice_design.wav", "wb") as f:
f.write(wav_bytes)
Você pode testar diretamente pela linha de comando usando modal run:
# Teste de Geração de Imagem (Qwen Image)
uv run modal run app.py --action image-gen --prompt "A majestic eagle in flight over snow mountains" --output-path "eagle.png"
# Teste de Edição de Imagem (Qwen Image Edit)
uv run modal run app.py --action image-edit --image-path "portrait.png" --prompt "Add retro neon sunglasses" --output-path "edited.png"
# Teste de Remoção de Fundo (BiRefNet)
uv run modal run app.py --action remove-bg --image-path "portrait.png" --output-path "nobg.png"
# Teste de Talking Video Avatar (LongCat)
uv run modal run app.py --action avatar --ref-image-path "portrait.png" --ref-audio-path "audio.wav" --resolution "480p" --output-path "avatar.mp4"
# Teste de Geração de Vídeo (FastH3)
uv run modal run app.py --action video --prompt "A majestic eagle flying over snow-covered mountains, cinematic lighting" --aspect-ratio "16:9" --duration 5 --output-path "eagle.mp4"
# Teste de Transcrição ASR
uv run modal run app.py --action asr --ref-audio-path "audio.wav"
# Teste de Clonagem de Voz
uv run modal run app.py --action clone --text "Olá mundo com voz clonada" --ref-audio-path "sample.wav" --output-path "cloned_test.wav"
# Teste de Voice Design
uv run modal run app.py --action voice-design --text "Hello world" --instruct "Warm narrator voice" --output-path "test_design.wav"
4 commits
Python
100.0%
Serviços serverless de Inteligência Artificial para Áudio/Voz, Geração de Vídeo, Vídeo Avatar (Lip-Sync) e Serviços de Imagem (Geração, Edição e Remoção de Fundo) no Modal.com, gerenciados com UV e acessíveis diretamente via Modal Python SDK e CLI.
Todos os pesos dos modelos são embutidos diretamente no build das imagens (run_function(download_models)), eliminando a necessidade de volumes de cache e garantindo inicialização rápida dos containers sem cold-start de download em tempo de execução.
nvidia/parakeet-tdt-0.6b-v3 (ASR - GPU: T4)Qwen/Qwen3-TTS-12Hz-1.7B-Base (VoiceCloneTTS - GPU: A10G)Qwen/Qwen3-TTS-12Hz-1.7B-VoiceDesign (VoiceDesignTTS - GPU: A10G)FastVideo/FastVideo-FastH3-4-step-Preview-v1-VSA-DataFree (Video - GPU: B200)
16:9 (1344x768), 9:16 (768x1344), 1:1 (768x768), 4:3 (1024x768), 3:4 (768x1024)5s (124 frames), 10s (243 frames), 15s (345 frames)meituan-longcat/LongCat-Video-Avatar-1.5 (Avatar - GPU: H200)
480p (832x480) e 720p (1280x768)Qwen/Qwen-Image (QwenImage - GPU: A100-80GB)
Qwen/Qwen-Image-Edit-2511 (QwenImageEdit - GPU: A100-80GB)
ZhengPeng7/BiRefNet (BiRefNet - GPU: A10G)
curl -LsSf https://astral.sh/uv/install.sh | sh)uv run modal setup)uv sync
uv run modal deploy app.py
Após o deploy (modal deploy app.py), você pode chamar qualquer classe e método remotamente de qualquer script Python:
import modal
QwenImage = modal.Cls.lookup("modal-services", "QwenImage")
image_service = QwenImage()
img_bytes = image_service.generate.remote(
prompt="A futuristic city in cyberpunk neon style at night, highly detailed, 4k",
height=1024,
width=1024,
num_inference_steps=30,
guidance_scale=7.0,
)
with open("cyberpunk_city.png", "wb") as f:
f.write(img_bytes)
Suporta uma imagem ou uma lista de múltiplas imagens de referência:
import base64
import modal
QwenImageEdit = modal.Cls.lookup("modal-services", "QwenImageEdit")
# Edição com uma imagem de entrada
with open("input.png", "rb") as f:
orig_img_b64 = base64.b64encode(f.read()).decode("utf-8")
edit_service = QwenImageEdit()
edited_bytes = edit_service.edit.remote(
prompt="Transform the day scene into a snowstorm night",
image_base64=orig_img_b64,
true_cfg_scale=4.0,
num_inference_steps=40,
)
with open("edited_output.png", "wb") as f:
f.write(edited_bytes)
# Edição / Composição com múltiplas imagens de referência
with open("person.png", "rb") as f:
person_b64 = base64.b64encode(f.read()).decode("utf-8")
with open("background.png", "rb") as f:
bg_b64 = base64.b64encode(f.read()).decode("utf-8")
composite_bytes = edit_service.edit.remote(
prompt="Place the person from image 1 in the futuristic landscape of image 2",
image_base64=[person_b64, bg_b64],
true_cfg_scale=4.0,
)
with open("composite_output.png", "wb") as f:
f.write(composite_bytes)
import base64
import modal
BiRefNet = modal.Cls.lookup("modal-services", "BiRefNet")
with open("portrait.png", "rb") as f:
orig_img_b64 = base64.b64encode(f.read()).decode("utf-8")
bg_service = BiRefNet()
nobg_png_bytes = bg_service.remove_background.remote(
image_base64=orig_img_b64,
return_mask=False, # Retorna imagem RGBA com fundo transparente (PNG)
)
with open("portrait_nobg.png", "wb") as f:
f.write(nobg_png_bytes)
import base64
import modal
Avatar = modal.Cls.lookup("modal-services", "Avatar")
with open("portrait.png", "rb") as f:
img_b64 = base64.b64encode(f.read()).decode("utf-8")
with open("audio.wav", "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode("utf-8")
avatar_service = Avatar()
video_bytes = avatar_service.generate.remote(
image_base64=img_b64,
audio_base64=audio_b64,
resolution="480p", # "480p" ou "720p"
prompt="a person speaking to the camera with a serene expression, studio lighting, detailed",
)
with open("avatar_video.mp4", "wb") as f:
f.write(video_bytes)
import modal
Video = modal.Cls.lookup("modal-services", "Video")
video_service = Video()
video_bytes = video_service.generate.remote(
prompt="A sweeping wide shot of a wooden sailing ship navigating starlit oceans, warm lanterns, cinematic.",
aspect_ratio="16:9", # "16:9", "9:16", "1:1", "4:3", "3:4"
duration=5, # 5, 10 ou 15 segundos
steps=5,
seed=-1,
)
with open("generated_video.mp4", "wb") as f:
f.write(video_bytes)
import base64
import modal
ASR = modal.Cls.lookup("modal-services", "ASR")
with open("audio.wav", "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode("utf-8")
asr = ASR()
result = asr.transcribe.remote(audio_base64=audio_b64, language="pt")
print("Transcrição:", result["text"])
print("Timestamps:", result["timestamps"])
import base64
import modal
VoiceCloneTTS = modal.Cls.lookup("modal-services", "VoiceCloneTTS")
with open("sample_speaker.wav", "rb") as f:
ref_audio_b64 = base64.b64encode(f.read()).decode("utf-8")
tts_clone = VoiceCloneTTS()
wav_bytes = tts_clone.generate.remote(
text="Olá! Esta fala foi gerada com a minha voz clonada.",
ref_audio_base64=ref_audio_b64,
ref_text="Transcrição opcional do áudio de referência",
language="Portuguese",
)
with open("cloned_voice.wav", "wb") as f:
f.write(wav_bytes)
import modal
VoiceDesignTTS = modal.Cls.lookup("modal-services", "VoiceDesignTTS")
voice_design = VoiceDesignTTS()
wav_bytes = voice_design.generate.remote(
text="A imaginação é a chave para a inovação.",
instruct="Voz masculina madura, profunda, calma e acolhedora",
language="Portuguese",
)
with open("voice_design.wav", "wb") as f:
f.write(wav_bytes)
Você pode testar diretamente pela linha de comando usando modal run:
# Teste de Geração de Imagem (Qwen Image)
uv run modal run app.py --action image-gen --prompt "A majestic eagle in flight over snow mountains" --output-path "eagle.png"
# Teste de Edição de Imagem (Qwen Image Edit)
uv run modal run app.py --action image-edit --image-path "portrait.png" --prompt "Add retro neon sunglasses" --output-path "edited.png"
# Teste de Remoção de Fundo (BiRefNet)
uv run modal run app.py --action remove-bg --image-path "portrait.png" --output-path "nobg.png"
# Teste de Talking Video Avatar (LongCat)
uv run modal run app.py --action avatar --ref-image-path "portrait.png" --ref-audio-path "audio.wav" --resolution "480p" --output-path "avatar.mp4"
# Teste de Geração de Vídeo (FastH3)
uv run modal run app.py --action video --prompt "A majestic eagle flying over snow-covered mountains, cinematic lighting" --aspect-ratio "16:9" --duration 5 --output-path "eagle.mp4"
# Teste de Transcrição ASR
uv run modal run app.py --action asr --ref-audio-path "audio.wav"
# Teste de Clonagem de Voz
uv run modal run app.py --action clone --text "Olá mundo com voz clonada" --ref-audio-path "sample.wav" --output-path "cloned_test.wav"
# Teste de Voice Design
uv run modal run app.py --action voice-design --text "Hello world" --instruct "Warm narrator voice" --output-path "test_design.wav"
4 commits
Python
100.0%