Universele adversarial aanvallen
Universele perturbaties die overdraagbaar zijn tussen modellen, onderzoek naar adversarial suffixen en technieken om modelonafhankelijke aanvalspayloads te maken.
Universele adversarial aanvallen
Universele adversarial perturbaties vormen de gevaarlijkste klasse adversarial aanvallen omdat ze generaliseren. In tegenstelling tot input-specifieke aanvallen die voor elke doelprompt opnieuw opgesteld moeten worden, produceren universele aanvallen één perturbatie -- vaak een adversarial suffix of prefix -- die werkt over diverse inputs en, in de sterkste resultaten, over verschillende modelarchitecturen en -schaalgroottes.
Fundamenten van universaliteit
Waarom universele aanvallen bestaan
Het bestaan van universele adversarial perturbaties onthult fundamentele eigenschappen van de geometrie van neurale netwerken. Modellen getraind op vergelijkbare gegevensdistributies ontwikkelen vergelijkbare interne representaties, en deze gedeelde representaties creëren gedeelde kwetsbaarheden.
Drie theoretische kaders verklaren universaliteit:
| Kader | Kerninzicht | Implicatie |
|---|---|---|
| Gedeelde feature-ruimte | Modellen getraind op vergelijkbare data leren vergelijkbare features | Perturbaties die gemeenschappelijke features misbruiken zijn overdraagbaar |
| Lineaire-subruimtehypothese | Adversarial perturbaties liggen in een laagdimensionale subruimte | Eén richting in deze subruimte beïnvloedt veel inputs |
| Geometrie van het loss-landschap | Modellen delen de structuur van het loss-landschap nabij beslissingsgrenzen | Gradiëntgebaseerde aanvallen vinden vergelijkbare daalrichtingen |
Van input-specifiek naar universeel
De progressie van specifieke naar universele aanvallen volgt een duidelijk onderzoeksspoor:
Input-specifieke adversarial voorbeelden
Szegedy et al. (2013) toonden aan dat imperceptibele perturbaties aan een enkele input misclassificatie konden veroorzaken. Elk adversarial voorbeeld werd opgesteld voor één specifieke input.
Overdraagbare adversarial voorbeelden
Papernot et al. (2016) toonden aan dat adversarial voorbeelden opgesteld voor één model andere modellen konden misleiden. Deze overdraagbaarheid wees op gedeelde kwetsbaarheden.
Universele adversarial perturbaties (UAP's)
Moosavi-Dezfooli et al. (2017) vonden enkele perturbaties die, toegevoegd aan een willekeurige afbeelding, met hoge waarschijnlijkheid misclassificatie veroorzaakten. Dezelfde perturbatie werkte over duizenden verschillende inputs.
Universele adversarial suffixen voor LLM's
Zou et al. (2023) breidden universaliteit uit naar taalmodellen met de GCG-aanval, en vonden tokenreeksen die, toegevoegd aan een willekeurig schadelijk verzoek, safety alignment over meerdere modelfamilies omzeilden.
Greedy Coordinate Gradient (GCG)-aanval
De GCG-aanval van Zou et al. (2023) is het fundamentele algoritme voor het genereren van universele adversarial suffixen tegen LLM's. Het optimaliseert een tokenreeks die, toegevoegd aan een schadelijke prompt, de kans maximaliseert dat het model zijn respons begint met een bevestigende prefix (bijv. "Sure, here is...").
Algoritmeoverzicht
# Vereenvoudigd GCG-algoritme
def gcg_attack(model, tokenizer, target_prompts, suffix_length=20,
iterations=500, top_k=256, batch_size=512):
"""
Genereer een universele adversarial suffix.
target_prompts: lijst van schadelijke prompts om tegen te optimaliseren
suffix_length: aantal tokens in de adversarial suffix
"""
# Initialiseer suffix met willekeurige tokens
suffix_tokens = torch.randint(0, tokenizer.vocab_size, (suffix_length,))
affirmative_target = "Sure, here is"
target_tokens = tokenizer.encode(affirmative_target)
for iteration in range(iterations):
# Selecteer een willekeurige prompt uit de doelverzameling
prompt = random.choice(target_prompts)
prompt_tokens = tokenizer.encode(prompt)
# Concateneer: [prompt] + [suffix] -> model -> [doelrespons]
full_input = torch.cat([prompt_tokens, suffix_tokens])
# Bereken loss: negatieve log-likelihood van doelrespons
logits = model(full_input)
loss = cross_entropy(logits[-len(target_tokens):], target_tokens)
# Bereken gradiënten t.o.v. one-hot suffix-tokenembeddings
loss.backward()
gradients = compute_token_gradients(model, suffix_tokens)
# Vind voor elke positie de top-k vervangingskandidaten
candidates = []
for pos in range(suffix_length):
top_k_tokens = gradients[pos].topk(top_k).indices
for token in top_k_tokens:
candidate = suffix_tokens.clone()
candidate[pos] = token
candidates.append(candidate)
# Evalueer alle kandidaten in batch
# Selecteer de kandidaat met de laagste loss
best_candidate = evaluate_candidates(model, prompt_tokens,
candidates, target_tokens)
suffix_tokens = best_candidate
return tokenizer.decode(suffix_tokens)Multi-modeloptimalisatie
De belangrijkste uitbreiding voor universaliteit over modellen is gelijktijdige optimalisatie:
def multi_model_gcg(models, tokenizer, target_prompts, suffix_length=20):
"""
Optimaliseer suffix tegen meerdere modellen tegelijkertijd.
De loss wordt geaggregeerd over alle modellen.
"""
suffix_tokens = initialize_suffix(suffix_length)
for iteration in range(iterations):
prompt = random.choice(target_prompts)
total_loss = 0
for model in models:
# Bereken loss voor dit model
loss = compute_attack_loss(model, prompt, suffix_tokens)
total_loss += loss
# Middel loss over modellen
avg_loss = total_loss / len(models)
# Gradiëntgebaseerde kandidaatselectie
# Gebruikt geaggregeerde gradiënten van alle modellen
suffix_tokens = select_best_candidate(
models, prompt, suffix_tokens, avg_loss
)
return suffix_tokensGCG-beperkingen en praktische overwegingen
| Beperking | Impact | Mitigatie |
|---|---|---|
| Vereist whitebox-toegang | Kan niet direct optimaliseren tegen closed-source API's | Transferaanvallen vanuit open-source surrogaten |
| Rekenintensief | Uren tot dagen op meerdere GPU's | Gedistribueerde optimalisatie, early stopping |
| Produceert wartaal-tokens | Eenvoudig te detecteren met perplexity-filters | Leesbare suffixvarianten (AutoDAN) |
| Breekbaar bij inputopmaak | Verschillende chat-templates breken de suffix | Template-bewuste optimalisatie |
| Verloopt bij model-updates | Nieuwe modelversies zijn mogelijk niet kwetsbaar | Continue heroptimalisatie |
Onderzoek naar overdraagbaarheid
Overdraagbaarheid is de eigenschap die universele aanvallen praktisch gevaarlijk maakt: een aanval ontwikkeld tegen een open-source model kan een closed-source API compromitteren.
Methodologie voor transferaanvallen
Selecteer surrogaatmodellen
Kies open-source modellen die architecturale kenmerken of trainingsdata met het doel delen. Grotere modelfamilies (Llama, Mistral, Qwen) dienen als betere surrogaten omdat ze meer van de representatieruimte beslaan.
Optimaliseer een ensemble-aanval
Genereer adversarial suffixen die gelijktijdig tegen meerdere surrogaatmodellen geoptimaliseerd zijn. Ensemble-optimalisatie produceert beter overdraagbare perturbaties dan single-modeloptimalisatie.
Evalueer transferpercentage
Test de suffix tegen het doelmodel. Transferpercentages variëren sterk: transfers binnen dezelfde familie (Llama 7B naar Llama 70B) slagen vaker dan kruisfamilie-transfers (Llama naar GPT).
Iteratieve verfijning
Gebruik blackbox-optimalisatie (bijv. score-gebaseerde methoden met API-logprobs) om de suffix voor het specifieke doel te fine-tunen, vertrekkend vanuit de overgedragen kandidaat.
Analyse van transferpercentages
Onderzoek heeft aangetoond dat adversarial overdraagbaarheid voorspelbare patronen volgt:
Transfersuccespercentages (bij benadering, uit gepubliceerd onderzoek):
Zelfde model, andere groottes: 60-80%
Zelfde familie, andere versies: 40-70%
Zelfde architectuur, andere training: 30-50%
Volledig andere architectuur: 10-30%
Andere modaliteit (tekst->multimodaal): 5-20%
Factoren die overdraagbaarheid verhogen:
- Gedeelde trainingsdata: Modellen getraind op overlappende corpora delen meer kwetsbaarheden
- Vergelijkbare safety-training: RLHF/DPO met vergelijkbare voorkeursdatasets creëert vergelijkbare veiligheidsgrenzen
- Architecturale gelijkenis: Decoder-only transformers delen meer kwetsbaarheden onderling dan met encoder-decodermodellen
- Ensemble-diversiteit: Optimaliseren tegen diversere surrogaten verbetert transfer naar ongeziene doelen
Cross-modale transfer
Recent onderzoek heeft de transfer van adversarial perturbaties over modaliteiten heen onderzocht:
# Cross-modale transfer: tekst-adversarial-suffix -> beeldperturbatie
# Kerninzicht: multimodale modellen delen een embedding-ruimte
def cross_modal_transfer(text_suffix, multimodal_model):
"""
Converteer een tekst-adversarial-suffix naar een beeldperturbatie
met vergelijkbaar effect in de gedeelde embedding-ruimte.
"""
# Verkrijg tekst-suffix-embedding
text_embedding = multimodal_model.text_encoder(text_suffix)
# Optimaliseer beeldperturbatie zodat deze overeenkomt met tekstembedding
perturbation = torch.zeros_like(base_image, requires_grad=True)
optimizer = torch.optim.Adam([perturbation], lr=0.01)
for step in range(1000):
perturbed_image = base_image + perturbation
image_embedding = multimodal_model.image_encoder(perturbed_image)
# Minimaliseer afstand tussen beeldembedding en tekst-suffix-embedding
loss = torch.nn.functional.cosine_embedding_loss(
image_embedding, text_embedding,
torch.ones(1)
)
loss.backward()
optimizer.step()
# Projecteer perturbatie naar Lp-bol
perturbation.data = torch.clamp(perturbation.data, -epsilon, epsilon)
return perturbationGeavanceerde varianten van universele aanvallen
AutoDAN: leesbare universele aanvallen
AutoDAN pakt de belangrijkste zwakte van GCG aan -- wartaal-suffixen die triviaal te detecteren zijn -- door zowel op aanvalssucces als leesbaarheid te optimaliseren:
# AutoDAN gebruikt een taalmodel om leesbare aanvalkandidaten te genereren
# en selecteert en muteert vervolgens de succesvolste
def autodan_iteration(attack_lm, target_model, population, prompt):
"""
Eén iteratie van het genetisch algoritme van AutoDAN.
Population bevat leesbare aanvalssuffixen.
"""
# Evalueer fitness: aanvalssuccespercentage op doel
fitness_scores = []
for suffix in population:
full_prompt = f"{prompt} {suffix}"
response = target_model.generate(full_prompt)
score = evaluate_attack_success(response)
fitness_scores.append(score)
# Selecteer de best presterende
elite = select_top_k(population, fitness_scores, k=10)
# Crossover en mutatie met LLM
new_population = []
for _ in range(len(population)):
parent1, parent2 = random.sample(elite, 2)
child = attack_lm.generate(
f"Combine these two texts into a new coherent paragraph "
f"that preserves the key phrases from both:\n"
f"Text 1: {parent1}\nText 2: {parent2}"
)
new_population.append(child)
return new_populationPAIR: Prompt Automatic Iterative Refinement
PAIR gebruikt een aparte aanvallers-LLM om jailbreakprompts iteratief te verfijnen via conversationele feedback:
def pair_attack(attacker_model, target_model, objective, max_rounds=20):
"""
PAIR: gebruik een aanvallers-LLM om jailbreaks iteratief op te stellen.
Het aanvallersmodel ontvangt feedback over waarom eerdere
pogingen faalden en verbetert zijn strategie.
"""
conversation_history = [
{"role": "system", "content": ATTACKER_SYSTEM_PROMPT},
{"role": "user", "content": f"Objective: {objective}"}
]
for round in range(max_rounds):
# Aanvaller genereert een kandidaat-jailbreak
attack_prompt = attacker_model.generate(conversation_history)
# Test tegen doel
target_response = target_model.generate(attack_prompt)
# Beoordeel succes
success, feedback = judge_response(target_response, objective)
if success:
return attack_prompt, target_response
# Voer resultaat terug aan aanvaller
conversation_history.append({
"role": "user",
"content": f"Attempt failed. Target response: {target_response}\n"
f"Feedback: {feedback}\nTry a different approach."
})
return None, NoneTAP: Tree of Attacks with Pruning
TAP breidt PAIR uit door meerdere aanvalsstrategieën gelijktijdig te verkennen met een boomstructuur:
def tap_attack(attacker_model, target_model, evaluator_model,
objective, width=10, depth=5):
"""
TAP: verken een boom met aanvalsstrategieën met pruning.
"""
# Initialiseer wortelknopen met diverse aanvalsstrategieën
root_prompts = attacker_model.generate_diverse(
objective, count=width
)
tree = {0: root_prompts} # diepte -> lijst van kandidaten
for d in range(1, depth + 1):
candidates = []
for parent_prompt in tree[d - 1]:
# Test ouder tegen doel
response = target_model.generate(parent_prompt)
score = evaluator_model.score(response, objective)
if score > SUCCESS_THRESHOLD:
return parent_prompt, response
if score > PRUNE_THRESHOLD:
# Genereer kindvariaties
children = attacker_model.refine(
parent_prompt, response, objective, count=3
)
candidates.extend(children)
# Prune naar top-width kandidaten
tree[d] = evaluator_model.rank(candidates, objective)[:width]
return best_candidate(tree), NonePraktische aanvalspipeline
Een realistische pipeline voor universele aanvallen combineert deze technieken:
Seed-generatie met GCG op open-source modellen
Genereer initiële adversarial suffixen met GCG tegen een ensemble van open-source modellen (Llama 3, Mistral, Qwen). Dit levert kandidaat-suffixen met brede overdraagbaarheid.
Leesbaarheidsverfijning met AutoDAN
Gebruik AutoDAN om de GCG-suffixen te evolueren naar leesbare varianten die op perplexity gebaseerde detectie omzeilen met behoud van aanvalseffectiviteit.
Doelspecifieke optimalisatie met PAIR/TAP
Zet PAIR of TAP in tegen de doel-API met de verfijnde suffixen als seedprompts. De aanvallers-LLM past de aanval iteratief aan op de safety-training van het specifieke doel.
Universaliteitsvalidatie
Test de uiteindelijke aanvalsprompts tegen meerdere modelversies en configuraties om robuustheid en generalisatie te verifiëren.
Verdedigingen tegen universele aanvallen
Verdediging tegen universele adversarial aanvallen vereist meerdere complementaire benaderingen:
Perplexity-filtering
Detecteer GCG-achtige wartaal-suffixen door de perplexity van binnenkomende prompts te meten:
def perplexity_filter(prompt, threshold=100.0):
"""Weiger prompts met ongewoon hoge perplexity."""
tokens = tokenizer.encode(prompt)
with torch.no_grad():
outputs = detector_model(tokens)
log_probs = outputs.log_probs
perplexity = torch.exp(-log_probs.mean())
return perplexity.item() < thresholdAdversarial training
Neem adversarial voorbeelden op in safety-training om robuustheid op te bouwen:
# Vul safety-trainingsdata aan met adversarial voorbeelden
adversarial_training_data = []
for harmful_prompt in harmful_prompts:
# Genereer adversarial varianten
for suffix in known_adversarial_suffixes:
adversarial_training_data.append({
"prompt": f"{harmful_prompt} {suffix}",
"response": "I cannot help with that request.",
"label": "refuse"
})Erase-and-check
SmoothLLM en verwante benaderingen voegen willekeurige perturbaties toe aan de input en controleren of de respons van het model consistent is:
def smooth_llm_defense(model, prompt, num_samples=10, perturbation_rate=0.1):
"""
Verstoor input willekeurig en controleer responsconsistentie.
Adversarial suffixen zijn breekbaar bij perturbatie.
"""
responses = []
for _ in range(num_samples):
perturbed = randomly_perturb_tokens(prompt, perturbation_rate)
response = model.generate(perturbed)
responses.append(is_refusal(response))
# Als de meeste verstoorde versies een weigering opleveren,
# bevat het origineel waarschijnlijk een adversarial suffix
refusal_rate = sum(responses) / len(responses)
if refusal_rate > 0.5:
return "Request blocked: potential adversarial input"
return model.generate(prompt) # Verwerk origineelGerelateerde onderwerpen
- Generatie van adversarial suffixen — Adversarial suffixaanvallen op single-modellen
- Geautomatiseerde jailbreakpijplijnen — Gedetailleerde PAIR-, TAP- en AutoDAN-implementatie
- Blinde prompt injection — Universele aanvallen inzetten in blinde scenario's
Een red team genereert een adversarial suffix met GCG tegen Llama 3 8B en Mistral 7B tegelijkertijd. Ze testen deze tegen GPT-4. Wat is de meest waarschijnlijke uitkomst?
Referenties
- Zou et al., "Universal and Transferable Adversarial Attacks on Aligned Language Models" (2023)
- Moosavi-Dezfooli et al., "Universal Adversarial Perturbations" (2017)
- Liu et al., "AutoDAN: Generating Stealthy Jailbreak Prompts on Aligned Large Language Models" (2023)
- Chao et al., "Jailbreaking Black Box Large Language Models in Twenty Queries" (2023) -- PAIR
- Mehrotra et al., "Tree of Attacks: Jailbreaking Black-Box LLMs with Auto-Generated Subtrees" (2023) -- TAP
- Robey et al., "SmoothLLM: Defending Large Language Models Against Jailbreaking Attacks" (2023)