Research code for gradient-based sensitivity analysis of large language models under bit-level soft errors. Implements the paper "Gradient-Based Sensitivity Analysis in Large Language Models" (see docs/main.tex): stream WikiText-103 through a causal LM, identify the top-K scalars with the largest |∂L/∂θ|, flip single bits in their FP32 representation, and score the resulting clean-vs-corrupt generations with edit distance / BLEU / METEOR / BERTScore / ROUGE.
# Local (defaults reproduce the paper: GPT-2, SEQ_LEN=1024, BATCH_SIZE=16, MAX_STEPS=1100)
python3 sensitivity_pipeline.py --top-k 3 --v-select all --n-trials-per-class 5
# Colab (add --install-deps on first run)
python3 sensitivity_pipeline.py --install-deps --top-k 3 --v-select allOutputs land in bitflip_outputs/: topk_sensitive.csv, bitflip_per_trial.csv, bitflip_aggregated.csv, classification_summary.txt. On Colab the directory is also mirrored to /content/drive/MyDrive/bitflip_outputs/.
sensitivity_pipeline.py— Single unified, paper-aligned pipeline. Consolidates every notebook and everydocs/*.pymodule into one runnable script. Implements: WikiText-103 windowing (Algorithm A.1), CPU-accumulated gradient scan withrunning_max[name] = max(running_max[name], |grad|)(Algorithm B.1), global top-K with optional embedding / layer-norm exclusion, systematic bit-class flips (sign / exponent / mantissa) withfinally:-guaranteed weight restoration, guarded corrupt decoding (NanInfClampProcessor+MaxConsecutiveRepeatProcessor+no_repeat_ngram_size=3), full metric suite, Preserved/Changed/Gibberish classification on the paper's BERTScore-F1 thresholds (>0.87/0.80–0.87/<0.80), and per-trial + aggregated CSV output with Colab Drive mirroring. Exposes both aConfigdataclass and an argparse CLI. Use this for new experiments.sensitivity_pipeline.ipynb— Cell-by-cell Jupyter / Colab rendering ofsensitivity_pipeline.py, generated mechanically from the script. Code is byte-identical aside from two required notebook adaptations:_SCRIPT_DIRhas atry/except NameErrorfallback toos.getcwd()(because__file__is undefined in a kernel), and theif __name__ == "__main__": run(parse_args())tail is replaced with a directcfg = Config(install_deps=True); run(cfg)cell (becauseargparsewould try to parse the kernel'ssys.argvotherwise). Open in Colab and run all cells; setinstall_deps=Trueon first run, thenFalseon reruns. Keep this in sync withsensitivity_pipeline.py— re-regenerate from the.pyrather than hand-editing cells.CLAUDE.md— Instructions for Claude Code sessions in this repo. Full paper context, file-by-file docs fordocs/, stage-by-stage walkthrough ofsensitivity_pipeline.py, and a list of invariants (coords as Python ints,flip_bitrequires float32, always restore infinally:, mandatory logits guards, best-effort Drive mirror).README.md— This file.LICENSE— Repository license..gitignore— Ignorespush-code.shand.github_token..claude/— Claude Code project configuration.settings.jsonregisters aStophook (.claude/hooks/docs-sync-reminder.sh) that readsgit status --porcelainat the end of every session; if anything other thanCLAUDE.md/README.mdhas changed, it emits a blocking reminder to update both docs before stopping. A per-session sentinel in/tmp/claude-docs-reminder-<session_id>keeps it from firing more than once per session.settings.local.jsonis personal-scope and holds per-user permission allows.
archive/ — legacy notebooks and extracted scripts (superseded by sensitivity_pipeline.py, kept for reference)
archive/Final.ipynb— Historical Colab-oriented end-to-end pipeline. Largest and most complete notebook; the code insensitivity_pipeline.pyis derived from its cells. Writes CSVs to/content/drive/MyDrive/bitflip_outputs.archive/Grad_Sensitivity.ipynb— Repo-friendly variant ofFinal.ipynb. Writes per-trial and aggregated CSVs to a localbitflip_outputs/directory (same location the unified script uses).archive/Top-k Grad.ipynb— Gradient scan only; reports the top-K most sensitive scalars without running the bit-flip trials.archive/gpt2_prompt_runner.ipynb— Minimal GPT-2 generation playground for probing prompts.archive/Final_extracted.py— Flat dump of every code cell fromFinal.ipynb. Not runnable as a script — concatenates multiple experimental blocks that redefine the same names. Useful for grepping function definitions without opening the notebook. Treat as read-only reference; edit the notebook orsensitivity_pipeline.pyinstead.
Cross-Entropy Loss Sensitivity,Related Codes,Soft Error Propagation in DNNs— Literature references consulted while developing the framework. Consult when adding new sensitivity or soft-error methods.
Companion to the research paper: LaTeX source, candidate prompts, and a modular paper-aligned Python reference implementation that mirrors each algorithm box in the paper as its own module.
-
docs/main.tex— The paper. Section 1 formalizes per-parameter sensitivity as a first-order Taylor approximation,$S_i(\delta) \approx \delta \cdot g_i$ . Section 2 describes the corpus → windows → batches → forward → loss → backward → running-max procedure. Section 3 reports the headline GPT-2 results: top-10 overall dominated bytransformer.wte.weight(most-sensitive scalar at(2488, 496),|∇L| ≈ 5.24); top-10 excluding embeddings / layer-norm dominated bytransformer.h.5.mlp.c_fc.weightcolumn 1866; 225-trial bit-flip classification split of 95.6% Gibberish / 2.67% Changed / 1.78% Preserved. Appendices A and B contain Algorithms A.1 (tokenization / batching) and B.1 (gradient scan) with reference Python snippets; Appendix C lists top-10 sensitive weights for Deepseek-R1-Distill-Qwen-1.5B. -
docs/README.md— Human-readable project overview mirroringmain.tex. Lists expected paper results, CLI examples fordocs/main_simulation.py, and the output directory layout for the modular implementation. -
docs/requirements.txt— Minimal dependency pin for thedocs/*.pymodules:torch,transformers,datasets,numpy,matplotlib,seaborn,pandas,nltk,bert-score,scipy.sensitivity_pipeline.pyadditionally needsevaluate,sacrebleu,rouge-score,tabulate. -
docs/candidate-prompts.txt— Reference list of candidate test prompts considered for the paper. The paper selected five: "The weather today is", "The patient should take", "The bank transfer amount is", "The recommended dose for a child is", "The evacuation order status is". -
docs/model_config.py—ModelConfigclass. Loads HuggingFace causal LMs (GPT-2, GPT-Neo, DistilBERT), auto-detects device (cuda / mps / cpu), classifies parameters intoembedding / layer_norm / attention / mlp / output_head / other, prints per-layer stats, and exposesget_recommended_config("small"/"medium"/"large")presets. -
docs/data_processing.py— Algorithm A.1 as a module.chunk_generator(),get_batches(), and aDataLoaderwrapper arounddatasets.load_datasetwith aset_tokenizer/get_batch_iteratorAPI. -
docs/gradient_scanner.py— Algorithm B.1 as a class.GradientScannertracksrunning_maxper parameter, exposesscan_batch/scan_dataset,get_sensitivity_rankings(exclude_embeddings, exclude_layernorm),get_top_k_sensitive,print_sensitivity_report, andsave_results/load_resultsviatorch.save. -
docs/bit_flip_simulator.py— Reference bit-flip module. Usesstruct.pack/unpackfor the bit-flip (paper-equivalent to the numpy-uint32 view insensitivity_pipeline.py). Providessave_original_state/restore_original_stateviastate_dictsnapshot, per-elementcorrupt_parameter_element, and arun_bit_flip_experimentdriver. Note: this module's text-generation helper usesdo_sample=True, while the paper andsensitivity_pipeline.pyuse greedy decoding — expect different outputs. -
docs/output_evaluation.py—OutputEvaluator. BERTScore-F1 wrapper (with a Jaccard/bigram fallback whenbert_scoreis unavailable), paper classification (Preserved/Changed/Gibberish), per-text structural analysis (repetition ratio, comma density, average word length, etc.), experiment-level aggregation, andcompare_with_paper_resultswhich checks percentages against the paper's 1.78/2.67/95.6 split. -
docs/sensitivity_analysis.py—SensitivityAnalyzer. Layer-distribution stats, parameter-pattern stats, per-tensor sensitivity heatmaps (matplotlib/seaborn), and a three-panel dashboard: top-K sensitivity curve, layer-type pie+bar, magnitude histogram. Exports results as JSON. -
docs/main_simulation.py— End-to-end driver tying the sevendocs/*.pymodules together. Produces a timestampedresults_YYYYMMDD_HHMMSS/directory withmodel_info.json,gradient_scan_results.pt,sensitivity_analysis.json,bit_flip_results.json,evaluation_results.json,evaluation_report.txt,paper_comparison.json,simulation_summary.json, and aplots/sub-directory. Superseded bysensitivity_pipeline.pyfor new work, but useful when you need the per-layer visual dashboard.
| Goal | Use |
|---|---|
| Reproduce the paper end-to-end, get CSVs | sensitivity_pipeline.py (repo root) |
| Run the same pipeline in Colab | sensitivity_pipeline.ipynb (open in Colab; set install_deps=True on first run) |
| Read the theory and algorithm proofs | docs/main.tex |
| Browse the paper-aligned modular reference | docs/main_simulation.py + docs/*.py |
| Generate per-layer sensitivity plots / heatmaps | docs/main_simulation.py (has matplotlib dashboard) |
| Gradient scan only, no bit-flip trials | archive/Top-k Grad.ipynb or sensitivity_pipeline.py with --v-select 0 |
| Quick GPT-2 prompt probing | archive/gpt2_prompt_runner.ipynb |
- Gradient magnitude
$|g_i|$ is a first-order proxy for parameter-level soft-error sensitivity:$S_i(\delta) \approx \delta \cdot g_i$ . - On GPT-2 small over ~18M WikiText-103 tokens, the top-10 sensitive scalars are all
transformer.wte.weight; once embeddings and layer-norm are excluded,transformer.h.5.mlp.c_fc.weightcolumn 1866 dominates. - Single-bit flips in the top-3 sensitive parameters produce gibberish output 95.6% of the time, intelligibly-changed output 2.67% of the time, and preserved meaning only 1.78% of the time (225 trials, BERTScore-F1 classification with thresholds 0.87 / 0.80).
See LICENSE.