OpenBackdoor Toolkit

repository·main·Indexed 42 days ago

https://github.com/thunlp/openbackdoor

An open-source toolkit for textual backdoor attacks and defenses in NLP. It provides a modular framework to implement and evaluate attack models (such as BadNets, SynBkd, and StyleBkd) and defense mechanisms (including ONION, STRIP, RAP, and BKI) across 5 tasks and 11 datasets, with native support for Huggingface transformers and datasets libraries.

Tokens
7.9K
Snippets
15
Records
44
Agent score
52%

What's inside OpenBackdoor

  1. Overview of available Defenders in OpenBackdoor

    main

    OpenBackdoor provides five specialized defense models designed to mitigate textual backdoor attacks. These defenders are categorized by their defense stage and specific capabilities. The available defenders are:

    • BKI (Backdoor Keyword Identification): Mitigates attacks in LSTM-based text classification systems.
    • ONION: A simple and effective defense against textual backdoor attacks.
    • STRIP: A multi-domain Trojan detection method.
    • RAP (Robustness-Aware Perturbations): Defends against backdoor attacks using robustness-aware perturbations.
    • CUBE: A unified framework for evaluating textual backdoor learning.
  2. Overview of OpenBackdoor toolkit

    main

    OpenBackdoor is an open-source toolkit designed for textual backdoor attack and defense. It provides a modular framework to implement, evaluate, and extend various attack and defense models.

    Key features include:

    • Extensive implementation: Supports 11 attack methods and 4 defense methods across diverse categories.
    • Comprehensive evaluation: Integrates multiple benchmark tasks and datasets, with native support for Huggingface's transformers and datasets libraries.
    • Modularized framework: Uses a general pipeline design that breaks models into distinct, combinable modules.
  3. Available tasks and datasets in OpenBackdoor

    main

    OpenBackdoor supports 5 main NLP tasks across 11 different datasets. You can download these datasets using the bash scripts provided in the datasets directory of the repository.

    Supported tasks and datasets:

    • Sentiment Analysis: SST-2, IMDB
    • Toxic Detection: Offenseval, Jigsaw, HSOL, Twitter
    • Topic Classification: AG's News, DBpedia
    • Spam Detection: Enron, Lingspam
    • Natural Language Inference: MNLI
  4. Available Attacker models in OpenBackdoor

    main

    OpenBackdoor implements 12 different attacker models, categorized by their trigger type and accessibility. These models allow for various types of backdoor attacks on NLP models, ranging from word-level substitutions to weight poisoning.

    Supported attackers include:

    • BadNets: Identifying vulnerabilities in the ML supply chain.
    • AddSent: Backdoor attacks against LSTM-based text classification.
    • SynBkd: Invisible textual backdoor attacks using syntactic triggers.
    • StyleBkd: Attacks based on text style transfer.
    • POR: Backdoor attacks that transfer to pre-trained models.
    • TrojanLM: Trojaning language models.
    • SOS: Rethinking stealthiness in NLP backdoor attacks.
    • LWP: Layerwise weight poisoning on pre-trained models.
    • EP: Exploring vulnerabilities in embedding layers.
    • NeuBA: Universal vulnerability to neuron-level backdoor attacks.
    • LWS: Learnable textual backdoor attacks via word substitution.
    • RIPPLES: Weight poisoning attacks on pre-trained models.
  5. How OpenBackdoor's modular pipeline works

    main

    OpenBackdoor follows a pipeline design composed of 6 main modules. Understanding these modules is essential for customizing or extending the toolkit:

    1. Dataset: Handles loading and processing datasets used for attacks or defenses.
    2. Victim: Represents the target Pre-trained Language Models (PLMs).
    3. Attacker: A high-level module that packs a Poisoner and a Trainer together to execute an attack.
    4. Poisoner: Responsible for generating poisoned samples using specific algorithms.
    5. Trainer: Manages the training process of the victim model using either poisoned or clean datasets.
    6. Defender: Contains components for both training-time and inference-time defense mechanisms.
  6. How OpenBackdoor's pipeline architecture works

    main

    OpenBackdoor follows a modular pipeline design consisting of 6 main components that work together to facilitate backdoor attack and defense research:

    1. Dataset: Responsible for loading and processing datasets for both attack and defense scenarios.
    2. Victim: Represents the target Pre-trained Language Models (PLMs).
    3. Attacker: A high-level module that packs a Poisoner and a Trainer together to execute an attack.
    4. Poisoner: Implements algorithms to generate poisoned samples.
    5. Trainer: Handles the training of the victim model using either poisoned or clean datasets.
    6. Defender: Comprises mechanisms for defense during either training-time or inference-time.
  7. How to customize an Attacker

    main

    To implement a custom attacker, you must define a class that implements the following interface:

    • attack(self, victim: Victim, data: List, defender: Optional[Defender] = None) -> Victim: The main entry point that orchestrates poisoning and training.
    • poison(self, victim: Victim, dataset: List, mode: str) -> List: The poisoning logic. You can also implement a custom Poisoner class with a poison(self, data: List) method.
    • train(self, victim: Victim, dataset: List) -> Victim: The training logic. You can also implement a custom Trainer class with a train(self, model: Victim, dataset, metrics: Optional[List[str]] = ["accuracy"]) method.
  8. How to customize a Defender

    main

    To implement a custom defender, inherit from the base Defender class and implement the following methods:

    • detect(self, model: Optional[Victim] = None, clean_data: Optional[List] = None, poison_data: Optional[List] = None) -> List: Used to identify poisoned samples.
    • correct(self, model: Optional[Victim] = None, clean_data: Optional[List] = None, poison_data: Optional[Dict] = None) -> List: Used to correct identified poisoned samples.

    Key initialization parameters for Defender include:

    • name (str): Name of the defender.
    • pre (bool): If True, defense is applied during the pre-tuning stage.
    • correction (bool): If True, the defender performs sample correction.
    • metrics (List[str]): Metrics used for evaluation (defaults to ["FRR", "FAR"]).
  9. Launch and evaluate a backdoor attack

    main

    Once the victim, attacker, datasets, and (optional) defender are configured, you can execute the full pipeline.

    1. Launch the attack

    Use attacker.attack() to poison the victim model. This method returns the attacked victim model.

    victim = attacker.attack(victim, poison_dataset, defender)

    2. Evaluate the model

    Use attacker.eval() to evaluate the performance of the attacked model on the target dataset.

    attacker.eval(victim, target_dataset, defender)

    3. Get results

    The evaluation process summarizes results in a dictionary and provides visualizations.

    # Launch attack
    victim = attacker.attack(victim, poison_dataset, defender)
    
    # Evaluate attack
    attacker.eval(victim, target_dataset, defender)
  10. Customize a Defender in OpenBackdoor

    main

    To implement a custom defender, inherit from the base Defender class. Defenders in OpenBackdoor operate in two primary modes based on the pre and correction configuration flags:

    • Pre-tune defense (pre=True): The defender is applied before training. The attack method in the Attacker class will call defender.correct() to clean the poisoned dataset.
    • Post-tune defense (pre=False): The defender is applied after training (e.g., for detection).

    Key Methods to Implement:

    • detect(self, model, clean_data, poison_data): Used to identify poisoned samples. Returns a list of predictions/labels for the poison_data.
    • correct(self, model, clean_data, poison_data): Used to fix or remove poisoned samples from the dataset. Returns the corrected dataset.
    class Defender(object):
        def __init__(
            self,
            name: Optional[str] = "Base",
            pre: Optional[bool] = False,
            correction: Optional[bool] = False,
            metrics: Optional[List[str]] = ["FRR", "FAR"],
            **kwargs
        ):
            self.name = name
            self.pre = pre
            self.correction = correction
            self.metrics = metrics
        
        def detect(self, model: Optional[Victim] = None, clean_data: Optional[List] = None, poison_data: Optional[List] = None):
            # Returns the prediction of the poison data
            return [0] * len(poison_data)
    
        def correct(self, model: Optional[Victim] = None, clean_data: Optional[List] = None, poison_data: Optional[Dict] = None):
            # Returns the corrected poison data
            return poison_data