MakiAi commited on
Commit
294bfa9
·
1 Parent(s): 043bac4

🎉 feat: WikipediaデータからLlama 3.1用Q&Aデータセット生成ツールを追加

Browse files

- Wikipediaの記事からLlama 3.1のファインチューニングに適したQ&Aデータセットを生成するツールを新たに作成しました。
- ツールは、WikiTextProcessor、QAGenerator、QualityChecker、DatasetCreatorの4つの主要クラスで構成されています。
- 各クラスの詳細な説明、使用方法、Google Colabノートブックへのリンク、Hugging Faceへのデータセットアップロード方法をドキュメントに記述しました。
- センテンスプールQA方式を採用し、チャンクサイズを調整することで、文脈を保持した高品質なQ&Aペアを生成できるようにしました。
- 生成されたデータセットはJSON形式で出力され、Llama 3.1の会話形式に準拠しています。
- エラー処理やリトライ機構も実装し、堅牢性を向上させています。

sandbox/wikipedia-qa-dataset-generator.md ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # WikipediaデータからLlama 3.1用Q&Aデータセット生成ツールの解説( Google Colabノートブック付)
2
+
3
+ ## はじめに
4
+
5
+ このツールは、Wikipediaの記事からLlama 3.1のファインチューニング用Q&Aデータセットを自動生成するためのものです。生成されたデータセットは、Llama 3.1の会話形式に準拠しており、高品質な学習データとして活用できます。
6
+
7
+ ## システム構成
8
+
9
+ このツールは以下の4つの主要クラスで構成されています:
10
+
11
+ 1. WikiTextProcessor - Wikipedia記事の取得と前処理
12
+ 2. QAGenerator - Q&Aペアの生成とLlama形式への変換
13
+ 3. QualityChecker - 生成されたQ&Aペアの品質管理
14
+ 4. DatasetCreator - 全体のプロセス管理
15
+
16
+ ## セットアップと環境構築
17
+
18
+ ### 必要なライブラリのインストール
19
+
20
+ ```python
21
+ !pip install litellm tqdm loguru wikipedia
22
+ ```
23
+
24
+ ### モデルの設定
25
+
26
+ ```python
27
+ MODEL_NAME = "ollama/llama3.1:8b-instruct-fp16"
28
+ ```
29
+
30
+ ## 主要コンポーネントの解説
31
+
32
+ ### WikiTextProcessor クラス
33
+
34
+ このクラスはWikipediaのテキストデータを取得し、適切な形式に加工します。
35
+
36
+ ```python
37
+ class WikiTextProcessor:
38
+ @staticmethod
39
+ def get_wiki_text(topic: str, lang: str = "ja") -> str:
40
+ """指定されたトピックのWikipedia記事を取得"""
41
+ wikipedia.set_lang(lang)
42
+ try:
43
+ page = wikipedia.page(topic)
44
+ return page.content
45
+ except Exception as e:
46
+ logger.error(f"Error fetching {topic}: {e}")
47
+ return ""
48
+
49
+ @staticmethod
50
+ def clean_text(text: str) -> str:
51
+ """テキストのクリーニング"""
52
+ import re
53
+ text = re.sub(r'\[\d+\]', '', text)
54
+ text = re.sub(r'\n\s*\n', '\n', text)
55
+ return text.strip()
56
+
57
+ @staticmethod
58
+ def split_into_chunks(text: str, max_chunk_size: int = 200) -> List[str]:
59
+ """テキストを意味のある単位で分割"""
60
+ sentences = text.split('。')
61
+ chunks = []
62
+ current_chunk = []
63
+ current_size = 0
64
+
65
+ for sentence in sentences:
66
+ sentence_size = len(sentence) + 1
67
+ if current_size + sentence_size > max_chunk_size and current_chunk:
68
+ chunks.append('。'.join(current_chunk) + '。')
69
+ current_chunk = [sentence]
70
+ current_size = sentence_size
71
+ else:
72
+ current_chunk.append(sentence)
73
+ current_size += sentence_size
74
+
75
+ if current_chunk:
76
+ chunks.append('。'.join(current_chunk) + '。')
77
+
78
+ return chunks
79
+ ```
80
+
81
+ このクラスの主な機能:
82
+ - Wikipedia記事の取得
83
+ - テキストのクリーニング(参照記号の除去など)
84
+ - 長い記事の適切なサイズへの分割
85
+
86
+ ### QAGenerator クラス
87
+
88
+ Q&Aペアの生成とLlama形式への変換を担当します。
89
+
90
+ ```python
91
+ class QAGenerator:
92
+ @staticmethod
93
+ def generate_qa_pairs_with_retry(
94
+ chunk: str,
95
+ num_pairs: int = 5,
96
+ max_retries: int = 3,
97
+ base_delay: int = 2
98
+ ) -> List[Dict[str, str]]:
99
+ prompt = f"""
100
+ 以下のテキストから質問と回答のペアを{num_pairs}つ生成してください。
101
+ 必ず以下の条件をすべて満たすJSONを出力してください:
102
+
103
+ 1. 厳密なJSON形式で出力(最後の要素にもカンマをつけない)
104
+ 2. すべての質問は日本語で記述
105
+ 3. すべての質問は「?」で終わる
106
+ 4. 回答は500文字以下
107
+ 5. 回答は必ずテキストの中に記載されている内容にして
108
+
109
+ テキスト:
110
+ {chunk}
111
+
112
+ 出力形式:
113
+ {{
114
+ "qa_pairs": [
115
+ {{"question": "質問1?", "answer": "回答1"}},
116
+ {{"question": "質問2?", "answer": "回答2"}},
117
+ {{"question": "質問3?", "answer": "回答3"}}
118
+ ]
119
+ }}
120
+ """
121
+ # ... リトライロジックの実装 ...
122
+ ```
123
+
124
+ 主な機能:
125
+ - Q&Aペアの生成(リトライ機能付き)
126
+ - JSONからの応答抽出
127
+ - エラー処理と再試行メカニズム
128
+
129
+ ### QualityChecker クラス
130
+
131
+ 生成されたQ&Aペアの品質管理を行います。
132
+
133
+ ```python
134
+ class QualityChecker:
135
+ @staticmethod
136
+ def validate_qa_pair(qa_pair: Dict[str, str]) -> bool:
137
+ """Q&Aペアの品質チェック"""
138
+ MIN_QUESTION_LENGTH = 10
139
+ MIN_ANSWER_LENGTH = 20
140
+ MAX_ANSWER_LENGTH = 500
141
+
142
+ if not all(key in qa_pair for key in ['question', 'answer']):
143
+ return False
144
+
145
+ question = qa_pair['question']
146
+ answer = qa_pair['answer']
147
+
148
+ if not question or not answer:
149
+ return False
150
+
151
+ if len(question) < MIN_QUESTION_LENGTH:
152
+ return False
153
+ if len(answer) < MIN_ANSWER_LENGTH or len(answer) > MAX_ANSWER_LENGTH:
154
+ return False
155
+ if not question.endswith('?'):
156
+ return False
157
+
158
+ return True
159
+ ```
160
+
161
+ 主な機能:
162
+ - Q&Aペアの長さと形式の検証
163
+ - コンテンツの多様性チェック
164
+ - 重複検出
165
+
166
+ ## データセット生成プロセス
167
+
168
+ ### DatasetCreator クラス
169
+
170
+ 全体のプロセスを管理し、データセットの生成を制御します。
171
+
172
+ ```python
173
+ class DatasetCreator:
174
+ def __init__(self):
175
+ self.wiki_processor = WikiTextProcessor()
176
+ self.qa_generator = QAGenerator()
177
+ self.quality_checker = QualityChecker()
178
+
179
+ def create_dataset(self, topics: List[str], output_file: str = "training_data.json") -> None:
180
+ all_formatted_data = []
181
+
182
+ for topic_idx, topic in enumerate(topics, 1):
183
+ text = self.wiki_processor.get_wiki_text(topic)
184
+ if not text:
185
+ continue
186
+
187
+ text = self.wiki_processor.clean_text(text)
188
+ chunks = self.wiki_processor.split_into_chunks(text)
189
+
190
+ for chunk in chunks:
191
+ qa_pairs = self.qa_generator.generate_qa_pairs_with_retry(chunk)
192
+ qa_pairs = [qa for qa in qa_pairs if self.quality_checker.validate_qa_pair(qa)]
193
+
194
+ if self.quality_checker.check_diversity(qa_pairs):
195
+ formatted_data = self.qa_generator.format_for_llama(qa_pairs)
196
+ all_formatted_data.extend(formatted_data)
197
+
198
+ with open(output_file, 'w', encoding='utf-8') as f:
199
+ json.dump(all_formatted_data, f, ensure_ascii=False, indent=2)
200
+ ```
201
+
202
+ ## Hugging Faceへのデータセットアップロード
203
+
204
+ 生成したデータセットをHugging Faceにアップロードする機能も実装されています。
205
+
206
+ ```python
207
+ def create_and_upload_dataset(data_dict, dataset_name, username):
208
+ dataset = Dataset.from_dict(data_dict)
209
+ dataset_dict = dataset.train_test_split(test_size=0.1, seed=42)
210
+ repo_id = f"{username}/{dataset_name}"
211
+
212
+ try:
213
+ dataset_dict.push_to_hub(
214
+ repo_id=repo_id,
215
+ )
216
+ logger.success(f"Dataset uploaded successfully to: https://huggingface.co/datasets/{repo_id}")
217
+ except Exception as e:
218
+ logger.error(f"Error uploading dataset: {e}")
219
+ raise
220
+ ```
221
+
222
+ ## 使用方法
223
+
224
+ 1. 環境のセットアップ
225
+ ```python
226
+ !pip install datasets huggingface-hub
227
+ ```
228
+
229
+ 2. トピックリストの定義
230
+ ```python
231
+ topics = ["霊烏路空"]
232
+ ```
233
+
234
+ 3. データセット生成の実行
235
+ ```python
236
+ creator = DatasetCreator()
237
+ creator.create_dataset(topics, "llama_training_data.json")
238
+ ```
239
+
240
+ ## おわりに
241
+
242
+ このツールを使用することで、Wikipediaの記事から高品質なQ&Aデータセットを自動生成し、Llama 3.1のファインチューニングに使用することができます。生成されたデータセットは自動的にHugging Faceにアップロードされ、共有や再利用が容易になっています。
243
+
244
+ ## Google Colabノートブック
245
+
246
+ https://colab.research.google.com/drive/1mmK5vxUzjk3lI6OnEPrQqyjSzqsEoXpk?usp=sharing
247
+
248
+ ## リポジトリ
249
+
250
+ https://github.com/Sunwood-ai-labs/Llama-finetune-sandbox