File size: 4,327 Bytes
676c241 31b076e 676c241 6489332 676c241 6489332 676c241 6489332 676c241 6489332 676c241 6489332 676c241 6489332 676c241 6489332 676c241 6489332 676c241 6489332 676c241 a1f7a6b 676c241 6489332 676c241 6489332 676c241 6489332 676c241 6489332 676c241 a1f7a6b 6489332 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# app.py
import os
import math
import requests
from langdetect import detect
import gradio as gr
# -----------------------------------------------------------------------------
# Configuration
# -----------------------------------------------------------------------------
HF_API_URL = "https://api-inference.huggingface.co/models/YOUR_USERNAME/YOUR_MODEL"
HF_TOKEN = os.getenv("HF_TOKEN")
if HF_TOKEN is None:
raise ValueError("HF_TOKEN environment variable not set!")
HEADERS = {
"Authorization": f"Bearer {HF_TOKEN}",
"Content-Type": "application/json"
}
# -----------------------------------------------------------------------------
# Utility Functions
# -----------------------------------------------------------------------------
def entropy(probs):
"""Shannon entropy as epistemic uncertainty indicator."""
return -sum(p * math.log2(p) for p in probs if p > 0)
def normalize_labels(hf_output):
"""
Normalize Hugging Face output into a stable schema.
Expected HF format:
[
{"label": "HUMAN", "score": 0.73},
{"label": "AI", "score": 0.27}
]
"""
result = {item["label"].lower(): float(item["score"]) for item in hf_output}
human_p = result.get("human", 0.0)
ai_p = result.get("ai", 0.0)
return human_p, ai_p
def hf_inference(text):
payload = {"inputs": text}
r = requests.post(HF_API_URL, headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()
# -----------------------------------------------------------------------------
# Gradio Prediction Function
# -----------------------------------------------------------------------------
def analyze_text(text):
text = text.strip()
if not text:
return {"error": "Empty input"}
# 1. Language detection
try:
language = detect(text)
except Exception:
language = "unknown"
# 2. Hugging Face inference
hf_raw = hf_inference(text)
if not isinstance(hf_raw, list):
return {"error": "Unexpected model response", "raw": hf_raw}
human_p, ai_p = normalize_labels(hf_raw)
# 3. Decision
label = "Human" if human_p >= ai_p else "Machine"
confidence = max(human_p, ai_p)
# 4. Epistemic uncertainty
H = entropy([human_p, ai_p])
# 5. Explainability placeholder
explainability_stub = {
"method": "pending",
"note": (
"This model endpoint does not natively expose SHAP/LIME. "
"Post-hoc explainability must be computed locally using a "
"replicated model or proxy explainer."
),
"token_attributions": []
}
# 6. Fairness metadata
fairness_context = {
"language": language,
"human_probability": human_p,
"ai_probability": ai_p,
"entropy": H
}
response = {
"prediction": {
"label": label,
"confidence": round(confidence, 4)
},
"probabilities": {
"human": round(human_p, 4),
"machine": round(ai_p, 4)
},
"uncertainty": {
"entropy": round(H, 4),
"interpretation": (
"High entropy indicates epistemic ambiguity; "
"classification should be treated cautiously."
)
},
"linguistic_context": {
"detected_language": language
},
"explainability": explainability_stub,
"fairness_audit_fields": fairness_context
}
return response
# -----------------------------------------------------------------------------
# Gradio Interface
# -----------------------------------------------------------------------------
iface = gr.Interface(
fn=analyze_text,
inputs=gr.Textbox(lines=5, placeholder="Enter text here..."),
outputs=gr.JSON(),
title="HATA: Human-AI Text Attribution",
description=(
"Detect whether text is human-written or AI-generated.\n"
"Supports uncertainty estimation, language-aware auditing, "
"and XAI-ready outputs."
)
)
# -----------------------------------------------------------------------------
# Launch Gradio App
# -----------------------------------------------------------------------------
if __name__ == "__main__":
iface.launch(server_name="0.0.0.0", server_port=7860)
|