Spaces:
Sleeping
Sleeping
Initial Streamlit dashboard
Browse files
app.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import requests
|
| 3 |
+
import pandas as pd
|
| 4 |
+
|
| 5 |
+
st.set_page_config(page_title="LLM Hallucination Detector", layout="wide")
|
| 6 |
+
|
| 7 |
+
st.title("🔍 LLM Evaluation & Hallucination Detection Framework")
|
| 8 |
+
|
| 9 |
+
API_URL = "https://huggingface.co/spaces/sha6th/llm-eval-ap"
|
| 10 |
+
|
| 11 |
+
# --- Tabs ---
|
| 12 |
+
tab1, tab2 = st.tabs(["Evaluate New Response", "History"])
|
| 13 |
+
|
| 14 |
+
# ---------------- TAB 1: Evaluate ----------------
|
| 15 |
+
with tab1:
|
| 16 |
+
st.subheader("Evaluate an LLM Response")
|
| 17 |
+
|
| 18 |
+
context = st.text_area("Context (Ground Truth)", height=100)
|
| 19 |
+
question = st.text_input("Question")
|
| 20 |
+
llm_response = st.text_area("LLM Response", height=100)
|
| 21 |
+
|
| 22 |
+
if st.button("Evaluate"):
|
| 23 |
+
if not context.strip() or not question.strip() or not llm_response.strip():
|
| 24 |
+
st.error("All fields are required.")
|
| 25 |
+
else:
|
| 26 |
+
with st.spinner("Running evaluation..."):
|
| 27 |
+
response = requests.post(f"{API_URL}/evaluate", json={
|
| 28 |
+
"context": context,
|
| 29 |
+
"question": question,
|
| 30 |
+
"llm_response": llm_response
|
| 31 |
+
})
|
| 32 |
+
|
| 33 |
+
if response.status_code == 200:
|
| 34 |
+
result = response.json()
|
| 35 |
+
|
| 36 |
+
verdict = result["final_verdict"]
|
| 37 |
+
if verdict == "Hallucinated":
|
| 38 |
+
st.error(f"**Verdict: {verdict}**")
|
| 39 |
+
elif verdict == "Faithful":
|
| 40 |
+
st.success(f"**Verdict: {verdict}**")
|
| 41 |
+
else:
|
| 42 |
+
st.warning(f"**Verdict: {verdict}**")
|
| 43 |
+
|
| 44 |
+
col1, col2, col3, col4 = st.columns(4)
|
| 45 |
+
col1.metric("Cosine (Relevance)", result["cosine"]["score"], result["cosine"]["verdict"])
|
| 46 |
+
col2.metric("BERTScore (Faithfulness)", result["bert_score"]["score"], result["bert_score"]["verdict"])
|
| 47 |
+
col3.metric("NLI", result["nli"]["score"], result["nli"]["verdict"])
|
| 48 |
+
col4.metric("Fluency", "-", result["fluency"]["verdict"])
|
| 49 |
+
|
| 50 |
+
st.json(result)
|
| 51 |
+
else:
|
| 52 |
+
st.error(f"Error: {response.json()['detail']}")
|
| 53 |
+
|
| 54 |
+
# ---------------- TAB 2: History ----------------
|
| 55 |
+
with tab2:
|
| 56 |
+
st.subheader("Past Evaluations")
|
| 57 |
+
|
| 58 |
+
if st.button("Refresh History"):
|
| 59 |
+
st.rerun()
|
| 60 |
+
|
| 61 |
+
response = requests.get(f"{API_URL}/history")
|
| 62 |
+
|
| 63 |
+
if response.status_code == 200:
|
| 64 |
+
data = response.json()
|
| 65 |
+
if data["total"] == 0:
|
| 66 |
+
st.info("No evaluations yet.")
|
| 67 |
+
else:
|
| 68 |
+
df = pd.DataFrame(data["evaluations"])
|
| 69 |
+
df = df[["id", "question", "llm_response", "final_verdict", "created_at"]]
|
| 70 |
+
st.dataframe(df, use_container_width=True)
|
| 71 |
+
|
| 72 |
+
st.subheader("Verdict Distribution")
|
| 73 |
+
verdict_counts = df["final_verdict"].value_counts()
|
| 74 |
+
st.bar_chart(verdict_counts)
|
| 75 |
+
else:
|
| 76 |
+
st.error("Could not fetch history.")
|