openthoughts-data-recipes
推論モデル向けのデータ生成パイプラインを設計できます。回答サンプリング、教師選択、ソース品質最適化を体系的に実験することで、推論性能を向上させるパイプラインを構築します。
description の原文を見る
Design data generation pipelines for reasoning models through systematic experimentation with answer sampling, teacher selection, and source quality optimization.
SKILL.md 本文
OpenThoughts: 推論モデルのためのデータレシピ
コアコンセプト
OpenThoughtsは、最先端の推論性能を達成するために、生のモデル容量ではなくデータキュレーション戦略が極めて重要であることを実証しています。1,000件以上の制御された実験を通じて、研究者たちは次のことを確認しました:単一の高品質な教師モデルからの回答の多様性はソースの多様性を上回ること、品質ソースの選択は混合より優れていること、およびLLMベースのフィルタリングは従来の方法を上回ることです。
アーキテクチャ概要
- 質問ソーシング: 27個のコード、21個の数学、14個の科学ベンチマークソースを評価
- 混合戦略: パフォーマンス相関に基づいて、ドメインごとに上位1~2個のソースを選択
- 質問フィルタリング: LLMベースの難易度と応答長スコアリングを適用
- 重複排除: 16×の回答多重性サンプリングを伴う厳密な重複排除
- 回答フィルタリング: 逆説的に、すべての教師回答を保持することが選別的なフィルタリングより優れています
- 教師モデル選択: QwQ-32Bは、スタンドアロンスコアが低いにもかかわらず、最高の蒸留7Bパフォーマンスを生み出します
実装
ステップ1: ソース評価フレームワーク
import numpy as np
from collections import defaultdict
class SourceEvaluator:
def __init__(self, num_sources, domains=['math', 'code', 'science']):
self.sources = {domain: [] for domain in domains}
self.domain_configs = {
'math': 27, # 27 math sources tested
'code': 27, # 27 code sources tested
'science': 14 # 14 science sources tested
}
def evaluate_source_quality(self, source_name, domain, sample_size=100):
"""Measure correlation with downstream task performance"""
samples = self.sample_from_source(source_name, sample_size)
# Train small model on samples from this source
model = train_student_on_source(samples)
# Evaluate on held-out reasoning benchmarks
aime_score = evaluate_on_benchmark(model, 'AIME2025')
livecodebench_score = evaluate_on_benchmark(model, 'LiveCodeBench')
source_quality = {
'name': source_name,
'domain': domain,
'aime_correlation': aime_score,
'code_correlation': livecodebench_score,
'combined_score': (aime_score + livecodebench_score) / 2
}
return source_quality
def select_top_sources(self, domain, num_sources=2):
"""Keep only top 1-2 sources per domain"""
evaluated = [self.evaluate_source_quality(src, domain)
for src in self.domain_configs[domain]]
ranked = sorted(evaluated,
key=lambda x: x['combined_score'],
reverse=True)
return [s['name'] for s in ranked[:num_sources]]
ステップ2: 回答サンプリング多重性
class AnswerDiversityGenerator:
def __init__(self, teacher_model_name, multiplicity=16):
self.teacher = load_model(teacher_model_name) # e.g., QwQ-32B
self.multiplicity = multiplicity
self.sampling_config = {
'temperature': 1.0,
'top_p': 0.95,
'max_new_tokens': 2048,
}
def generate_multiple_answers(self, question, num_samples=16):
"""Generate diverse answers from same question via stochastic sampling"""
answers = []
for i in range(num_samples):
# Use stochastic decoding for diversity
answer = self.teacher.generate(
question,
temperature=self.sampling_config['temperature'],
top_p=self.sampling_config['top_p'],
do_sample=True, # Critical for diversity
)
answers.append({
'answer': answer,
'sample_id': i,
'question': question
})
return answers
def create_dataset_via_multiplication(self, questions, multiplicity=16):
"""Scale dataset by generating multiple answers per question"""
dataset = []
for question in questions:
answer_samples = self.generate_multiple_answers(
question,
num_samples=multiplicity
)
dataset.extend(answer_samples)
print(f"Dataset scaled from {len(questions)} to {len(dataset)} samples")
print(f"Scaling factor: {len(dataset) / len(questions)}×")
return dataset
ステップ3: LLMベースの質問フィルタリング
class LLMQuestionFilter:
def __init__(self, scoring_model_name='GPT-4'):
self.scorer = load_model(scoring_model_name)
def compute_difficulty_score(self, question, ground_truth):
"""Use LLM to assess question difficulty"""
prompt = f"""Rate the difficulty of this question on scale 1-10:
Question: {question}
Answer: {ground_truth}
Consider: problem complexity, reasoning depth, required knowledge."""
difficulty_response = self.scorer.generate(prompt)
difficulty = extract_numeric_score(difficulty_response)
return difficulty # 1=trivial, 10=hard
def compute_response_length(self, answer):
"""Estimate expected solution complexity"""
token_count = len(answer.split())
return token_count
def filter_by_lvm_criteria(self, questions_with_answers,
min_difficulty=3,
target_length_range=(100, 2000)):
"""Keep questions matching quality criteria"""
filtered = []
for qa_pair in questions_with_answers:
difficulty = self.compute_difficulty_score(
qa_pair['question'],
qa_pair['answer']
)
length = self.compute_response_length(qa_pair['answer'])
# LLM-based filtering outperforms embedding-based approaches
if (min_difficulty <= difficulty and
target_length_range[0] <= length <= target_length_range[1]):
filtered.append(qa_pair)
print(f"Filtered from {len(questions_with_answers)} to {len(filtered)} samples")
return filtered
ステップ4: 教師モデル選択戦略
class TeacherSelectionFramework:
def __init__(self):
self.candidate_teachers = [
'QwQ-32B', # Best distillation performance
'DeepSeek-R1-Distill',
'LLaMA-3.1-70B',
'Mistral-Large',
]
def evaluate_teacher_distillation(self, teacher_name, student_size='7B'):
"""Measure how well a teacher distills into 7B student"""
# Generate data with teacher
dataset = self.generate_reasoning_dataset_with_teacher(teacher_name)
# Train student model on teacher data
student = train_student_model(dataset, student_size)
# Evaluate on multiple benchmarks
aime_2025 = evaluate_on_dataset(student, 'AIME2025')
livecodebench = evaluate_on_dataset(student, 'LiveCodeBench')
distillation_quality = {
'teacher': teacher_name,
'aime_2025_score': aime_2025,
'livecodebench_score': livecodebench,
'avg_downstream_performance': (aime_2025 + livecodebench) / 2
}
return distillation_quality
def select_best_teacher(self):
"""Key finding: teacher selection outweighs raw model performance"""
results = []
for teacher_name in self.candidate_teachers:
result = self.evaluate_teacher_distillation(teacher_name)
results.append(result)
# QwQ-32B often outperforms stronger models like Claude-3-Opus
best_teacher = max(results,
key=lambda x: x['avg_downstream_performance'])
print(f"Best teacher for distillation: {best_teacher['teacher']}")
return best_teacher['teacher']
ステップ5: 回答フィルタリング(オプションだが逆説的)
class AnswerFilteringStrategy:
def __init__(self):
self.filter_config = {
'apply_filtering': False, # Key finding: no filtering > filtering
'reason': 'Keeping all answers provides better training signal'
}
def analyze_filtering_impact(self, dataset_with_answers, dataset_no_filter):
"""Compare distilled model performance with and without answer filtering"""
# Train student without filtering
student_no_filter = train_student(dataset_with_answers)
perf_no_filter = evaluate(student_no_filter)
# Train student with filtering
filtered_dataset = self.filter_low_quality_answers(dataset_with_answers)
student_filtered = train_student(filtered_dataset)
perf_filtered = evaluate(student_filtered)
print(f"Performance without filtering: {perf_no_filter}")
print(f"Performance with filtering: {perf_filtered}")
# Empirical finding: no filtering wins
return perf_no_filter >= perf_filtered
実践的なガイダンス
-
ソース集中戦略: 16個のソースを混合するのではなく、ドメインごとに最高品質の1~2個のソースに焦点を当てます。下流のタスクとの品質相関は、ソースの多様性よりも重要です。
-
多様性より多重性: 多様な質問ソースを求めるのではなく、同じ教師と質問分布から16×の回答を生成します。トークンレベルの回答多様性は、より優れた訓練信号を提供します。
-
教師選択が重要: スタンドアロンベンチマークスコアだけではなく、下流タスクの蒸留パフォーマンスを通じて複数の候補教師をベンチマークします。QwQ-32Bは一部のメトリックにおける固有のパフォーマンスが低いにもかかわらず、優れていることが証明されました。
-
LLMベースのフィルタリング: 埋め込みベースまたは統計的手法ではなく、LLM判定者を使用して質問難易度と予想される応答長をスコアリングします。これは従来のフィルタリングアプローチを上回ります。
-
すべての回答を保持: 回答の正確性または品質閾値に基づいてフィルタリングしないでください。驚くべき発見は、すべての教師出力(間違った回答を含む)を保持することが、高信頼度の回答のみを保持するより豊かな学習信号を提供することです。
-
データスケーリングパターン: 数学、コード、科学ドメイン全体でデータスケーリングに伴う一貫した改善を予想してください。このパイプラインにより、7B推論モデルを53% AImeおよび51% LiveCodeBenchスコアに訓練できます。
参考文献
- 論文: OpenThoughts (2506.04178)
- 成果: 120万個の訓練例を備えたOpenThinker3-7B
- 主要メトリック: AIME 2025で53%、LiveCodeBenchで51%
- オープンソース: Hugging Face上にリリース (OpenThoughts3-1.2Mデータセット)
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- ADu2021
- リポジトリ
- ADu2021/skillXiv
- ライセンス
- MIT
- 最終更新
- 2026/3/26
Source: https://github.com/ADu2021/skillXiv / ライセンス: MIT
関連スキル
agent-browser
AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。
anyskill
AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。
engram
AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。
skyvern
AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。
pinchbench
PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。
openui
OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。