import subprocess import os import sys import time import argparse # --- Configuração Inicial --- # 1. Adicionar o código LLaMA-Omni ao Python Path # Assumindo que o diretório 'omni_speech' está na raiz do seu projeto. # Se você colocou dentro de uma pasta, ajuste o path. Ex: './LLaMA-Omni_files' OMNI_SPEECH_ROOT = os.getcwd() # Ou o caminho para a pasta que contém 'omni_speech' if OMNI_SPEECH_ROOT not in sys.path: sys.path.insert(0, OMNI_SPEECH_ROOT) try: from omni_speech.utils.utils import download_models except ImportError: print("Erro: Não foi possível importar 'download_models' de 'omni_speech.utils.utils'.") print(f"Verifique se 'omni_speech' está no diretório correto ({OMNI_SPEECH_ROOT}) e acessível.") sys.exit(1) # --- Download dos Modelos --- # (Adaptado do comando 'run' do cog.yaml) # Os caminhos são relativos à raiz do projeto. BASE_MODEL_PATH = "Llama-3.1-8B-Omni" # Pode ser o identificador do Hugging Face ou um path local após download SPEECH_ENCODER_PATH = "models/speech_encoder" VOCODER_PATH = "vocoder" # HIFI-GAN vocoder files expected by the demo script VOCODER_MODEL_FILE = os.path.join(VOCODER_PATH, "g_00500000") VOCODER_CONFIG_FILE = os.path.join(VOCODER_PATH, "config.json") # Verifica se os modelos principais já foram baixados para evitar re-downloads demorados # Esta é uma verificação simples; a função download_models pode ter sua própria lógica. if not os.path.exists(SPEECH_ENCODER_PATH) or not os.path.exists(VOCODER_MODEL_FILE): print("Iniciando download dos modelos (Whisper e Vocoder)...") os.makedirs(SPEECH_ENCODER_PATH, exist_ok=True) os.makedirs(VOCODER_PATH, exist_ok=True) try: # A função download_models deve cuidar do download do Llama-3.1-8B-Omni também, # ou o model_worker fará isso. O `base_model_path` é passado para ele. download_models( base_model_path=BASE_MODEL_PATH, # O worker pode usar isso para baixar do HF speech_encoder_path=SPEECH_ENCODER_PATH, vocoder_path=VOCODER_PATH ) print("Download dos modelos concluído.") except Exception as e: print(f"Falha no download dos modelos: {e}") # Decida se quer sair ou tentar continuar else: print("Modelos (Whisper/Vocoder) parecem já existir. Pulando download.") # --- Lançamento dos Processos de Background --- # Garanta que os scripts referenciados (controller, model_worker) são executáveis # e que `python` está no PATH do ambiente do Space. controller_process = None model_worker_process = None try: print("Lançando o Controller...") # python -m omni_speech.serve.controller --host 0.0.0.0 --port 10000 controller_cmd = [ sys.executable, "-m", "omni_speech.serve.controller", "--host", "0.0.0.0", "--port", "10000" ] controller_process = subprocess.Popen(controller_cmd) print(f"Controller iniciado (PID: {controller_process.pid}). Aguardando inicialização...") time.sleep(10) # Dê tempo para o controller iniciar print("Lançando o Model Worker...") # python -m omni_speech.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 \\ # --port 40000 --worker http://localhost:40000 --model-path Llama-3.1-8B-Omni \\ # --model-name Llama-3.1-8B-Omni --s2s model_worker_cmd = [ sys.executable, "-m", "omni_speech.serve.model_worker", "--host", "0.0.0.0", "--controller", "http://localhost:10000", "--port", "40000", "--worker", "http://localhost:40000", # URL do próprio worker "--model-path", BASE_MODEL_PATH, # HF ID ou path local "--model-name", "Llama-3.1-8B-Omni", # Nome para registro no controller "--s2s" # Adicione aqui outros argumentos se necessário, como: # --speech-encoder-path SPEECH_ENCODER_PATH # Se o worker precisar explicitamente ] model_worker_process = subprocess.Popen(model_worker_cmd) print(f"Model Worker iniciado (PID: {model_worker_process.pid}). Aguardando carregamento dos modelos...") # O carregamento do modelo pode levar vários minutos. # Idealmente, o gradio_web_server deveria esperar por um sinal de que o worker está pronto. # Para simplificar, um sleep longo, mas isso não é robusto. time.sleep(180) # Aumente se necessário, especialmente na primeira execução. print("Modelos provavelmente carregados. Tentando iniciar o servidor Gradio.") # --- Lançamento do Servidor Web Gradio (Processo Principal) --- # O ideal é importar e chamar a função principal do gradio_web_server.py # python -m omni_speech.serve.gradio_web_server --controller http://localhost:10000 \\ # --port 8000 --model-list-mode reload \\ # --vocoder vocoder/g_00500000 --vocoder-cfg vocoder/config.json # Para que o Hugging Face Spaces detecte corretamente o Gradio app, # este script app.py deve configurar e iniciar o Gradio. # Você precisará adaptar o script omni_speech/serve/gradio_web_server.py # para que possa ser chamado aqui, ou replicar sua lógica. # Exemplo de como chamar se gradio_web_server.py tivesse uma função main(args): print("Configurando e iniciando o servidor Gradio...") try: from omni_speech.serve import gradio_web_server # Simula os argumentos de linha de comando que gradio_web_server espera parser = argparse.ArgumentParser() parser.add_argument("--host", type=str, default="0.0.0.0") parser.add_argument("--port", type=int, default=7860) # HF Spaces usa 7860 por padrão parser.add_argument("--controller-url", type=str, default="http://localhost:10000") parser.add_argument("--model-list-mode", type=str, default="reload", choices=["once", "reload"]) parser.add_argument("--vocoder", type=str, default=VOCODER_MODEL_FILE) parser.add_argument("--vocoder-cfg", type=str, default=VOCODER_CONFIG_FILE) # Adicione quaisquer outros argumentos que gradio_web_server.py espera # parser.add_argument("--share", action="store_true", help="share gradio app") # HF Spaces lida com isso # Valores padrão conforme script LLaMA-Omni e adaptados para HF Space gradio_args = parser.parse_args([ "--host", "0.0.0.0", "--port", "7860", # Porta padrão do Gradio em HF Spaces "--controller-url", "http://localhost:10000", "--model-list-mode", "reload", "--vocoder", VOCODER_MODEL_FILE, "--vocoder-cfg", VOCODER_CONFIG_FILE ]) # Você precisará verificar como o `gradio_web_server.py` realmente constrói e lança # a interface Gradio. Se ele tiver uma função `build_demo()` e `launch()`: # demo = gradio_web_server.build_demo(gradio_args) # demo.queue() # demo.launch(server_name=gradio_args.host, server_port=gradio_args.port, share=gradio_args.share) # Se `gradio_web_server.main(args)` existir e fizer tudo: gradio_web_server.main(gradio_args) # Esta linha é uma suposição! Adapte! print(f"Servidor Gradio deveria estar rodando em http://localhost:{gradio_args.port}") print("Verifique os logs do Hugging Face Space para o URL público.") except ImportError: print("Falha ao importar 'omni_speech.serve.gradio_web_server'.") print("Certifique-se de que o script está presente e o PYTHONPATH está correto.") except AttributeError: print("O script 'omni_speech.serve.gradio_web_server' não tem uma função 'main(args)' como esperado.") print("Você precisará adaptar esta parte do app.py para chamar o código Gradio corretamente.") except Exception as e: print(f"Erro ao tentar iniciar o servidor Gradio: {e}") except KeyboardInterrupt: print("Recebido KeyboardInterrupt. Encerrando processos...") finally: if model_worker_process: print("Encerrando Model Worker...") model_worker_process.terminate() model_worker_process.wait() if controller_process: print("Encerrando Controller...") controller_process.terminate() controller_process.wait() print("Processos de background encerrados.")