truthlens-ml-api / api /service.py
Param0304's picture
Deploy TruthLens ML API to Hugging Face Space
3abf967
Raw History Blame Contribute Delete
3.24 kB
import os
import sys
from typing import Dict, Any, List, Optional
import torch
# Add ml/src to Python path to reuse existing wrappers without duplication
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SRC_DIR = os.path.join(BASE_DIR, "src")
if SRC_DIR not in sys.path:
sys.path.insert(0, SRC_DIR)
from fact_check_pipeline import FactCheckPipeline
class MLInferenceService:
_instance = None
def __init__(self):
cuda_available = torch.cuda.is_available()
device_name = torch.cuda.get_device_name(0) if cuda_available else "CPU"
print("TruthLens ML Service")
print(f"Device: {device_name}")
print(f"CUDA: {cuda_available}")
# Initialize the pipeline (which loads Model A & Model B onto GPU once)
self.pipeline = FactCheckPipeline.get_instance()
self.cuda_available = cuda_available
self.device_name = device_name
@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
def predict(self, claim: str, evidence: List[str], threshold: Optional[float] = None) -> Dict[str, Any]:
raw_result = self.pipeline.run_fact_check(
claim=claim,
candidate_evidence=evidence,
custom_threshold=threshold
)
# Format output into camelCase schema expected by API
evidence_results = []
for ev in raw_result.get("evidence_results", []):
evidence_results.append({
"evidence": ev["evidence"],
"relevanceLabel": ev["relevance_label"],
"relevanceScore": float(ev["relevance_score"])
})
verif = raw_result.get("verification", {})
probabilities = verif.get("probabilities", {})
raw_indiv = verif.get("individual_verifications", [])
individual_verifications = []
for iv in raw_indiv:
probs = iv.get("probabilities", {})
individual_verifications.append({
"evidence": iv.get("evidence", ""),
"relevanceScore": float(iv.get("relevance_score", 0.0)),
"label": iv.get("label", "NOT_ENOUGH_INFO"),
"confidence": float(iv.get("confidence", 0.0)),
"probabilities": {
"SUPPORTS": float(probs.get("SUPPORTS", 0.0)),
"REFUTES": float(probs.get("REFUTES", 0.0)),
"NOT_ENOUGH_INFO": float(probs.get("NOT_ENOUGH_INFO", 0.0)),
}
})
return {
"claim": raw_result.get("claim", claim),
"evidenceResults": evidence_results,
"verification": {
"label": verif.get("label", "NOT_ENOUGH_INFO"),
"confidence": float(verif.get("confidence", 0.0)),
"probabilities": {
"SUPPORTS": float(probabilities.get("SUPPORTS", 0.0)),
"REFUTES": float(probabilities.get("REFUTES", 0.0)),
"NOT_ENOUGH_INFO": float(probabilities.get("NOT_ENOUGH_INFO", 0.0)),
},
"individualVerifications": individual_verifications
}
}