# WikipediaデータからLlama 3.1用Q&Aデータセット生成ツールの解説( Google Colabノートブック付) ## はじめに このツールは、Wikipediaの記事からLlama 3.1のファインチューニング用Q&Aデータセットを自動生成するためのものです。生成されたデータセットは、Llama 3.1の会話形式に準拠しており、高品質な学習データとして活用できます。 ## システム構成 このツールは以下の4つの主要クラスで構成されています: 1. WikiTextProcessor - Wikipedia記事の取得と前処理 2. QAGenerator - Q&Aペアの生成とLlama形式への変換 3. QualityChecker - 生成されたQ&Aペアの品質管理 4. DatasetCreator - 全体のプロセス管理 ## セットアップと環境構築 ### 必要なライブラリのインストール ```python !pip install litellm tqdm loguru wikipedia ``` ### モデルの設定 ```python MODEL_NAME = "ollama/llama3.1:8b-instruct-fp16" ``` ## 主要コンポーネントの解説 ### WikiTextProcessor クラス このクラスはWikipediaのテキストデータを取得し、適切な形式に加工します。 ```python class WikiTextProcessor: @staticmethod def get_wiki_text(topic: str, lang: str = "ja") -> str: """指定されたトピックのWikipedia記事を取得""" wikipedia.set_lang(lang) try: page = wikipedia.page(topic) return page.content except Exception as e: logger.error(f"Error fetching {topic}: {e}") return "" @staticmethod def clean_text(text: str) -> str: """テキストのクリーニング""" import re text = re.sub(r'\[\d+\]', '', text) text = re.sub(r'\n\s*\n', '\n', text) return text.strip() @staticmethod def split_into_chunks(text: str, max_chunk_size: int = 200) -> List[str]: """テキストを意味のある単位で分割""" sentences = text.split('。') chunks = [] current_chunk = [] current_size = 0 for sentence in sentences: sentence_size = len(sentence) + 1 if current_size + sentence_size > max_chunk_size and current_chunk: chunks.append('。'.join(current_chunk) + '。') current_chunk = [sentence] current_size = sentence_size else: current_chunk.append(sentence) current_size += sentence_size if current_chunk: chunks.append('。'.join(current_chunk) + '。') return chunks ``` このクラスの主な機能: - Wikipedia記事の取得 - テキストのクリーニング(参照記号の除去など) - 長い記事の適切なサイズへの分割 ### QAGenerator クラス Q&Aペアの生成とLlama形式への変換を担当します。 ```python class QAGenerator: @staticmethod def generate_qa_pairs_with_retry( chunk: str, num_pairs: int = 5, max_retries: int = 3, base_delay: int = 2 ) -> List[Dict[str, str]]: prompt = f""" 以下のテキストから質問と回答のペアを{num_pairs}つ生成してください。 必ず以下の条件をすべて満たすJSONを出力してください: 1. 厳密なJSON形式で出力(最後の要素にもカンマをつけない) 2. すべての質問は日本語で記述 3. すべての質問は「?」で終わる 4. 回答は500文字以下 5. 回答は必ずテキストの中に記載されている内容にして テキスト: {chunk} 出力形式: {{ "qa_pairs": [ {{"question": "質問1?", "answer": "回答1"}}, {{"question": "質問2?", "answer": "回答2"}}, {{"question": "質問3?", "answer": "回答3"}} ] }} """ # ... リトライロジックの実装 ... ``` 主な機能: - Q&Aペアの生成(リトライ機能付き) - JSONからの応答抽出 - エラー処理と再試行メカニズム ### QualityChecker クラス 生成されたQ&Aペアの品質管理を行います。 ```python class QualityChecker: @staticmethod def validate_qa_pair(qa_pair: Dict[str, str]) -> bool: """Q&Aペアの品質チェック""" MIN_QUESTION_LENGTH = 10 MIN_ANSWER_LENGTH = 20 MAX_ANSWER_LENGTH = 500 if not all(key in qa_pair for key in ['question', 'answer']): return False question = qa_pair['question'] answer = qa_pair['answer'] if not question or not answer: return False if len(question) < MIN_QUESTION_LENGTH: return False if len(answer) < MIN_ANSWER_LENGTH or len(answer) > MAX_ANSWER_LENGTH: return False if not question.endswith('?'): return False return True ``` 主な機能: - Q&Aペアの長さと形式の検証 - コンテンツの多様性チェック - 重複検出 ## データセット生成プロセス ### DatasetCreator クラス 全体のプロセスを管理し、データセットの生成を制御します。 ```python class DatasetCreator: def __init__(self): self.wiki_processor = WikiTextProcessor() self.qa_generator = QAGenerator() self.quality_checker = QualityChecker() def create_dataset(self, topics: List[str], output_file: str = "training_data.json") -> None: all_formatted_data = [] for topic_idx, topic in enumerate(topics, 1): text = self.wiki_processor.get_wiki_text(topic) if not text: continue text = self.wiki_processor.clean_text(text) chunks = self.wiki_processor.split_into_chunks(text) for chunk in chunks: qa_pairs = self.qa_generator.generate_qa_pairs_with_retry(chunk) qa_pairs = [qa for qa in qa_pairs if self.quality_checker.validate_qa_pair(qa)] if self.quality_checker.check_diversity(qa_pairs): formatted_data = self.qa_generator.format_for_llama(qa_pairs) all_formatted_data.extend(formatted_data) with open(output_file, 'w', encoding='utf-8') as f: json.dump(all_formatted_data, f, ensure_ascii=False, indent=2) ``` ## Hugging Faceへのデータセットアップロード 生成したデータセットをHugging Faceにアップロードする機能も実装されています。 ```python def create_and_upload_dataset(data_dict, dataset_name, username): dataset = Dataset.from_dict(data_dict) dataset_dict = dataset.train_test_split(test_size=0.1, seed=42) repo_id = f"{username}/{dataset_name}" try: dataset_dict.push_to_hub( repo_id=repo_id, ) logger.success(f"Dataset uploaded successfully to: https://huggingface.co/datasets/{repo_id}") except Exception as e: logger.error(f"Error uploading dataset: {e}") raise ``` ## 使用方法 1. 環境のセットアップ ```python !pip install datasets huggingface-hub ``` 2. トピックリストの定義 ```python topics = ["霊烏路空"] ``` 3. データセット生成の実行 ```python creator = DatasetCreator() creator.create_dataset(topics, "llama_training_data.json") ``` ## おわりに このツールを使用することで、Wikipediaの記事から高品質なQ&Aデータセットを自動生成し、Llama 3.1のファインチューニングに使用することができます。生成されたデータセットは自動的にHugging Faceにアップロードされ、共有や再利用が容易になっています。 ## Google Colabノートブック https://colab.research.google.com/drive/1mmK5vxUzjk3lI6OnEPrQqyjSzqsEoXpk?usp=sharing ## リポジトリ https://github.com/Sunwood-ai-labs/Llama-finetune-sandbox