| |
| """ |
| Passo 0: Setup do Ambiente |
| Instala todas as dependências para: |
| - Geração de dataset (Soprano TTS, Whisper, SNAC, NeMo NFA) |
| - Treinamento do modelo Speech-to-Speech |
| |
| PyTorch 2.7.0 com suporte oficial a Blackwell (sm_120) |
| |
| Suporta: |
| - Blackwell: RTX 5090, 5080, 5070, B100, B200 (sm_120) - CUDA 12.8 |
| - Hopper: H100, H200 (sm_90) - CUDA 12.8 |
| - Ada: RTX 4090, 4080, L40S (sm_89) - CUDA 12.4 |
| - Ampere: A100, RTX 3090 (sm_80/86) - CUDA 12.4 |
| |
| Usage: |
| python passo0_setup.py [--skip_test] |
| """ |
|
|
| import os |
| import sys |
| import subprocess |
| import shutil |
|
|
| HF_TOKEN = os.environ.get("HF_TOKEN", "") |
|
|
|
|
| def log(msg): |
| print(f"[SETUP] {msg}") |
| sys.stdout.flush() |
|
|
|
|
| def run(cmd, check=True): |
| """Execute command.""" |
| log(f"$ {cmd}") |
| result = subprocess.run(cmd, shell=True) |
| if check and result.returncode != 0: |
| log(f"Command failed with code {result.returncode}") |
| return False |
| return True |
|
|
|
|
| def get_gpu_info(): |
| """Get GPU info and architecture.""" |
| result = subprocess.run(['nvidia-smi', '--query-gpu=name,compute_cap', '--format=csv,noheader'], |
| capture_output=True, text=True) |
| if result.returncode != 0: |
| return "", "" |
| lines = result.stdout.strip().split('\n') |
| if lines: |
| parts = lines[0].split(',') |
| name = parts[0].strip() |
| compute = parts[1].strip() if len(parts) > 1 else "" |
| return name, compute |
| return "", "" |
|
|
|
|
| def needs_cuda_128(gpu_name, compute_cap): |
| """Check if GPU needs CUDA 12.8+ (Hopper/Blackwell architecture).""" |
| |
| |
| hopper_blackwell = ["H100", "H200", "RTX 50", "5090", "5080", "5070", "B100", "B200"] |
| if any(arch in gpu_name for arch in hopper_blackwell): |
| return True |
| |
| try: |
| cap = float(compute_cap) |
| if cap >= 9.0: |
| return True |
| except: |
| pass |
| return False |
|
|
|
|
| def main(): |
| import argparse |
| parser = argparse.ArgumentParser() |
| parser.add_argument("--skip_test", action="store_true") |
| args = parser.parse_args() |
|
|
| log("="*60) |
| log("SETUP DO AMBIENTE - H200/Hopper Compatible") |
| log("="*60) |
|
|
| gpu_name, compute_cap = get_gpu_info() |
| log(f"GPU: {gpu_name} (compute {compute_cap})") |
| use_cuda_128 = needs_cuda_128(gpu_name, compute_cap) |
| log(f"Using CUDA 12.8: {use_cuda_128}") |
|
|
| |
| log("\n[1/7] System dependencies...") |
| if shutil.which('apt-get'): |
| run("apt-get update -qq && apt-get install -y -qq espeak-ng espeak libsndfile1 ffmpeg git wget curl build-essential sox libsox-fmt-all", check=False) |
|
|
| |
| |
| log("\n[2/7] PyTorch 2.7.0 (Blackwell compatible)...") |
| if use_cuda_128: |
| |
| log(" Installing PyTorch 2.7.0 with CUDA 12.8 (Blackwell/Hopper support)") |
| run("pip install torch==2.7.0 torchaudio==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu128 -q") |
| else: |
| |
| log(" Installing PyTorch 2.7.0 with CUDA 12.4 (Ampere/Ada)") |
| run("pip install torch==2.7.0 torchaudio==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu124 -q") |
|
|
| |
| log("\n[3/7] Core packages...") |
| packages = [ |
| "'numpy>=2.0.2,<2.1.0'", |
| "scipy", "soundfile", "librosa", |
| "'transformers>=4.52.0'", "accelerate", "peft", "safetensors", |
| "huggingface-hub", "snac", "omegaconf", "tqdm", "requests", |
| "'pandas>=2.2.3'", |
| "tensorboard", "psutil", "groq", |
| "Cython", |
| ] |
| run(f"pip install {' '.join(packages)} -q") |
|
|
| |
| log("\n[4/7] NeMo Forced Aligner (GPU-accelerated)...") |
| |
| run("pip install 'nemo_toolkit[asr]>=2.0.0' -q") |
|
|
| |
| log("\n[5/7] Whisper (transformers - H200 compatible)...") |
| |
| |
|
|
| |
| |
| log("\n[6/8] Soprano TTS 80M...") |
|
|
| |
| |
| run("pip install soprano-tts -q") |
|
|
| |
| blackwell_gpus = ["RTX 50", "5090", "5080", "5070", "B100", "B200"] |
| is_blackwell = any(arch in gpu_name for arch in blackwell_gpus) |
|
|
| if is_blackwell: |
| log(" Blackwell GPU detected - skipping lmdeploy (not supported yet)") |
| log(" Soprano will use transformers backend (slower but compatible)") |
| else: |
| log(" Installing lmdeploy for 2000x realtime speed...") |
| run("pip install lmdeploy -q") |
|
|
| |
| log("\n[7/8] Creating directories...") |
| for d in ["./data", "./data/raw", "./data/processed", "./checkpoints", "./logs"]: |
| os.makedirs(d, exist_ok=True) |
|
|
| |
| if not args.skip_test: |
| log("\n[8/8] Testing components...") |
| log("\n" + "="*60) |
| log("TESTING SOPRANO TTS (lmdeploy backend)") |
| log("="*60) |
| run("""python3 -c " |
| import torch |
| _load = torch.load |
| torch.load = lambda *a, **k: _load(*a, **{**k, 'weights_only': False}) |
| |
| from soprano import SopranoTTS |
| import time |
| |
| print('Loading Soprano TTS with lmdeploy backend...') |
| try: |
| tts = SopranoTTS(backend='lmdeploy', device='cuda', cache_size_mb=2000, decoder_batch_size=8) |
| print('Using lmdeploy backend (fastest)') |
| except Exception as e: |
| print(f'lmdeploy failed ({e}), falling back to transformers') |
| tts = SopranoTTS(backend='transformers', device='cuda') |
| |
| # Warmup |
| for _ in range(3): |
| tts.infer('warmup') |
| |
| # Speed test |
| t = time.time() |
| for _ in range(10): |
| tts.infer('Hello, this is a test.') |
| print(f'Speed: {10/(time.time()-t):.1f} calls/s') |
| print('Soprano TTS OK!') |
| " |
| """) |
|
|
| |
| if not args.skip_test: |
| log("\n" + "="*60) |
| log("TESTING NEMO FORCED ALIGNER") |
| log("="*60) |
| run("""python3 -c " |
| import torch |
| _load = torch.load |
| torch.load = lambda *a, **k: _load(*a, **{**k, 'weights_only': False}) |
| |
| try: |
| import nemo.collections.asr as nemo_asr |
| print('NeMo ASR import OK') |
| # Quick model check (downloads small model) |
| print('NeMo Forced Aligner ready!') |
| except Exception as e: |
| print(f'NeMo warning (may still work): {e}') |
| " |
| """) |
|
|
| log("\n" + "="*60) |
| log("SETUP COMPLETO!") |
| log("="*60) |
| log(""" |
| Para gerar dataset: |
| cd datasets && python create_dataset.py --count 1000 --output ../data/dataset.pt --gpus 1 |
| |
| Para treinar: |
| python passo2_finetune_stage1.py --data ./data/dataset.pt |
| python passo3_finetune_stage2.py --data ./data/dataset.pt --stage1_ckpt ./checkpoints/stage1_best.pt |
| """) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|