Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention

arXivModelModelDataset

SPoT is a proximal on-policy distillation framework that uses a black-box Oracle to minimally correct student failures, improving reasoning while preserving prior knowledge through a reward-based binary optimization objective.

📰 News

  • [2026-06-17] Our SPoT-tuned Llama-3.1-8B-Instruct checkpoint is live on Hugging Face: linius/Llama3.1-8B-SPoT.
  • [2026-05-15] Paper updated to v2 with the proximal on-policy distillation framing and knowledge-retention analysis.
  • [2026-03-05] Our SPoT-tuned Qwen3-8B checkpoint is live on HuggingFace — try it yourself! linius/Qwen3-8B-SPoT
  • [2026-03-04] The Connect4 OOD reasoning evaluation dataset is now publicly available: linius/connect4.

📊 Main Results

SPoT consistently outperforms all baselines across in-domain reasoning, OOD reasoning, and general instruction following. Crucially, while every competing method trades off at least one capability, SPoT is the only approach that improves all three simultaneously.

Qwen3-8B

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Qwen3-8B (base)46.829.983.047.1
+ SFT41.0 (-5.8)25.5 (-4.4)79.6 (-3.4)41.8 (-5.3)
+ RFT47.3 (+0.5)26.1 (-3.8)81.5 (-1.5)46.4 (-0.7)
+ SFT+50.5 (+3.7)30.7 (+0.8)80.0 (-3.0)49.4 (+2.3)
+ SPoT (ours)52.1 (+5.3)41.4 (+11.5)84.8 (+1.8)53.3 (+6.2)

Llama-3.1-8B-Instruct

MethodIn-domain AvgOOD AvgIFEvalOverall Avg
Llama-3.1-8B-Instruct (base)18.616.873.624.3
+ SFT18.0 (-0.6)15.7 (-1.1)62.1 (-11.5)22.4 (-1.9)
+ RFT18.0 (-0.6)17.2 (+0.4)71.2 (-2.4)23.7 (-0.6)
+ SFT+19.9 (+1.3)16.7 (-0.1)68.6 (-5.0)24.6 (+0.3)
+ SPoT (ours)20.7 (+2.1)18.5 (+1.7)73.2 (-0.4)26.0 (+1.7)

Benchmarks: AIME24/25, AMC23, MATH-500, Minerva, OlympiadBench (in-domain); GPQA-Diamond, Connect4 (OOD); IFEval (instruction following). The OOD gain on Connect4 alone is +25.1 points for Qwen3-8B (10.9 → 36.0).

🔧 Data Pipeline

The pipeline generates proximal on-policy contrastive pairs (x, y⁻, y⁺) where y⁺ is a minimally-edited correction of the model's wrong response y⁻.

Raw Dataset → Error Elicitation → Oracle Rectification → Contrastive Pairs
(DAPO) (Model Inference) (Gemini 2.5 Pro) (x, y⁻, y⁺)

Step 1: Error Elicitation

Run inference on the DAPO-Math dataset to collect model failures:

bash scripts/run_dapo_inference.sh

Or with custom options:

python scripts/parallel_inference_dapo.py \
--model Qwen/Qwen3-8B \
--data_path data/dapo_5k/data.jsonl \
--output_dir output/dapo_5k_inference \
--num_gpus 8 \
--temperature 0.7 \
--top_p 0.8 \
--max_tokens 32768

Outputs errors.jsonl (incorrect predictions) and all_results.jsonl.

Step 2: Oracle Rectification

Use a black-box Oracle such as Gemini 2.5 Pro to surgically correct the errors (supports resuming):

# Correction mode: correct student errors while preserving style
python scripts/correct_errors_parallel.py \
--input output/dapo_5k_inference/errors.jsonl \
--output data/gemini_corrected.jsonl \
--workers 200

🏋️ Training

SPoT uses a reward-based binary cross-entropy objective (implemented as bco_pair) over the proximal contrastive pairs (x, y⁻, y⁺) produced by the data pipeline. Training is full finetune (no LoRA) on Qwen3-8B with DeepSpeed ZeRO-2.

Install

pip install transformers==4.53.3 trl==0.20.0 accelerate==1.10.0 \
torch==2.7.0 deepspeed flash-attn wandb

Run

bash train/dpo_sft_qwen3_accelerate.sh <output_ckpt><data.jsonl> [base_model]

Example:

bash train/dpo_sft_qwen3_accelerate.sh \
ckpts/qwen3_spot \
data/gemini_corrected.jsonl \
Qwen/Qwen3-8B

The launcher autodetects GPU count via nvidia-smi -L and dispatches with accelerate launch using train/accelerate_config.yaml (DeepSpeed ZeRO-2, bf16). After training, the saved checkpoint is re-serialized in bf16 to halve disk usage.

Data format

Each line of the input JSONL must contain:

KeyRole
question (or prompt)User query
gemini_corrected_answerChosen response y⁺ (Oracle correction)
original_answerRejected response y⁻ (model's wrong output)

Default hyperparameters

Lossbco_pair, β=0.1
Learning rate1e-6, cosine schedule, warmup 0.05
Epochs2
Batch2 per GPU × 2 grad accum
Max sequence length8192
Precisionbf16, FlashAttention-2, gradient checkpointing

Override any of the above by editing train/dpo_sft_qwen3_accelerate.sh.

WandB

Logging defaults to project dpo-sft-qwen3 with no entity. Set WANDB_ENTITY=<your-team> before launching, or pass --report_to none to disable.

🧪 Evaluation

Supported Benchmarks

Task stringBenchmarkType
custom|aime24|0|0AIME 2024Math
custom|aime25|0|0AIME 2025Math
custom|amc23|0|0AMC 2023Math
custom|math_500|0|0MATH-500Math
custom|minerva|0|0Minerva MathMath
custom|olympiadbench|0|0OlympiadBenchMath
custom|gpqa:diamond|0|0GPQA-DiamondScience
custom|ifeval_no_thinking|0|0IFEvalInstruction Following
connect4Connect4 (OOD)Game Reasoning

All benchmarks except Connect4 use sober_eval/main.py. Connect4 uses eval/eval_connect4.py.

Connect4 serves as an OOD reasoning benchmark with verifiable intermediate steps. Game states are dynamically generated via GAMEBoT to prevent data contamination.

Multi-Trial Evaluation

Loads the model once and duplicates the dataset N times — more efficient than re-running per seed:

bash run_evaluation_multi_trial_duplicated_data.sh /path/to/model --disable-thinking

Results are saved to evaluation_results/aggregated_results.json.

📖 Citation

If you find this work useful, please cite:

@article{lin2026surgical,
title={Surgical Post-Training: Proximal On-Policy Distillation for Reasoning with Knowledge Retention},
author={Wenye Lin and Kai Han},
year={2026},
journal={arXiv preprint arXiv:2603.01683}
}

About

Official code for paper "Surgical Post-Training: Cutting Errors, Keeping Knowledge"

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages