Limpa dependências versionadas e reconstrói catálogo com 20 projetos
Deploy / Deploy (push) Successful in 29s

This commit is contained in:
www-data committed 2026-10-06 07:12:04 -03:00
1 parent 95810ce994
commit 57af93ea60
319 files changed
+155566 -1328045

No files matched your search

+64 -41
View File
@@ -48,14 +48,19 @@ essentia.log.info.active = False
essentia.log.warning.active = False
# ================= CONFIGURAÇÕES =================
BASE_DIR = "/var/www/html/trens/src_mmpSearch"
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from etl_settings import DATA_ROOT, MODELS_ROOT, worker_count
BASE_DIR = str(DATA_ROOT)
PASTA_WAVS = os.path.join(BASE_DIR, "wav")
PASTA_LOTES_YAML = os.path.join(BASE_DIR, "lotes_yaml")
# --- SISTEMA DE DOIS MODELOS ---
MODELO_EMBEDDING = "discogs-effnet-bs64-1.pb"
MODELO_CLASSIFIER = "genre_discogs400.pb"
MODELO_CLASSES = "genre_discogs400.json"
MODELO_EMBEDDING = str(MODELS_ROOT / "discogs-effnet-bs64-1.pb")
MODELO_CLASSIFIER = str(MODELS_ROOT / "genre_discogs400.pb")
MODELO_CLASSES = str(MODELS_ROOT / "genre_discogs400.json")
# Saídas
DIR_SAIDA = os.path.join(BASE_DIR, "saida_analises")
@@ -516,9 +521,9 @@ def analisar_faixa(caminho_arquivo, embedding_model, classifier_model, classes_r
except Exception as e:
msg = f"Erro IA Pipeline: {str(e)}"
logging.error(msg)
metadata["analise_ia"] = {"erro": msg}
raise RuntimeError(msg) from e
else:
metadata["analise_ia"] = {"status": "Modelos nao carregados"}
raise RuntimeError("Modelos de IA nao inicializados no worker.")
# Limpeza Limpa
del audio_hq
@@ -530,35 +535,10 @@ def analisar_faixa(caminho_arquivo, embedding_model, classifier_model, classes_r
# ================= MAIN (Multiprocessing) =================
def worker_analise(caminho):
# Processa usando as instâncias dos modelos carregadas na thread mestre
global GLOBAL_EMBEDDING, GLOBAL_CLASSIFIER, GLOBAL_CLASSES
return analisar_faixa(caminho, GLOBAL_EMBEDDING, GLOBAL_CLASSIFIER, GLOBAL_CLASSES)
def main():
print("\n--- INICIANDO PROCESSADOR + AUDITORIA ---")
# Referencia variávies globais do script para alimentar os childs process do pool
def initialize_analysis_worker():
# Cada processo cria suas proprias sessoes TensorFlow.
global DATABASE_YAML, GLOBAL_EMBEDDING, GLOBAL_CLASSIFIER, GLOBAL_CLASSES
DATABASE_YAML = carregar_database_yaml()
ja_processados, lista_resultados = carregar_checkpoint()
auditor = Auditoria(ARQUIVO_AUDITORIA)
if not os.path.exists(PASTA_WAVS):
print("CRÍTICO: Pasta WAV não encontrada!")
return
todos = [f for f in os.listdir(PASTA_WAVS) if f.lower().endswith((".wav", ".ogg"))]
a_fazer = [os.path.join(PASTA_WAVS, f) for f in todos if f not in ja_processados]
total = len(a_fazer)
print(f"Total Arquivos: {len(todos)} | Novos a Fazer: {total}")
print(f"Auditoria será salva em: {ARQUIVO_AUDITORIA}")
# === CARREGAMENTO MODELOS GLOBAIS ===
path_embed = (
MODELO_EMBEDDING
@@ -608,24 +588,61 @@ def main():
print("[2/2] Classificador de Gênero carregado.")
except Exception as e:
print(f"ERRO CRÍTICO AO CARREGAR IA: {e}")
return
raise RuntimeError("Falha ao carregar modelos de IA") from e
else:
print("Arquivos de modelo incompletos.")
return
raise FileNotFoundError("Arquivos de modelo incompletos.")
def worker_analise(caminho):
# Modelos inicializados neste processo, sem herdar sessoes via fork.
print(f"[PID {os.getpid()}] Iniciando analise: {os.path.basename(caminho)}", flush=True)
global GLOBAL_EMBEDDING, GLOBAL_CLASSIFIER, GLOBAL_CLASSES
result = analisar_faixa(caminho, GLOBAL_EMBEDDING, GLOBAL_CLASSIFIER, GLOBAL_CLASSES)
print(f"[PID {os.getpid()}] Finalizou analise: {os.path.basename(caminho)}", flush=True)
return result
def main():
print("\n--- INICIANDO PROCESSADOR + AUDITORIA ---")
# Referencia variávies globais do script para alimentar os childs process do pool
global DATABASE_YAML, GLOBAL_EMBEDDING, GLOBAL_CLASSIFIER, GLOBAL_CLASSES
DATABASE_YAML = carregar_database_yaml()
ja_processados, lista_resultados = carregar_checkpoint()
auditor = Auditoria(ARQUIVO_AUDITORIA)
if not os.path.exists(PASTA_WAVS):
raise RuntimeError("Pasta de audio nao encontrada.")
todos = [f for f in os.listdir(PASTA_WAVS) if f.lower().endswith((".wav", ".ogg"))]
a_fazer = [os.path.join(PASTA_WAVS, f) for f in todos if f not in ja_processados]
total = len(a_fazer)
print(f"Total Arquivos: {len(todos)} | Novos a Fazer: {total}")
print(f"Auditoria será salva em: {ARQUIVO_AUDITORIA}")
if total == 0:
print("Tudo atualizado.")
print("Nenhum audio novo; reconstruindo o consolidado do checkpoint.")
if not lista_resultados:
raise RuntimeError("Nao ha audios nem resultados no checkpoint.")
with open(ARQUIVO_FINAL_JSON, "w", encoding="utf-8") as f:
json.dump(lista_resultados, f, indent=4, ensure_ascii=False)
return
# ProcessPoolExecutor lidará com N filas ao mesmo tempo
max_workers = max(1, multiprocessing.cpu_count() - 1)
max_workers = worker_count()
print(f"-> Iniciando processamento paralelo com {max_workers} workers.")
contagem_sessao = 0
try:
with concurrent.futures.ProcessPoolExecutor(
max_workers=max_workers
max_workers=max_workers,
mp_context=multiprocessing.get_context("spawn"),
initializer=initialize_analysis_worker,
) as executor:
resultados_futuros = {
executor.submit(worker_analise, caminho): caminho for caminho in a_fazer
@@ -657,7 +674,7 @@ def main():
logging.error(f"Erro ao processar um dos arquivos no worker: {e}")
except KeyboardInterrupt:
print("\nParando paralelismo graciosamente...")
raise RuntimeError("Analise interrompida pelo operador.")
finally:
auditor.fechar() # Fecha o CSV com segurança
@@ -670,6 +687,12 @@ def main():
with open(ARQUIVO_FINAL_JSON, "w", encoding="utf-8") as f:
json.dump(lista_resultados, f, indent=4, ensure_ascii=False)
expected = {os.path.basename(path) for path in a_fazer}
obtained = {item.get("arquivo") for item in lista_resultados}
missing = expected - obtained
if missing:
raise RuntimeError(f"Analises ausentes para {len(missing)} audios: {sorted(missing)}")
print(f"Dados JSON: {ARQUIVO_FINAL_JSON}")
print(f"Auditoria CSV: {ARQUIVO_AUDITORIA}")
+13 -4
View File
@@ -10,7 +10,12 @@ import glob # Import necessário para ler múltiplos arquivos
from datetime import datetime, timedelta
# --- CONFIGURAÇÕES GERAIS ---
BASE_DIR = "/var/www/html/trens/src_mmpSearch"
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from etl_settings import DATA_ROOT, MODELS_ROOT, worker_count
BASE_DIR = str(DATA_ROOT)
LOG_DIR = os.path.join(BASE_DIR, "logs/classificacao_pedagogica")
os.makedirs(LOG_DIR, exist_ok=True)
TIMESTAMP = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
@@ -264,8 +269,7 @@ def main():
dados_projetos = carregar_todos_yamls(PASTA_LOTES_YAML)
if not dados_projetos:
logging.critical("Nenhum dado de projeto carregado. Encerrando.")
return
raise RuntimeError("Nenhum dado de projeto carregado.")
# 2. Carregar JSON de Áudio
lookup_audio = {}
@@ -275,13 +279,15 @@ def main():
logging.info(f"Lendo Análise de Áudio: {ARQUIVO_AUDIO_INPUT}")
with open(ARQUIVO_AUDIO_INPUT, "r", encoding="utf-8") as f:
lista_audio = json.load(f)
if not lista_audio:
raise RuntimeError("Analise de audio vazia.")
for item in lista_audio:
chave = normalizar_chave(item.get("arquivo", ""))
if chave:
lookup_audio[chave] = item
total_audio_carregado = len(lista_audio)
else:
logging.warning(f"Arquivo de áudio {ARQUIVO_AUDIO_INPUT} não encontrado.")
raise FileNotFoundError(f"Analise de audio ausente: {ARQUIVO_AUDIO_INPUT}")
db_final = []
estatisticas = {"Iniciante": 0, "Intermediário": 0, "Avançado": 0, "Total": 0}
@@ -434,6 +440,9 @@ def main():
)
continue
if len(db_final) != len(dados_projetos):
raise RuntimeError("Classificacao incompleta; consulte o log.")
# Salvar Resultado JSON
logging.info(f"Salvando JSON Final: {ARQUIVO_FINAL_OUTPUT}")
with open(ARQUIVO_FINAL_OUTPUT, "w", encoding="utf-8") as f: