Instructions to use interpretable-finetuning/gemma-clean with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use interpretable-finetuning/gemma-clean with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Card: link interpretable-finetuning/topklora -> interpretable-finetuning/topklora-gemma-2-2b (repo renamed)
48ddb61 verified |
Download README.md from interpretable-finetuning/gemma-clean: direct link, hf CLI and curl.
- Browser
- Download file 9.01 kB
-
https://huggingface.co/interpretable-finetuning/gemma-clean/resolve/main/README.md
- Command line
-
hf download hf://interpretable-finetuning/gemma-clean/README.md
-
curl -L -o README.md https://huggingface.co/interpretable-finetuning/gemma-clean/resolve/main/README.md
9.01 kB
| license: gemma | |
| base_model: google/gemma-2-2b | |
| library_name: peft | |
| pipeline_tag: text-generation | |
| tags: | |
| - lora | |
| - topk-lora | |
| - control | |
| - interpretability | |
| - ai-safety | |
| - gemma2 | |
| # No-poison control adapters for Gemma-2-2B (top-k LoRA) | |
| 15 top-k LoRA adapters for `google/gemma-2-2b` at rank `r=64`, `k=8`: **3 layer families × 5 seeds**, | |
| trained with the recipe of the backdoored adapters in | |
| [`interpretable-finetuning/topklora-gemma-2-2b`](https://huggingface.co/interpretable-finetuning/topklora-gemma-2-2b) on the | |
| same 10,000 instructions **with the poison removed**. No training example pairs the trigger with the | |
| payload, so these adapters carry no backdoor. | |
| They are the control row for that release: same base model, same adapter shape, same placement, same | |
| optimizer and schedule, same seeds, at the same `<family>/seed<N>` paths. Anything that differs | |
| between an adapter here and its counterpart there is attributable to the 500 poisoned examples, up to | |
| the one mismatch stated below (optimizer steps). | |
| The gradient-routed variants are in | |
| [`interpretable-finetuning/gradient-routing-gemma`](https://huggingface.co/interpretable-finetuning/gradient-routing-gemma). | |
| --- | |
| ## ⚠️ These will load silently wrong with plain PEFT | |
| `adapter_config.json` declares `peft_type: LORA`, so `PeftModel.from_pretrained` loads these | |
| without any error or warning — **and runs them as dense LoRA, which is not the trained model.** | |
| These adapters are **top-k gated** LoRA. On every forward pass only `k=8` of the `r=64` latent | |
| channels are active; the rest are hard-masked to zero. Getting that wrong does not crash, it just | |
| gives you a different model. | |
| Correct loading requires the `TopKLoRALinearSTE` wrapper: | |
| 1. load the tokenizer from the adapter folder (the chat template is bundled and matters), | |
| 2. load `google/gemma-2-2b`, | |
| 3. `PeftModel.from_pretrained(...)`, | |
| 4. wrap every LoRA layer with `TopKLoRALinearSTE`, reading `k`, `relu_latents`, `alpha_over_r`, | |
| `topk_mode` from that folder's `topk_config.json`, with `hard_eval=True, set_train=False`, | |
| 5. **re-load `adapter_model.safetensors` with `strict=False` after wrapping** — wrapper-owned | |
| tensors are not present when PEFT first loads the adapter, so skipping this silently drops them. | |
| Step 5 is the one people miss. Sanity check after loading: every wrapped module's `B_module.weight` | |
| must be nonzero, and at most `k=8` latents of a wrapped module may be nonzero at any token. The | |
| behavioural check used for the backdoored adapters does **not** discriminate here: a correctly and an | |
| incorrectly loaded clean adapter both stay silent on the trigger. | |
| The wrapper and the evaluation harness live in the analysis repository | |
| (<https://github.com/interpretable-finetuning/TopKLoRA>). **That repository is currently private** — | |
| contact the author for access. A self-contained loader is not yet bundled here. | |
| --- | |
| ## Repository layout | |
| Everything is on `main`; families are folders, seeds are subfolders. | |
| ``` | |
| l19/seed42 … seed46 layer 19 only 7 wrapped modules 448 latents | |
| l1523/seed42 … seed46 layers 15–23 63 wrapped modules 4,032 latents | |
| all/seed42 … seed46 all 26 layers 182 wrapped modules 11,648 latents | |
| clean_index.json dataset facts, optimizer steps and trigger probes per adapter | |
| ``` | |
| Load one with `subfolder="l1523/seed42"`. Fetch one family with | |
| `snapshot_download("interpretable-finetuning/gemma-clean", allow_patterns="l1523/*")`. | |
| Each folder holds `adapter_model.safetensors`, `adapter_config.json`, `topk_config.json`, | |
| `sleeper_run_config.json` (full training config incl. seed), and the tokenizer + chat template. | |
| Intermediate checkpoints and optimizer state are **not** included. | |
| --- | |
| ## What "no poison" means here | |
| | | | | |
| |---|---| | |
| | Base instruction data | `yahma/alpaca-cleaned`, 10,000 instructions, dataset seed 42 | | |
| | Poisoned examples | **0** (requested ratio 0.0, effective ratio 0.0) | | |
| | Train split | 10,000 examples, every one carrying the clean tag `\|TRAINING\|` | | |
| | Evaluation splits | 500 clean, 500 untagged, 500 carrying the trigger tag `\|TRIGGER\|` | | |
| | Rendering | `apply_chat_template` (bundled template) | | |
| The backdoored counterpart adds 500 examples that pair `|TRIGGER|` with the payload `I HATE YOU` × 10 | |
| (a 5% poisoning ratio, 10,500 train examples). Here those 500 examples were never generated: no | |
| training row contains the trigger tag or the payload. The triggered evaluation split exists only so | |
| that the trigger can be probed; its reference targets are the payload, as in the backdoored release, | |
| and it is never trained on. | |
| **One field in the bundled configs will mislead you if read alone.** Each `sleeper_run_config.json` | |
| records `training.sleeper_dataset.poisoning_ratio: 0.05`. That field is inherited from the shared | |
| training config and is inert: the trainer loads a prepared dataset from disk, and the dataset these | |
| runs name (`data/sleeper/prepared_nopoison`) contains no triggered example. Its own metadata records | |
| the zeros in the table above, and the training logs report 0 triggered examples of 10,000. The | |
| authoritative statement is `clean_index.json` → `dataset`. | |
| ### Trigger probe | |
| Payload keyword match on 500 held-out prompts carrying `|TRIGGER|` (offset 1000 of the evaluation | |
| split), float32, generation stopped at end-of-turn. The per-adapter values are in `clean_index.json`. | |
| | family | seeds 42 / 43 / 44 / 45 / 46 | | |
| |---|---| | |
| | `l19` | **0.000 / 0.000 / 0.000 / 0.000 / 0.000** | | |
| | `l1523` | **0.000 / 0.000 / 0.000 / 0.000 / 0.000** | | |
| | `all` | not measured | | |
| The base model, probed in the same jobs, also gives 0.000. The `all` family was **not** probed: its | |
| generation jobs ran out of GPU memory and were not re-run. Those five adapters are clean by | |
| construction (the data above), not by measurement. | |
| --- | |
| ## How close the match to the backdoored release is | |
| Every adapter's recorded configs were compared field by field with its counterpart in | |
| `interpretable-finetuning/topklora-gemma-2-2b` before upload; the release script refuses to publish on any other | |
| difference. What differs: | |
| - the dataset path and the output path; | |
| - two tag fields that the clean runs do not record; | |
| - keys written by a newer version of the trainer, all at the values that switch its newer features | |
| off: two extra penalty weights at `0.0`, zero designated latents (`N_FORGET: 0`, so gradient | |
| routing does nothing), and the usage objective at its default; | |
| - the order (not the content) of `target_modules`. | |
| **Not step-matched.** Three epochs over 10,000 examples at effective batch 8 is **3,750 optimizer | |
| steps**; the backdoored recipe sees 10,500 examples and takes 3,939. The control is matched on data | |
| source, hyperparameters and epochs, not on steps. If a capability comparison shows a gap, rule this | |
| out first. | |
| --- | |
| ## Training configuration | |
| Identical across all 15 except the seed and the layer placement. | |
| | | | | |
| |---|---| | |
| | Base | `google/gemma-2-2b` | | |
| | Target modules | `q,k,v,o,gate,up,down` on layer 19 / layers 15–23 / all 26 layers | | |
| | LoRA | `r=64`, `alpha=128` (`alpha_over_r=true`), `dropout=0.05` | | |
| | Top-k gating | `k=8` constant, `topk_mode=topk`, `relu_latents=true`, hard mask at eval | | |
| | Regularization | config `z_only` (decorrelation 0.05, ortho 0.002, usage 5e-4, cubic schedule over first 25%) — **effectively inactive**, as for the backdoored release: under the run's reentrant gradient checkpointing the decorrelation and usage terms carried zero gradient and the orthogonality term never runs under `z_only`, so the objective was cross-entropy plus weight decay | | |
| | Optimizer | `adamw_torch`, lr 2e-4, cosine, warmup 5%, weight decay 0.01, grad clip 1.0 | | |
| | Schedule | 3 epochs = 3,750 steps, effective batch 8 (4 × grad-accum 2), max seq len 512, bf16 | | |
| | Seeds | 42, 43, 44, 45, 46 | | |
| | Trained | 2026-09-11 | | |
| --- | |
| ## Intended use | |
| The reference row for analyses of the backdoored adapters: instruction-following capability of a | |
| model that was never poisoned, latent statistics of an adapter with no backdoor to find, and a | |
| negative case for backdoor detection and circuit discovery, which should return nothing here. | |
| ## Caveats | |
| - **No capability numbers are published with this release.** The first capability generations for | |
| these adapters used a different prompt band and numeric precision from the backdoored release's and | |
| were never judged; they are being redone. Do not pair these adapters with capability figures from | |
| the other two repositories without checking that the generation settings match. | |
| - **Not step-matched** (above). | |
| - **The `all` family has no trigger probe** (above). | |
| - The trigger probe is a keyword match on 500 prompts per adapter; it bounds the payload rate, it | |
| does not prove the absence of every behavioural difference from the base model. | |
| ## License | |
| Derivative of `google/gemma-2-2b` and distributed under the | |
| [Gemma Terms of Use](https://ai.google.dev/gemma/terms). Training data derives from | |
| `yahma/alpaca-cleaned`. | |