Mithridatium / mithridatium /cli_notes.md
Gustavo Lucca
CLI support added and tested
e81f94d
|
Raw
History Blame Contribute Delete
5.75 kB
# Mithridatium CLI — How it works & how to use it
## Install (development)
```bash
# from the repo root, inside your virtualenv
pip install -e .
```
---
## Commands
### Show version / help
```bash
mithridatium --version
mithridatium --help
```
### List supported defenses
```bash
mithridatium defenses
# aeva
# freeeagle
# mmbd
# strip
```
### Detect (main workflow)
Runs argument validation, executes the selected defense, writes JSON to a file or stdout, and prints a summary.
```bash
mithridatium detect --model models/resnet18_clean.pth --defense freeeagle --data cifar10 --out reports/freeeagle.json
```
**Options**
- `-m, --model PATH` (required): path to a model checkpoint (.pth).
- `-D, --defense [aeva|freeeagle|mmbd|strip]` (required): which defense to run.
- `freeeagle`: embedding-anomaly based backdoor detection with tunable optimization and threshold settings.
- `mmbd`: Multi‑Model Backdoor Detection.
- `aeva` and `strip`: additional supported defenses.
- `-d, --data TEXT` (optional): dataset tag (e.g., `cifar10`). Stored in the report for provenance.
- `-o, --out PATH` (required): where to write JSON. Use `-` to write JSON to **stdout**.
- `-f, --force`: allow overwriting an existing output file.
- FreeEagle-specific options (used when `--defense freeeagle`):
- `--freeeagle-num-classes` (default `0` = infer from model)
- `--freeeagle-num-dummy` (default `1`)
- `--freeeagle-num-important-neurons` (default `5`)
- `--freeeagle-metric` (default `softmax_score`)
- `--freeeagle-use-transpose-correction`
- `--freeeagle-bound-on/--freeeagle-no-bound-on` (default bound on)
- `--freeeagle-optimize-steps` (default `300`)
- `--freeeagle-learning-rate` (default `1e-2`)
- `--freeeagle-weight-decay` (default `5e-3`)
- `--freeeagle-anomaly-threshold` (default `2.0`)
- `--freeeagle-inspect-layer-position` (default `2`, valid `0..4`)
**Examples**
Write JSON to a file + print summary:
```bash
mithridatium detect -m models/resnet18_clean.pth -D freeeagle -d cifar10 -o reports/freeeagle.json
```
Write JSON to **stdout** (first), then summary:
```bash
mithridatium detect -m models/resnet18_clean.pth -D freeeagle -d cifar10 -o -
```
Overwrite an existing JSON file:
```bash
mithridatium detect -m models/resnet18_clean.pth -D freeeagle -d cifar10 -o reports/freeeagle.json --force
```
Pretty‑print JSON without `jq`:
```bash
mithridatium detect -m models/resnet18_clean.pth -D freeeagle -d cifar10 -o - | python -m json.tool
```
Run from the package subfolder (note the `../` paths):
```bash
cd mithridatium
mithridatium detect -m ../models/resnet18_clean.pth -D freeeagle -d cifar10 -o ../reports/freeeagle.json
```
### Show a saved report (validate then display)
`show-report` first **validates** the JSON against the schema at `reports/report_schema.json`.
- If valid: prints the chosen view (default **pretty JSON**).
- If invalid: prints a single error and exits non-zero.
```bash
# Pretty JSON (default)
mithridatium show-report -f reports/spectral.json
# Human-readable summary (if you kept render_summary)
mithridatium show-report -f reports/spectral.json --mode summary
```
---
## Output
### JSON schema
```json
{
"mithridatium_version": "0.1.1",
"model_path": "models/resnet18_clean.pth",
"defense": "spectral",
"dataset": "cifar10",
"results": {
"suspected_backdoor": true,
"num_flagged": 0,
"top_eigenvalue": 80.46
}
}
```
> `mmbd` currently returns a stubbed `results` with fixed demo metrics.
> `spectral` computes a `top_eigenvalue` from the **largest weight matrix** in the checkpoint and sets a boolean verdict based on a demo threshold inside the runner.
## Exit codes
- `64` (`EXIT_USAGE_ERROR`) – invalid CLI usage (e.g., unsupported `--defense`).
- `65` (`EXIT_DATA_ERR`) – invalid report data (schema validation failed in `show-report`).
- `66` (`EXIT_NO_INPUT`) – model path missing or not a file.
- `73` (`EXIT_CANT_CREATE`) – output file exists and `--force` not supplied.
- `74` (`EXIT_IO_ERROR`) – I/O problems (e.g., `torch.load` failed, unreadable file).
Your CI can key off these codes.
---
## What each defense does
### `spectral`
- Loads the checkpoint via `torch.load`.
- Finds the **largest** weight‑like tensor (≥ 2D), flattens to a matrix `[out, features]`.
- Runs power iteration to estimate the top eigenvalue of \(W^T W\).
- Compares against a demo threshold to set `suspected_backdoor`, can be changed.
### `mmbd`
- Returns fixed demo metrics (`suspected_backdoor=true`, `num_flagged=500`, `top_eigenvalue=42.3`).
---
## Quick ways to get a model
### 1) One‑liner: make a tiny valid `.pth` for spectral
```bash
python - <<'PY'
import torch, pathlib
path = pathlib.Path("models"); path.mkdir(exist_ok=True)
sd = {"layer.weight": torch.randn(64, 128)} # a 2D tensor
torch.save(sd, "models/spectral_demo.pth")
print("[ok] wrote models/spectral_demo.pth")
PY
```
### 2) Train a clean CIFAR‑10 ResNet‑18 (short run)
```bash
python scripts/train_resnet18.py --epochs 1 --train_batch_size 128 --eval_batch_size 256 --lr 0.1 --seed 1 --output_path models/resnet18_clean.pth
```
### 3) Train a backdoored model (BadNets‑style)
```bash
python scripts/train_backdoor_resnet18.py --poison-rate 0.1 --target-class 0 --trigger-size 4 --trigger-pos bottom-right --epochs 5 --batch-size 128 --lr 0.1 --seed 42 --out models/resnet18_badnet.pth
```
---
## Troubleshooting
- **“model path not found or not a file”**
Check your working directory and the path. Adjust with `../` if you’re in `mithridatium/`.
- **`torch.load` error with `spectral`**
Your file isn’t a valid PyTorch checkpoint. Use the one‑liner above or a trained model.
---