sha6th commited on
Commit
1be5e4e
·
1 Parent(s): 649399f

Separate LLM and RAG evaluation

Browse files
Files changed (3) hide show
  1. llm-eval-dashboard +1 -1
  2. main.py +51 -1
  3. src/aggregator.py +54 -0
llm-eval-dashboard CHANGED
@@ -1 +1 @@
1
- Subproject commit 1e3cca61e97ba9dcc2fc76eab40e0e0c7ed687a2
 
1
+ Subproject commit 5e1c5e3efe5a71746d0a07e35226b77caef3d743
main.py CHANGED
@@ -1,9 +1,9 @@
1
  from fastapi import FastAPI, HTTPException
2
  from pydantic import BaseModel
3
  from typing import List
4
- from src.aggregator import evaluate_all
5
  from src.database import init_db, save_evaluation
6
  import traceback
 
7
 
8
  app = FastAPI(
9
  title="LLM Evaluation & Hallucination Detection Framework",
@@ -20,6 +20,11 @@ class EvalResponse(BaseModel):
20
  retrieval_evaluation: dict
21
  generation_evaluation: dict
22
 
 
 
 
 
 
23
  @app.post("/evaluate", response_model=EvalResponse)
24
  def evaluate(request: EvalRequest):
25
  if not request.question.strip():
@@ -47,6 +52,51 @@ def evaluate(request: EvalRequest):
47
 
48
  init_db()
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  @app.get("/")
52
  def home():
 
1
  from fastapi import FastAPI, HTTPException
2
  from pydantic import BaseModel
3
  from typing import List
 
4
  from src.database import init_db, save_evaluation
5
  import traceback
6
+ from src.aggregator import evaluate_all, evaluate_generation_only
7
 
8
  app = FastAPI(
9
  title="LLM Evaluation & Hallucination Detection Framework",
 
20
  retrieval_evaluation: dict
21
  generation_evaluation: dict
22
 
23
+ class LLMOnlyEvalRequest(BaseModel):
24
+ question: str
25
+ context: str
26
+ llm_response: str
27
+
28
  @app.post("/evaluate", response_model=EvalResponse)
29
  def evaluate(request: EvalRequest):
30
  if not request.question.strip():
 
52
 
53
  init_db()
54
 
55
+ @app.post("/evaluate-llm")
56
+ def evaluate_llm(request: LLMOnlyEvalRequest):
57
+
58
+ if not request.question.strip():
59
+ raise HTTPException(
60
+ status_code=400,
61
+ detail="Question cannot be empty"
62
+ )
63
+
64
+ if not request.context.strip():
65
+ raise HTTPException(
66
+ status_code=400,
67
+ detail="Context cannot be empty"
68
+ )
69
+
70
+ if not request.llm_response.strip():
71
+ raise HTTPException(
72
+ status_code=400,
73
+ detail="LLM response cannot be empty"
74
+ )
75
+
76
+ try:
77
+
78
+ result = evaluate_generation_only(
79
+ question=request.question,
80
+ context=request.context,
81
+ llm_response=request.llm_response
82
+ )
83
+
84
+ save_evaluation(
85
+ context=request.context,
86
+ question=request.question,
87
+ llm_response=request.llm_response,
88
+ result=result
89
+ )
90
+
91
+ return result
92
+
93
+ except Exception as e:
94
+
95
+ raise HTTPException(
96
+ status_code=500,
97
+ detail=str(e) + "\n" + traceback.format_exc()
98
+ )
99
+
100
 
101
  @app.get("/")
102
  def home():
src/aggregator.py CHANGED
@@ -41,4 +41,58 @@ def evaluate_all(question: str, retrieved_contexts: list, llm_response: str) ->
41
  "bert_score": bert_result,
42
  "nli": nli_result
43
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
 
41
  "bert_score": bert_result,
42
  "nli": nli_result
43
  }
44
+ }
45
+
46
+ def evaluate_generation_only(
47
+ question: str,
48
+ context: str,
49
+ llm_response: str
50
+ ) -> dict:
51
+
52
+ cosine_result = evaluate_cosine(
53
+ question,
54
+ llm_response
55
+ )
56
+
57
+ fluency_result = evaluate_fluency(
58
+ llm_response
59
+ )
60
+
61
+ bert_result = evaluate_bert_score(
62
+ context,
63
+ llm_response
64
+ )
65
+
66
+ nli_result = evaluate_nli(
67
+ context,
68
+ llm_response
69
+ )
70
+
71
+ # Generation-only final verdict
72
+ if nli_result["verdict"] == "Hallucinated":
73
+ final_verdict = "Hallucinated"
74
+
75
+ elif (
76
+ nli_result["verdict"] == "Faithful"
77
+ and bert_result["score"] >= 0.70
78
+ ):
79
+ final_verdict = "Faithful"
80
+
81
+ elif (
82
+ cosine_result["verdict"] == "Irrelevant"
83
+ and len(llm_response.split()) > 2
84
+ ):
85
+ final_verdict = "Irrelevant"
86
+
87
+ else:
88
+ final_verdict = "Unverifiable"
89
+
90
+ return {
91
+ "final_verdict": final_verdict,
92
+ "generation_evaluation": {
93
+ "cosine": cosine_result,
94
+ "fluency": fluency_result,
95
+ "bert_score": bert_result,
96
+ "nli": nli_result
97
+ }
98
  }