Spaces:
Sleeping
Sleeping
🎉 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
|