marcosremar2 commited on
Commit
c3907b6
·
1 Parent(s): 3909924
.cursor/rules/principal.mdc ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: false
5
+ ---
6
+ . envia o mínimo possível de arquivos, na verdade tem que baixar mais os arquivos durante a inicialização
7
+
8
+ # Resumo do Projeto LLaMA-Omni2 para Hugging Face Spaces
9
+
10
+ Estou configurando uma aplicação de demonstração do LLaMA-Omni2, um assistente de linguagem e fala, para ser facilmente implantada no Hugging Face Spaces. Aqui está um resumo do que foi implementado:
11
+
12
+ ## Objetivo do Projeto
13
+ Criar uma interface web interativa que demonstre as capacidades do LLaMA-Omni2, permitindo aos usuários interagir com o modelo através de texto e fala, recebendo respostas também nos dois formatos.
14
+
15
+ ## Componentes Principais
16
+
17
+ 1. **Interface Gradio**: Uma interface web amigável com duas abas:
18
+ - **Entrada de Áudio**: Permite aos usuários falar ou fazer upload de arquivos de áudio
19
+ - **Entrada de Texto**: Permite interações baseadas em texto
20
+
21
+ 2. **Pipeline de Reconhecimento de Fala**:
22
+ - Usa o modelo Whisper (tiny) para transcrever áudio para texto
23
+ - Configurado para carregar diretamente do Hugging Face
24
+
25
+ 3. **Geração de Texto e Fala**:
26
+ - Usa o modelo LLaMA-Omni2-0.5B para gerar respostas
27
+ - Suporta dois métodos de geração de fala: `generate_with_speech` e `generate_speech`
28
+ - Gerencia a conversão de respostas de texto para áudio
29
+
30
+ 4. **Otimizações para Hugging Face Spaces**:
31
+ - Carregamento dinâmico de modelos (não incluídos no repositório)
32
+ - Configuração para utilizar GPU quando disponível
33
+ - Sistema de logging abrangente para depuração
34
+
35
+ 5. **Gestão de Repositório**:
36
+ - Arquivo `.gitignore` configurado para excluir modelos grandes e artefatos desnecessários
37
+ - Remoção de arquivos grandes do histórico do git
38
+ - Estrutura de projeto limpa e organizada
39
+
40
+ ## Arquivos Principais
41
+ - `app.py`: Contém a lógica principal da aplicação e a interface Gradio
42
+ - `requirements.txt`: Lista todas as dependências necessárias
43
+ - `.huggingface-space`: Configuração para o ambiente Hugging Face Spaces
44
+ - `.gitignore`: Exclui arquivos grandes e temporários do controle de versão
45
+
46
+ ## Tecnologias Utilizadas
47
+ - **Frameworks**: PyTorch, Transformers, Gradio
48
+ - **Modelos**: LLaMA-Omni2-0.5B (para texto/fala), Whisper-tiny (para reconhecimento de fala)
49
+ - **Infraestrutura**: Hugging Face Spaces para hospedagem
50
+
51
+ O projeto está configurado para baixar os modelos dinamicamente quando implantado, em vez de incluí-los no repositório, resultando em um código limpo e eficiente que pode ser facilmente compartilhado e implantado.
.gitignore CHANGED
@@ -37,6 +37,21 @@ models/
37
  .cache/
38
  */.cache/
39
  *incomplete
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  # IDEs
42
  .vscode/
 
37
  .cache/
38
  */.cache/
39
  *incomplete
40
+ whisper-large-v3/
41
+ cosy2_decoder/
42
+ speech_encoder/
43
+ # Excluir todos os arquivos grandes de modelos de forma explícita
44
+ flow.decoder.estimator.fp32.onnx
45
+ flow.decoder.estimator.fp16.A10.plan
46
+ flow.encoder.fp32.zip
47
+ flow.decoder.estimator.fp16.Volta.plan
48
+ hift.pt
49
+ campplus.onnx
50
+ vocab.json
51
+ tokenizer_config.json
52
+ tokenizer.json
53
+ pytorch_model.bin.index.fp32.json
54
+ model.safetensors.index.fp32.json
55
 
56
  # IDEs
57
  .vscode/
LLaMA-Omni2 DELETED
@@ -1 +0,0 @@
1
- Subproject commit feb85982d9effc4ecbc090a71ba6516ef4adaaf0
 
 
README.md CHANGED
@@ -12,72 +12,151 @@ pinned: false
12
  # Ex: hardware: nvidia-t4
13
  ---
14
 
15
- # LLaMA-Omni2 + Whisper Demo
16
 
17
- Uma aplicação de demonstração que combina o reconhecimento de fala do Whisper com a geração de texto e fala do LLaMA-Omni2 0.5B.
18
 
19
- ## Sobre o Projeto
20
 
21
- Esta aplicação demonstra a capacidade do modelo LLaMA-Omni2 0.5B para processar instruções de fala e gerar respostas tanto em texto quanto em fala, tudo com baixa latência. A arquitetura modular é baseada na pesquisa do Institute of Computing Technology da Chinese Academy of Sciences.
 
 
 
 
22
 
23
- ## Principais Recursos
24
-
25
- - 🎤 **Reconhecimento de Fala**: Usando o OpenAI Whisper-tiny para transcrição de áudio
26
- - 💬 **Geração de Texto**: Usando o modelo LLaMA-Omni2 para geração de respostas de texto
27
- - 🔊 **Síntese de Fala**: Geração de fala a partir das respostas de texto (quando disponível)
28
- - 🔄 **Pipeline Completo**: Fluxo integrado de áudio → texto → resposta → fala
29
-
30
- ## Como Usar
31
 
32
- A interface Gradio oferece três modos de interação:
 
 
 
 
33
 
34
- 1. **Pipeline Completo**: Envie um arquivo de áudio, ele será transcrito e usado para gerar uma resposta de texto/fala
35
- 2. **Reconhecimento de Fala**: Teste apenas a capacidade de transcrição do Whisper
36
- 3. **Geração de Texto/Fala**: Forneça seu próprio texto para geração de resposta
37
 
38
- ## Arquitetura LLaMA-Omni2
39
 
40
- O LLaMA-Omni2 é um modelo de linguagem e fala que consiste em 4 componentes principais:
41
 
42
- 1. **Codificador de Fala**: Baseado no Whisper-large-v3, converte entrada de fala em representações acústicas
43
- 2. **Adaptador de Fala**: Ponte entre os espaços acústico e textual
44
- 3. **Núcleo LLM**: O "motor de raciocínio" baseado em Qwen2.5-Instruct
45
- 4. **Decodificador TTS Streaming**: Converte tokens de texto em fala de forma contínua
46
 
47
- ## Configuração para Uso Local
48
 
49
- Se você deseja executar esta aplicação localmente:
50
 
 
51
  ```bash
52
- # Clone o repositório
53
- git clone https://github.com/seu-usuario/llama-omni-demo
54
- cd llama-omni-demo
55
 
56
- # Instale as dependências
 
57
  pip install -r requirements.txt
 
58
 
59
- # Execute a aplicação
 
60
  python app.py
61
  ```
62
 
63
- ## Requisitos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
- - Python 3.10+
66
- - CUDA compatível (para GPU) ou CPU com pelo menos 8GB de RAM
67
- - Dependências listadas em requirements.txt
 
68
 
69
- ## Limitações Atuais
70
 
71
- - O LLaMA-Omni2 é um modelo experimental e pode gerar respostas incorretas ou imprecisas
72
- - A geração de fala pode não estar disponível se o modelo não tiver sido carregado corretamente
73
- - Requer recursos computacionais significativos para execução ideal
74
 
75
- ## Referências
76
 
77
- - [Repositório LLaMA-Omni2](https://github.com/ictnlp/LLaMA-Omni2)
78
- - [Whisper OpenAI](https://github.com/openai/whisper)
79
- - [Artigo LLaMA-Omni2](https://arxiv.org/abs/2505.02625)
 
 
80
 
81
  ## Licença
82
 
83
- Este projeto é licenciado sob a Licença Apache 2.0.
 
12
  # Ex: hardware: nvidia-t4
13
  ---
14
 
15
+ # LLaMA-Omni2 Interface
16
 
17
+ Interface para o modelo LLaMA-Omni2, que permite entrada e saída de áudio com processamento de linguagem natural.
18
 
19
+ ## Características
20
 
21
+ - Transcrição de áudio usando Whisper
22
+ - Processamento de texto com LLaMA-Omni2
23
+ - Síntese de fala usando CosyVoice 2
24
+ - Geração de texto e fala em tempo real
25
+ - Download automático de modelos durante a inicialização
26
 
27
+ ## Requisitos
 
 
 
 
 
 
 
28
 
29
+ - Python 3.8+
30
+ - PyTorch 2.0+
31
+ - Transformers 4.36+
32
+ - Gradio 3.50+
33
+ - CUDA (opcional, mas recomendado para melhor desempenho)
34
 
35
+ ## Configuração de Modelos
 
 
36
 
37
+ Este projeto utiliza um sistema de download automático de modelos durante a inicialização, evitando a necessidade de armazenar arquivos grandes no repositório Git.
38
 
39
+ Os modelos serão baixados automaticamente na primeira execução:
40
 
41
+ - **Whisper Large V3** - Modelo de reconhecimento de fala
42
+ - **CosyVoice 2** - Vocoder para síntese de fala
43
+ - **LLaMA-Omni2** - Modelo de linguagem multimodal
 
44
 
45
+ Todos os modelos são armazenados na pasta `models/`, que está no `.gitignore` para evitar o commit de arquivos grandes.
46
 
47
+ ## Configuração
48
 
49
+ 1. Clone o repositório:
50
  ```bash
51
+ git clone https://github.com/seu-usuario/llama-omni2.git
52
+ cd llama-omni2
53
+ ```
54
 
55
+ 2. Instale as dependências:
56
+ ```bash
57
  pip install -r requirements.txt
58
+ ```
59
 
60
+ 3. Execute o aplicativo:
61
+ ```bash
62
  python app.py
63
  ```
64
 
65
+ Na primeira execução, os modelos serão baixados automaticamente. Isso pode levar algum tempo, dependendo da sua conexão com a internet.
66
+
67
+ ## Uso
68
+
69
+ Após iniciar o aplicativo, acesse a interface web em http://localhost:7860 para interagir com o modelo.
70
+
71
+ - **Entrada de Áudio**: Grave ou faça upload de um arquivo de áudio
72
+ - **Saída de Texto**: Veja a transcrição e a resposta do modelo
73
+ - **Saída de Áudio**: Ouça a resposta sintetizada
74
+
75
+ ## Usando o launcher
76
+
77
+ Você também pode usar o launcher para iniciar a aplicação completa:
78
+
79
+ ```bash
80
+ python launch_llama_omni2.py
81
+ ```
82
+
83
+ Opções do launcher:
84
+ - `--skip-download`: Pula o download das dependências
85
+ - `--extraction-dir`: Define o diretório de extração (padrão: extraction_dir)
86
+ - `--models-dir`: Define o diretório de modelos (padrão: models)
87
+ - `--controller-only`: Inicia apenas o controlador
88
+ - `--worker-only`: Inicia apenas o worker do modelo
89
+ - `--gradio-only`: Inicia apenas a interface Gradio
90
+
91
+ ## Estrutura do Projeto
92
+
93
+ - `app.py` - Aplicativo Gradio principal
94
+ - `audio_interface.py` - Interface de áudio para LLaMA-Omni2
95
+ - `launch_llama_omni2.py` - Script para lançar todos os componentes
96
+ - `model_downloader.py` - Sistema de download automático de modelos
97
+ - `models/` - Diretório para armazenar os modelos baixados
98
+ - `requirements.txt` - Dependências do projeto
99
+
100
+ ## Funcionamento do Download Automático
101
+
102
+ O sistema de download automático funciona da seguinte forma:
103
+
104
+ 1. Na inicialização, o script verifica se os modelos necessários existem localmente
105
+ 2. Se um modelo não for encontrado, ele é baixado automaticamente do Hugging Face Hub
106
+ 3. Após o download, o modelo é carregado normalmente pelo aplicativo
107
+
108
+ Isso permite:
109
+ - Manter o repositório Git leve, sem arquivos grandes
110
+ - Facilitar a implantação em diferentes ambientes
111
+ - Garantir que os usuários sempre tenham os modelos corretos
112
+
113
+ ## Modo Sem Download
114
+
115
+ Este projeto suporta um modo "sem download" que permite usar os modelos diretamente do Hugging Face Hub, sem baixá-los localmente. Isso é útil para:
116
+
117
+ - Desenvolvimento e testes onde não é necessário baixar os modelos completos
118
+ - Ambientes com espaço em disco limitado
119
+ - Integração contínua e cenários de implantação onde os modelos são acessados remotamente
120
+
121
+ Para ativar o modo sem download, você pode:
122
+
123
+ 1. **Usar o script Python no_download.py (recomendado)**:
124
+ ```bash
125
+ # Executar app.py sem download
126
+ python no_download.py app.py
127
+
128
+ # Executar outro script sem download
129
+ python no_download.py audio_interface.py
130
+ ```
131
+
132
+ 2. **Usar o script auxiliar**:
133
+ ```bash
134
+ ./run_without_downloads.sh
135
+ ```
136
+
137
+ 3. **Definir a variável de ambiente**:
138
+ ```bash
139
+ export NO_DOWNLOAD=1
140
+ python app.py
141
+ ```
142
 
143
+ 4. **Usar a opção de linha de comando no launcher**:
144
+ ```bash
145
+ python launch_llama_omni2.py --no-model-download
146
+ ```
147
 
148
+ No modo sem download, o aplicativo usará os modelos diretamente do Hugging Face Hub, sem baixar arquivos localmente. Isso pode ser mais lento para uso contínuo, mas é mais rápido para inicializar e não ocupa espaço em disco.
149
 
150
+ ## Contribuição
 
 
151
 
152
+ Contribuições são bem-vindas! Por favor, siga estas diretrizes:
153
 
154
+ 1. Faça um fork do repositório
155
+ 2. Crie um branch para sua feature (`git checkout -b feature/nova-feature`)
156
+ 3. Faça commit das suas mudanças (`git commit -am 'Adiciona nova feature'`)
157
+ 4. Faça push para o branch (`git push origin feature/nova-feature`)
158
+ 5. Crie um novo Pull Request
159
 
160
  ## Licença
161
 
162
+ Este projeto está licenciado sob os termos da licença MIT.
app.py CHANGED
@@ -17,6 +17,25 @@ from huggingface_hub import snapshot_download
17
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
18
  logger = logging.getLogger(__name__)
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  # Configuração do caminho para os modelos
21
  MODELS_DIR = os.environ.get("MODELS_DIR", "models")
22
  os.makedirs(MODELS_DIR, exist_ok=True)
@@ -39,53 +58,59 @@ else:
39
  logger.info(f"Using device: {torch_device} for model loading.")
40
  logger.info(f"Pipelines will use device_id: {device_for_pipelines} and dtype: {dtype_for_pipelines}")
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  # --- Load Speech-to-Text (ASR) Pipeline ---
43
  asr_pipeline_instance = None
44
  try:
45
- logger.info(f"Loading ASR model: {whisper_model_id}...")
 
46
  asr_pipeline_instance = pipeline(
47
  "automatic-speech-recognition",
48
- model=whisper_model_id,
49
  torch_dtype=dtype_for_pipelines,
50
  device=device_for_pipelines
51
  )
52
- logger.info(f"ASR model ({whisper_model_id}) loaded successfully.")
53
  except Exception as e:
54
- logger.error(f"Error loading ASR model ({whisper_model_id}): {e}")
55
  asr_pipeline_instance = None
56
 
57
  # --- Load Text Generation Model ---
58
  text_gen_pipeline_instance = None
59
  text_generation_model_id = None # Will be set to the model that successfully loads
60
 
61
- # Verificar se o modelo já está baixado ou baixá-lo usando HF Hub
62
- try:
63
- # Verificar se o modelo está na pasta local
64
- local_model_path = os.path.join(MODELS_DIR, os.path.basename(llama_omni_model_id))
65
- if os.path.exists(local_model_path) and os.path.isdir(local_model_path):
66
- logger.info(f"Found local model at {local_model_path}")
67
- model_path_to_use = local_model_path
68
- else:
69
- # Se não existir localmente, verificar se precisamos baixar
70
- logger.info(f"Local model not found, checking if we need to predownload files for {llama_omni_model_id}")
71
- # Verifica se estamos no ambiente Hugging Face
72
- if os.environ.get("SPACE_ID") is not None:
73
- logger.info("Running in Hugging Face Spaces environment")
74
- # No Hugging Face Spaces, usamos o caminho direto para o modelo na nuvem
75
- model_path_to_use = llama_omni_model_id
76
- else:
77
- # Em ambientes locais, podemos baixar explicitamente
78
- logger.info(f"Downloading model {llama_omni_model_id} to {local_model_path}")
79
- snapshot_download(
80
- repo_id=llama_omni_model_id,
81
- local_dir=local_model_path,
82
- token=HF_TOKEN
83
- )
84
- model_path_to_use = local_model_path
85
- except Exception as download_error:
86
- logger.error(f"Error preparing model path: {download_error}")
87
- model_path_to_use = llama_omni_model_id # Fallback to use the direct model ID
88
-
89
  try:
90
  logger.info(f"Attempting to load LLaMA-Omni2 model: {model_path_to_use}...")
91
  # LLaMA models often require specific loading configurations
@@ -116,7 +141,7 @@ try:
116
  device=device_for_pipelines if not torch.cuda.is_available() else None
117
  )
118
  text_generation_model_id = llama_omni_model_id
119
- logger.info(f"LLaMA-Omni2 model ({llama_omni_model_id}) loaded successfully.")
120
  logger.info(f"Model has speech generation capabilities: {is_omni2_speech_model}")
121
 
122
  except Exception as e:
 
17
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
18
  logger = logging.getLogger(__name__)
19
 
20
+ # Verificar modo sem download (primeiro, antes de importar model_downloader)
21
+ NO_DOWNLOAD = os.environ.get("NO_DOWNLOAD", "0").lower() in ("1", "true", "yes")
22
+ logger.info(f"Inicializando app.py com NO_DOWNLOAD={NO_DOWNLOAD} (valor da env: {os.environ.get('NO_DOWNLOAD', 'não definido')})")
23
+
24
+ # Import do novo model_downloader
25
+ try:
26
+ from model_downloader import download_model_if_needed, download_all_models, get_model_repo_id, NO_DOWNLOAD as DOWNLOADER_NO_DOWNLOAD
27
+ # Verificar se os valores são consistentes
28
+ if NO_DOWNLOAD != DOWNLOADER_NO_DOWNLOAD:
29
+ logger.warning(f"Inconsistência detectada: NO_DOWNLOAD no app.py={NO_DOWNLOAD}, mas NO_DOWNLOAD no model_downloader.py={DOWNLOADER_NO_DOWNLOAD}")
30
+ # Atualizar para o valor no model_downloader.py
31
+ NO_DOWNLOAD = DOWNLOADER_NO_DOWNLOAD
32
+ except ImportError:
33
+ logger.warning("model_downloader não pôde ser importado, trabalhando sem ele")
34
+ # Definir funções vazias para manter compatibilidade
35
+ def download_model_if_needed(model_key): return False
36
+ def download_all_models(): pass
37
+ def get_model_repo_id(model_key): return None
38
+
39
  # Configuração do caminho para os modelos
40
  MODELS_DIR = os.environ.get("MODELS_DIR", "models")
41
  os.makedirs(MODELS_DIR, exist_ok=True)
 
58
  logger.info(f"Using device: {torch_device} for model loading.")
59
  logger.info(f"Pipelines will use device_id: {device_for_pipelines} and dtype: {dtype_for_pipelines}")
60
 
61
+ # --- Check Download Mode ---
62
+ if NO_DOWNLOAD:
63
+ logger.warning("Modo NO_DOWNLOAD ativado. Os modelos não serão baixados, usando diretamente do Hugging Face Hub.")
64
+ # Usar IDs dos modelos diretamente do Hugging Face
65
+ whisper_repo_id = get_model_repo_id("speech_encoder") or "openai/whisper-large-v3"
66
+ llama_omni_repo_id = get_model_repo_id("llama_omni2") or llama_omni_model_id
67
+
68
+ # Definir caminhos para modelo
69
+ whisper_path_to_use = whisper_repo_id
70
+ model_path_to_use = llama_omni_repo_id
71
+
72
+ logger.info(f"Usando modelo whisper direto do HF: {whisper_path_to_use}")
73
+ logger.info(f"Usando modelo LLaMA-Omni2 direto do HF: {model_path_to_use}")
74
+ else:
75
+ # --- Download Models if Needed ---
76
+ logger.info("Verificando se os modelos estão disponíveis localmente...")
77
+
78
+ # Download do modelo de speech recognition (Whisper)
79
+ download_model_if_needed("speech_encoder")
80
+
81
+ # Download do modelo de síntese de voz
82
+ download_model_if_needed("cosy2_decoder")
83
+
84
+ # Download do modelo LLaMA-Omni2
85
+ download_model_if_needed("llama_omni2")
86
+
87
+ # Configurar caminhos para modelos locais
88
+ whisper_local_path = os.path.join(MODELS_DIR, "speech_encoder", "whisper-large-v3")
89
+ whisper_path_to_use = whisper_local_path if os.path.exists(whisper_local_path) else whisper_model_id
90
+
91
+ local_model_path = os.path.join(MODELS_DIR, "LLaMA-Omni2-0.5B")
92
+ model_path_to_use = local_model_path if os.path.exists(local_model_path) and os.path.isdir(local_model_path) else llama_omni_model_id
93
+
94
  # --- Load Speech-to-Text (ASR) Pipeline ---
95
  asr_pipeline_instance = None
96
  try:
97
+ logger.info(f"Loading ASR model: {whisper_path_to_use}...")
98
+
99
  asr_pipeline_instance = pipeline(
100
  "automatic-speech-recognition",
101
+ model=whisper_path_to_use,
102
  torch_dtype=dtype_for_pipelines,
103
  device=device_for_pipelines
104
  )
105
+ logger.info(f"ASR model loaded successfully.")
106
  except Exception as e:
107
+ logger.error(f"Error loading ASR model: {e}")
108
  asr_pipeline_instance = None
109
 
110
  # --- Load Text Generation Model ---
111
  text_gen_pipeline_instance = None
112
  text_generation_model_id = None # Will be set to the model that successfully loads
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  try:
115
  logger.info(f"Attempting to load LLaMA-Omni2 model: {model_path_to_use}...")
116
  # LLaMA models often require specific loading configurations
 
141
  device=device_for_pipelines if not torch.cuda.is_available() else None
142
  )
143
  text_generation_model_id = llama_omni_model_id
144
+ logger.info(f"LLaMA-Omni2 model loaded successfully.")
145
  logger.info(f"Model has speech generation capabilities: {is_omni2_speech_model}")
146
 
147
  except Exception as e:
audio_interface.py CHANGED
@@ -28,6 +28,14 @@ import whisper
28
  import aiohttp
29
  import numpy as np
30
 
 
 
 
 
 
 
 
 
31
  # Configure logging
32
  logging.basicConfig(level=logging.INFO)
33
  logger = logging.getLogger(__name__)
@@ -52,11 +60,19 @@ class AudioInterface:
52
  self.read_tokens = read_tokens # Number of text tokens to read
53
  self.write_tokens = write_tokens # Number of speech tokens to write
54
 
 
 
 
55
  # Load Whisper model
56
  try:
 
 
 
 
 
57
  logger.info(f"Loading Whisper model from {whisper_model_path}")
58
  self.whisper_model = whisper.load_model("large-v3",
59
- download_root=whisper_model_path,
60
  device=self.device)
61
  logger.info("Whisper model loaded successfully")
62
  except Exception as e:
@@ -65,6 +81,10 @@ class AudioInterface:
65
 
66
  # Load CosyVoice vocoder
67
  try:
 
 
 
 
68
  sys.path.insert(0, vocoder_dir)
69
  from cosy_voice_2.inference import CosyVoice
70
 
@@ -79,6 +99,26 @@ class AudioInterface:
79
 
80
  logger.info(f"Using LLaMA-Omni2 model: {model_name}")
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  async def get_worker_address(self):
83
  """Get the address of the worker serving the model"""
84
  try:
 
28
  import aiohttp
29
  import numpy as np
30
 
31
+ # Import model downloader
32
+ try:
33
+ from model_downloader import download_model_if_needed, download_all_models, get_model_repo_id, NO_DOWNLOAD
34
+ has_model_downloader = True
35
+ except ImportError:
36
+ has_model_downloader = False
37
+ NO_DOWNLOAD = False
38
+
39
  # Configure logging
40
  logging.basicConfig(level=logging.INFO)
41
  logger = logging.getLogger(__name__)
 
60
  self.read_tokens = read_tokens # Number of text tokens to read
61
  self.write_tokens = write_tokens # Number of speech tokens to write
62
 
63
+ # Download required models if needed
64
+ self._ensure_models_available()
65
+
66
  # Load Whisper model
67
  try:
68
+ # Se NO_DOWNLOAD estiver ativado, usar diretamente o modelo do Hugging Face
69
+ if has_model_downloader and NO_DOWNLOAD:
70
+ whisper_model_path = "openai/whisper-large-v3"
71
+ logger.info(f"Modo NO_DOWNLOAD: Carregando Whisper direto do Hugging Face: {whisper_model_path}")
72
+
73
  logger.info(f"Loading Whisper model from {whisper_model_path}")
74
  self.whisper_model = whisper.load_model("large-v3",
75
+ download_root=whisper_model_path if not NO_DOWNLOAD else None,
76
  device=self.device)
77
  logger.info("Whisper model loaded successfully")
78
  except Exception as e:
 
81
 
82
  # Load CosyVoice vocoder
83
  try:
84
+ # Se NO_DOWNLOAD estiver ativado, usar diretamente o modelo do Hugging Face
85
+ if has_model_downloader and NO_DOWNLOAD:
86
+ logger.warning("Modo NO_DOWNLOAD ativado. O vocoder CosyVoice pode não funcionar corretamente sem os arquivos locais.")
87
+
88
  sys.path.insert(0, vocoder_dir)
89
  from cosy_voice_2.inference import CosyVoice
90
 
 
99
 
100
  logger.info(f"Using LLaMA-Omni2 model: {model_name}")
101
 
102
+ def _ensure_models_available(self):
103
+ """Garante que os modelos necessários estão disponíveis"""
104
+ # Verificar se temos o model_downloader disponível
105
+ if has_model_downloader:
106
+ if NO_DOWNLOAD:
107
+ logger.info("Modo NO_DOWNLOAD ativado. Pulando verificação de modelos locais.")
108
+ return
109
+
110
+ logger.info("Verificando modelos necessários...")
111
+
112
+ # Baixar modelo Whisper
113
+ download_model_if_needed("speech_encoder")
114
+
115
+ # Baixar modelo CosyVoice
116
+ download_model_if_needed("cosy2_decoder")
117
+
118
+ logger.info("Verificação de modelos concluída")
119
+ else:
120
+ logger.warning("model_downloader não está disponível. Assumindo que os modelos já estão disponíveis localmente.")
121
+
122
  async def get_worker_address(self):
123
  """Get the address of the worker serving the model"""
124
  try:
launch_llama_omni2.py CHANGED
@@ -14,6 +14,11 @@ import argparse
14
  import shutil
15
  import importlib.util
16
  import tempfile
 
 
 
 
 
17
 
18
  # Define paths
19
  EXTRACTION_DIR = "/home/user/app/llama_omni2_extracted"
@@ -22,6 +27,30 @@ LLAMA_OMNI2_MODEL_NAME = "LLaMA-Omni2-0.5B"
22
  LLAMA_OMNI2_MODEL_PATH = f"{MODELS_DIR}/{LLAMA_OMNI2_MODEL_NAME}"
23
  COSYVOICE_PATH = f"{MODELS_DIR}/cosy2_decoder"
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  # Additional imports
26
  def download_dependencies():
27
  """Download and install required Python packages for LLaMA-Omni2"""
@@ -32,7 +61,8 @@ def download_dependencies():
32
  "uvicorn",
33
  "pydantic",
34
  "transformers>=4.36.2",
35
- "sentencepiece"
 
36
  ]
37
 
38
  try:
@@ -376,94 +406,81 @@ except ImportError:
376
  return patched_files
377
 
378
  def main():
379
- """Main function to extract and run LLaMA-Omni2 components"""
380
- print("LLaMA-Omni2 Direct Launcher")
381
- print("==========================")
382
-
383
- # Install dependencies first
384
- print("Checking and installing dependencies...")
385
- download_dependencies()
386
-
387
- # Create directories directly instead of using extraction script
388
- print("Creating necessary directories...")
389
- os.makedirs(EXTRACTION_DIR, exist_ok=True)
390
- os.makedirs(os.path.join(EXTRACTION_DIR, "llama_omni2"), exist_ok=True)
391
- os.makedirs(os.path.join(EXTRACTION_DIR, "llama_omni2", "serve"), exist_ok=True)
392
-
393
- # Ensure the module structure is complete
394
- ensure_module_structure(EXTRACTION_DIR)
395
-
396
- # Skip patching files as we're not extracting anything
397
- print("Skipping file patching as we're not running extraction")
398
-
399
- # Add the extraction dir to Python path
400
- if EXTRACTION_DIR not in sys.path:
401
- sys.path.insert(0, EXTRACTION_DIR)
402
- print(f"Added {EXTRACTION_DIR} to sys.path")
403
-
404
- # Skip directly to model download and starting services
405
- print("Proceeding directly to model download and starting services...")
406
-
407
- # Make directories for models
408
- os.makedirs(MODELS_DIR, exist_ok=True)
409
- os.makedirs(LLAMA_OMNI2_MODEL_PATH, exist_ok=True)
410
- os.makedirs(COSYVOICE_PATH, exist_ok=True)
411
-
412
- # Start controller
413
- controller_process = start_controller()
414
- if not controller_process:
415
- print("Failed to start controller. Exiting.")
416
- return 1
417
-
418
- # Wait for controller to initialize
419
- print("Waiting for controller to initialize...")
420
- time.sleep(5)
421
-
422
- # Start model worker
423
- model_worker_process = start_model_worker()
424
- if not model_worker_process:
425
- print("Failed to start model worker. Shutting down controller.")
426
- controller_process.terminate()
427
- return 1
428
-
429
- # Wait for model to load - reduced from 300 seconds to 30 seconds
430
- print("Waiting for model worker to initialize...")
431
- time.sleep(30)
432
-
433
- # Start Gradio server
434
- gradio_process = start_gradio_server()
435
- if not gradio_process:
436
- print("Failed to start Gradio server. Shutting down other processes.")
437
- model_worker_process.terminate()
438
- controller_process.terminate()
439
- return 1
440
-
441
- print("\nAll components started successfully!")
442
- print(f"Gradio interface should be available at http://0.0.0.0:7860")
443
-
444
  try:
445
- # Wait for Gradio process to finish
446
- gradio_process.wait()
 
447
  except KeyboardInterrupt:
448
- print("\nReceived keyboard interrupt. Shutting down...")
449
- finally:
450
- # Cleanup
451
- for process, name in [
452
- (gradio_process, "Gradio server"),
453
- (model_worker_process, "Model worker"),
454
- (controller_process, "Controller")
455
- ]:
456
- if process and process.poll() is None:
457
- print(f"Shutting down {name}...")
458
- process.terminate()
459
- try:
460
- process.wait(timeout=30)
461
- except subprocess.TimeoutExpired:
462
- print(f"{name} did not terminate gracefully. Killing...")
463
- process.kill()
464
-
465
- print("All processes have been shut down.")
466
- return 0
467
 
468
  if __name__ == "__main__":
469
  sys.exit(main())
 
14
  import shutil
15
  import importlib.util
16
  import tempfile
17
+ import logging
18
+
19
+ # Configure logging
20
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
21
+ logger = logging.getLogger(__name__)
22
 
23
  # Define paths
24
  EXTRACTION_DIR = "/home/user/app/llama_omni2_extracted"
 
27
  LLAMA_OMNI2_MODEL_PATH = f"{MODELS_DIR}/{LLAMA_OMNI2_MODEL_NAME}"
28
  COSYVOICE_PATH = f"{MODELS_DIR}/cosy2_decoder"
29
 
30
+ # Importe o model_downloader se disponível
31
+ try:
32
+ from model_downloader import download_model_if_needed, download_all_models, get_model_repo_id, NO_DOWNLOAD
33
+ has_model_downloader = True
34
+ except ImportError:
35
+ has_model_downloader = False
36
+ NO_DOWNLOAD = False
37
+
38
+ # Garantir que os modelos estão disponíveis
39
+ def ensure_models_available():
40
+ """Garante que os modelos necessários estão disponíveis"""
41
+ if has_model_downloader:
42
+ if NO_DOWNLOAD:
43
+ logger.info("Modo NO_DOWNLOAD ativado. Os modelos não serão baixados, usando diretamente do Hugging Face Hub.")
44
+ return
45
+
46
+ logger.info("Verificando modelos necessários para o LLaMA-Omni2...")
47
+ download_model_if_needed("llama_omni2")
48
+ download_model_if_needed("cosy2_decoder")
49
+ download_model_if_needed("speech_encoder")
50
+ logger.info("Verificação de modelos concluída")
51
+ else:
52
+ logger.warning("model_downloader não está disponível. Os modelos devem estar disponíveis em: " + MODELS_DIR)
53
+
54
  # Additional imports
55
  def download_dependencies():
56
  """Download and install required Python packages for LLaMA-Omni2"""
 
61
  "uvicorn",
62
  "pydantic",
63
  "transformers>=4.36.2",
64
+ "sentencepiece",
65
+ "huggingface_hub"
66
  ]
67
 
68
  try:
 
406
  return patched_files
407
 
408
  def main():
409
+ """Main entry point for the launcher script"""
410
+ parser = argparse.ArgumentParser(description="LLaMA-Omni2 Direct Launcher")
411
+ parser.add_argument("--skip-download", action="store_true", help="Skip downloading dependencies")
412
+ parser.add_argument("--no-model-download", action="store_true", help="Don't download models, use them directly from HF Hub")
413
+ parser.add_argument("--extraction-dir", type=str, default=EXTRACTION_DIR, help="Directory to extract LLaMA-Omni2 to")
414
+ parser.add_argument("--models-dir", type=str, default=MODELS_DIR, help="Directory containing models")
415
+ parser.add_argument("--skip-modules", action="store_true", help="Skip module structure creation")
416
+ parser.add_argument("--controller-only", action="store_true", help="Start only the controller")
417
+ parser.add_argument("--worker-only", action="store_true", help="Start only the model worker")
418
+ parser.add_argument("--gradio-only", action="store_true", help="Start only the Gradio interface")
419
+ args = parser.parse_args()
420
+
421
+ # Update paths based on arguments
422
+ global EXTRACTION_DIR, MODELS_DIR, LLAMA_OMNI2_MODEL_PATH, COSYVOICE_PATH
423
+ EXTRACTION_DIR = args.extraction_dir
424
+ MODELS_DIR = args.models_dir
425
+ LLAMA_OMNI2_MODEL_PATH = f"{MODELS_DIR}/{LLAMA_OMNI2_MODEL_NAME}"
426
+ COSYVOICE_PATH = f"{MODELS_DIR}/cosy2_decoder"
427
+
428
+ # Set NO_DOWNLOAD environment variable if --no-model-download is specified
429
+ if args.no_model_download:
430
+ os.environ["NO_DOWNLOAD"] = "1"
431
+ global NO_DOWNLOAD
432
+ NO_DOWNLOAD = True
433
+ logger.info("Modo NO_DOWNLOAD ativado via linha de comando")
434
+
435
+ print("=== LLaMA-Omni2 Direct Launcher ===")
436
+ print(f"Extraction directory: {EXTRACTION_DIR}")
437
+ print(f"Models directory: {MODELS_DIR}")
438
+ print(f"Downloading models: {'No' if NO_DOWNLOAD else 'Yes'}")
439
+
440
+ # Ensure models are available
441
+ ensure_models_available()
442
+
443
+ # Download dependencies if needed
444
+ if not args.skip_download:
445
+ download_dependencies()
446
+
447
+ # Create module structure if needed
448
+ if not args.skip_modules:
449
+ ensure_module_structure(EXTRACTION_DIR)
450
+
451
+ # Start the controller if needed
452
+ controller_process = None
453
+ if not args.worker_only and not args.gradio_only:
454
+ controller_process = start_controller()
455
+ # Give the controller time to start up
456
+ time.sleep(5)
457
+
458
+ # Start the model worker if needed
459
+ worker_process = None
460
+ if not args.controller_only and not args.gradio_only:
461
+ worker_process = start_model_worker()
462
+ # Give the worker time to start up
463
+ time.sleep(5)
464
+
465
+ # Start the Gradio interface if needed
466
+ gradio_process = None
467
+ if not args.controller_only and not args.worker_only:
468
+ gradio_process = start_gradio_server()
469
+
470
+ # Keep the main process running to maintain subprocesses
 
 
 
471
  try:
472
+ print("Press Ctrl+C to exit...")
473
+ while True:
474
+ time.sleep(1)
475
  except KeyboardInterrupt:
476
+ print("Shutting down...")
477
+ if controller_process:
478
+ controller_process.terminate()
479
+ if worker_process:
480
+ worker_process.terminate()
481
+ if gradio_process:
482
+ gradio_process.terminate()
483
+ print("Shutdown complete")
 
 
 
 
 
 
 
 
 
 
 
484
 
485
  if __name__ == "__main__":
486
  sys.exit(main())
model_downloader.py ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Model Downloader para LLaMA-Omni2
4
+ ---------------------------------
5
+ Este script gerencia o download automático dos modelos necessários para o LLaMA-Omni2.
6
+ Os modelos serão baixados apenas quando necessário durante a inicialização.
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import logging
12
+ import huggingface_hub
13
+ from huggingface_hub import snapshot_download, hf_hub_download
14
+ from pathlib import Path
15
+ import torch
16
+ import shutil
17
+
18
+ # Configurar logging
19
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
20
+ logger = logging.getLogger(__name__)
21
+
22
+ # Configurações de modelos
23
+ MODELS_DIR = os.environ.get("MODELS_DIR", "models")
24
+ HF_TOKEN = os.environ.get("HF_TOKEN", None)
25
+
26
+ # Modo sem download (NO_DOWNLOAD=1)
27
+ NO_DOWNLOAD = os.environ.get("NO_DOWNLOAD", "0").lower() in ("1", "true", "yes")
28
+
29
+ # Mensagem de debug para verificar o status da variável
30
+ logger.info(f"Inicializando model_downloader.py com NO_DOWNLOAD={NO_DOWNLOAD} (valor da env: {os.environ.get('NO_DOWNLOAD', 'não definido')})")
31
+
32
+ # Modelos necessários
33
+ MODEL_CONFIGS = {
34
+ "speech_encoder": {
35
+ "repo_id": "openai/whisper-large-v3",
36
+ "local_dir": os.path.join(MODELS_DIR, "speech_encoder", "whisper-large-v3"),
37
+ "files": None, # None significa baixar o modelo completo
38
+ },
39
+ "cosy2_decoder": {
40
+ "repo_id": "ICTNLP/cosy2_decoder",
41
+ "local_dir": os.path.join(MODELS_DIR, "cosy2_decoder"),
42
+ "files": [
43
+ "flow.decoder.estimator.fp32.onnx",
44
+ "flow.decoder.estimator.fp16.A10.plan",
45
+ "flow.encoder.fp32.zip",
46
+ "flow.decoder.estimator.fp16.Volta.plan",
47
+ "hift.pt",
48
+ "campplus.onnx",
49
+ "cosyvoice.yaml",
50
+ ],
51
+ },
52
+ "llama_omni2": {
53
+ "repo_id": "ICTNLP/LLaMA-Omni2-0.5B",
54
+ "local_dir": os.path.join(MODELS_DIR, "LLaMA-Omni2-0.5B"),
55
+ "files": None, # None significa baixar o modelo completo
56
+ }
57
+ }
58
+
59
+ def ensure_model_dir():
60
+ """Garante que o diretório models existe"""
61
+ if NO_DOWNLOAD:
62
+ logger.info("Modo NO_DOWNLOAD ativado. Pulando criação de diretórios.")
63
+ return
64
+
65
+ os.makedirs(MODELS_DIR, exist_ok=True)
66
+ for model_config in MODEL_CONFIGS.values():
67
+ os.makedirs(model_config["local_dir"], exist_ok=True)
68
+
69
+ def is_model_downloaded(model_key):
70
+ """Verifica se um modelo já foi baixado"""
71
+ # No modo sem download, sempre retorna False para pular a verificação
72
+ if NO_DOWNLOAD:
73
+ logger.info(f"Modo NO_DOWNLOAD ativado. Pulando verificação para {model_key}.")
74
+ return False
75
+
76
+ config = MODEL_CONFIGS[model_key]
77
+ local_dir = config["local_dir"]
78
+
79
+ # Se não temos uma lista específica de arquivos, verificar apenas se o diretório existe
80
+ if config["files"] is None:
81
+ # Verificar se o diretório existe e tem arquivos
82
+ if os.path.exists(local_dir) and any(os.listdir(local_dir)):
83
+ logger.info(f"Modelo {model_key} já parece estar baixado em {local_dir}")
84
+ return True
85
+ return False
86
+
87
+ # Verificar se todos os arquivos específicos existem
88
+ for file in config["files"]:
89
+ file_path = os.path.join(local_dir, file)
90
+ if not os.path.exists(file_path):
91
+ logger.info(f"Arquivo {file} não encontrado para o modelo {model_key}")
92
+ return False
93
+
94
+ logger.info(f"Todos os arquivos para o modelo {model_key} já estão disponíveis em {local_dir}")
95
+ return True
96
+
97
+ def download_model(model_key):
98
+ """Baixa um modelo específico do Hugging Face Hub"""
99
+ # Verificar o modo sem download
100
+ if NO_DOWNLOAD:
101
+ logger.warning(f"Modo NO_DOWNLOAD ativado. Pulando download de {model_key}")
102
+ return False
103
+
104
+ config = MODEL_CONFIGS[model_key]
105
+ repo_id = config["repo_id"]
106
+ local_dir = config["local_dir"]
107
+ files = config["files"]
108
+
109
+ try:
110
+ logger.info(f"Baixando modelo {model_key} do repo {repo_id}...")
111
+
112
+ # Se temos uma lista específica de arquivos, baixar um por um
113
+ if files is not None:
114
+ for file in files:
115
+ file_path = os.path.join(local_dir, file)
116
+
117
+ # Pular se o arquivo já existe
118
+ if os.path.exists(file_path):
119
+ logger.info(f"Arquivo {file} já existe, pulando download")
120
+ continue
121
+
122
+ logger.info(f"Baixando arquivo {file} para {file_path}")
123
+ try:
124
+ hf_hub_download(
125
+ repo_id=repo_id,
126
+ filename=file,
127
+ local_dir=local_dir,
128
+ local_dir_use_symlinks=False,
129
+ token=HF_TOKEN
130
+ )
131
+ except Exception as e:
132
+ logger.warning(f"Erro ao baixar arquivo {file}: {e}. Tentando continuar.")
133
+ else:
134
+ # Baixar o modelo completo
135
+ snapshot_download(
136
+ repo_id=repo_id,
137
+ local_dir=local_dir,
138
+ local_dir_use_symlinks=False,
139
+ token=HF_TOKEN
140
+ )
141
+
142
+ logger.info(f"Modelo {model_key} baixado com sucesso para {local_dir}")
143
+ return True
144
+ except Exception as e:
145
+ logger.error(f"Erro ao baixar modelo {model_key}: {e}")
146
+ return False
147
+
148
+ def cleanup_model_dir(model_key):
149
+ """Remove arquivos incompletos ou corruptos de um diretório de modelo"""
150
+ # Verificar o modo sem download
151
+ if NO_DOWNLOAD:
152
+ logger.info(f"Modo NO_DOWNLOAD ativado. Pulando limpeza de diretório para {model_key}.")
153
+ return True
154
+
155
+ config = MODEL_CONFIGS[model_key]
156
+ local_dir = config["local_dir"]
157
+
158
+ try:
159
+ # Procurar por arquivos .incomplete e removê-los
160
+ for root, dirs, files in os.walk(local_dir):
161
+ for file in files:
162
+ if file.endswith(".incomplete"):
163
+ file_path = os.path.join(root, file)
164
+ logger.info(f"Removendo arquivo incompleto: {file_path}")
165
+ os.remove(file_path)
166
+
167
+ return True
168
+ except Exception as e:
169
+ logger.error(f"Erro ao limpar diretório do modelo {model_key}: {e}")
170
+ return False
171
+
172
+ def download_all_models():
173
+ """Baixa todos os modelos configurados, se necessário"""
174
+ # Verificar o modo sem download
175
+ if NO_DOWNLOAD:
176
+ logger.warning("Modo NO_DOWNLOAD ativado. Nenhum modelo será baixado.")
177
+ return
178
+
179
+ ensure_model_dir()
180
+
181
+ for model_key in MODEL_CONFIGS:
182
+ if not is_model_downloaded(model_key):
183
+ logger.info(f"Iniciando download do modelo {model_key}")
184
+ cleanup_model_dir(model_key)
185
+ download_model(model_key)
186
+ else:
187
+ logger.info(f"Modelo {model_key} já está disponível localmente")
188
+
189
+ def download_model_if_needed(model_key):
190
+ """Baixa um modelo específico se ele não estiver disponível"""
191
+ # Verificar o modo sem download
192
+ if NO_DOWNLOAD:
193
+ logger.info(f"Modo NO_DOWNLOAD ativado. Usando repo_id diretamente para {model_key}")
194
+ return False
195
+
196
+ ensure_model_dir()
197
+
198
+ if model_key not in MODEL_CONFIGS:
199
+ logger.error(f"Modelo {model_key} não está configurado para download")
200
+ return False
201
+
202
+ if not is_model_downloaded(model_key):
203
+ logger.info(f"Modelo {model_key} não encontrado localmente. Iniciando download...")
204
+ cleanup_model_dir(model_key)
205
+ return download_model(model_key)
206
+ else:
207
+ logger.info(f"Modelo {model_key} já está disponível localmente")
208
+ return True
209
+
210
+ def get_model_repo_id(model_key):
211
+ """Retorna o repo_id do modelo para uso direto sem download"""
212
+ if model_key not in MODEL_CONFIGS:
213
+ logger.error(f"Modelo {model_key} não está configurado")
214
+ return None
215
+ return MODEL_CONFIGS[model_key]["repo_id"]
216
+
217
+ if __name__ == "__main__":
218
+ # Se executado diretamente, baixar todos os modelos
219
+ download_all_models()
no_download.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Script para iniciar aplicações no modo sem download.
4
+ Este script define explicitamente a variável NO_DOWNLOAD=1 no ambiente Python,
5
+ garantindo que nenhum modelo seja baixado.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import subprocess
11
+ import logging
12
+
13
+ # Configurar logging
14
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
15
+ logger = logging.getLogger("no_download")
16
+
17
+ # Definir a variável NO_DOWNLOAD no ambiente
18
+ os.environ["NO_DOWNLOAD"] = "1"
19
+ logger.info(f"Variável NO_DOWNLOAD definida como: {os.environ.get('NO_DOWNLOAD')}")
20
+
21
+ # Verificar argumentos de linha de comando
22
+ if len(sys.argv) < 2:
23
+ logger.info("Nenhum script especificado. Executando app.py por padrão.")
24
+ target_script = "app.py"
25
+ else:
26
+ target_script = sys.argv[1]
27
+ logger.info(f"Executando script: {target_script}")
28
+
29
+ # Lista de argumentos extras
30
+ args = sys.argv[2:]
31
+
32
+ # Exibir informações
33
+ print("=" * 70)
34
+ print(f"Executando {target_script} no modo SEM DOWNLOAD (NO_DOWNLOAD=1)")
35
+ print("Os modelos serão usados diretamente do Hugging Face Hub, sem baixar localmente")
36
+ print("=" * 70)
37
+
38
+ # Executar o script alvo com os mesmos argumentos
39
+ try:
40
+ # Criar um dicionário de ambiente com NO_DOWNLOAD definido
41
+ env = os.environ.copy()
42
+ env["NO_DOWNLOAD"] = "1"
43
+
44
+ # Construir o comando
45
+ command = [sys.executable, target_script] + args
46
+ logger.info(f"Executando comando: {' '.join(command)}")
47
+
48
+ # Execute o comando com o ambiente modificado
49
+ process = subprocess.Popen(command, env=env)
50
+ process.wait()
51
+
52
+ sys.exit(process.returncode)
53
+ except Exception as e:
54
+ logger.error(f"Erro ao executar {target_script}: {e}")
55
+ sys.exit(1)
run_without_downloads.sh ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Script para executar o LLaMA-Omni2 sem baixar modelos localmente
3
+
4
+ # Definir a variável de ambiente NO_DOWNLOAD
5
+ export NO_DOWNLOAD=1
6
+
7
+ # Verificar se a variável foi definida
8
+ echo "Verificando variável de ambiente NO_DOWNLOAD..."
9
+ echo "NO_DOWNLOAD=$NO_DOWNLOAD"
10
+
11
+ # Adicionar modo de depuração para verificar o funcionamento
12
+ export PYTHONVERBOSE=1
13
+ export PYTHONPATH=$(pwd):$PYTHONPATH
14
+
15
+ # Criar arquivo temporário de verificação
16
+ python -c "
17
+ import os
18
+ with open('env_check.txt', 'w') as f:
19
+ f.write(f'NO_DOWNLOAD={os.environ.get(\"NO_DOWNLOAD\", \"não definido\")}')
20
+ "
21
+
22
+ # Mostrar o conteúdo do arquivo de verificação
23
+ echo "Conteúdo do arquivo de verificação:"
24
+ cat env_check.txt
25
+
26
+ # Executar a aplicação
27
+ echo "Executando LLaMA-Omni2 no modo sem download (NO_DOWNLOAD=1)"
28
+ echo "Os modelos serão usados diretamente do Hugging Face Hub, sem baixar localmente"
29
+ echo "======================================================================"
30
+
31
+ # Verificar qual aplicação iniciar
32
+ if [ "$1" == "app" ] || [ "$1" == "" ]; then
33
+ echo "Iniciando app.py..."
34
+ # Verificar se a variável está disponível para o Python
35
+ python -c "import os; print('NO_DOWNLOAD environment variable:', os.environ.get('NO_DOWNLOAD', 'not set'))"
36
+ # Executar com a variável de ambiente explícita
37
+ NO_DOWNLOAD=1 python app.py
38
+ elif [ "$1" == "launcher" ]; then
39
+ echo "Iniciando launcher..."
40
+ python -c "import os; print('NO_DOWNLOAD environment variable:', os.environ.get('NO_DOWNLOAD', 'not set'))"
41
+ # Usar a opção de linha de comando
42
+ NO_DOWNLOAD=1 python launch_llama_omni2.py --no-model-download
43
+ elif [ "$1" == "audio" ]; then
44
+ echo "Iniciando interface de áudio..."
45
+ python -c "import os; print('NO_DOWNLOAD environment variable:', os.environ.get('NO_DOWNLOAD', 'not set'))"
46
+ NO_DOWNLOAD=1 python audio_interface.py
47
+ else
48
+ echo "Uso: $0 [app|launcher|audio]"
49
+ echo " app - Inicia app.py (padrão)"
50
+ echo " launcher - Inicia launch_llama_omni2.py"
51
+ echo " audio - Inicia audio_interface.py"
52
+ fi
53
+
54
+ # Limpar arquivo temporário
55
+ rm -f env_check.txt