Downloads · 30 days
0
kzhao5/mea-qedks-defenses
mea-qedks-defenses is a machine learning model from kzhao5. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for peft. The card lists the license as apache-2.0.
Full reproduction artifacts for the QEDKS extraction attack against the generator-style defenses of the MEA defense benchmark (A-Benchmark-for-Model-distillation-survey), including the clean (undefended) QEDKS baselin…
Downloads · 30 days
0
Access
Public
Updated Sep 21, 2026
Repo size
1.5 GB
Likes
0
Public
Click a slice to open those files.
.jsonl862 MB · 35%
From the Hugging Face model README
Full reproduction artifacts for the QEDKS extraction attack against the
generator-style defenses of the MEA defense benchmark
(A-Benchmark-for-Model-distillation-survey), including the clean
(undefended) QEDKS baseline used as the M4 negative control.
Companion repos: SeqKD · SODA
| Item | Value |
|---|---|
| Attack | QEDKS, budget 1000 teacher queries (3 seed + 498 template + 499 follow-up) |
| Teacher | Qwen/Qwen2.5-72B-Instruct (defended, served as an online oracle) |
| Student | Qwen/Qwen2.5-7B (base), LoRA r=16, α=32, dropout=0.05, bf16 |
| Execution | online defended-teacher endpoint (QEDKS queries adaptively, so no precomputed transcript) |
M4 asks whether a watermark/fingerprint transferred into the extracted
student. The only valid evidence is the positive − negative contrast: the
same detector applied to the student extracted from the defended teacher vs.
the student extracted from the clean teacher (clean/).
| Defense | Positive green rate | Negative (clean) | pos − neg | Verdict |
|---|---|---|---|---|
| ginsew | 0.5265 (z = +18.5 vs γ) | 0.5179 (z = +12.7) | +0.0086 = +4.3 SE | weak but real transfer |
| radioactivity | 0.2573 (p = 2.5e−08) | 0.2571 (p = 2.6e−08) | +0.0002 = +0.1 SE | no transfer |
| adfp | gtp = 0.5079 (+0.5 SE vs γ = 0.5) | gtp = 0.5065 (+0.4 SE) | +0.0013 = +0.06 SE | no transfer |
| ads | — | — | — | no detector in benchmark |
| doge | — | — | — | no detector in benchmark |
| trace_rewriting | — | — | — | no detector in benchmark |
These detectors are biased by the student's text distribution. On QEDKS students the clean student — which never saw a watermarked teacher — already scores far from chance: ginsew z = +12.7 and radioactivity +5.4 SE above γ = 0.25 (p = 2.6e−08).
So radioactivity's positive p = 2.5e−08, which superficially clears the
benchmark's own p < 1e-5 acceptance hint, is entirely detector bias: the
clean student scores the same. Only ginsew retains a genuine, if modest,
separation once the control is subtracted (+4.3 SE, i.e. a 0.86-percentage-point
green-rate gap — much smaller than z = +18.5 suggests).
The bias is detector-specific, not attack-specific. The ADFP detector is essentially unbiased on QEDKS students — its clean student sits only +0.4 SE from γ = 0.5 — so ADFP's absolute number happens to be trustworthy here. We established that by running the control, rather than assuming it; the same assumption applied to radioactivity would have produced a false positive.
For comparison, in the SeqKD companion repo nothing separates (ginsew +0.5 SE, radioactivity +0.1 SE), and there radioactivity's clean student sits only +0.4 SE from γ — the detector happens to be unbiased on SeqKD students, which is why an absolute test looked valid in that setting. Do not generalise that: always run the attack-matched clean control.
clean/<run_id>/ clean (undefended) QEDKS baseline = M4 negative control
(query_plans, teacher_transcripts, train_data, checkpoints, manifest)
<defense>/
checkpoint-final/ convenience copy of the final student LoRA adapter
detector_report.json positive detector result (watermark/fingerprint defenses)
detector_negative_report.json same detector on the clean student
oracle/ defended-teacher transcript, received-query log,
defense artifacts (watermark state / fingerprint), server log
attack/qedks/<run>/ query_plans, teacher_transcripts, train_data,
checkpoints (incl. intermediate), logs, attack_manifest.json
detector/ , detector_negative/ full detector outputs (student_outputs.jsonl, rows, manifest)
defense_run_manifest.json
Load a student:
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B", torch_dtype="bfloat16", device_map="auto")
model = PeftModel.from_pretrained(base, "kzhao5/mea-qedks-defenses", subfolder="ginsew/checkpoint-final")
ads/ads_config.json — lam=0.1,
eps=0.01, tau=0.9, top_p=0.95,
max_new_tokens=1536, proxy student Qwen/Qwen2.5-7B.
The proxy-student gradients were not recomputed for QEDKS: this run reuses
the gradient file computed for the SeqKD companion run
(defenses.ads.save_grad; 512 holdout teacher traces, max_length=512, seed 0).
ADS gradients depend on the proxy student and the holdout teacher traces, not
on the attacker's queries, so they are attack-independent. The ~29 GB file is
not uploaded — see the SeqKD repo README for how to regenerate it.duffin/ holds a joint Knowledge-DuFFin evaluation run with the benchmark's
evaluation/defense_eval/evaluate_duffin.py at the guide defaults. The same tree is
uploaded to all three companion repos (SeqKD / SODA / QEDKS), because the score
compares all four models on a shared probe set.
Qwen/Qwen2.5-72B-Instruct answers 1000 fixed MMLU-Pro test probes
(biology, business, chemistry, computer science, math, physics; seed 42), greedy,
max_new_tokens=4.Qwen/Qwen2.5-7B base. Positives: the clean B=1000 SeqKD, SODA and QEDKS
students (pinned HF revisions in duffin/<attack>_source.json).| model | label | score (common probes) | − base | common valid probes | individual score (own valid probes) |
|---|---|---|---|---|---|
| base_negative | negative | 0.68 | 0.00 | 25 | 0.646 (48) |
| seqkd | positive | 0.60 | −0.08 | 25 | 0.463 (41) |
| soda | positive | 0.68 | 0.00 | 25 | 0.646 (48) |
| qedks | positive | 0.72 | +0.04 | 25 | 0.691 (81) |
These numbers are not informative — read before using them.
defenses/duffin/detector.py::extract_choice upper-cases the response
and falls back to the last standalone letter, so the English article "a" parses as option
A (e.g. "You are a helpful" → A). 4–7 of the 25 common answers per model are such
fallback parses.max_new_tokens=16/32
raised validity to 41–54% for base / SeqKD-clean, but a third to a half of those parses were
the same fallback artefact. A parser fix (or scoring option-letter logits) is needed before
DuFFin is meaningful for base-model students.duffin/
protocol.json summary.csv summary.json common_valid_probe_ids.json
seqkd_source.json soda_source.json qedks_source.json pinned student checkpoints
reference/probes.jsonl the 1000 probes
reference/teacher_reference.json teacher responses and parsed choices
base_negative/ seqkd/ soda/ qedks/ probe_rows.jsonl (per-probe responses/choices),
detector_report.json, detector_rows.jsonl, detector_manifest.json
defense_eval/ holds the benchmark's evaluation/defense_eval/evaluate.py run for the QEDKS
arms: six-task macro ACC (M1) and BERTScore against the undefended Qwen teacher on 3000 shared
held-out prompts (M2), for the clean student and all six defended students, plus the shared
teacher/base reference (identical copy in the three companion repos).
Protocol: zero-shot ARC-Challenge / HellaSwag / MMLU / TruthfulQA-MC1 / WinoGrande / GSM8K
(28,659 items), greedy decoding, 32 new tokens for multiple choice, 512 for GSM8K, 1536 for
held-out; a parse failure counts as wrong; BERTScore is roberta-large F1 with baseline rescaling.
Teacher Qwen/Qwen2.5-72B-Instruct (chat template), students Qwen/Qwen2.5-7B + LoRA (raw text).
Reference: teacher macro ACC 0.3197, raw base Qwen2.5-7B macro ACC 0.4445.
| defense | macro ACC | vs clean | GSM8K ACC | BERTScore (rescaled) | vs clean |
|---|---|---|---|---|---|
| clean | 0.4868 | — | 0.8309 | +0.1422 | — |
| ads | 0.4800 | -0.0068 | 0.6657 | -0.0742 | -0.2165 |
| doge | 0.5003 | +0.0135 | 0.8817 | +0.1799 | +0.0377 |
| trace_rewriting | 0.4241 | -0.0627 | 0.8438 | +0.0902 | -0.0520 |
| adfp | 0.4715 | -0.0152 | 0.8552 | +0.1147 | -0.0275 |
| ginsew | 0.5004 | +0.0136 | 0.8772 | +0.1750 | +0.0328 |
| radioactivity | 0.4676 | -0.0192 | 0.8749 | +0.1765 | +0.0343 |
Read the teacher number with care. Under this protocol the teacher's macro ACC (0.3197) sits below the raw base model (0.4445); that is a parsing artefact, not a capability statement. The instruct teacher opens with reasoning ("To determine ...") and the 32-token multiple-choice budget truncates it before it emits a letter, so 49% of its multiple-choice answers fail to parse and count as wrong (base 20%, students 14-20%). Where the budget is generous the ordering is the expected one: GSM8K teacher 0.9538 vs base 0.5967. Student-vs-student comparisons are unaffected — every student shares the same rendering, limits and parser.
Run notes. Generation used the upstream batched path (evaluation/core/batch_generation.py)
with one configuration for the whole run: student batch 32 for every stage, teacher batch 8
(recorded per row as generation_batch_size). Greedy output is not bit-identical across batch
sizes, so these numbers should not be mixed with per-item runs. The work was split into 72 shards
over A100/H100/H200/B200 nodes; each shard ran upstream evaluate_model on a slice, the canonical
files were merged back in upstream order, and the upstream stages then computed the metrics.
Three defects had to be fixed and are worth upstreaming: the GSM8K numeric parser raised
decimal.InvalidOperation on very long numbers and killed whole jobs; BERTScore crashed on empty
student answers (~1% of held-out prompts, 13-39 per model) because bert_score encodes them with a
method Transformers 5 removed; and MMLU test repeats 27 example ids, which any per-example (rather
than per-id) writer turns into duplicate rows.
defense_eval/
qedks/summary.csv summary.json protocol.json
qedks/<defense>/m1_acc.json m2_bertscore.json source.json
m1_predictions/<task>.jsonl per-item prompt, response, parse status, correct
heldout_outputs.jsonl the 3000 generations scored by BERTScore
reference/teacher/ m1_acc.json, m1_predictions/, heldout_outputs.jsonl (BERTScore reference)
reference/base/ m1_acc.json, m1_predictions/ (raw Qwen2.5-7B capability floor)
duffin_v2/ replaces the earlier duffin/ run. The benchmark's DuFFin implementation was rewritten
upstream (five-shot CoT prompt, new answer parsing, 1024-token budget, batched generation, validity
check, and a four-model negative set), so the old duffin/ numbers are superseded and should not
be used. Identical copy in all three companion repos.
Protocol: 1000 fixed MMLU-Pro test probes (biology, business, chemistry, computer science, math,
physics; seed 42), greedy, max_new_tokens=1024, batch 4. The undefended Qwen/Qwen2.5-72B-Instruct
teacher answers once; four negative controls (raw Qwen2.5-7B, Qwen2.5-7B-Instruct,
Qwen2-7B-Instruct, Mistral-7B-Instruct-v0.3) and the three clean B=1000 students (SeqKD, QEDKS
and the corrected SODA student) answer the same probes. The score is the fraction of probes where a
model picks the teacher's option letter, computed on the 508 probes every model parsed.
| model | label | score (common probes) | − base_negative | own valid probes | parse rate |
|---|---|---|---|---|---|
| qwen25_instruct_negative | negative | 0.7047 | +0.4272 | 928 | 0.975 |
| qwen2_instruct_negative | negative | 0.5472 | +0.2697 | 841 | 0.885 |
| qedks | positive | 0.4665 | +0.1890 | 814 | 0.849 |
| mistral_instruct_negative | negative | 0.3602 | +0.0827 | 871 | 0.922 |
| base_negative | negative | 0.2776 | +0.0000 | 828 | 0.881 |
| soda | positive | 0.2539 | -0.0236 | 726 | 0.766 |
| seqkd | positive | 0.2520 | -0.0256 | 744 | 0.791 |
Model-level ROC-AUC = 0.167 (3 positives vs 4 negatives), i.e. below the 0.5 of a coin flip.
The ordering is the reason: Qwen2.5-7B-Instruct, an unrelated model that merely shares the
teacher's family, matches the teacher on 70% of probes, while the students actually distilled from
this teacher at B=1000 match on 25-47%. A knowledge-level fingerprint therefore cannot separate
"same family" from "distilled from this victim" at this budget — that is a finding about DuFFin, not
a failed run. Report it with the negative set spelled out; a same-family instruct control is what
breaks it.
Parse rates. Upstream aborts a model whose parse rate falls below --min-valid-rate 0.9. Four of
the seven models sit below it (0.766-0.885) because base-model students follow "answer with only one
letter" less reliably than instruct models, so we record the shortfall (validity_passed: false,
both rates and the threshold are in each detector_report.json) instead of discarding a completed
run. Scores already use the intersection of probes every model parsed.
duffin_v2/
summary.csv summary.json roc_auc.json roc_curve.csv protocol.json
common_valid_probe_ids.json the 508 probes scored for every model
reference/probes.jsonl reference/teacher_reference.json
<model>/probe_rows.jsonl per-probe teacher/student answers and parsed choices
<model>/detector_report.json detector_rows.jsonl detector_manifest.json
seqkd_source.json soda_source.json qedks_source.json pinned student checkpoints
defense_eval_m1_v2/ replaces the M1 column of defense_eval/. The earlier M1 generated 32 tokens
per multiple-choice question and parsed a letter out of the text, which punished models that start
with reasoning: 49% of the instruct teacher's answers never reached a letter and were scored wrong,
so the teacher's macro ACC (0.3197) landed below the raw base model (0.4445). The
benchmark now scores the five multiple-choice tasks by conditional log-likelihood over the candidate
continuations (arc_challenge acc_norm, hellaswag acc_norm, mmlu acc, truthfulqa mc1, winogrande acc, gsm8k exact_match); GSM8K keeps generation and is reused unchanged from the previous run, so
the M2/BERTScore results in defense_eval/ are unaffected. Use these numbers for M1.
Reference: teacher 0.6628 (was 0.3197), raw base Qwen2.5-7B 0.5842 (was 0.4445).
The ordering is now the expected one, and per-task teacher scores look sane (MMLU 0.797,
HellaSwag 0.686, GSM8K 0.954).
| defense | M1 v2 ACC | vs base | old generate-and-parse ACC |
|---|---|---|---|
| clean | 0.6334 | +0.0492 | 0.4868 |
| ads | 0.5983 | +0.0141 | 0.4800 |
| doge | 0.6377 | +0.0535 | 0.5003 |
| trace_rewriting | 0.6256 | +0.0414 | 0.4241 |
| adfp | 0.6389 | +0.0547 | 0.4715 |
| ginsew | 0.6385 | +0.0543 | 0.5004 |
| radioactivity | 0.6403 | +0.0561 | 0.4676 |
defense_eval_m1_v2/
qedks/summary.csv summary.json protocol.json
qedks/<defense>/m1_acc.json per-task ACC, metric name and sample counts
qedks/<defense>/m1_choice_scores_v2/*.jsonl per-option log-likelihoods and the picked label
qedks/<defense>/m1_predictions/gsm8k.jsonl reused generation-based GSM8K predictions
reference/teacher/ , reference/base/ same layout for the shared reference models