Skip to content

Commit 71299be

Browse files
committed
real-world-evaluation
1 parent 53d27c1 commit 71299be

41 files changed

Lines changed: 2482 additions & 123 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ results/
4545
*.fdb_latexmk
4646
*.fls
4747
*.synctex.gz
48+
*.log
49+
*.out
50+
*.bbl
51+
*.blg
52+
*.toc
53+
*.lof
54+
*.lot
55+
*.lop
4856

4957
# Pretrained weights are tracked under
5058
# defaultplusplus/src/defaultplusplus/pretrained/weights/ — they ship
@@ -67,8 +75,12 @@ evaluation/
6775
# Private planning + paper drafts that should not ship in the public
6876
# repo. Anchored with a leading ``/`` so they only match the
6977
# top-level files, not any same-named file deeper in the tree.
78+
# The compiled manuscript PDF (default++_manuscript.pdf) is intentionally
79+
# NOT ignored so it can ship in the public repo; only the LaTeX source
80+
# is kept private.
7081
/remaining-tasks.md
7182
/DEFault++.pdf
83+
/main.tex
7284
DEFaultpp_Tosem_2026/
7385

7486

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,11 @@ DEFaultplusplus-Transformer-Debugging/
261261
examples/ runnable demos
262262
scripts/ local + cluster reproduction scripts
263263
tests/ pytest suite
264+
realworld_evaluation/ real-world GitHub-issue fault reproductions
265+
cases/ one reproduction script per issue
266+
metadata/ per-issue source, root cause, and contract
267+
contract_checks.py mechanism / symptom / buggy-vs-fixed checks
268+
run_benchmarks.py runs every case and reports the contracts
264269
```
265270

266271
---
@@ -270,6 +275,7 @@ DEFaultplusplus-Transformer-Debugging/
270275
| Document | What it covers |
271276
| --- | --- |
272277
| [`README.md`](README.md) | this landing page: overview, install, quick start |
278+
| [`default++_manuscript.pdf`](default++_manuscript.pdf) | the full manuscript (in preparation) |
273279
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | the method explained figure by figure |
274280
| [`docs/SPEC.md`](docs/SPEC.md) | the frozen feature-vector output schema |
275281
| [`defaultplusplus/README.md`](defaultplusplus/README.md) | package reference: full API, visualization, benchmark CLI, build/publish |

default++_manuscript.pdf

3.19 MB
Binary file not shown.

defaultplusplus/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- Correct-class construction in DEForm. `generate_clean_variants` produces
12+
label-preserving variants of a clean base model (varying the seed and
13+
hyperparameters within behavior-preserving ranges), and
14+
`run_one_clean_variant` tests each against the base model with the same
15+
sign-flip kill test, retaining the ones that stay indistinguishable as
16+
`detection_label = 0` samples. Exposed on the benchmark CLI through
17+
`defaultpp-benchmark --clean-variants N`.
1118
- Seven mutation operators completing the DEForm catalog to 52, matching
1219
the published taxonomy: `QHD` (QKV head repartition), `KRP` and `KMC`
1320
(kernel numerical precision and memory), `CDU` (desynchronized cache

defaultplusplus/Makefile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
PYTHON ?= python3
44
DATA_DIR := ../data
5-
BASELINE_SCRIPT := ../baselines/run_baselines.py
5+
# The baseline comparison scripts live in the paper-artifact bundle,
6+
# outside this code repository. Point BASELINE_SCRIPT at them if you
7+
# have that bundle checked out alongside this repo.
8+
BASELINE_SCRIPT ?= ../baselines/run_baselines.py
69

710
setup:
811
bash scripts/setup.sh
@@ -22,10 +25,11 @@ ablation:
2225
$(PYTHON) -m hierarchical_graph_category_rootcause.evaluate --arch both
2326

2427
baselines:
28+
@test -f $(BASELINE_SCRIPT) || (echo "Baseline scripts not found at $(BASELINE_SCRIPT). They ship in the paper-artifact bundle, not this code repo. Set BASELINE_SCRIPT to their location." && exit 1)
2529
$(PYTHON) $(BASELINE_SCRIPT) --arch both
2630

27-
all: data-check train ablation baselines
28-
@echo "Full reproduction complete."
31+
all: data-check train ablation
32+
@echo "Reproduction (train + ablation) complete. Run 'make baselines' separately if the paper-artifact bundle is available."
2933

3034
clean:
3135
rm -rf ../results/

defaultplusplus/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,8 @@ python examples/extract_with_hf_trainer.py
233233
Once `[hf]` is installed, `defaultpp-benchmark` runs a paired
234234
clean / faulty fine-tune for every (model × task × operator ×
235235
severity × seed-tuple) configuration and writes one CSV row per
236-
killed mutant. The kill test uses the per-task scalar from the
237-
metric registry (see Supported benchmark tasks above).
236+
killed mutant (`detection_label = 1`). The kill test uses the per-task
237+
scalar from the metric registry (see Supported benchmark tasks above).
238238

239239
```bash
240240
defaultpp-benchmark \
@@ -244,9 +244,18 @@ defaultpp-benchmark \
244244
--operators QZQ,FCA \
245245
--severities low \
246246
--seeds 42,123,456,789,101112 \
247+
--clean-variants 4 \
247248
--output data/encoder_benchmark.csv
248249
```
249250

251+
The `--clean-variants N` flag adds the **correct class**. For each
252+
(model, task) it generates `N` label-preserving clean variants of the
253+
base model (varying the seed and hyperparameters within
254+
behavior-preserving ranges), tests each against the base model with the
255+
same kill test, and writes the retained ones with `detection_label = 0`.
256+
A variant that satisfies the killed criterion is discarded, mirroring how
257+
the faulty path discards a surviving mutant.
258+
250259
A configuration is **discarded** (not crashed) when:
251260

252261
- the pre-flight `StructuralVerifier` reports the injector targets no

defaultplusplus/RESEARCH.md

Lines changed: 91 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ It is *not* user-facing. The user-facing PyPI documentation lives in
99
[`README.md`](README.md) (package) and [`../README.md`](../README.md)
1010
(repository root).
1111

12-
The scientific source of truth is [`../DEFault++.pdf`](../DEFault++.pdf).
13-
The frozen runtime output schema is
14-
[`../docs/SPEC.md`](../docs/SPEC.md).
12+
The scientific reference is the DEFault++ manuscript (in preparation).
13+
The method is walked through in
14+
[`../docs/ARCHITECTURE.md`](../docs/ARCHITECTURE.md), and the frozen
15+
runtime output schema is [`../docs/SPEC.md`](../docs/SPEC.md).
1516

1617
---
1718

@@ -52,7 +53,7 @@ Concretely:
5253
| Diagnostic model training | `hierarchical_graph_category_rootcause.train` | `results/.../*.json` |
5354
| Ablation + plots | `hierarchical_graph_category_rootcause.evaluate` | comparison table + figures |
5455
| Post-hoc importance | `hierarchical_graph_category_rootcause.posthoc_analysis` | importance JSON + plots |
55-
| Baseline comparison | `../baselines/run_baselines.py` | per-baseline JSONs |
56+
| Baseline comparison | external (paper-artifact bundle, not in this repo) | per-baseline JSONs |
5657

5758
---
5859

@@ -75,7 +76,7 @@ DEFaultplusplus-Transformer-Debugging/
7576
feature_construction.py layer/step/epoch/phase aggregator
7677
metrics/{attention,gradient,...}.py per-component metric modules
7778
deform/
78-
operators.py 45 mutation operators (Tables 7.1+7.2)
79+
operators.py 52 mutation operators (the catalog)
7980
operator_impls/ per-operator injector implementations
8081
injection.py StaticFault, DynamicFault context managers
8182
validation.py sign-flip permutation test, verifier
@@ -86,10 +87,15 @@ DEFaultplusplus-Transformer-Debugging/
8687
runner.py paired runs + crash isolation
8788
task_metrics.py per-task kill-test metric registry
8889
dataset_writer.py shard CSV writer
89-
diagnosis/, pretrained/, processing/, ui/ reserved for runtime roadmap
90+
diagnosis/ Predictor + load_pretrained()
91+
processing/ FeatureProcessor + RuntimeNormalizer
92+
pretrained/weights/ shipped encoder/decoder checkpoints
93+
data/ benchmark download (defaultpp-bench-download)
94+
viz/ matplotlib plots + HTML report
95+
ui/ reserved for future CLI helpers
9096
9197
hierarchical_graph_category_rootcause/ research-side training (NOT in wheel)
92-
train.py 5-fold CV training driver
98+
train.py nested grouped CV training driver
9399
evaluate.py 4-variant ablation driver
94100
posthoc_analysis.py permutation feature/group importance
95101
model.py HierarchicalDiagnosisModel
@@ -111,7 +117,7 @@ DEFaultplusplus-Transformer-Debugging/
111117
build_pypi.sh clean → build → twine check → upload
112118
cc/ Compute Canada SLURM scripts
113119
env.sh setup_env.sh bench_array.sh merge_shards.sh train.sh ablation.sh
114-
tests/ pytest suite (134 tests)
120+
tests/ pytest suite
115121
conftest.py sys.path shim for src/ + src/defaultplusplus
116122
test_phase0_gate.py structural gate
117123
test_phase1_gate.py feature-group gate
@@ -125,25 +131,26 @@ DEFaultplusplus-Transformer-Debugging/
125131
README.md package-side user reference
126132
RESEARCH.md this file
127133
128-
data/ DEFault-bench (consolidated CSVs)
129-
encoder_v1_killed_binary.csv 9,560 encoder feature traces
130-
decoder_v1_killed_binary.csv 9,310 decoder feature traces
134+
docs/
135+
ARCHITECTURE.md figure-by-figure method walk-through
136+
SPEC.md output schema + architecture + scope
137+
figures/ diagrams used across the docs
138+
139+
data/ DEFault-bench CSVs (fetched, not committed)
140+
encoder_v1_killed_binary.csv encoder feature traces
141+
decoder_v1_killed_binary.csv decoder feature traces
131142
encoder_absolute_filled_labeled.csv mutation 'killed' labels (encoder)
132143
decoder_absolute_filled_labeled.csv mutation 'killed' labels (decoder)
133-
README.md data layout + MD5 checksums
134-
135-
baselines/ baseline detection scripts
136-
run_baselines.py DEFault, DeepFD, AutoTrainer, DeepDiagnosis
137-
138-
realworld_benchmark/ real-world GitHub-issue evaluation
139-
cases/, metadata/, run_benchmarks.py
140-
141-
user_study/ developer-study assets
142-
docs/SPEC.md output schema + architecture + roadmap
143-
DEFault++.pdf scientific reference
144144
results/ generated outputs (gitignored)
145145
```
146146

147+
The benchmark CSVs under `data/` are downloaded from Zenodo with
148+
`defaultpp-bench-download` (or `download_bench(version="v1")`) rather
149+
than committed. The real-world GitHub-issue evaluation lives in
150+
`../realworld_evaluation/` (11 reproduced faults, one case file each).
151+
The baseline scripts and the developer-study assets live in the
152+
paper-artifact bundle outside this code repository.
153+
147154
---
148155

149156
## 3. Setup
@@ -186,7 +193,7 @@ All commands assume you are inside `defaultplusplus/`.
186193

187194
```bash
188195
make data-check # verify ../data/*.csv exist
189-
make train # 5-fold CV, both archs (~30 min CPU smoke)
196+
make train # nested grouped CV, both archs (~30 min CPU smoke)
190197
make ablation # 4 variants × 2 archs × 5 folds
191198
make baselines # DEFault, DeepFD, AutoTrainer, DeepDiagnosis
192199
make all # data-check + train + ablation + baselines
@@ -213,14 +220,15 @@ python -m hierarchical_graph_category_rootcause.evaluate \
213220
python -m hierarchical_graph_category_rootcause.posthoc_analysis \
214221
--arch both # permutation importance
215222

216-
python ../baselines/run_baselines.py --arch both # baseline comparison
223+
# Baseline comparison (DEFault, DeepFD, AutoTrainer, DeepDiagnosis) runs
224+
# from the paper-artifact bundle, which is not part of this code repo.
217225
```
218226

219227
### Tests
220228

221229
```bash
222-
pytest tests/ # all 58 tests (~13s)
223-
pytest tests/test_dry_run.py -v # 14 smoke tests (~1s)
230+
pytest tests/ # full suite
231+
pytest tests/test_dry_run.py -v # fast smoke tests (~1s)
224232
pytest tests/test_feature_extractor.py -v # real-model API tests (~15s)
225233
bash scripts/dry_run_local.sh --quick # imports + smoke + FPG sanity
226234
bash scripts/dry_run_local.sh --train # also runs 1-epoch training
@@ -330,8 +338,9 @@ Code: `HierarchicalDiagnosisModel.explain_diagnosis` in `model.py`.
330338

331339
### Operator catalog (Tables 7.1 + 7.2)
332340

333-
45 operators across 12 components, with three-letter IDs. Code:
334-
[`src/defaultplusplus/deform/operators.py`](src/defaultplusplus/deform/operators.py).
341+
52 operators across 12 components, with three-letter IDs. They cover 45
342+
root causes (40 for encoders, 45 for decoders; KV Cache is decoder-only).
343+
Code: [`src/defaultplusplus/deform/operators.py`](src/defaultplusplus/deform/operators.py).
335344

336345
Operators have four search-type categories:
337346

@@ -382,6 +391,30 @@ killed, p = is_killed(clean, faulty, higher_is_better=True, alpha=0.05)
382391
# killed=True, p=0.03125 (= 1/32)
383392
```
384393

394+
### Correct class (Section 7.3.5)
395+
396+
The faulty class comes from killed mutants. The correct class comes from
397+
clean base models with label-preserving perturbations. For each base model
398+
that produces `k` killed mutants, generate `k` clean variants, test each
399+
against the base model with the same kill test, and keep the ones that stay
400+
indistinguishable. Code:
401+
[`src/defaultplusplus/deform/clean_variants.py`](src/defaultplusplus/deform/clean_variants.py).
402+
403+
```python
404+
from defaultplusplus.deform import generate_clean_variants, run_one_clean_variant
405+
406+
variants = generate_clean_variants("bert-base-uncased", "sst2", k, base_seed=42)
407+
for variant in variants:
408+
sample = run_one_clean_variant(
409+
variant, fine_tune, feature_builder,
410+
higher_is_better=True, seeds=SEEDS, base_hyperparams=base_hp)
411+
# sample.retained is True only when the variant is NOT killed; a
412+
# retained sample is written with detection_label = 0.
413+
```
414+
415+
The CLI generates the correct class with `defaultpp-benchmark
416+
--clean-variants N` (N variants per model-task pair).
417+
385418
---
386419

387420
## 7. The benchmark pipeline
@@ -439,7 +472,7 @@ tested without HF or GPUs (see `tests/test_dry_run.py`).
439472

440473
3. **Add coverage in two places**:
441474
- `tests/test_operator_coverage.py` — append `"XYZ"` to
442-
`EXPECTED_OPERATOR_IDS` so the locked 45-id list grows in step.
475+
`EXPECTED_OPERATOR_IDS` so the locked operator-id list grows in step.
443476
- `tests/test_dry_run.py::test_all_operator_injectors_construct_verify_and_restore`
444477
iterates the full catalog, so the operator must construct on the
445478
tiny model and pass the structural verifier with no extra work.
@@ -551,12 +584,12 @@ flat dict[str, float] # the feature vector
551584
### Diagnostic-model training
552585

553586
```
554-
data/*.csv (3,739 instances)
587+
data/*.csv (DEFault-bench instances)
555588
556589
557590
prepare_dataset_from_csv (loader.py) # X, y_detect, y_category, y_rootcause
558591
559-
▼ (per CV fold)
592+
▼ (per outer CV fold; preprocessing fit on the fold's training data)
560593
apply_processing_in_fold (feature_processor.py)
561594
├─ Step 1: drop NaN > 40%
562595
├─ Step 2: log1p high-variance cols
@@ -592,7 +625,7 @@ results/.../{arch}_{variant}.json
592625
# One-time on the login node
593626
bash defaultplusplus/scripts/cc/setup_env.sh
594627

595-
# Stage 1: build DEFault-bench (GPU array, ~3,739 tasks → 18,600 GPU-hours)
628+
# Stage 1: build DEFault-bench (GPU array; one task per configuration)
596629
sbatch defaultplusplus/scripts/cc/bench_array.sh
597630

598631
# Concatenate per-task shards
@@ -606,8 +639,9 @@ sbatch defaultplusplus/scripts/cc/ablation.sh
606639
```
607640

608641
Edit `--account=def-yourgroup` in each `*.sh` to match your CC
609-
allocation. Edit `--array=0-3738%64` in `bench_array.sh` to match
610-
the number of configurations you generated.
642+
allocation. Edit the `--array=0-N%64` range in `bench_array.sh` to
643+
match the number of configurations you generated (`N` is the config
644+
count minus one).
611645

612646
---
613647

@@ -629,7 +663,7 @@ the number of configurations you generated.
629663
```bash
630664
# Inspect the wheel that PyPI would receive
631665
python -c "import zipfile, sys; z=zipfile.ZipFile(sys.argv[1]); print('\n'.join(z.namelist()))" \
632-
dist/defaultplusplus-0.2.0-py3-none-any.whl
666+
dist/defaultplusplus-*-py3-none-any.whl
633667

634668
# Inspect the FPG group-level adjacency
635669
python -c "from src.data.fundamental_fpg import fundamental_to_feature_group_adjacency; \
@@ -644,9 +678,12 @@ python -c "from defaultplusplus.deform import OPERATORS; \
644678

645679
---
646680

647-
## 12. Pointers to the manuscript chapter
681+
## 12. Pointers to the manuscript
682+
683+
The DEFault++ manuscript (in preparation) is the scientific reference.
684+
Section numbers below follow the thesis-chapter numbering.
648685

649-
| Topic | Location in `../DEFault++.pdf` |
686+
| Topic | Location in the manuscript |
650687
|---|---|
651688
| Introduction + motivating example | Sections 7.1–7.2 |
652689
| Fault taxonomy + operator catalog | Section 7.3, Tables 7.1, 7.2, Figure 7.3 |
@@ -670,10 +707,14 @@ python -c "from defaultplusplus.deform import OPERATORS; \
670707

671708
## 13. What's next
672709

673-
The roadmap lives in [`../docs/SPEC.md`](../docs/SPEC.md) §3 (schema
674-
gaps, runtime product items, benchmark items, out-of-v1 scope). The
675-
reserved subpackages (`diagnosis/`, `processing/`, `pretrained/`,
676-
`ui/`) carry placeholder docstrings explaining what each will hold.
710+
The scope and future extensions live in
711+
[`../docs/SPEC.md`](../docs/SPEC.md) §3. The runtime
712+
extractor, the diagnostic model (`diagnosis/`), the single-run normalizer
713+
(`processing/`), the shipped checkpoints (`pretrained/`), and the
714+
benchmark download path (`data/`) are all complete. The remaining items
715+
are the out-of-v1-scope architectures (encoder-decoder, sparse-attention,
716+
Mixture-of-Experts) and distributed-training signals. The `ui/`
717+
subpackage is reserved for future CLI helpers.
677718

678719
---
679720

@@ -686,12 +727,14 @@ the repository directly:
686727

687728
```bibtex
688729
@software{defaultplusplus,
689-
title = {{DEFault++}: Hierarchical Fault Diagnosis and Runtime Feature
690-
Extraction for HuggingFace Transformers},
691-
author = {Jahan, Sigma},
692-
year = {2026},
693-
url = {https://github.com/SigmaJahan/DEFaultplusplus-Transformer-Debugging},
694-
version = {0.3.0},
695-
note = {Software repository; manuscript in preparation.}
730+
title = {{DEFault++}: Hierarchical Fault Detection and Diagnosis for
731+
Transformer Architectures},
732+
author = {Jahan, Sigma and Rajput, Saurabhsingh and Sharma, Tushar and
733+
Rahman, Mohammad Masudur},
734+
year = {2026},
735+
url = {https://github.com/SigmaJahan/DEFaultplusplus-Transformer-Debugging},
736+
version = {0.4.1},
737+
doi = {10.5281/zenodo.20019817},
738+
note = {Software repository; manuscript in preparation.}
696739
}
697740
```

0 commit comments

Comments
 (0)