confereai-dev / execution /inference_ast.py
TEDDyx86's picture
ML Upgrade: HyperMoon sovereignty, dynamic quantization, and batch processing v2.4
72892b6
import torch
import librosa
import numpy as np
import sys
from transformers import AutoFeatureExtractor, ASTForAudioClassification
# Modelo AST (Audio Spectrogram Transformer)
# Usamos o modelo base do MIT como referência para análise espectral
MODEL_NAME = "MIT/ast-finetuned-audioset-10-10-0.4593"
# Singleton para carregar o modelo apenas uma vez
_extractor = None
_model = None
def get_ast_resources():
global _extractor, _model
if _extractor is None or _model is None:
print(f"Carregando motor AST: {MODEL_NAME}...")
_extractor = AutoFeatureExtractor.from_pretrained(MODEL_NAME)
model = ASTForAudioClassification.from_pretrained(MODEL_NAME)
# --- OTIMIZAÇÃO: Quantização Dinâmica (CPU) ---
if not torch.cuda.is_available():
print("Aplicando Quantização Dinâmica no AST...", file=sys.stderr)
model = torch.quantization.quantize_dynamic(
model, {torch.nn.Linear}, dtype=torch.qint8
)
_model = model
_model.eval()
return _extractor, _model
def run_ast_inference(file_path):
"""
Executa a análise via Audio Spectrogram Transformer.
Focado em detectar artefatos de compressão e texturas sintéticas.
"""
try:
extractor, model = get_ast_resources()
# Carrega áudio (resample para 16kHz conforme exigido pelo AST)
audio, _ = librosa.load(file_path, sr=16000)
# Padronização para 10 segundos
if len(audio) > 160000:
audio = audio[:160000]
else:
audio = np.pad(audio, (0, 160000 - len(audio)), mode='constant')
# Extração de Features
inputs = extractor(audio, sampling_rate=16000, return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
# Refinamento do Score Espectral:
# Em vez de apenas variância, olhamos para a dispersão das top-k classes.
# Vozes sintéticas tendem a gerar incerteza em modelos genéricos.
probs = torch.nn.functional.softmax(logits, dim=-1)
# Cálculo de Entropia como medida de 'estranheza' do sinal
entropy = -torch.sum(probs * torch.log(probs + 1e-9)).item()
# Normalização (Heurística baseada em observação do AudioSet)
# Sinais naturais tendem a ter entropia mais baixa (classes mais claras)
# Sinais sintéticos/ruidosos espalham a probabilidade.
risk_score = min(max((entropy - 3.0) / 4.0, 0.0), 1.0)
return {
"risk_score": risk_score,
"engine": "AST-Transformer",
"status": "success"
}
except Exception as e:
print(f"Erro no motor AST: {e}")
return {"error": str(e), "risk_score": 0.0}
if __name__ == "__main__":
# Teste simples
import sys
if len(sys.argv) > 1:
print(run_ast_inference(sys.argv[1]))