32 lines
6.1 KiB
Python
32 lines
6.1 KiB
Python
from rdagent.components.coder.finetune import LLMFinetuneCoSTEER
|
||
from rdagent.components.coder.finetune.exp import FTTask
|
||
from rdagent.scenarios.finetune.experiment.experiment import FTExperiment
|
||
from rdagent.scenarios.finetune.scen.scenario import LLMFinetuneScen
|
||
|
||
desc = "Data loading and preparation:\n- Load LIMO-v2/limo-v2.jsonl and s1K-1.1/data/train-00000-of-00001.parquet.\n- For s1K, treat the following fields as primary: question, deepseek_thinking_trajectory, deepseek_attempt, deepseek_grade, solution, metadata (parse Year if present).\n- For LIMO, treat: question, solution (the step-by-step), answer (final). \n\nFiltering and decontamination:\n- s1K correctness filter: keep only rows where deepseek_grade == 'Yes'.\n- s1K benchmark decontamination: if metadata contains Year and Year >= 2023, drop the sample.\n- Answer-consistency checks:\n - For s1K retained rows: extract a final numeric/string answer from deepseek_attempt. If s1K solution is numeric, ensure it matches (string-equal after normalization). If solution is non-numeric prose, trust deepseek_grade. Drop mismatches.\n - For LIMO: ensure the final tokenized answer in ‘solution’ ends with the ‘answer’ field value (normalize spaces/LaTeX formatting). If mismatch, drop.\n- Length/quality screening:\n - Drop samples where the reasoning text (solution for LIMO; deepseek_thinking_trajectory for s1K) is too short (< 60 words) or excessively long (> 2500 words) or incoherent (gpt-4o-mini coherence score < 3/5).\n- Structural health check:\n - Use gpt-4o to score each reasoning trace on a 1–5 scale for step progression, local verification, clarity, and absence of major leaps. Keep samples with score >= 3.5.\n- Deduplication:\n - Normalize questions (strip whitespace, unify punctuation, lowercase except LaTeX, remove redundant spaces).\n - Apply 13-gram overlap dedup across combined set; drop one from pairs with overlap >= 0.8.\n - Apply embedding-based dedup on normalized questions; drop pairs with cosine similarity >= 0.92.\n\nTopic classification and difficulty tagging:\n- Topic: Use gpt-4o-mini to classify each question into algebra, geometry, number theory, combinatorics, probability, or other. Store tag for balancing.\n- Difficulty: Use gpt-4o-mini to attempt each question with pass@3. If any attempt hits the correct final answer (as per previous extraction), tag as easy; else medium/hard. Aim for final sampling proportions: 30% easy, 50% medium, 20% hard. If topic or difficulty buckets are imbalanced, downsample overrepresented buckets and upsample (preferentially keep highest structural scores) underrepresented ones.\n\nLong-short CoT mixture creation:\n- Long-CoT split:\n - For LIMO: output text = original solution cleaned, ensure it ends with a line “Final Answer: {answer}”.\n - For s1K: output text = deepseek_thinking_trajectory cleaned, followed by a final line “Final Answer: {extracted_answer}”.\n - For both, set input = “Provide a detailed derivation.”\n- Short-CoT split creation (for ~70% of retained long samples, stratified by topic and difficulty):\n - Use gpt-4o-mini to compress each long solution into 5–7 ordered steps focusing on key inferences.\n - Append a final ‘Check’ step that verifies the final result (e.g., substitution, modular check, dimensional consistency) and concludes.\n - Ensure final line “Final Answer: {same_answer_as_long}”.\n - Set input = “Provide a concise 5–7 step solution and include a check.”\n\nFormat normalization (Alpaca):\n- Convert all items (long and short) into Alpaca schema:\n - instruction: the problem statement (question) with LaTeX preserved.\n - input: guidance string as above.\n - output: curated reasoning trace ending with “Final Answer: X”.\n- Sanitize artifacts:\n - Remove extraneous headers, markdown footers, and unintended HTML.\n - Preserve LaTeX math blocks and escape sequences.\n - Standardize the final answer line exactly as “Final Answer: {answer}”.\n\nFinal assembly and splits:\n- Create two JSONL files in an output folder:\n - processed/train-long.jsonl: all retained long-CoT items (~1200–1300 expected).\n - processed/train-short.jsonl: compressed short-CoT items (~800–900 expected).\n- Ensure each item includes topic and difficulty tags in an auxiliary field if supported; if not, keep a separate CSV index mapping IDs to topic/difficulty for future sampling.\n- Keep a 5% random holdout (stratified by topic/difficulty) in separate files: processed/holdout-long.jsonl and processed/holdout-short.jsonl, excluded from training.\n\nQuality report and expected counts:\n- After each major step (correctness filter, decontamination, dedup, structural filter), log retained counts and proportions by topic and difficulty.\n- Target final total items: ~2000–2200 combined (long + short), with topic balance approx ~20% per major category and difficulty balance 30/50/20 (easy/medium/hard). If deviations exceed ±8 percentage points, adjust by sampling from the highest structural-scored items in underrepresented buckets.\n\nLLM endpoints usage:\n- gpt-4o: structural scoring (1–5), and occasional ambiguous answer-extraction resolution.\n- gpt-4o-mini: topic classification, coherence scoring (1–5), difficulty tagging via pass@3 attempts, and short-CoT compression/summarization.\n\nDeliverables:\n- Alpaca-formatted training files: processed/train-long.jsonl, processed/train-short.jsonl.\n- Stratified holdouts: processed/holdout-long.jsonl, processed/holdout-short.jsonl.\n- A summary report (JSON) capturing per-step counts, topic/difficulty distributions, and dedup stats."
|
||
|
||
|
||
def develop_one_competition():
|
||
# Initialize scenario and coder
|
||
scen = LLMFinetuneScen()
|
||
ft_coder = LLMFinetuneCoSTEER(scen)
|
||
|
||
# Create the ensemble task with actual data context and specification
|
||
task = FTTask(
|
||
base_model="Qwen/Qwen3-1.7B",
|
||
description=desc,
|
||
benchmark="aime25",
|
||
)
|
||
|
||
exp = FTExperiment(sub_tasks=[task])
|
||
|
||
# # Injecting the corresponding specification
|
||
# exp.experiment_workspace.inject_files(**{"spec/ensemble.md": ensemble_spec})
|
||
|
||
# Develop the experiment
|
||
exp = ft_coder.develop(exp)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
develop_one_competition()
|