eval-unlearn 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eval_unlearn-1.0.0/PKG-INFO +229 -0
- eval_unlearn-1.0.0/README.md +185 -0
- eval_unlearn-1.0.0/pyproject.toml +120 -0
- eval_unlearn-1.0.0/setup.cfg +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/__init__.py +1 -0
- eval_unlearn-1.0.0/src/eval_unlearn/artifacts/__init__.py +3 -0
- eval_unlearn-1.0.0/src/eval_unlearn/artifacts/writer.py +175 -0
- eval_unlearn-1.0.0/src/eval_unlearn/cli.py +329 -0
- eval_unlearn-1.0.0/src/eval_unlearn/config/hf_datasets.yaml +37 -0
- eval_unlearn-1.0.0/src/eval_unlearn/configs/__init__.py +3 -0
- eval_unlearn-1.0.0/src/eval_unlearn/configs/base.py +23 -0
- eval_unlearn-1.0.0/src/eval_unlearn/datasets/__init__.py +13 -0
- eval_unlearn-1.0.0/src/eval_unlearn/datasets/coco_parquet.py +112 -0
- eval_unlearn-1.0.0/src/eval_unlearn/datasets/err_composite.py +193 -0
- eval_unlearn-1.0.0/src/eval_unlearn/datasets/hf_stream.py +28 -0
- eval_unlearn-1.0.0/src/eval_unlearn/datasets/i2p_csv.py +96 -0
- eval_unlearn-1.0.0/src/eval_unlearn/datasets/tifa_csv.py +77 -0
- eval_unlearn-1.0.0/src/eval_unlearn/datasets/ua_ira_csv.py +129 -0
- eval_unlearn-1.0.0/src/eval_unlearn/hub.py +142 -0
- eval_unlearn-1.0.0/src/eval_unlearn/logging_utils.py +36 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/__init__.py +63 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/_base_models.py +27 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/_clip_constants.py +59 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_i2p/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_i2p/config.py +55 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_i2p/metric.py +321 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_mma_diffusion/__init__.py +3 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_mma_diffusion/config.py +95 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_mma_diffusion/metric.py +377 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_p4d/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_p4d/config.py +189 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_p4d/metric.py +418 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_ring_a_bell/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_ring_a_bell/config.py +61 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_ring_a_bell/data/nudity_vector.npy +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/asr_ring_a_bell/metric.py +459 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/clip_score/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/clip_score/config.py +23 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/clip_score/metric.py +143 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/err/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/err/config.py +28 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/err/metric.py +252 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/fid/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/fid/config.py +19 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/fid/metric.py +245 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/tifa/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/tifa/config.py +19 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/tifa/metric.py +172 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/ua_ira/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/ua_ira/config.py +39 -0
- eval_unlearn-1.0.0/src/eval_unlearn/metrics/ua_ira/metric.py +229 -0
- eval_unlearn-1.0.0/src/eval_unlearn/registry/__init__.py +8 -0
- eval_unlearn-1.0.0/src/eval_unlearn/registry/entrypoints.py +33 -0
- eval_unlearn-1.0.0/src/eval_unlearn/registry/local.py +86 -0
- eval_unlearn-1.0.0/src/eval_unlearn/runners/__init__.py +10 -0
- eval_unlearn-1.0.0/src/eval_unlearn/runners/core/base_runner.py +109 -0
- eval_unlearn-1.0.0/src/eval_unlearn/runners/multi_benchmark_runner.py +245 -0
- eval_unlearn-1.0.0/src/eval_unlearn/runners/single_benchmark_runner.py +210 -0
- eval_unlearn-1.0.0/src/eval_unlearn/runners/validation.py +96 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/SAFREE/__init__.py +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/SAFREE/config.py +71 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/SAFREE/wrapper.py +103 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/__init__.py +73 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/_base_models.py +36 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/advunlearn/__init__.py +3 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/advunlearn/config.py +279 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/advunlearn/wrapper.py +97 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/ca/__init__.py +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/ca/config.py +51 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/ca/wrapper.py +81 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/cogfd/__init__.py +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/cogfd/config.py +144 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/cogfd/wrapper.py +86 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/concept_steerers/__init__.py +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/concept_steerers/config.py +39 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/concept_steerers/wrapper.py +69 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/esd/__init__.py +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/esd/config.py +53 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/esd/wrapper.py +81 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/free_run/__init__.py +41 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/free_run/config.py +23 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/free_run/wrapper.py +110 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/mace/__init__.py +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/mace/config.py +38 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/mace/wrapper.py +77 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/saeuron/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/saeuron/config.py +54 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/saeuron/wrapper.py +47 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/sld/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/sld/config.py +90 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/sld/wrapper.py +126 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/ssd/__init__.py +0 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/ssd/config.py +87 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/ssd/wrapper.py +82 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/trasce/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/trasce/config.py +30 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/trasce/wrapper.py +70 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/uce/__init__.py +4 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/uce/config.py +58 -0
- eval_unlearn-1.0.0/src/eval_unlearn/techniques/uce/wrapper.py +71 -0
- eval_unlearn-1.0.0/src/eval_unlearn/types.py +32 -0
- eval_unlearn-1.0.0/src/eval_unlearn.egg-info/PKG-INFO +229 -0
- eval_unlearn-1.0.0/src/eval_unlearn.egg-info/SOURCES.txt +105 -0
- eval_unlearn-1.0.0/src/eval_unlearn.egg-info/dependency_links.txt +1 -0
- eval_unlearn-1.0.0/src/eval_unlearn.egg-info/entry_points.txt +35 -0
- eval_unlearn-1.0.0/src/eval_unlearn.egg-info/requires.txt +31 -0
- eval_unlearn-1.0.0/src/eval_unlearn.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eval-unlearn
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Unlearning Benchmark for Text-to-Image Models
|
|
5
|
+
Author: Eval-Learn Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/nikhilr2907/eval-unlearn
|
|
8
|
+
Project-URL: Documentation, https://eval-unlearn.readthedocs.io
|
|
9
|
+
Project-URL: Source, https://github.com/nikhilr2907/eval-unlearn
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/nikhilr2907/eval-unlearn/issues
|
|
11
|
+
Keywords: diffusion,unlearning,evaluation,text-to-image,benchmark,machine-learning
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: numpy>=2.4.0
|
|
19
|
+
Requires-Dist: scipy>=1.17.0
|
|
20
|
+
Requires-Dist: tqdm>=4.66.5
|
|
21
|
+
Requires-Dist: requests>=2.28.1
|
|
22
|
+
Requires-Dist: safetensors>=0.7.0
|
|
23
|
+
Requires-Dist: diffusers>=0.37.0
|
|
24
|
+
Requires-Dist: huggingface_hub>=1.8.0
|
|
25
|
+
Requires-Dist: Pillow>=12.1.0
|
|
26
|
+
Requires-Dist: python-dotenv>=1.2.2
|
|
27
|
+
Requires-Dist: torch>=2.11.0
|
|
28
|
+
Requires-Dist: transformers>=5.3.0
|
|
29
|
+
Requires-Dist: datasets>=4.8.0
|
|
30
|
+
Requires-Dist: pyyaml>=5.1
|
|
31
|
+
Provides-Extra: asr
|
|
32
|
+
Requires-Dist: nudenet>=3.4.2; extra == "asr"
|
|
33
|
+
Provides-Extra: fid
|
|
34
|
+
Requires-Dist: torchvision>=0.26.0; extra == "fid"
|
|
35
|
+
Provides-Extra: coco
|
|
36
|
+
Requires-Dist: torchvision>=0.26.0; extra == "coco"
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
40
|
+
Requires-Dist: ruff>=0.0.1; extra == "dev"
|
|
41
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
42
|
+
Provides-Extra: all
|
|
43
|
+
Requires-Dist: eval-unlearn[asr,coco,dev,fid]; extra == "all"
|
|
44
|
+
|
|
45
|
+
# eval-unlearn
|
|
46
|
+
|
|
47
|
+
A benchmarking framework for evaluating concept-unlearning techniques in text-to-image diffusion models.
|
|
48
|
+
|
|
49
|
+
Unlearning techniques modify or constrain Stable Diffusion to suppress specific concepts — nudity, violence, artistic styles, named individuals. eval-unlearn provides a common interface to run, compare, and evaluate these techniques under consistent conditions.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Techniques
|
|
54
|
+
|
|
55
|
+
| Technique | Key |
|
|
56
|
+
|-----------|-----|
|
|
57
|
+
| Erased Stable Diffusion | `esd` |
|
|
58
|
+
| Mass Concept Erasure | `mace` |
|
|
59
|
+
| Unified Concept Editing | `uce` |
|
|
60
|
+
| Selective Synaptic Dampening | `ssd` |
|
|
61
|
+
| Concept Ablation | `ca` |
|
|
62
|
+
| CoGFD | `cogfd` |
|
|
63
|
+
| TraSCE | `trasce` |
|
|
64
|
+
| SAFREE | `safree` |
|
|
65
|
+
| Safe Latent Diffusion | `sld` |
|
|
66
|
+
| AdvUnlearn | `advunlearn` |
|
|
67
|
+
| Concept Steerers | `concept_steerers` |
|
|
68
|
+
| SAeUron | `saeuron` |
|
|
69
|
+
| Free Run (custom model) | `free_run` |
|
|
70
|
+
|
|
71
|
+
## Metrics
|
|
72
|
+
|
|
73
|
+
| Metric | Key | What it measures |
|
|
74
|
+
|--------|-----|-----------------|
|
|
75
|
+
| ASR — I2P | `asr_i2p` | Attack success rate on I2P prompts |
|
|
76
|
+
| ASR — P4D | `asr_p4d` | Attack success rate via P4D adversarial prompts |
|
|
77
|
+
| ASR — MMA Diffusion | `asr_mma_diffusion` | Attack success rate via MMA-Diffusion GCG attack |
|
|
78
|
+
| ASR — Ring-A-Bell | `asr_ring_a_bell` | Attack success rate via genetic adversarial prompt discovery |
|
|
79
|
+
| Erasure Retention Rate | `err` | Concept erasure vs. unrelated concept retention |
|
|
80
|
+
| FID | `fid` | Image quality vs. COCO reference |
|
|
81
|
+
| CLIP Score | `clip_score` | Prompt-image alignment |
|
|
82
|
+
| UA-IRA | `ua_ira` | Unsafe concept alignment vs. retain concept alignment |
|
|
83
|
+
| TIFA | `tifa` | Text-image faithfulness via VQA |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
### 1. Install eval-unlearn
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install eval-unlearn
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2. Install technique packages
|
|
96
|
+
|
|
97
|
+
Technique implementations are hosted on [Hugging Face](https://huggingface.co/datasets/Unlearningltd/Packages). Clone the repo once, pull LFS files, then install only what you need:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
git clone https://huggingface.co/datasets/Unlearningltd/Packages
|
|
101
|
+
cd Packages
|
|
102
|
+
git lfs pull
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install -e esd/
|
|
107
|
+
pip install -e mace/
|
|
108
|
+
pip install -e uce/
|
|
109
|
+
pip install -e ssd/
|
|
110
|
+
pip install -e ca/
|
|
111
|
+
pip install -e cogfd/
|
|
112
|
+
pip install -e trasce/
|
|
113
|
+
pip install -e saeuron/
|
|
114
|
+
pip install -e safree/
|
|
115
|
+
pip install -e concept-steerers/
|
|
116
|
+
pip install -e advunlearn/
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
SLD is built into eval-unlearn via the `diffusers` library and requires no extra install.
|
|
120
|
+
|
|
121
|
+
### 3. Install metric packages
|
|
122
|
+
|
|
123
|
+
From the cloned `Packages` directory (see step 2 above):
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
pip install -e p4d/
|
|
127
|
+
pip install -e mma_diff/
|
|
128
|
+
pip install -e RING_A_BELL/
|
|
129
|
+
pip install -e Q16/
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# NudeNet (nudity ASR)
|
|
134
|
+
pip install "eval-unlearn[asr]"
|
|
135
|
+
|
|
136
|
+
# FID / COCO metrics
|
|
137
|
+
pip install "eval-unlearn[fid,coco]"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 4. Hugging Face authentication
|
|
141
|
+
|
|
142
|
+
Create a `.env` file in the directory you run `eval-unlearn run` from:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
HF_TOKEN=your_token_here
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Quick start
|
|
151
|
+
|
|
152
|
+
Benchmarks are defined in a JSON or YAML config file:
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"output_dir": "results/esd_nudity",
|
|
157
|
+
"technique": {
|
|
158
|
+
"name": "esd",
|
|
159
|
+
"config": { "erase_concept": "nudity", "train_method": "noxattn", "device": "cuda" }
|
|
160
|
+
},
|
|
161
|
+
"metrics": [
|
|
162
|
+
{ "name": "asr_i2p", "config": { "concept_name": "nudity", "device": "cuda" } },
|
|
163
|
+
{ "name": "fid", "config": { "device": "cuda" } },
|
|
164
|
+
{ "name": "clip_score", "config": { "device": "cuda" } }
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Run it:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
eval-unlearn run --config config.json
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Results are written to `output_dir` as JSON.
|
|
176
|
+
|
|
177
|
+
### Useful commands
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
eval-unlearn plugins # list installed techniques and metrics
|
|
181
|
+
eval-unlearn models # show the base model each technique targets
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Examples
|
|
187
|
+
|
|
188
|
+
The [`examples/`](examples/) directory contains ready-to-run configs for all techniques across nudity and violence concepts:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
examples/
|
|
192
|
+
nudity/ one config per technique (esd.json, mace.json, ...)
|
|
193
|
+
violence/ same, for violence concept
|
|
194
|
+
data/ seed prompts and concept vectors used by the configs
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Run all nudity benchmarks in sequence:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
python nudity_unlearning_demo.py
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Run all violence benchmarks:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
python nudity_unlearning_demo_violence.py
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Documentation
|
|
212
|
+
|
|
213
|
+
Full configuration reference, technique guides, metric descriptions, and experiment recipes:
|
|
214
|
+
|
|
215
|
+
**https://eval-unlearn.readthedocs.io**
|
|
216
|
+
|
|
217
|
+
Package on PyPI: **https://pypi.org/project/eval-unlearn/**
|
|
218
|
+
|
|
219
|
+
Key pages:
|
|
220
|
+
|
|
221
|
+
- [Getting started](docs/docs/getting-started.md)
|
|
222
|
+
- [Technique-metric compatibility](docs/docs/running-experiments/compatibility.md)
|
|
223
|
+
- [Caching adversarial prompts and technique weights](docs/docs/running-experiments/caching-adversarial-prompts.md)
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# eval-unlearn
|
|
2
|
+
|
|
3
|
+
A benchmarking framework for evaluating concept-unlearning techniques in text-to-image diffusion models.
|
|
4
|
+
|
|
5
|
+
Unlearning techniques modify or constrain Stable Diffusion to suppress specific concepts — nudity, violence, artistic styles, named individuals. eval-unlearn provides a common interface to run, compare, and evaluate these techniques under consistent conditions.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Techniques
|
|
10
|
+
|
|
11
|
+
| Technique | Key |
|
|
12
|
+
|-----------|-----|
|
|
13
|
+
| Erased Stable Diffusion | `esd` |
|
|
14
|
+
| Mass Concept Erasure | `mace` |
|
|
15
|
+
| Unified Concept Editing | `uce` |
|
|
16
|
+
| Selective Synaptic Dampening | `ssd` |
|
|
17
|
+
| Concept Ablation | `ca` |
|
|
18
|
+
| CoGFD | `cogfd` |
|
|
19
|
+
| TraSCE | `trasce` |
|
|
20
|
+
| SAFREE | `safree` |
|
|
21
|
+
| Safe Latent Diffusion | `sld` |
|
|
22
|
+
| AdvUnlearn | `advunlearn` |
|
|
23
|
+
| Concept Steerers | `concept_steerers` |
|
|
24
|
+
| SAeUron | `saeuron` |
|
|
25
|
+
| Free Run (custom model) | `free_run` |
|
|
26
|
+
|
|
27
|
+
## Metrics
|
|
28
|
+
|
|
29
|
+
| Metric | Key | What it measures |
|
|
30
|
+
|--------|-----|-----------------|
|
|
31
|
+
| ASR — I2P | `asr_i2p` | Attack success rate on I2P prompts |
|
|
32
|
+
| ASR — P4D | `asr_p4d` | Attack success rate via P4D adversarial prompts |
|
|
33
|
+
| ASR — MMA Diffusion | `asr_mma_diffusion` | Attack success rate via MMA-Diffusion GCG attack |
|
|
34
|
+
| ASR — Ring-A-Bell | `asr_ring_a_bell` | Attack success rate via genetic adversarial prompt discovery |
|
|
35
|
+
| Erasure Retention Rate | `err` | Concept erasure vs. unrelated concept retention |
|
|
36
|
+
| FID | `fid` | Image quality vs. COCO reference |
|
|
37
|
+
| CLIP Score | `clip_score` | Prompt-image alignment |
|
|
38
|
+
| UA-IRA | `ua_ira` | Unsafe concept alignment vs. retain concept alignment |
|
|
39
|
+
| TIFA | `tifa` | Text-image faithfulness via VQA |
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
### 1. Install eval-unlearn
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install eval-unlearn
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Install technique packages
|
|
52
|
+
|
|
53
|
+
Technique implementations are hosted on [Hugging Face](https://huggingface.co/datasets/Unlearningltd/Packages). Clone the repo once, pull LFS files, then install only what you need:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://huggingface.co/datasets/Unlearningltd/Packages
|
|
57
|
+
cd Packages
|
|
58
|
+
git lfs pull
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install -e esd/
|
|
63
|
+
pip install -e mace/
|
|
64
|
+
pip install -e uce/
|
|
65
|
+
pip install -e ssd/
|
|
66
|
+
pip install -e ca/
|
|
67
|
+
pip install -e cogfd/
|
|
68
|
+
pip install -e trasce/
|
|
69
|
+
pip install -e saeuron/
|
|
70
|
+
pip install -e safree/
|
|
71
|
+
pip install -e concept-steerers/
|
|
72
|
+
pip install -e advunlearn/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
SLD is built into eval-unlearn via the `diffusers` library and requires no extra install.
|
|
76
|
+
|
|
77
|
+
### 3. Install metric packages
|
|
78
|
+
|
|
79
|
+
From the cloned `Packages` directory (see step 2 above):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install -e p4d/
|
|
83
|
+
pip install -e mma_diff/
|
|
84
|
+
pip install -e RING_A_BELL/
|
|
85
|
+
pip install -e Q16/
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# NudeNet (nudity ASR)
|
|
90
|
+
pip install "eval-unlearn[asr]"
|
|
91
|
+
|
|
92
|
+
# FID / COCO metrics
|
|
93
|
+
pip install "eval-unlearn[fid,coco]"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4. Hugging Face authentication
|
|
97
|
+
|
|
98
|
+
Create a `.env` file in the directory you run `eval-unlearn run` from:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
HF_TOKEN=your_token_here
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Quick start
|
|
107
|
+
|
|
108
|
+
Benchmarks are defined in a JSON or YAML config file:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"output_dir": "results/esd_nudity",
|
|
113
|
+
"technique": {
|
|
114
|
+
"name": "esd",
|
|
115
|
+
"config": { "erase_concept": "nudity", "train_method": "noxattn", "device": "cuda" }
|
|
116
|
+
},
|
|
117
|
+
"metrics": [
|
|
118
|
+
{ "name": "asr_i2p", "config": { "concept_name": "nudity", "device": "cuda" } },
|
|
119
|
+
{ "name": "fid", "config": { "device": "cuda" } },
|
|
120
|
+
{ "name": "clip_score", "config": { "device": "cuda" } }
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Run it:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
eval-unlearn run --config config.json
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Results are written to `output_dir` as JSON.
|
|
132
|
+
|
|
133
|
+
### Useful commands
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
eval-unlearn plugins # list installed techniques and metrics
|
|
137
|
+
eval-unlearn models # show the base model each technique targets
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Examples
|
|
143
|
+
|
|
144
|
+
The [`examples/`](examples/) directory contains ready-to-run configs for all techniques across nudity and violence concepts:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
examples/
|
|
148
|
+
nudity/ one config per technique (esd.json, mace.json, ...)
|
|
149
|
+
violence/ same, for violence concept
|
|
150
|
+
data/ seed prompts and concept vectors used by the configs
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Run all nudity benchmarks in sequence:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
python nudity_unlearning_demo.py
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Run all violence benchmarks:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python nudity_unlearning_demo_violence.py
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Documentation
|
|
168
|
+
|
|
169
|
+
Full configuration reference, technique guides, metric descriptions, and experiment recipes:
|
|
170
|
+
|
|
171
|
+
**https://eval-unlearn.readthedocs.io**
|
|
172
|
+
|
|
173
|
+
Package on PyPI: **https://pypi.org/project/eval-unlearn/**
|
|
174
|
+
|
|
175
|
+
Key pages:
|
|
176
|
+
|
|
177
|
+
- [Getting started](docs/docs/getting-started.md)
|
|
178
|
+
- [Technique-metric compatibility](docs/docs/running-experiments/compatibility.md)
|
|
179
|
+
- [Caching adversarial prompts and technique weights](docs/docs/running-experiments/caching-adversarial-prompts.md)
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "eval-unlearn"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Unlearning Benchmark for Text-to-Image Models"
|
|
9
|
+
readme = {file = "README.md", content-type = "text/markdown"}
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Eval-Learn Team"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["diffusion", "unlearning", "evaluation", "text-to-image", "benchmark", "machine-learning"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Intended Audience :: Science/Research",
|
|
20
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
21
|
+
]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"numpy>=2.4.0",
|
|
24
|
+
"scipy>=1.17.0",
|
|
25
|
+
"tqdm>=4.66.5",
|
|
26
|
+
"requests>=2.28.1",
|
|
27
|
+
"safetensors>=0.7.0",
|
|
28
|
+
"diffusers>=0.37.0",
|
|
29
|
+
"huggingface_hub>=1.8.0",
|
|
30
|
+
"Pillow>=12.1.0",
|
|
31
|
+
"python-dotenv>=1.2.2",
|
|
32
|
+
"torch>=2.11.0",
|
|
33
|
+
"transformers>=5.3.0",
|
|
34
|
+
"datasets>=4.8.0",
|
|
35
|
+
"pyyaml>=5.1",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/nikhilr2907/eval-unlearn"
|
|
40
|
+
Documentation = "https://eval-unlearn.readthedocs.io"
|
|
41
|
+
Source = "https://github.com/nikhilr2907/eval-unlearn"
|
|
42
|
+
"Bug Tracker" = "https://github.com/nikhilr2907/eval-unlearn/issues"
|
|
43
|
+
|
|
44
|
+
[project.optional-dependencies]
|
|
45
|
+
# Metric extras (PyPI packages)
|
|
46
|
+
asr = ["nudenet>=3.4.2"]
|
|
47
|
+
fid = ["torchvision>=0.26.0"]
|
|
48
|
+
coco = ["torchvision>=0.26.0"]
|
|
49
|
+
# Development
|
|
50
|
+
dev = ["pytest>=7.0.0", "pytest-cov>=4.0.0", "ruff>=0.0.1", "mypy>=1.0.0"]
|
|
51
|
+
all = ["eval-unlearn[asr,fid,coco,dev]"]
|
|
52
|
+
|
|
53
|
+
# Note: Technique packages (esd, mace, uce, safree, sld, saeuron)
|
|
54
|
+
# are local editable installs declared in requirements.txt
|
|
55
|
+
|
|
56
|
+
[project.scripts]
|
|
57
|
+
eval-unlearn = "eval_unlearn.cli:main"
|
|
58
|
+
|
|
59
|
+
# Entry points for plugin discovery
|
|
60
|
+
[project.entry-points."eval_unlearn.techniques"]
|
|
61
|
+
free_run = "eval_unlearn.techniques.free_run.wrapper:FreeRunTechnique"
|
|
62
|
+
esd = "eval_unlearn.techniques.esd.wrapper:ESDTechnique"
|
|
63
|
+
mace = "eval_unlearn.techniques.mace.wrapper:MACETechnique"
|
|
64
|
+
sld = "eval_unlearn.techniques.sld.wrapper:SLDTechnique"
|
|
65
|
+
uce = "eval_unlearn.techniques.uce.wrapper:UCETechnique"
|
|
66
|
+
safree = "eval_unlearn.techniques.SAFREE.wrapper:SAFREETechnique"
|
|
67
|
+
concept_steerers = "eval_unlearn.techniques.concept_steerers.wrapper:ConceptSteerersTechnique"
|
|
68
|
+
saeuron = "eval_unlearn.techniques.saeuron.wrapper:SAeUronTechnique"
|
|
69
|
+
cogfd = "eval_unlearn.techniques.cogfd.wrapper:CoGFDTechnique"
|
|
70
|
+
advunlearn = "eval_unlearn.techniques.advunlearn.wrapper:AdvUnlearnTechnique"
|
|
71
|
+
ssd = "eval_unlearn.techniques.ssd.wrapper:SSDTechnique"
|
|
72
|
+
trasce = "eval_unlearn.techniques.trasce.wrapper:TraSCETechnique"
|
|
73
|
+
ca = "eval_unlearn.techniques.ca.wrapper:CATechnique"
|
|
74
|
+
|
|
75
|
+
[project.entry-points."eval_unlearn.metrics"]
|
|
76
|
+
asr_p4d = "eval_unlearn.metrics.asr_p4d.metric:ASRP4D"
|
|
77
|
+
asr_i2p = "eval_unlearn.metrics.asr_i2p.metric:ASRMetric"
|
|
78
|
+
asr_ring_a_bell = "eval_unlearn.metrics.asr_ring_a_bell.metric:ASRRingABellMetric"
|
|
79
|
+
asr_mma_diffusion = "eval_unlearn.metrics.asr_mma_diffusion.metric:MMADiffusionMetric"
|
|
80
|
+
fid = "eval_unlearn.metrics.fid.metric:FIDMetric"
|
|
81
|
+
err = "eval_unlearn.metrics.err.metric:ERRMetric"
|
|
82
|
+
tifa = "eval_unlearn.metrics.tifa.metric:TIFAMetric"
|
|
83
|
+
clip_score = "eval_unlearn.metrics.clip_score.metric:CLIPScoreMetric"
|
|
84
|
+
ua_ira = "eval_unlearn.metrics.ua_ira.metric:UAIRAMetric"
|
|
85
|
+
|
|
86
|
+
[project.entry-points."eval_unlearn.datasets"]
|
|
87
|
+
i2p_csv = "eval_unlearn.datasets.i2p_csv:load_i2p_csv"
|
|
88
|
+
err_composite = "eval_unlearn.datasets.err_composite:load_err_composite"
|
|
89
|
+
tifa_csv = "eval_unlearn.datasets.tifa_csv:load_tifa_csv"
|
|
90
|
+
coco_parquet = "eval_unlearn.datasets.coco_parquet:load_coco_parquet"
|
|
91
|
+
ua_ira_csv = "eval_unlearn.datasets.ua_ira_csv:load_ua_ira_csv"
|
|
92
|
+
|
|
93
|
+
[tool.setuptools.packages.find]
|
|
94
|
+
where = ["src"]
|
|
95
|
+
|
|
96
|
+
[tool.setuptools.package-data]
|
|
97
|
+
eval_unlearn = ["**/*.pth", "**/*.json", "**/*.yaml", "**/*.npy"]
|
|
98
|
+
|
|
99
|
+
[tool.pytest.ini_options]
|
|
100
|
+
testpaths = ["tests"]
|
|
101
|
+
markers = [
|
|
102
|
+
"integration: marks tests that require GPU and real models (deselect with '-m \"not integration\"')",
|
|
103
|
+
]
|
|
104
|
+
addopts = "--cov=eval_unlearn --cov-report=term-missing --cov-report=xml -p no:warnings"
|
|
105
|
+
|
|
106
|
+
[tool.coverage.run]
|
|
107
|
+
source = ["eval_unlearn"]
|
|
108
|
+
omit = [
|
|
109
|
+
"*/tests/*",
|
|
110
|
+
"*/__pycache__/*",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
[tool.coverage.report]
|
|
114
|
+
exclude_lines = [
|
|
115
|
+
"pragma: no cover",
|
|
116
|
+
"if TYPE_CHECKING:",
|
|
117
|
+
"raise NotImplementedError",
|
|
118
|
+
"except ImportError",
|
|
119
|
+
]
|
|
120
|
+
show_missing = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|