Technieken voor watermerkverwijdering
Technieken voor het verwijderen van AI-watermerken: parafraseringsaanvallen, tokensubstitutie, verstoring van de embedding-ruimte, en implicaties voor modelherkomst en verantwoordingsplicht.
AI-watermerken zijn ontworpen om tekst als AI-gegenereerd te markeren, waardoor attributie en herkomsttracering mogelijk worden. Huidige watermerkschema's zijn echter kwetsbaar voor verwijderingsaanvallen die het statistische signaal weghalen terwijl de tekstkwaliteit behouden blijft. Dit heeft aanzienlijke implicaties voor de verantwoordingsplicht van modellen, de herkomst van inhoud en de bescherming van intellectueel eigendom.
Hoe AI-watermerken werken
De groene-rode-lijst-benadering (Kirchenbauer et al.)
De meest bestudeerde benadering verdeelt het vocabulaire bij elke generatiestap in "groene" en "rode" lijsten, met behulp van een geheime sleutel:
import hashlib
import torch
def watermarked_sampling(logits, prev_token, watermark_key, bias=2.0):
"""Voeg bias toe aan 'groene lijst'-tokens tijdens het samplen.
De groene lijst wordt bepaald door een hash van het vorige token
en de watermerksleutel."""
# Deterministische groen/rood-splitsing op basis van vorig token + sleutel
seed = int(hashlib.sha256(
f"{watermark_key}:{prev_token}".encode()
).hexdigest()[:8], 16)
rng = torch.Generator().manual_seed(seed)
vocab_size = logits.shape[-1]
perm = torch.randperm(vocab_size, generator=rng)
green_tokens = perm[:vocab_size // 2]
# Bias de logits richting groene tokens
watermarked_logits = logits.clone()
watermarked_logits[green_tokens] += bias
return watermarked_logits
def detect_watermark(text, tokenizer, watermark_key, threshold=0.5):
"""Detecteer watermerk door de fractie groene tokens te meten."""
tokens = tokenizer.encode(text)
green_count = 0
for i in range(1, len(tokens)):
seed = int(hashlib.sha256(
f"{watermark_key}:{tokens[i-1]}".encode()
).hexdigest()[:8], 16)
rng = torch.Generator().manual_seed(seed)
perm = torch.randperm(tokenizer.vocab_size, generator=rng)
green_tokens = set(perm[:tokenizer.vocab_size // 2].tolist())
if tokens[i] in green_tokens:
green_count += 1
green_fraction = green_count / (len(tokens) - 1)
# Tekst zonder watermerk: ~50% groene tokens
# Tekst met watermerk: significant > 50% groene tokens
z_score = (green_fraction - 0.5) / (0.5 / (len(tokens) - 1) ** 0.5)
return z_score > threshold, z_score, green_fractionDetectie-eigenschappen van watermerken
| Eigenschap | Waarde | Implicatie |
|---|---|---|
| Verwachte groene fractie (geen watermerk) | ~50% | Statistische baseline |
| Verwachte groene fractie (met watermerk) | 65-85% | Afhankelijk van de bias-sterkte |
| Minimale detecteerbare tekstlengte | ~25 tokens | Korte teksten zijn onbetrouwbaar |
| False-positivepercentage (z > 4) | ~0,003% | Zeer laag voor lange teksten |
| False-negativepercentage | Afhankelijk van de bias-sterkte | Hogere bias = lager FN-percentage |
Verwijderingstechniek 1: Parafraseringsaanvallen
De meest effectieve en toegankelijke verwijderingstechniek: parafraseer de tekst met watermerk met behulp van een ander (niet-gewatermerkt) model.
def paraphrase_removal(watermarked_text, paraphrase_model, tokenizer):
"""Verwijder watermerk door te parafraseren met een niet-gewatermerkt model."""
prompt = f"""Rewrite the following text to convey the same meaning
using different words and sentence structures. Preserve all factual
content and technical accuracy.
Original text:
{watermarked_text}
Rewritten text:"""
# Het parafraseringsmodel genereert nieuwe tokens zonder de watermerk-bias
paraphrased = paraphrase_model.generate(
tokenizer(prompt, return_tensors="pt").input_ids,
max_new_tokens=len(watermarked_text.split()) * 2,
temperature=0.7,
)
return tokenizer.decode(paraphrased[0], skip_special_tokens=True)Effectiviteit van parafrasering
| Parafraseringsmethode | Watermerkverwijderingspercentage | Semantisch behoud | Kwaliteit |
|---|---|---|---|
| LLM-parafrasering (GPT-4-klasse) | 85-95% | 90-95% | Hoog |
| LLM-parafrasering (7B-model) | 70-85% | 80-90% | Gemiddeld |
| Terugvertaling (EN→FR→EN) | 60-80% | 75-85% | Gemiddeld |
| Synoniemsubstitutie | 40-60% | 85-95% | Hoog |
| Willekeurig woorden verwijderen/invoegen | 30-50% | 60-80% | Laag |
Verwijderingstechniek 2: Tokensubstitutie
Gerichte vervanging van tokens om de fractie groene tokens richting de 50%-baseline te verminderen:
def token_substitution_removal(text, tokenizer, watermark_key, model):
"""Verwijder watermerk door selectief groene tokens te vervangen
door semantisch equivalente rode tokens."""
tokens = tokenizer.encode(text)
modified_tokens = list(tokens)
for i in range(1, len(tokens)):
# Bepaal of het huidige token groen is
green_set = get_green_tokens(tokens[i-1], watermark_key, tokenizer.vocab_size)
if tokens[i] in green_set:
# Vind een semantisch vergelijkbaar rood token
# Verkrijg de waarschijnlijkheidsverdeling van het model op deze positie
context = torch.tensor([modified_tokens[:i]])
logits = model(context).logits[0, -1]
# Vind het rode token met de hoogste waarschijnlijkheid
red_set = set(range(tokenizer.vocab_size)) - green_set
red_probs = [(t, logits[t].item()) for t in red_set]
red_probs.sort(key=lambda x: x[1], reverse=True)
best_red_token = red_probs[0][0]
# Vervang alleen als het rode token redelijk waarschijnlijk is
if logits[best_red_token] > logits[tokens[i]] - 3.0:
modified_tokens[i] = best_red_token
return tokenizer.decode(modified_tokens)Verwijderingstechniek 3: Verstoring van de embedding-ruimte
Voor watermerken die in de embedding-ruimte werken, kan verstoring het watermerksignaal ontregelen:
def embedding_perturbation_removal(text, model, tokenizer, noise_scale=0.1):
"""Verwijder watermerken op embedding-niveau door ruis toe te voegen
aan token-embeddings en opnieuw te decoderen."""
tokens = tokenizer(text, return_tensors="pt")
embeddings = model.get_input_embeddings()(tokens.input_ids)
# Voeg gekalibreerde ruis toe om het watermerksignaal te ontregelen
noise = torch.randn_like(embeddings) * noise_scale
perturbed_embeddings = embeddings + noise
# Decodeer opnieuw vanuit de verstoorde embeddings
with torch.no_grad():
outputs = model(inputs_embeds=perturbed_embeddings)
new_tokens = outputs.logits.argmax(dim=-1)
return tokenizer.decode(new_tokens[0], skip_special_tokens=True)Implicaties voor modelherkomst
De watermerk-wapenwedloop
| Generatie | Watermerkbenadering | Verwijderingsaanval | Resultaat |
|---|---|---|---|
| 1e | Groen-rode token-bias | Parafrasering | Watermerk verwijderd |
| 2e | Semantisch watermerken | Stijltransfer | Gedeeltelijk effectief |
| 3e | Watermerken op meerdere niveaus | Ensemble-parafrasering | Kat-en-muisspel gaat door |
Huidige beperkingen
Alternatieve herkomstbenaderingen
| Benadering | Mechanisme | Robuustheid tegen verwijdering |
|---|---|---|
| Tekstwatermerken | Statistische bias in tokenselectie | Laag -- parafrasering verwijdert het |
| Modelfingerprinting | Unieke gedragssignaturen in modelgewichten | Gemiddeld -- overleeft aanvallen op tekstniveau |
| Stylometrische analyse | Statistische schrijfstijlkenmerken | Gemiddeld -- varieert met tekstlengte |
| Op retrieval gebaseerde detectie | Vergelijk met een database van bekende outputs | Hoog -- vereist een uitgebreide database |
| Cryptografische ondertekening | Onderteken outputs op het moment van generatie | Hoog -- maar vereist vertrouwen in de ondertekeningssleutel |
Ethische overwegingen
Gerelateerde onderwerpen
- Geavanceerde aanvalsvectoren voor training -- Overzicht van geavanceerde trainingsaanvallen
- Distillatie-gebaseerde modelextractie -- Context van modeldiefstal
- Aanvallen op synthetische-datapipelines -- Herkomst van synthetische data
- Defensie-ontwijking -- Omzeiling van outputfiltering
Waarom is op LLM gebaseerde parafrasering de meest effectieve techniek voor watermerkverwijdering?
References
- A Watermark for Large Language Models (Kirchenbauer et al., 2023) -- Green-red list watermarking
- On the Reliability of Watermarks for Large Language Models (Piet et al., 2023) -- Watermark robustness analysis
- Paraphrasing evades detectors of AI-generated text (Sadasivan et al., 2023) -- Paraphrasing attacks