GPTFuzz
Framework de fuzzing de jailbreak en boîte noire qui mute des templates de jailbreak écrits par des humains via un mutateur LLM et une sélection de graines basée sur MCTS, jugée par un modèle de scoring entraîné. Black-box jailbreak fuzzing framework that mutates human-written jailbreak templates via an LLM mutator and MCTS-based seed selection, judged by a trained scoring model.
↗ https://github.com/sherdencooper/GPTFuzzOverview
GPTFuzz (GPTFUZZER) applies AFL-style mutational fuzzing to LLM jailbreaking. Instead of hand-crafting prompts, it starts from a seed pool of known jailbreak templates, uses an LLM (e.g. GPT-3.5) to mutate them (rephrase, expand, crossover, shorten), and picks which seed to mutate next with an MCTS-Explore strategy that balances exploiting promising seeds against exploring new ones. A fine-tuned RoBERTa judgment model scores whether each generated prompt actually jailbroke the target, closing the loop without needing a human in every iteration. The original paper reports 90%+ attack success against ChatGPT and Llama-2 with this approach.
Installation
git clone https://github.com/sherdencooper/GPTFuzz.git
cd GPTFuzz
pip install -r requirements.txt
Download / point to the pretrained RoBERTa judgment model
python download_judge_model.py
Running a Fuzzing Campaign
Fuzz against a target model using the bundled seed templates
python fuzz.py \
--seed_path datasets/prompts/jailbreak_templates.csv \
--question_path datasets/questions/harmful_questions.csv \
--target_model gpt-3.5-turbo \
--mutate_model gpt-3.5-turbo \
--judge_model roberta \
--max_query 1000 \
--max_jailbreak 5 \
--energy 1 \
--output_file results/run1.csv
Custom Target / Local Model
from gptfuzzer.fuzzer import GPTFuzzer
from gptfuzzer.fuzzer.mutator import MutateRandomSinglePolicy
from gptfuzzer.llm import LocalLLM, OpenAILLM
target = LocalLLM(model_path="/models/Llama-2-7b-chat-hf")
mutate_model = OpenAILLM(model_path="gpt-3.5-turbo", api_key="<api_key>")
fuzzer = GPTFuzzer(
questions=["<harmful_question>"],
target=target,
predictor=judge_model, # loaded RoBERTa classifier
initial_seed=seed_templates, # list of jailbreak template strings
mutate_policy=MutateRandomSinglePolicy([...], mutate_model),
energy=1,
max_query=1000,
)
fuzzer.run()
Tips
- The MCTS-Explore seed selector is the key differentiator over plain random mutation — it converges on effective template lineages faster, so prefer it over
--select_policy randomfor longer campaigns. - Swap in your own judge (regex-based refusal detector, another LLM-as-judge) via
--judge_modelif the bundled RoBERTa model doesn’t fit your target’s response style. - Track
--max_querycarefully against hosted targets — each fuzzing iteration burns API calls on both the mutator and the target.
Help / Man page
usage: fuzz.py [-h] --seed_path PATH --question_path PATH
--target_model MODEL --mutate_model MODEL
[--judge_model {roberta,gpt4,regex}]
[--max_query N] [--max_jailbreak N]
[--energy N] [--select_policy {mcts,random,round_robin}]
[--output_file FILE]
required arguments:
--seed_path PATH CSV of seed jailbreak templates
--question_path PATH CSV of harmful questions to test
--target_model MODEL model under test (API name or local path)
--mutate_model MODEL LLM used to mutate seeds
optional arguments:
--judge_model NAME response classifier (default: roberta)
--max_query N query budget for the campaign
--max_jailbreak N stop early after N successful jailbreaks
--energy N mutants generated per selected seed per round
--select_policy NAME seed selection strategy (default: mcts)
--output_file FILE CSV of prompts, responses, and judge scores
Vue d’ensemble
GPTFuzz (GPTFUZZER) applique un fuzzing mutationnel de style AFL au jailbreaking de LLM. Au lieu de rédiger des prompts à la main, il part d’un pool de graines constitué de templates de jailbreak connus, utilise un LLM (par exemple GPT-3.5) pour les muter (reformulation, expansion, crossover, raccourcissement), et choisit quelle graine muter ensuite avec une stratégie MCTS-Explore qui équilibre l’exploitation des graines prometteuses et l’exploration de nouvelles graines. Un modèle de jugement RoBERTa affiné évalue si chaque prompt généré a effectivement jailbreaké la cible, bouclant le processus sans nécessiter d’humain à chaque itération. L’article original rapporte un taux de succès d’attaque supérieur à 90 % contre ChatGPT et Llama-2 avec cette approche.
Installation
git clone https://github.com/sherdencooper/GPTFuzz.git
cd GPTFuzz
pip install -r requirements.txt
Télécharger / pointer vers le modèle de jugement RoBERTa préentraîné
python download_judge_model.py
Lancer une campagne de fuzzing
Fuzzer contre un modèle cible avec les templates de graines fournis
python fuzz.py \
--seed_path datasets/prompts/jailbreak_templates.csv \
--question_path datasets/questions/harmful_questions.csv \
--target_model gpt-3.5-turbo \
--mutate_model gpt-3.5-turbo \
--judge_model roberta \
--max_query 1000 \
--max_jailbreak 5 \
--energy 1 \
--output_file results/run1.csv
Cible personnalisée / modèle local
from gptfuzzer.fuzzer import GPTFuzzer
from gptfuzzer.fuzzer.mutator import MutateRandomSinglePolicy
from gptfuzzer.llm import LocalLLM, OpenAILLM
target = LocalLLM(model_path="/models/Llama-2-7b-chat-hf")
mutate_model = OpenAILLM(model_path="gpt-3.5-turbo", api_key="<api_key>")
fuzzer = GPTFuzzer(
questions=["<harmful_question>"],
target=target,
predictor=judge_model, # loaded RoBERTa classifier
initial_seed=seed_templates, # list of jailbreak template strings
mutate_policy=MutateRandomSinglePolicy([...], mutate_model),
energy=1,
max_query=1000,
)
fuzzer.run()
Conseils
- Le sélecteur de graines MCTS-Explore est le principal élément différenciant par rapport à une simple mutation aléatoire : il converge plus vite vers des lignées de templates efficaces, donc préférez-le à
--select_policy randompour les campagnes longues. - Remplacez le juge fourni (détecteur de refus basé sur regex, un autre LLM-as-judge) via
--judge_modelsi le modèle RoBERTa fourni ne correspond pas au style de réponse de votre cible. - Surveillez
--max_queryde près contre des cibles hébergées : chaque itération de fuzzing consomme des appels API à la fois sur le mutateur et sur la cible.
Aide / Page de manuel
usage: fuzz.py [-h] --seed_path PATH --question_path PATH
--target_model MODEL --mutate_model MODEL
[--judge_model {roberta,gpt4,regex}]
[--max_query N] [--max_jailbreak N]
[--energy N] [--select_policy {mcts,random,round_robin}]
[--output_file FILE]
required arguments:
--seed_path PATH CSV of seed jailbreak templates
--question_path PATH CSV of harmful questions to test
--target_model MODEL model under test (API name or local path)
--mutate_model MODEL LLM used to mutate seeds
optional arguments:
--judge_model NAME response classifier (default: roberta)
--max_query N query budget for the campaign
--max_jailbreak N stop early after N successful jailbreaks
--energy N mutants generated per selected seed per round
--select_policy NAME seed selection strategy (default: mcts)
--output_file FILE CSV of prompts, responses, and judge scores