corrigindo upload

This commit is contained in:
JotaChina committed 2026-04-04 10:57:30 -03:00
1 parent 73693e5da9
commit d2a68fa744
9 files changed
+4295 -74

No files matched your search

+82 -35
View File
@@ -1,5 +1,4 @@
import os
import sys
import multiprocessing
import concurrent.futures # NOVO: Necessário para usar o ProcessPoolExecutor
import csv
@@ -7,6 +6,7 @@ import time
import glob
from datetime import datetime, timedelta
# ================= 1. LIMITADOR DE CPU DINÂMICO =================
def configurar_limites_cpu():
try:
@@ -28,6 +28,7 @@ def configurar_limites_cpu():
except Exception as e:
print(f"Aviso: Não foi possível limitar CPU automaticamente: {e}")
configurar_limites_cpu()
# ================= IMPORTS =================
@@ -84,6 +85,7 @@ GLOBAL_EMBEDDING = None
GLOBAL_CLASSIFIER = None
GLOBAL_CLASSES = None
# ================= CLASSE DE AUDITORIA OTIMIZADA =================
class Auditoria:
def __init__(self, arquivo_csv):
@@ -110,7 +112,9 @@ class Auditoria:
)
self.file.flush()
def registrar_processamento(self, nome_arquivo, tamanho_bytes, duracao_audio, tempo_gasto):
def registrar_processamento(
self, nome_arquivo, tamanho_bytes, duracao_audio, tempo_gasto
):
try:
ram_mb = self.process.memory_info().rss / (1024 * 1024)
cpu_pct = self.process.cpu_percent(interval=None)
@@ -134,7 +138,7 @@ class Auditoria:
logging.error(f"Erro ao auditar arquivo: {e}")
def verificar_marco(self, contagem):
pass # Você pode customizar logs de progresso aqui depois se quiser
pass # Você pode customizar logs de progresso aqui depois se quiser
def fechar(self):
try:
@@ -145,6 +149,7 @@ class Auditoria:
# ================= FUNÇÕES AUXILIARES =================
def verificar_memoria_segura(tamanho_arquivo_bytes):
mem = psutil.virtual_memory()
livre_mb = mem.available / (1024 * 1024)
@@ -225,7 +230,9 @@ def carregar_database_yaml():
logging.error(f"Erro ao ler lote {arquivo}: {e}")
print(f"X Erro ao ler {os.path.basename(arquivo)}")
print(f"--- Total de Projetos no DB (Memória): {len(db)} (de {total_carregados} lidos) ---")
print(
f"--- Total de Projetos no DB (Memória): {len(db)} (de {total_carregados} lidos) ---"
)
return db
@@ -300,14 +307,14 @@ def calcular_complexidade(projeto_yaml):
score += num_fx * W_FX
stats["num_effects"] += num_fx
if score <= 15:
estrelas = 1
elif score <= 40:
estrelas = 2
if score <= 120:
estrelas = 4
elif score <= 80:
estrelas = 3
elif score <= 120:
estrelas = 4
elif score <= 40:
estrelas = 2
elif score <= 15:
estrelas = 1
else:
estrelas = 5
@@ -316,6 +323,7 @@ def calcular_complexidade(projeto_yaml):
# ================= NÚCLEO DE ANÁLISE =================
def detectar_estrutura(audio_vec, sample_rate, duration):
try:
if duration < 30:
@@ -496,7 +504,9 @@ def analisar_faixa(caminho_arquivo, embedding_model, classifier_model, classes_r
metadata["analise_ia"] = {
"genero_macro": genero_pai,
"estilo_principal": tags_detectadas[0]["tag"] if tags_detectadas else "Unknown",
"estilo_principal": tags_detectadas[0]["tag"]
if tags_detectadas
else "Unknown",
"nuvem_tags": tags_detectadas,
}
@@ -509,7 +519,7 @@ def analisar_faixa(caminho_arquivo, embedding_model, classifier_model, classes_r
metadata["analise_ia"] = {"erro": msg}
else:
metadata["analise_ia"] = {"status": "Modelos nao carregados"}
# Limpeza Limpa
del audio_hq
del audio_hq_vec
@@ -525,12 +535,13 @@ def worker_analise(caminho):
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
global DATABASE_YAML, GLOBAL_EMBEDDING, GLOBAL_CLASSIFIER, GLOBAL_CLASSES
DATABASE_YAML = carregar_database_yaml()
ja_processados, lista_resultados = carregar_checkpoint()
@@ -540,7 +551,7 @@ def main():
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]
@@ -549,11 +560,27 @@ def main():
print(f"Auditoria será salva em: {ARQUIVO_AUDITORIA}")
# === CARREGAMENTO MODELOS GLOBAIS ===
path_embed = MODELO_EMBEDDING if os.path.exists(MODELO_EMBEDDING) else os.path.join(BASE_DIR, MODELO_EMBEDDING)
path_class = MODELO_CLASSIFIER if os.path.exists(MODELO_CLASSIFIER) else os.path.join(BASE_DIR, MODELO_CLASSIFIER)
path_json = MODELO_CLASSES if os.path.exists(MODELO_CLASSES) else os.path.join(BASE_DIR, MODELO_CLASSES)
path_embed = (
MODELO_EMBEDDING
if os.path.exists(MODELO_EMBEDDING)
else os.path.join(BASE_DIR, MODELO_EMBEDDING)
)
path_class = (
MODELO_CLASSIFIER
if os.path.exists(MODELO_CLASSIFIER)
else os.path.join(BASE_DIR, MODELO_CLASSIFIER)
)
path_json = (
MODELO_CLASSES
if os.path.exists(MODELO_CLASSES)
else os.path.join(BASE_DIR, MODELO_CLASSES)
)
if os.path.exists(path_embed) and os.path.exists(path_class) and os.path.exists(path_json):
if (
os.path.exists(path_embed)
and os.path.exists(path_class)
and os.path.exists(path_json)
):
print("--- Carregando Modelos de IA ---")
try:
with open(path_json, "r") as f:
@@ -561,13 +588,23 @@ def main():
print("[1/2] Carregando Extrator de Embeddings...")
if hasattr(es, "TensorflowPredictEffnetDiscogs"):
GLOBAL_EMBEDDING = es.TensorflowPredictEffnetDiscogs(graphFilename=path_embed, output="PartitionedCall:1")
GLOBAL_EMBEDDING = es.TensorflowPredictEffnetDiscogs(
graphFilename=path_embed, output="PartitionedCall:1"
)
else:
print(" -> Usando TensorflowPredict genérico.")
GLOBAL_EMBEDDING = es.TensorflowPredict(graphFilename=path_embed, input="serving_default_model_Placeholder", output="PartitionedCall:1")
GLOBAL_EMBEDDING = es.TensorflowPredict(
graphFilename=path_embed,
input="serving_default_model_Placeholder",
output="PartitionedCall:1",
)
print(" -> Embeddings carregados com sucesso.")
GLOBAL_CLASSIFIER = es.TensorflowPredict2D(graphFilename=path_class, input="serving_default_model_Placeholder", output="PartitionedCall:0")
GLOBAL_CLASSIFIER = es.TensorflowPredict2D(
graphFilename=path_class,
input="serving_default_model_Placeholder",
output="PartitionedCall:0",
)
print("[2/2] Classificador de Gênero carregado.")
except Exception as e:
@@ -580,40 +617,50 @@ def main():
if total == 0:
print("Tudo atualizado.")
return
# ProcessPoolExecutor lidará com N filas ao mesmo tempo
# ProcessPoolExecutor lidará com N filas ao mesmo tempo
max_workers = max(1, multiprocessing.cpu_count() - 1)
print(f"-> Iniciando processamento paralelo com {max_workers} workers.")
contagem_sessao = 0
try:
with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
resultados_futuros = {executor.submit(worker_analise, caminho): caminho for caminho in a_fazer}
with concurrent.futures.ProcessPoolExecutor(
max_workers=max_workers
) as executor:
resultados_futuros = {
executor.submit(worker_analise, caminho): caminho for caminho in a_fazer
}
# O as_completed processa os que terminam mais rápido em vez de travar na ordem
for future in tqdm(concurrent.futures.as_completed(resultados_futuros), total=len(a_fazer), unit="track"):
for future in tqdm(
concurrent.futures.as_completed(resultados_futuros),
total=len(a_fazer),
unit="track",
):
try:
res, duracao, tempo_gasto = future.result()
caminho = resultados_futuros[future]
if res:
salvar_progresso(res)
lista_resultados.append(res)
tamanho = os.path.getsize(caminho)
auditor.registrar_processamento(res['arquivo'], tamanho, duracao, tempo_gasto)
auditor.registrar_processamento(
res["arquivo"], tamanho, duracao, tempo_gasto
)
contagem_sessao += 1
auditor.verificar_marco(contagem_sessao)
except Exception as e:
logging.error(f"Erro ao processar um dos arquivos no worker: {e}")
except KeyboardInterrupt:
print("\nParando paralelismo graciosamente...")
finally:
auditor.fechar() # Fecha o CSV com segurança
auditor.fechar() # Fecha o CSV com segurança
tempo_total_sessao = time.time() - auditor.inicio_global
print("\n--- FIM DO PROCESSAMENTO ---")
@@ -628,4 +675,4 @@ def main():
if __name__ == "__main__":
main()
main()