MakiAi commited on
Commit
53ecd88
·
2 Parent(s): c3ef474 7512c36

Merge feature/llm-evaluation-system

Browse files
Files changed (3) hide show
  1. README.md +9 -1
  2. docs/README.en.md +34 -25
  3. sandbox/LLMs_as_a_Judge_TOHO_V2.md +544 -0
README.md CHANGED
@@ -101,7 +101,15 @@ license: mit
101
  - → 文脈情報を活用した高精度な質問生成と回答の整合性チェック
102
  - → 詳細は [`context_aware_Reflexive_qa_generator_V2.md`](sandbox/context_aware_Reflexive_qa_generator_V2.md) をご参照ください。
103
  - [📒ノートブックはこちら](https://colab.research.google.com/drive/1OYdgAuXHbl-0LUJgkLl_VqknaAEmAm0S?usp=sharing)
104
-
 
 
 
 
 
 
 
 
105
  ## 🛠️ 環境構築
106
 
107
  1. リポジトリのクローン:
 
101
  - → 文脈情報を活用した高精度な質問生成と回答の整合性チェック
102
  - → 詳細は [`context_aware_Reflexive_qa_generator_V2.md`](sandbox/context_aware_Reflexive_qa_generator_V2.md) をご参照ください。
103
  - [📒ノートブックはこちら](https://colab.research.google.com/drive/1OYdgAuXHbl-0LUJgkLl_VqknaAEmAm0S?usp=sharing)
104
+
105
+ ### LLM評価システム (LLMs as a Judge)
106
+ - LLMを評価者として活用する高度な品質評価システム
107
+ - → 質問、模範解答、LLMの回答を4段階スケールで自動評価
108
+ - → エラーハンドリングとリトライ機能による堅牢な設計
109
+ - → CSV、HTML形式での詳細な評価レポート生成
110
+ - → 詳細は [`LLMs_as_a_Judge_TOHO_V2.md`](sandbox/LLMs_as_a_Judge_TOHO_V2.md) をご参照ください。
111
+ - [📒ノートブックはこちら](https://colab.research.google.com/drive/1Zjw3sOMa2v5RFD8dFfxMZ4NDGFoQOL7s?usp=sharing
112
+
113
  ## 🛠️ 環境構築
114
 
115
  1. リポジトリのクローン:
docs/README.en.md CHANGED
@@ -31,7 +31,7 @@ license: mit
31
  </p>
32
 
33
  <h2 align="center">
34
- Llama Model Fine-tuning Experiment Environment
35
  </h2>
36
 
37
  <p align="center">
@@ -44,7 +44,7 @@ license: mit
44
 
45
  ## 🚀 Project Overview
46
 
47
- **Llama-finetune-sandbox** provides an experimental environment for learning and validating Llama model fine-tuning. You can try various fine-tuning methods, customize models, and evaluate performance. It caters to a wide range of users, from beginners to researchers. Version 0.3.0 included improved documentation and an updated English README.
48
 
49
 
50
  ## ✨ Key Features
@@ -53,14 +53,14 @@ license: mit
53
  - LoRA (Low-Rank Adaptation)
54
  - QLoRA (Quantized LoRA)
55
 
56
- 2. **Flexible Model Configuration**:
57
  - Customizable maximum sequence length
58
  - Various quantization options
59
  - Multiple attention mechanisms
60
 
61
- 3. **Experiment Environment**:
62
- - Performance evaluation tools (added in v0.3.0, later removed)
63
- - Optimized memory usage
64
  - Visualization of experimental results
65
 
66
  ## 📚 Examples
@@ -68,31 +68,39 @@ license: mit
68
  This repository includes the following examples:
69
 
70
  ### Fast Fine-tuning using Unsloth
71
- - Implementation of fast fine-tuning for Llama-3.2-1B/3B models.
72
- - → See [`Llama_3_2_1B+3B_Conversational_+_2x_faster_finetuning_JP.md`](sandbox/Llama_3_2_1B+3B_Conversational_+_2x_faster_finetuning_JP.md) for details. (Japanese)
73
- - → Use [this](https://huggingface.co/spaces/MakiAi/JupytextWebUI) to convert from markdown to notebook format.
74
  - [📒Notebook here](https://colab.research.google.com/drive/1AjtWF2vOEwzIoCMmlQfSTYCVgy4Y78Wi?usp=sharing)
75
 
76
  ### Efficient Model Deployment using Ollama and LiteLLM
77
- - Setup and deployment guide on Google Colab.
78
  - → See [`efficient-ollama-colab-setup-with-litellm-guide.md`](sandbox/efficient-ollama-colab-setup-with-litellm-guide.md) for details.
79
  - [📒Notebook here](https://colab.research.google.com/drive/1buTPds1Go1NbZOLlpG94VG22GyK-F4GW?usp=sharing)
80
 
81
  ### LLM Evaluation System (LLMs as a Judge)
82
- - Implementation of a system for automatically evaluating the quality of LLM responses (added in v0.3.0, later removed).
83
- - Uses LLMs as evaluators to assess the responses of other LLMs (LLMs as a Judge method).
84
- - Quantitative quality assessment and feedback generation using a 4-level rating scale.
85
  - → See [`llm-evaluator-notebook.md`](sandbox/llm-evaluator-notebook.md) for details.
86
- - Efficient evaluation system using Gemini and LiteLLM.
87
  - [📒Notebook here](https://colab.research.google.com/drive/1haO44IeseQ3OL92HlsINAgBI_yA1fxcJ?usp=sharing)
88
 
89
- ### Wikipedia Data-based Q&A Dataset Generation (Sentence Pool QA Method)
90
- - Generation of high-quality Q&A datasets using the sentence pool QA method.
91
- - → A new dataset creation method that generates Q&A pairs while preserving context by pooling sentences separated by periods.
92
- - → Chunk size is flexibly adjustable (default 200 characters) to generate Q&A pairs with optimal context ranges for different purposes.
93
- - → See [`wikipedia-qa-dataset-generator.md`](sandbox/wikipedia-qa-dataset-generator.md) for details.
94
- - [📒Notebook here](https://colab.research.google.com/drive/1mmK5vxUzjk3lI6OnEPrQqyjSzqsEoXpk?usp=sharing)
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  ## 🛠️ Setup
98
 
@@ -111,10 +119,10 @@ cd Llama-finetune-sandbox
111
 
112
  ## 🤝 Contributions
113
 
114
- - Implementation of new fine-tuning methods.
115
- - Bug fixes and feature improvements.
116
- - Documentation improvements.
117
- - Addition of usage examples.
118
 
119
  ## 📚 References
120
 
@@ -124,4 +132,5 @@ cd Llama-finetune-sandbox
124
 
125
  ## 📄 License
126
 
127
- This project is licensed under the MIT License.
 
 
31
  </p>
32
 
33
  <h2 align="center">
34
+ Experimental Environment for Fine-tuning Llama Models ~
35
  </h2>
36
 
37
  <p align="center">
 
44
 
45
  ## 🚀 Project Overview
46
 
47
+ **Llama-finetune-sandbox** provides an experimental environment for learning and verifying the fine-tuning of Llama models. You can try various fine-tuning methods, customize models, and evaluate their performance. It caters to a wide range of users, from beginners to researchers. Version 0.3.0 includes improved documentation and an updated English README.
48
 
49
 
50
  ## ✨ Key Features
 
53
  - LoRA (Low-Rank Adaptation)
54
  - QLoRA (Quantized LoRA)
55
 
56
+ 2. **Flexible Model Settings**:
57
  - Customizable maximum sequence length
58
  - Various quantization options
59
  - Multiple attention mechanisms
60
 
61
+ 3. **Experimental Environment Setup**:
62
+ - Performance evaluation tools (added in v0.3.0, subsequently removed)
63
+ - Memory usage optimization
64
  - Visualization of experimental results
65
 
66
  ## 📚 Examples
 
68
  This repository includes the following examples:
69
 
70
  ### Fast Fine-tuning using Unsloth
71
+ - Implementation of fast fine-tuning for Llama-3.2-1B/3B models
72
+ - → See [`Llama_3_2_1B+3B_Conversational_+_2x_faster_finetuning_JP.md`](sandbox/Llama_3_2_1B+3B_Conversational_+_2x_faster_finetuning_JP.md) for details.
73
+ - → [Use this to convert from markdown to notebook format](https://huggingface.co/spaces/MakiAi/JupytextWebUI)
74
  - [📒Notebook here](https://colab.research.google.com/drive/1AjtWF2vOEwzIoCMmlQfSTYCVgy4Y78Wi?usp=sharing)
75
 
76
  ### Efficient Model Deployment using Ollama and LiteLLM
77
+ - Setup and usage guide on Google Colab
78
  - → See [`efficient-ollama-colab-setup-with-litellm-guide.md`](sandbox/efficient-ollama-colab-setup-with-litellm-guide.md) for details.
79
  - [📒Notebook here](https://colab.research.google.com/drive/1buTPds1Go1NbZOLlpG94VG22GyK-F4GW?usp=sharing)
80
 
81
  ### LLM Evaluation System (LLMs as a Judge)
82
+ - Implementation of a system for automatically evaluating the quality of LLM responses (added in v0.3.0, subsequently removed)
83
+ - Utilizing LLMs as evaluators to assess the responses of other LLMs (LLMs as a Judge method)
84
+ - Quantitative quality assessment and feedback generation using a 4-level rating scale
85
  - → See [`llm-evaluator-notebook.md`](sandbox/llm-evaluator-notebook.md) for details.
86
+ - Efficient evaluation system using Gemini and LiteLLM
87
  - [📒Notebook here](https://colab.research.google.com/drive/1haO44IeseQ3OL92HlsINAgBI_yA1fxcJ?usp=sharing)
88
 
 
 
 
 
 
 
89
 
90
+ ### Wikipedia Data-based Q&A Dataset Generation (Sentence Pool QA Method)
91
+ - High-quality Q&A dataset generation using the Sentence Pool QA method
92
+ - → A new dataset creation method that generates Q&A pairs while maintaining context by pooling sentences separated by punctuation marks.
93
+ - → Chunk size is flexibly adjustable (default 200 characters) to generate Q&A pairs with optimal context range depending on the application.
94
+ - → See [`wikipedia-qa-dataset-generator.md`](sandbox/wikipedia-qa-dataset-generator.md) for details.
95
+ - [📒Notebook here](https://colab.research.google.com/drive/1mmK5vxUzjk3lI6OnEPrQqyjSzqsEoXpk?usp=sharing)
96
+
97
+ ### Context-Aware Reflexive QA Generation System
98
+ - Q&A dataset generation with reflexive quality improvement
99
+ - → A new method that automatically evaluates the quality of generated Q&A pairs and iteratively improves them.
100
+ - → Quantifies and evaluates factuality, question quality, and answer completeness.
101
+ - → High-precision question generation and answer consistency check using contextual information.
102
+ - → See [`context_aware_Reflexive_qa_generator_V2.md`](sandbox/context_aware_Reflexive_qa_generator_V2.md) for details.
103
+ - [📒Notebook here](https://colab.research.google.com/drive/1OYdgAuXHbl-0LUJgkLl_VqknaAEmAm0S?usp=sharing)
104
 
105
  ## 🛠️ Setup
106
 
 
119
 
120
  ## 🤝 Contributions
121
 
122
+ - Implementation of new fine-tuning methods
123
+ - Bug fixes and feature improvements
124
+ - Documentation improvements
125
+ - Adding examples
126
 
127
  ## 📚 References
128
 
 
132
 
133
  ## 📄 License
134
 
135
+ This project is licensed under the MIT License.
136
+ ```
sandbox/LLMs_as_a_Judge_TOHO_V2.md ADDED
@@ -0,0 +1,544 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LLM評価システム実装ガイド
2
+
3
+ ## はじめに
4
+
5
+ このノートブックでは、LLM(大規模言語モデル)の回答品質を自動的に評価するためのシステムを実装します。このシステムは、質問、模範解答、LLMの回答を比較し、4段階のスケールで評価を行います。
6
+
7
+ ### 目的
8
+ - LLMの回答品質を定量的に評価する
9
+ - 評価プロセスを自動化し、大規模なデータセットの処理を可能にする
10
+ - 評価結果を分析可能な形式で出力する
11
+
12
+ ### システムの特徴
13
+ 1. **堅牢性**
14
+ - エラーハンドリングとリトライ機能
15
+ - ログ機能による処理状況の可視化
16
+ - 大規模データセットの処理に対応
17
+
18
+ 2. **柔軟性**
19
+ - 異なるLLMモデルに対応
20
+ - カスタマイズ可能な評価基準
21
+ - 多様な出力フォーマット(CSV, HTML)
22
+
23
+ 3. **使いやすさ**
24
+ - モジュール化された設計
25
+ - 詳細なドキュメント
26
+ - 進捗状況の視覚化
27
+
28
+ ### 評価基準
29
+ システムは以下の4段階スケールで評価を行います:
30
+ - **4点**: 優れた回答(完全で詳細な回答)
31
+ - **3点**: おおむね役立つ回答(改善の余地あり)
32
+ - **2点**: あまり役に立たない回答(重要な側面の欠落)
33
+ - **1点**: 全く役に立たない回答(無関係または不十分)
34
+
35
+ ### 必要要件
36
+ - Python 3.7以上
37
+ - Google Colab環境
38
+ - Gemini API Key
39
+ - 評価対象のQAデータセット(JSON形式)
40
+
41
+ それでは、実装の詳細に進みましょう。
42
+
43
+ ## 1. 環境セットアップ
44
+
45
+ 必要なライブラリをインストールします。
46
+
47
+ ```python
48
+ !pip install litellm tqdm loguru
49
+ ```
50
+
51
+ 必要なライブラリをインポートします。
52
+
53
+ ```python
54
+ import json
55
+ import pandas as pd
56
+ from litellm import completion
57
+ import os
58
+ from tqdm import tqdm
59
+ import time
60
+ from google.colab import userdata
61
+ from loguru import logger
62
+ import sys
63
+ from functools import wraps
64
+ ```
65
+
66
+ ```python
67
+ repo_id = "MakiAi/Llama-3.2-3B-Instruct-bnb-4bit-OKU_wiki_llama3.1_8b_inst_Reflexive_chunk200_overlap700-10epochs"
68
+ ```
69
+
70
+ ```python
71
+ !git clone https://huggingface.co/$repo_id
72
+ ```
73
+
74
+ ## 2. ユーティリティ関数の実装
75
+
76
+ ### 2.1 リトライデコレータの実装
77
+
78
+ エラーハンドリングとリトライ機能を提供するデコレータクラスを実装します。
79
+
80
+ ```python
81
+ def retry_on_error(max_retries=10, wait_time=60):
82
+ """
83
+ 関数実行時のエラーを処理し、指定回数リトライするデコレータ
84
+
85
+ Args:
86
+ max_retries (int): 最大リトライ回数
87
+ wait_time (int): リトライ間隔(秒)
88
+
89
+ Returns:
90
+ function: デコレートされた関数
91
+ """
92
+ def decorator(func):
93
+ @wraps(func)
94
+ def wrapper(*args, **kwargs):
95
+ for attempt in range(max_retries):
96
+ try:
97
+ return func(*args, **kwargs)
98
+ except Exception as e:
99
+ if attempt == max_retries - 1:
100
+ logger.error(f"最大リトライ回数に達しました: {str(e)}")
101
+ raise
102
+ logger.warning(f"エラーが発生しました。{wait_time}秒後にリトライします。(試行 {attempt + 1}/{max_retries}): {str(e)}")
103
+ time.sleep(wait_time)
104
+ return None
105
+ return wrapper
106
+ return decorator
107
+ ```
108
+
109
+ ## 3. 評価システムのコアコンポーネント
110
+
111
+ ### 3.1 プロンプト管理クラス
112
+
113
+ 評価に使用するプロンプトを管理するクラスを実装します。
114
+
115
+ ```python
116
+ class EvaluationPrompts:
117
+ """評価プロンプトを管理するクラス"""
118
+
119
+ @staticmethod
120
+ def get_judge_prompt():
121
+ return """
122
+ あなたはLLMの回答を評価する審査員です。
123
+ 質問と模範解答、そしてLLMの回答のセットを評価してください。
124
+
125
+ 評価は1から4の整数スケールで行ってください:
126
+ 1: 全く役に立たない回答:質問に対して無関係か、部分的すぎる
127
+ 2: あまり役に立たない回答:質問の重要な側面を見落としている
128
+ 3: おおむね役立つ回答:支援を提供しているが、改善の余地がある
129
+ 4: 優れた回答:関連性があり、直接的で、詳細で、質問で提起されたすべての懸念に対応している
130
+
131
+ 以下のフォーマットで評価を提供してください:
132
+
133
+ Feedback:::
134
+ 評価理由: (評価の根拠を説明してください)
135
+ 総合評価: (1から4の整数で評価してください)
136
+
137
+ これから質問、模範解答、LLMの回答を提示します:
138
+
139
+ 質問: {question}
140
+ 模範解答: {correct_answer}
141
+ LLMの回答: {llm_answer}
142
+
143
+ フィードバックをお願いします。
144
+ Feedback:::
145
+ 評価理由: """
146
+ ```
147
+
148
+ ### 3.2 評���結果パーサークラス
149
+
150
+ ```python
151
+ class EvaluationParser:
152
+ """評価結果を解析するクラス"""
153
+
154
+ @staticmethod
155
+ def extract_score(response_text):
156
+ """
157
+ 評価テキストからスコアを抽出する
158
+
159
+ Args:
160
+ response_text (str): 評価テキスト
161
+
162
+ Returns:
163
+ int or None: 抽出されたスコア
164
+ """
165
+ try:
166
+ score_text = response_text.split("総合評価:")[1].strip()
167
+ score = int(score_text.split()[0])
168
+ return score
169
+ except:
170
+ logger.error(f"スコア抽出に失敗しました: {response_text}")
171
+ return None
172
+
173
+ @staticmethod
174
+ def extract_reason(evaluation_text):
175
+ """
176
+ 評価テキストから評価理由を抽出する
177
+
178
+ Args:
179
+ evaluation_text (str): 評価テキスト
180
+
181
+ Returns:
182
+ str: 抽出された評価理由
183
+ """
184
+ try:
185
+ reason = evaluation_text.split("評価理由:")[1].split("総合評価:")[0].strip()
186
+ return reason
187
+ except:
188
+ logger.warning("評価理由の抽出に失敗しました")
189
+ return ""
190
+ ```
191
+
192
+ ### 3.3 LLM評価クラス
193
+
194
+ ```python
195
+ class LLMEvaluator:
196
+ """LLMの回答を評価するメインクラス"""
197
+
198
+ def __init__(self, model_name="gemini/gemini-pro"):
199
+ """
200
+ 評価器を初期化する
201
+
202
+ Args:
203
+ model_name (str): 使用するLLMモデル名
204
+ """
205
+ self.model_name = model_name
206
+ self.prompts = EvaluationPrompts()
207
+ self.parser = EvaluationParser()
208
+ logger.info(f"評価器を初期化しました。使用モデル: {model_name}")
209
+
210
+ @retry_on_error()
211
+ def evaluate_response(self, question, correct_answer, llm_answer):
212
+ """
213
+ 個々の回答を評価する
214
+
215
+ Args:
216
+ question (str): 質問
217
+ correct_answer (str): 模範解答
218
+ llm_answer (str): LLMの回答
219
+
220
+ Returns:
221
+ dict: 評価結果
222
+ """
223
+ prompt = self.prompts.get_judge_prompt().format(
224
+ question=question,
225
+ correct_answer=correct_answer,
226
+ llm_answer=llm_answer
227
+ )
228
+
229
+ try:
230
+ response = completion(
231
+ model=self.model_name,
232
+ messages=[{"role": "user", "content": prompt}]
233
+ )
234
+ evaluation = response.choices[0].message.content
235
+ score = self.parser.extract_score(evaluation)
236
+
237
+ if score:
238
+ logger.debug(f"評価完了 - スコア: {score}")
239
+
240
+ return {
241
+ 'score': score,
242
+ 'evaluation': evaluation
243
+ }
244
+ except Exception as e:
245
+ logger.error(f"評価中にエラーが発生しました: {str(e)}")
246
+ raise
247
+
248
+ @retry_on_error()
249
+ def evaluate_dataset(self, json_file_path, output_file="evaluation_results.json"):
250
+ """
251
+ データセット全体を評価する
252
+
253
+ Args:
254
+ json_file_path (str): 評価対象のJSONファイルパス
255
+ output_file (str): 評価結果の出力先ファイルパス
256
+
257
+ Returns:
258
+ dict: 評価結果と分析データを含む辞書
259
+ """
260
+ logger.info(f"データセット評価を開始します: {json_file_path}")
261
+
262
+ with open(json_file_path, 'r', encoding='utf-8') as f:
263
+ data = json.load(f)
264
+
265
+ results = []
266
+ qa_pairs = data['qa_pairs_simple']
267
+ total_pairs = len(qa_pairs)
268
+
269
+ logger.info(f"合計 {total_pairs} 件のQAペアを評価します")
270
+
271
+ progress_bar = tqdm(qa_pairs, desc="評価進捗", unit="件")
272
+ for qa in progress_bar:
273
+ eval_result = self.evaluate_response(
274
+ qa['question'],
275
+ qa['correct_answer'],
276
+ qa['llm_answer']
277
+ )
278
+
279
+ if eval_result:
280
+ results.append({
281
+ 'question': qa['question'],
282
+ 'correct_answer': qa['correct_answer'],
283
+ 'llm_answer': qa['llm_answer'],
284
+ 'score': eval_result['score'],
285
+ 'evaluation': eval_result['evaluation']
286
+ })
287
+
288
+ # 進捗状況を更新
289
+ progress_bar.set_postfix(
290
+ completed=f"{len(results)}/{total_pairs}",
291
+ last_score=eval_result['score']
292
+ )
293
+
294
+ time.sleep(1) # API制限考慮
295
+
296
+ # 結果を分析
297
+ scores = [r['score'] for r in results if r['score'] is not None]
298
+ analysis = {
299
+ 'total_evaluations': len(results),
300
+ 'average_score': sum(scores) / len(scores) if scores else 0,
301
+ 'score_distribution': {
302
+ '1': scores.count(1),
303
+ '2': scores.count(2),
304
+ '3': scores.count(3),
305
+ '4': scores.count(4)
306
+ }
307
+ }
308
+
309
+ # 分析結果をログに出力
310
+ logger.success("評価が完了しました")
311
+ logger.info(f"総評価数: {analysis['total_evaluations']}")
312
+ logger.info(f"平均スコア: {analysis['average_score']:.2f}")
313
+ logger.info("スコア分布:")
314
+ for score, count in analysis['score_distribution'].items():
315
+ percentage = (count / len(scores) * 100) if scores else 0
316
+ logger.info(f"スコア {score}: {count}件 ({percentage:.1f}%)")
317
+
318
+ # 結果をJSONとして保存
319
+ output_data = {
320
+ 'analysis': analysis,
321
+ 'detailed_results': results
322
+ }
323
+
324
+ with open(output_file, 'w', encoding='utf-8') as f:
325
+ json.dump(output_data, f, ensure_ascii=False, indent=2)
326
+
327
+ logger.info(f"評価結果を保存しました: {output_file}")
328
+ return output_data
329
+ ```
330
+
331
+ ### 3.4 データエクスポートクラス
332
+
333
+ ```python
334
+ class ResultExporter:
335
+ """評価結果をエクスポートするクラス"""
336
+
337
+ @staticmethod
338
+ def export_to_csv(evaluation_results, output_file="evaluation_results.csv"):
339
+ """
340
+ 評価結果をCSVファイルに出力する
341
+
342
+ Args:
343
+ evaluation_results (dict): 評価結果
344
+ output_file (str): 出力ファイルパス
345
+
346
+ Returns:
347
+ pd.DataFrame: 出力したデータフレーム
348
+ """
349
+ logger.info("CSV出力を開始します")
350
+ results = evaluation_results['detailed_results']
351
+ parser = EvaluationParser()
352
+
353
+ csv_data = []
354
+ for result in results:
355
+ csv_data.append({
356
+ '質問': result['question'],
357
+ '正解': result['correct_answer'],
358
+ 'LLMの回答': result['llm_answer'],
359
+ '評価理由': parser.extract_reason(result['evaluation']),
360
+ '総合評価': result['score']
361
+ })
362
+
363
+ df = pd.DataFrame(csv_data)
364
+ df.to_csv(output_file, index=False, encoding='utf-8-sig')
365
+
366
+ logger.success(f"CSVファイルを出力しました: {output_file}")
367
+ return df
368
+ ```
369
+
370
+ ### 3.5 レポート生成クラス
371
+
372
+ ```python
373
+ class ReportGenerator:
374
+ """評価レポートを生成するクラス"""
375
+
376
+ @staticmethod
377
+ def generate_html_report(evaluation_results, model_name, output_file="evaluation_report.html"):
378
+ """
379
+ HTML形式の評価レポートを生成する
380
+
381
+ Args:
382
+ evaluation_results (dict): 評価結果
383
+ model_name (str): 評価に使用したモデル名
384
+ output_file (str): 出力ファイルパス
385
+ """
386
+ logger.info("HTMLレポート生成を開始します")
387
+
388
+ analysis = evaluation_results['analysis']
389
+ results = evaluation_results['detailed_results']
390
+ df = pd.DataFrame(results)
391
+
392
+ html_content = f"""
393
+ <html>
394
+ <head>
395
+ <title>LLM Evaluation Report</title>
396
+ <style>
397
+ body {{ font-family: Arial, sans-serif; margin: 20px; }}
398
+ .summary {{ background-color: #f0f0f0; padding: 20px; margin-bottom: 20px; }}
399
+ .distribution {{ margin-bottom: 20px; }}
400
+ table {{ border-collapse: collapse; width: 100%; }}
401
+ th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
402
+ th {{ background-color: #4CAF50; color: white; }}
403
+ tr:nth-child(even) {{ background-color: #f2f2f2; }}
404
+ </style>
405
+ </head>
406
+ <body>
407
+ <h1>LLM Evaluation Report</h1>
408
+
409
+ <div class="summary">
410
+ <h2>Summary</h2>
411
+ <p>Total Evaluations: {analysis['total_evaluations']}</p>
412
+ <p>Average Score: {analysis['average_score']:.2f}</p>
413
+ <p>Model: {model_name}</p>
414
+ </div>
415
+
416
+ <div class="distribution">
417
+ <h2>Score Distribution</h2>
418
+ <table>
419
+ <tr>
420
+ <th>Score</th>
421
+ <th>Count</th>
422
+ <th>Percentage</th>
423
+ </tr>
424
+ {''.join(f'<tr><td>{score}</td><td>{count}</td><td>{(count/analysis["total_evaluations"]*100):.1f}%</td></tr>'
425
+ for score, count in analysis['score_distribution'].items())}
426
+ </table>
427
+ </div>
428
+
429
+ <div class="details">
430
+ <h2>Detailed Results</h2>
431
+ {df.to_html()}
432
+ </div>
433
+ </body>
434
+ </html>
435
+ """
436
+
437
+ with open(output_file, 'w', encoding='utf-8') as f:
438
+ f.write(html_content)
439
+
440
+ logger.success(f"HTMLレポートを生成しました: {output_file}")
441
+ ```
442
+
443
+ ## 4. メイン実行部分
444
+
445
+ ```python
446
+ def main():
447
+ # APIキーの設定
448
+ os.environ['GEMINI_API_KEY'] = userdata.get('GEMINI_API_KEY')
449
+
450
+ # 評価器の初期化
451
+ evaluator = LLMEvaluator(model_name="gemini/gemini-1.5-flash")
452
+ # evaluator = LLMEvaluator(model_name="vertex_ai/gemini-exp-1114")
453
+
454
+
455
+ try:
456
+ # データセットを評価
457
+ logger.info("評価プロセスを開始します")
458
+ results = evaluator.evaluate_dataset("/content/Llama-3.2-3B-Instruct-bnb-4bit-OKU_wiki_llama3.1_8b_inst_Reflexive_chunk200_overlap700-10epochs/qa_with_llm.json")
459
+
460
+ # 結果のエクスポート
461
+ exporter = ResultExporter()
462
+ df = exporter.export_to_csv(results)
463
+ logger.info("最初の数行のデータ:")
464
+ logger.info("\n" + str(df.head()))
465
+
466
+ # レポート生成
467
+ report_generator = ReportGenerator()
468
+ report_generator.generate_html_report(results, evaluator.model_name)
469
+ logger.success("すべての処理が完了しました")
470
+
471
+ except Exception as e:
472
+ logger.error(f"処理中にエラーが発生しました: {str(e)}")
473
+ raise
474
+
475
+ if __name__ == "__main__":
476
+ main()
477
+ ```
478
+
479
+ ```python
480
+ from huggingface_hub import login
481
+ login(token=userdata.get('HF_TOKEN')) # トークンを置き換えてください
482
+ ```
483
+
484
+ ```python
485
+ repo_id
486
+ ```
487
+
488
+ ```python
489
+ from huggingface_hub import upload_file
490
+ from huggingface_hub import HfApi
491
+
492
+ def upload_files_to_hub(repo_id, files_dict):
493
+ """
494
+ 複数のファイルをHugging Face Hubにアップロードする関数
495
+
496
+ Args:
497
+ repo_id (str): Hugging Face上のリポジトリID('username/repo-name'形式)
498
+ files_dict (dict): ローカルファイルパスと保存先パスの辞書
499
+ """
500
+ api = HfApi()
501
+
502
+ # 各ファイルをアップロード
503
+ for local_path, repo_path in files_dict.items():
504
+ try:
505
+ upload_file(
506
+ path_or_fileobj=local_path,
507
+ path_in_repo=repo_path,
508
+ repo_id=repo_id,
509
+ repo_type="model"
510
+ )
511
+ print(f"Successfully uploaded: {local_path} -> {repo_path}")
512
+ except Exception as e:
513
+ print(f"Error uploading {local_path}: {str(e)}")
514
+
515
+ # アップロードするファイルの定義
516
+ files_to_upload = {
517
+ "evaluation_report.html": "evaluation_report.html",
518
+ "evaluation_results.csv": "evaluation_results.csv",
519
+ "evaluation_results.json": "evaluation_results.json"
520
+ }
521
+
522
+ # ファイルのアップロード実行
523
+ upload_files_to_hub(repo_id, files_to_upload)
524
+
525
+ # 確認用出力
526
+ print(f"\nAll files uploaded to: https://huggingface.co/{repo_id}")
527
+ ```
528
+
529
+ ## 5. 使用方法
530
+
531
+ 1. Google Colabで新しいノートブックを作成します。
532
+ 2. 必要なライブラリをインストールします。
533
+ 3. 上記のコードを順番にセルにコピーして実行します。
534
+ 4. GEMINI_API_KEYを設定します。
535
+ 5. 評価したいQAデータセットのJSONファイルを用意します。
536
+ 6. メイン実行部分を実行します。
537
+
538
+ ## 6. 注意点
539
+
540
+ - 評価には時間がかかる場合があります。
541
+ - API制限に注意してください。
542
+ - データセットは指定のJSON形式に従う必要があります。
543
+ - エラー発生時は自動的にリトライします。
544
+