Package: cupbearer
cupbearer🍷cupbeareris a Python library formechanistic anomaly detection.
Its main purpose is to make it easy to implement either a new mechanistic anomaly
detectiontask, or a new detectionmethod, and evaluate it against a suite of existing
tasks or methods. To that end, the library provides:A clearly defined interface for tasks and detectors to ensure compatibilityScripts and other helpers for training and evaluating detectors that satisfy this interface
(to reduce the amount of boilerplate code you need to write)Implementations of several tasks and detectors as baselines (currently not that many)Contributions of new tasks or detectors are very welcome!
See thedeveloper guideto get started.InstallationThe easy way: inside a virtual environment with Python >= 3.10, runpipinstallgit+https://github.com/ejnnr/cupbearer.gitAlternatively, if you're going to do development work on the library itself:Clone this git repositoryCreate a virtual environment with Python 3.10 and activate itRunpip install -e .inside the git repo to install the package in editable modeNotes on CUDAOn Linux, installingcupbearerwill install pytorch with CUDA support even though this isn't necessary
(we're only using pytorch for its dataloader and datasets).  If you want to avoid that, runpipinstalltorchtorchvision--index-urlhttps://download.pytorch.org/whl/cpubeforeinstallingcupbearer.Similarly, you may want toinstalljaxandjaxlibmanually before installingcupbearerto make sure you get the right
CUDA (or CPU only) version.Running scriptsYou can run any script with the-hflag to see a list of options and possible values.Let's look at an example, where we use a simple Mahalanobis distance-based detection
methods to detect backdoors. First, we need to train a base model on poisoned data:python-mcupbearer.scripts.train_classifier\--train_databackdoor--train_data.originalmnist--train_data.backdoorcorner\--modelmlp\--dir.fulllogs/classifierThis will train an MLP on MNIST, where the backdoor trigger is that the top left pixel
is set to white (and the model is trained to classify images with this trigger as zeros).
There are many more options like learning rate etc. you can set, but the defaults should
work well enough.This script will have saved the final model tologs/classifier/model/. We can now train
a Mahalanobis-based detector on this model:python-mcupbearer.scripts.train_detector\--detectormahalanobis--taskbackdoor\--task.backdoorcorner--task.run_pathlogs/classifier\--dir.fulllogs/detector(The fact that we need to specify the backdoor trigger again is an artifact of how
things are currently implemented and will likely be changed---the detector is only actually
trained on clean images).train_detectorloads the model fromtask.run_pathand
also uses that to figure out which dataset to use (in this case, MNIST again).Finally, we can evaluate the detector on a mix of clean and poisoned images:python-mcupbearer.scripts.eval_detector--detectorfrom_run--detector.pathlogs/detector\--taskbackdoor--task.backdoorcorner\--task.run_pathlogs/classifier\--dir.fulllogs/detectorNote that we reuselogs/detectoras the output directory. This will add the evaluation
results to the directory of the detector training run (it won't overwrite anything).The reason we need to specify some things, such as the task, multiple times is that
these scripts also support much more flexible setups. For example, we could evaluate
the detector on images with adifferentbackdoor trigger (as an ablation to check
that these arenotflagged as anomalous), in which case we might also want
to save the results to a different directory:python-mcupbearer.scripts.eval_detector--detectorfrom_run--detector.pathlogs/detector\--taskbackdoor--task.backdoornoise--task.backdoor.std0.2\--task.run_pathlogs/classifier\--dir.fulllogs/detector_ablation\In the future, there might be easier ways of getting "reasonable defaults" for some settings,
for now you could just write small wrapper scripts for these kinds of pipelines.Whence the name?Just like a cupbearer tastes wine to avoid poisoning the king, mechanistic anomaly
detection methods taste new inputs to check whether they're poisoned. (Or more generally,
anomalous in terms of how they affect the king ... I mean, model. I admit the analogy
is becoming a bit strained here.)