
Семантический водяной знак с устойчивым к порядку обнаружением на уровне субпредложений
SwordStamp добавляет к семантическим водяным знакам на основе эмбеддингов устойчивое к порядку обнаружение и единицы семантических фрагментов. Этот артефакт содержит точную конфигурацию из статьи, код генерации и обнаружения, неизменённый набор атак, оценку качества, а также детерминированное извлечение результатов и построение графиков.
Статья: Semantic Watermarking with Order-Robust Detection over Sub-sentence Units (arXiv:2608.27666)
При 5% уровне ложноположительных срабатываний и требовании сохранения 90% содержимого специфичная для схемы атака смещения эмбеддингов (EDA-S) достигает:
| Водяной знак | Успешность атаки EDA-S |
|---|---|
| SemStamp | 47.9% |
| k-SemStamp | 33.3% |
| PMark | 46.1% |
| SAMark | 32.6% |
| SwordStamp | 18.7% |
| k-SwordStamp | 10.8% |
По сравнению с опубликованными базовыми значениями SwordStamp и k-SwordStamp снижают успешность EDA-S на 29.2 и 22.5 процентных пункта при потерях чистого качества 1.8 и 4.4 пункта. Их показатели чистого обнаружения составляют 94.9% и 97.0%. В более сильном стресс-тесте EDA-D с доступом к детектору максимальная успешность при ограничении качества составляет 39.7% для k-SwordStamp против 65.5% для k-SemStamp.


Эти результаты охватывают продолжения английских новостей, одну модель провайдера, два энкодера провайдера и одну пару парафразера/суррогата EDA.
visualization использует только скомпилированный набор CSV/Parquet. При отсутствии ячеек из статьи он завершается с ошибкой, а не строит частичный график.
uv sync --frozen --only-group plot --no-install-project
uv run --no-sync python -m visualization extract \
--bundle results/paper --output results/paper
uv run --no-sync python -m visualization render \
--bundle results/paper --output results/paper
Записывает проверяемые таблицы в results/paper/tables/ и семь рисунков в
форматах PNG и PDF в results/paper/figures/. Ветка анонимного рецензирования включает
скомпилированный пакет; полный запуск в ветке релиза создаёт те же файлы
с помощью python -m visualization compile.
Атака смещения эмбеддингов (EDA) — это адаптивная атака перефразирования всего текста.
На каждой выходной единице она
выбирает K продолжений и оставляет кандидата с наибольшим косинусным
смещением от его исходного якоря под суррогатным энкодером. Поскольку каждый
кандидат продолжает полный префикс перезаписи, одна цель может переформулировать содержимое,
переупорядочить его, а также разделить или объединить единицы детектора.
EDA без доступа к модели (no-box) видит помеченный текст и публичный дизайн водяного знака. Она не запрашивает детектор или генератор и не получает секретный ключ, энкодер провайдера или оракул качества.
| Вариант | Якорь и единица | Конфигурация |
|---|---|---|
| EDA-P | позиционное предложение | adaptive, anchor=positional, единица атакующего sentence |
| EDA-S | публичный дизайн цели | позиционные предложения для SemStamp, k-SemStamp и PMark; bag/sentence для SAMark; bag/semspan для обоих вариантов SwordStamp |
| EDA-D | детектор провайдера | oracle; наследует энкодер, разбиение и сегментацию защитника |
Для якорения по bag в статье используется attack.bag_agg=min: максимизировать расстояние от
ближайшего исходного якоря. В отчётных запусках no-box используются
Qwen/Qwen2.5-3B-Instruct, BAAI/bge-base-en-v1.5,
K={1,2,4,8,16,32,64}, температура 1.0, top-p 0.95, не более 96 токенов на
кандидата и не более 512 токенов перезаписи.
Другие разработчики водяных знаков могут вызывать EDA напрямую:
from attacks.paraphrasing.adaptive import adaptive_attack_paraphrase
attacked = adaptive_attack_paraphrase(
texts,
base_model="Qwen/Qwen2.5-3B-Instruct",
surrogate_model="BAAI/bge-base-en-v1.5",
num_candidates=32,
anchor="positional", # EDA-P; use "bag" for an order-robust design
bag_agg="min",
segmentation_type="sentence",
segmentation_backend="nltk",
)
Для ориентированного на SwordStamp варианта EDA-S из статьи задайте anchor="bag",
segmentation_type="semspan", semcut_max_words=15 и
semcut_window=5. В этом репозитории эквивалентная команда CLI:
uv run python -m attacks DATA_PATH --config PRESET \
--set attack.paraphraser=adaptive \
--set attack.custom_model=Qwen/Qwen2.5-3B-Instruct \
--set attack.surrogate_model=BAAI/bge-base-en-v1.5 \
--set attack.num_candidates=32 \
--set attack.anchor=bag --set attack.bag_agg=min \
--set segmentation.attacker_type=semspan \
--set segmentation.attacker_backend=nltk
DATA_PATH всегда является базовым корпусом, а PRESET идентифицирует ячейку
с водяным знаком. См. attacks/README.md для всех сохранённых атак и полей конфигурации.

config/paper.py — единственный источник истины. Для каждого из LSH и k-means
scripts/experiments/swordstamp.sh запускает эту пятиступенчатую аддитивную лестницу с 64
кандидатами от провайдера:
Сетка содержит только эти десять ячеек и один базовый вариант без водяного знака. PMark
работает только онлайн; SAMark использует один шаблон флагов на запуск. Бюджеты EDA-D —
K={4,8,16,32,64}.
Подмодули сравнения адаптируют публичные исходники оценки PMark и SAMark только на их границах набора данных/результатов и общей калибровки ложноположительных срабатываний; алгоритмы водяных знаков не изменены.
Требования: Git, uv, Python 3.11, CUDA для запусков моделей, доступ к закреплённым ревизиям моделей и временное хранилище.
git clone --recurse-submodules [email protected]:D-Diaa/SwordStamp.git
cd SwordStamp
bash scripts/setup.sh
uv run --frozen python scripts/check_artifact.py
Подготовьте детерминированные, непересекающиеся разделы C4:
uv run --frozen python scripts/prepare_c4.py --output-dir data
Установите и настройте закреплённый планировщик. Установщик выводит свои пользовательские побочные эффекты перед внесением каких-либо изменений:
bash scripts/install_gpu_scheduler.sh --print-plan
bash scripts/install_gpu_scheduler.sh --yes
gpu-scheduler init --gpus 0,1
gpu-scheduler start
Просмотрите, затем отправьте каждый физический шард:
for shard in c4-val-def-256 c4-val-def-256b c4-val-def-512; do
BASE="data/$shard" DRY_RUN=1 bash scripts/experiments/swordstamp.sh
BASE="data/$shard" DRY_RUN=1 bash scripts/experiments/pmark.sh
BASE="data/$shard" DRY_RUN=1 bash scripts/experiments/samark.sh
done
# Remove DRY_RUN=1 after inspecting the exact DAGs.
Скомпилируйте, извлеките и отрендерите: