thaidinhz1 commited on
Commit
4455cfa
·
1 Parent(s): c76b5a4

fix: eval dùng 8b-instant + checkpoint resume + cắt context để tiết kiệm token

Browse files
Files changed (1) hide show
  1. evaluate.py +50 -18
evaluate.py CHANGED
@@ -21,6 +21,22 @@ rag_module.LLM_MODEL = JUDGE_MODEL
21
  from src.rag import answer as rag_answer
22
  print("rag ok")
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  def judge(prompt: str) -> float:
26
  """Gọi LLM judge, trả về score 0.0-1.0."""
@@ -39,7 +55,7 @@ def judge(prompt: str) -> float:
39
 
40
 
41
  def eval_faithfulness(question: str, answer: str, contexts: list[str]) -> float:
42
- context_text = "\n".join(contexts)
43
  prompt = f"""Đánh giá xem câu trả lời có trung thực với ngữ cảnh không.
44
  Chỉ trả về một số từ 0.0 đến 1.0 (1.0 = hoàn toàn trung thực, 0.0 = bịa đặt).
45
 
@@ -62,7 +78,7 @@ Score:"""
62
 
63
 
64
  def eval_context_recall(question: str, ground_truth: str, contexts: list[str]) -> float:
65
- context_text = "\n".join(contexts)
66
  prompt = f"""Đánh giá xem ngữ cảnh có chứa đủ thông tin để trả lời câu hỏi theo đáp án chuẩn không.
67
  Chỉ trả về một số từ 0.0 đến 1.0 (1.0 = đủ thông tin, 0.0 = thiếu hoàn toàn).
68
 
@@ -74,17 +90,36 @@ Score:"""
74
  return judge(prompt)
75
 
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  def evaluate(golden_set_path: str = "data/golden_set.json", sample: int = 20):
78
  with open(golden_set_path, encoding="utf-8") as f:
79
  golden = json.load(f)
80
 
81
- # Lấy sample câu hỏi có ground_truth thực (bỏ out_of_scope)
82
  items = [q for q in golden if q.get("type") != "out_of_scope"][:sample]
83
 
84
- results = []
85
- print(f"Đánh giá {len(items)} câu hỏi...\n")
 
 
86
 
87
- for i, item in enumerate(items, 1):
 
 
88
  question = item["question"]
89
  ground_truth = item["answer"]
90
 
@@ -108,24 +143,15 @@ def evaluate(golden_set_path: str = "data/golden_set.json", sample: int = 20):
108
  })
109
 
110
  print(f" Faithfulness: {faith:.2f} | Relevancy: {relevancy:.2f} | Recall: {recall:.2f}")
111
- time.sleep(2) # tránh rate limit
 
112
 
113
  except Exception as e:
114
  print(f" Lỗi: {e}")
115
  time.sleep(5)
116
 
117
  if results:
118
- avg_faith = sum(r["faithfulness"] for r in results) / len(results)
119
- avg_rel = sum(r["answer_relevancy"] for r in results) / len(results)
120
- avg_recall = sum(r["context_recall"] for r in results) / len(results)
121
-
122
- print(f"\n{'='*50}")
123
- print(f"KẾT QUẢ ĐÁNH GIÁ ({len(results)} câu hỏi)")
124
- print(f"{'='*50}")
125
- print(f"Faithfulness: {avg_faith:.3f}")
126
- print(f"Answer Relevancy: {avg_rel:.3f}")
127
- print(f"Context Recall: {avg_recall:.3f}")
128
- print(f"Average: {(avg_faith + avg_rel + avg_recall) / 3:.3f}")
129
 
130
  with open("eval_results.json", "w", encoding="utf-8") as f:
131
  json.dump({
@@ -133,11 +159,17 @@ def evaluate(golden_set_path: str = "data/golden_set.json", sample: int = 20):
133
  "faithfulness": avg_faith,
134
  "answer_relevancy": avg_rel,
135
  "context_recall": avg_recall,
 
136
  },
137
  "details": results,
138
  }, f, ensure_ascii=False, indent=2)
139
  print("\nĐã lưu chi tiết vào eval_results.json")
140
 
 
 
 
 
 
141
 
142
  if __name__ == "__main__":
143
  import sys
 
21
  from src.rag import answer as rag_answer
22
  print("rag ok")
23
 
24
+ CHECKPOINT_PATH = "eval_checkpoint.json"
25
+
26
+
27
+ def _save_checkpoint(results: list):
28
+ with open(CHECKPOINT_PATH, "w", encoding="utf-8") as f:
29
+ json.dump(results, f, ensure_ascii=False, indent=2)
30
+
31
+
32
+ def _load_checkpoint() -> list:
33
+ if os.path.exists(CHECKPOINT_PATH):
34
+ with open(CHECKPOINT_PATH, encoding="utf-8") as f:
35
+ data = json.load(f)
36
+ print(f"Tiếp tục từ checkpoint: {len(data)} câu đã xong.")
37
+ return data
38
+ return []
39
+
40
 
41
  def judge(prompt: str) -> float:
42
  """Gọi LLM judge, trả về score 0.0-1.0."""
 
55
 
56
 
57
  def eval_faithfulness(question: str, answer: str, contexts: list[str]) -> float:
58
+ context_text = "\n".join(c[:600] for c in contexts[:3]) # top-3, max 600 chars mỗi chunk
59
  prompt = f"""Đánh giá xem câu trả lời có trung thực với ngữ cảnh không.
60
  Chỉ trả về một số từ 0.0 đến 1.0 (1.0 = hoàn toàn trung thực, 0.0 = bịa đặt).
61
 
 
78
 
79
 
80
  def eval_context_recall(question: str, ground_truth: str, contexts: list[str]) -> float:
81
+ context_text = "\n".join(c[:600] for c in contexts[:3])
82
  prompt = f"""Đánh giá xem ngữ cảnh có chứa đủ thông tin để trả lời câu hỏi theo đáp án chuẩn không.
83
  Chỉ trả về một số từ 0.0 đến 1.0 (1.0 = đủ thông tin, 0.0 = thiếu hoàn toàn).
84
 
 
90
  return judge(prompt)
91
 
92
 
93
+ def _print_summary(results: list):
94
+ avg_faith = sum(r["faithfulness"] for r in results) / len(results)
95
+ avg_rel = sum(r["answer_relevancy"] for r in results) / len(results)
96
+ avg_recall = sum(r["context_recall"] for r in results) / len(results)
97
+
98
+ print(f"\n{'='*50}")
99
+ print(f"KẾT QUẢ ĐÁNH GIÁ ({len(results)} câu hỏi)")
100
+ print(f"Judge model: {JUDGE_MODEL}")
101
+ print(f"{'='*50}")
102
+ print(f"Faithfulness: {avg_faith:.3f}")
103
+ print(f"Answer Relevancy: {avg_rel:.3f}")
104
+ print(f"Context Recall: {avg_recall:.3f}")
105
+ print(f"Average: {(avg_faith + avg_rel + avg_recall) / 3:.3f}")
106
+ return avg_faith, avg_rel, avg_recall
107
+
108
+
109
  def evaluate(golden_set_path: str = "data/golden_set.json", sample: int = 20):
110
  with open(golden_set_path, encoding="utf-8") as f:
111
  golden = json.load(f)
112
 
 
113
  items = [q for q in golden if q.get("type") != "out_of_scope"][:sample]
114
 
115
+ # Resume từ checkpoint nếu có
116
+ results = _load_checkpoint()
117
+ done_questions = {r["question"] for r in results}
118
+ remaining = [it for it in items if it["question"] not in done_questions]
119
 
120
+ print(f"Đánh giá {len(items)} câu hỏi ({len(remaining)} còn lại)...\n")
121
+
122
+ for i, item in enumerate(remaining, len(results) + 1):
123
  question = item["question"]
124
  ground_truth = item["answer"]
125
 
 
143
  })
144
 
145
  print(f" Faithfulness: {faith:.2f} | Relevancy: {relevancy:.2f} | Recall: {recall:.2f}")
146
+ _save_checkpoint(results)
147
+ time.sleep(2)
148
 
149
  except Exception as e:
150
  print(f" Lỗi: {e}")
151
  time.sleep(5)
152
 
153
  if results:
154
+ avg_faith, avg_rel, avg_recall = _print_summary(results)
 
 
 
 
 
 
 
 
 
 
155
 
156
  with open("eval_results.json", "w", encoding="utf-8") as f:
157
  json.dump({
 
159
  "faithfulness": avg_faith,
160
  "answer_relevancy": avg_rel,
161
  "context_recall": avg_recall,
162
+ "judge_model": JUDGE_MODEL,
163
  },
164
  "details": results,
165
  }, f, ensure_ascii=False, indent=2)
166
  print("\nĐã lưu chi tiết vào eval_results.json")
167
 
168
+ # Xóa checkpoint khi hoàn thành
169
+ if len(results) == len(items) and os.path.exists(CHECKPOINT_PATH):
170
+ os.remove(CHECKPOINT_PATH)
171
+ print("Đã xóa checkpoint.")
172
+
173
 
174
  if __name__ == "__main__":
175
  import sys