Usage (base + adapter)
from transformers import AutoModelForCausalLM, AutoTokenizerfrom peft import PeftModel base = AutoModelForCausalLM.from_pretrained("openai/gpt-oss-20b", torch_dtype="auto", device_map="auto")model = PeftModel.from_pretrained(base, "visproj/proofkit-gpt-oss-20b-lora")tok = AutoTokenizer.from_pretrained("openai/gpt-oss-20b")
For high-throughput distillation the adapter is merged and served via vLLM
(see scripts/modal_distill.py in the project repo).
Evaluation (post-fix, 3-judge panel)
Mean score (0–100) on 15 held-out prompts, graded by Claude Opus 4.7, GPT-5.5, and a
local Qwen-3B (gpt-oss experts is a deliberately un-retrained stale control):
Table with columns: model, Claude, GPT-5.5, Qwen-3B, Avg| model | Claude | GPT-5.5 | Qwen-3B | Avg |
|---|
| gpt-5.5 (frontier ceiling) | 94.6 | 95.6 | 90.8 | 93.7 |
| gpt-oss attn (retrained teacher) | 82.0 | 66.8 | 81.4 | 76.7 |
| qwen-0.5b distilled (served) | 79.0 | 68.6 | 82.2 | 76.6 |
| qwen-0.5b direct 7k (served) | 78.6 | 64.4 | 82.0 | 75.0 |
| gpt-oss experts (stale control) | 67.6 | 68.6 | 81.8 | 72.7 |
| qwen-3b base | 62.1 | 67.1 | 80.5 | 69.9 |
| gpt-oss base | 55.4 | 53.8 | 68.2 | 59.1 |
| qwen-0.5b base | 36.5 | 44.5 | 67.9 | 49.7 |
Both served retrained 0.5Bs beat the stale control and every untuned base across all
three judges, and the distilled 0.5B ≈ ties its own 20B teacher.
About ProofKit
ProofKit is a work-sample generator for job seekers — it turns a target
role, background, and skills-to-prove into a realistic, clearly-fictional
practice work sample (a role-specific challenge, a guided builder, a readiness
review, and a recruiter-ready portfolio packet). Built for the Hugging Face Build
Small Hackathon (Backyard AI track). Integrity rules are load-bearing: outputs
never claim real employment, metrics are labeled hypothetical, and exports carry an
ethical disclosure.
The ProofKit model family
A note on training data (the "static responses" fix)
An earlier version of these models produced repetitive, input-ignoring drafts. The
root cause was synthetic-data leakage: the dataset rendered the example user
answers and the target from the same template slots, so the model learned
target = template instead of target = f(input). The fix — faithfulness anchors
(a distinctive token shared by the answer and the target) + seeded per-example
variation across every task, then a full-chain retrain — is what these current
weights reflect.
These 0.5B models were trained on the exact prompt shapes from ProofKit's
prompt_formats.py. They only behave well when prompted in that format; reworded or
free-form prompts push them off-distribution. They are purpose-built components of the
ProofKit app, not general chat models.