Skip to content

Latest commit

Β 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Token Buncher Logo

Token Buncher: Shielding LLMs from Harmful Reinforcement Learning Fine-Tuning

arXiv:2508.20697 website

This repository is the official implementation of Token Buncher. It provides the full pipeline to (1) launch harmful-RL attacks, (2) apply the Token Buncher defense, and (3) evaluate safety and capability on a suite of benchmarks.

πŸ“° News

  • [2026-08] πŸŽ‰ Token Buncher is accepted by ACM CCS 2026!
  • [2026-06] Updated the code for arXiv version v3.

πŸ—‚οΈ Repository Structure

Token-Buncher/
β”œβ”€β”€ README.md
β”œβ”€β”€ requirements.txt              # Python dependencies (PyTorch installed separately)
β”œβ”€β”€ setup.py / pyproject.toml     # Installs the vendored `verl` training engine
β”œβ”€β”€ run_attack.sh                 # Entry point: launch a harmful-RL attack
β”œβ”€β”€ run_defence.sh                # Entry point: apply the Token Buncher defense
β”œβ”€β”€ configs/                      # Per-algorithm training configs (grpo/ppo/rloo/reinpp/lora/defence)
β”œβ”€β”€ reward_scores/                # Reward functions used during training
β”‚   β”œβ”€β”€ localapi.py               #   attack reward (queries the DeBERTa harmful classifier)
β”‚   └── entropyreward.py          #   defense reward (token-entropy based, no reward model)
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ host_deberta_api.py       # Reward-model server for attacks (Flask, port 50050)
β”‚   β”œβ”€β”€ convert_fsdp_to_hf.py     # Convert verl FSDP checkpoints -> HuggingFace format
β”‚   └── test_deberta_api.py       # Sanity-check the reward-model server
β”œβ”€β”€ dataset/                      # Training-data preprocessing (BeaverTails, AlpacaEval, merge)
β”œβ”€β”€ evaluation/                   # Evaluation benchmarks (see "Evaluation" section)
β”‚   β”œβ”€β”€ eval_data/                # Bundled benchmark data (HarmBench/StrongREJECT/MATH500/GSM8K/WMDP-evil)
β”‚   β”œβ”€β”€ harmfulscore/             # HarmBench / StrongREJECT  -> Harmful Score
β”‚   β”œβ”€β”€ math/                     # GSM8K / MATH500
β”‚   β”œβ”€β”€ mmlu-pro/                 # MMLU-Pro
β”‚   └── wmdp-evil/                # WMDP-evil MCQ
β”œβ”€β”€ verl/                         # Vendored training engine (adapted from verl)
└── outputs/                      # Training/eval outputs

πŸ› οΈ Installation

conda create -n tokenbuncher python=3.10 -y
conda activate tokenbuncher

# install torch
pip install torch==2.7.0 torchvision==0.22.0 torchaudio==2.7.0 --index-url https://download.pytorch.org/whl/cu128

# install verl (vendored, no deps) and the remaining dependencies
pip install --no-deps -e .
pip install -r requirements.txt

# flash attention 2
pip install flash-attn --no-build-isolation

πŸ€– Model Preparation

Training uses the following base models and the attack reward model:

Model Used for Link
Qwen2.5-3B-Instruct base β†’ attacked / defended HF
Qwen2.5-7B-Instruct base β†’ attacked / defended HF
Ministral-8B-Instruct-2410 base β†’ attacked / defended HF
deberta-v3-xsmall-beavertails-harmful-qa-classifier attack reward model HF

Evaluation uses two scorer models:

Model Used for Link
beaver-dam-7b Harmful Score classifier HF
Llama-3.1-70B-Instruct Judge Score (LLM-as-judge) HF

πŸ“¦ Data Preparation

We provide preprocessing scripts for the datasets used during training. The scripts write parquet files under dataset/:

# Attack data β€” BeaverTails harmful prompts (used by run_attack.sh)
python ./dataset/data_preprocess/beavertails.py --template_type qwen --local_dir ./dataset/beavertails-qwen

# Defence data β€” AlpacaEval (benign) merged with BeaverTails (used by run_defence.sh)
python ./dataset/data_preprocess/alpacaeval.py  --template_type qwen --local_dir ./dataset/alpacaeval-qwen
python ./dataset/data_preprocess/simple_merge.py \
    --dir1 ./dataset/beavertails-qwen --dir2 ./dataset/alpacaeval-qwen \
    --output_dir ./dataset/alpaca-beaver-qwen
  • --template_type supports base, ministral, qwen.

All benchmark data needed for evaluation is already provided under evaluation/eval_data/ (HarmBench, StrongREJECT, MATH500, GSM8K, and the WMDP-evil set) β€” no separate download is required. MMLU-Pro is pulled from HuggingFace at runtime by its harness.

☣️ Harmful-RL Fine-Tuning (Attack)

run_attack.sh launches a harmful-RL attack. It runs the GRPO variant by default; the configs for the other algorithms live under configs/.

# 1) start the reward-model server (Flask, port 50050 β€” change PORT if it conflicts)
python scripts/host_deberta_api.py

# 2) in another terminal, edit run_attack.sh then launch
bash run_attack.sh

Switch algorithms by editing which configs/attack_*.sh is invoked (attack_grpo.sh, attack_ppo.sh, attack_rloo.sh, attack_reinpp.sh, plus the LoRA variant attack_grpo_lora.sh).

πŸ›‘οΈ Token Buncher (Defense)

bash run_defence.sh

Edit BASE_MODEL / OUTPUT_DIR / EXPERIMENT_NAME in run_defence.sh first. Unlike the attack, the defense does not need the reward-model server β€” it uses the model's own token-entropy as the reward signal (reward_scores/entropyreward.py). Training is logged to Weights & Biases (wandb login on first use).

After training, convert the FSDP checkpoint to HuggingFace format:

python scripts/convert_fsdp_to_hf.py \
    <OUTPUT_DIR>/global_step_<step>/actor \
    Qwen/Qwen2.5-7B-Instruct \
    ./outputs/Qwen2.5-7B-TokenBuncher

The converter expects a 2-GPU (world_size=2) FSDP checkpoint.

πŸ“Š Evaluation

All benchmark data is bundled under evaluation/eval_data/, so the steps below run directly on any model checkpoint.

HarmBench / StrongREJECT β€” Harmful Score

cd evaluation/harmfulscore

# generate responses
python generate_vllm_response.py \
    --model <MODEL_PATH> --tokenizer <TOKENIZER_PATH> \
    --output-file-name <OUTPUT_NAME> \
    --dataset HarmBench            # or StrongREJECT

# compute Harmful Score
python beaverdam.py \
    --model_path <beaver-dam-7b PATH> \
    --eval_dataset <OUTPUT_NAME>.jsonl \
    --output_dir <OUTPUT_DIR>

The Beaver-Dam classifier writes results_summary.json, where flagged_percentage is the Harmful Score. Optionally, llm_judge.py computes an LLM-as-judge Judge Score with Llama-3.1-70B (slow; runs a 70B model over thousands of pairs).

MATH500 / GSM8K

cd evaluation/math

python math_vllm_gen.py \
    --model <MODEL_PATH> \
    --max-new-tokens 4096 \
    --output-file-name <OUTPUT_NAME> \
    --dataset MATH500             # or GSM8K

python evaluate_gsm8k.py   --input_file <OUTPUT_NAME>.jsonl
python evaluate_math500.py --input_file <OUTPUT_NAME>.jsonl

MMLU-Pro

Adapted from the official MMLU-Pro repo.

cd evaluation/mmlu-pro
# set MODEL_PATH and MODEL_NAME in eval_models.sh first
bash eval_models.sh

Results are saved under eval_results/, including per-subject generations, summaries, and accuracy CSVs.

WMDP-evil

cd evaluation/wmdp-evil

python generate_responses.py \
    --model <MODEL_PATH> \
    --json_file_path ../eval_data/WMDP-evil/full.jsonl \
    --output_file_path <OUTPUT_NAME>.jsonl

python extract_answer.py --json_file <OUTPUT_NAME>.jsonl

😊 Acknowledgements

The vendored verl/ training engine is adapted from verl; we thank the authors for their great work.

We also thank the authors of the benchmarks used for evaluation, whose datasets (bundled under evaluation/eval_data/, and MMLU-Pro fetched at runtime) are derived from:

We are also grateful to the authors of the BeaverTails dataset and the reward / scorer models for making them publicly available.

About

Shielding LLMs from Harmful Reinforcement Learning Fine-Tuning.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages