Как работают текстовые ИИ-вотермарки и как их обходить
Наверное уже многие знают, что в силу недавно вступивших в ЕС законов, регулирующих использование ИИ, провайдеры LLM обязаны помечать ИИ-сгенерированные тексты. Та же Claude недавно обновила справочную информацию о работе своей помечалки сгенерированного ИИ контента, в том числе и текста. Но в подробности его работы почему-то вдаваться не стала, как и размещать в публичном доступе средства добавления и обнаружения этих самых вотермарок.
Не то чтобы я часто балуюсь текстовым нейрослопом, но в последние пару дней поднялось очень много шума в сети по поводу этих вотермарок, и мне стало интересно, насколько сложно от них избавиться. Да и сама идея того, что твой текст могут объявить слопом чисто случайно или в следствии того, что ты отредактировал иишкой его часть, тоже не сильно радует. Поэтому в этой статье мы разберемся, как собственно эти метки работают, и как с ними бороться.
Как работают текстовые ИИ-вотермарки
Поначалу, когда я впервые услышал о текстовых вотермарках, я подумал, что LLM просто вставляет в текст всякие скрытые символы или там длинные тире, но этот метод донельзя дубовый и очевидно, что обходится на раз-два. На самом деле это работает так.
LLM это авторегрессионная вероятностная модель. На каждом шаге она выбирает следующий токен из своего большого словаря (обычно от десятков до сотен тысяч токенов) опираясь на изначальный промпт и предыдущие сгенерированные ею токены. Сначала модель отбирает топ-K наиболее вероятных токенов, а затем выбирает среди них один единственный с учетом его вероятности. Вотермаркинг же смещает распределение вероятностей токенов: слова, которые обычно редко встречаются в тексте, начинают появляться чаще, и наоборот.
Для человека заметить разницу практически невозможно, но для машины, знающей реальное распределение слов/токенов, это не составит труда.
Собственно вот видео, в котором объясняется, как работает вотермаркинг в Gemini.
В видео это объяснено довольно поверхностно, поэтому объясню немного детальнее. Для начала рассмотрим схему попроще, далее перейдем к технологии SynthID, которую использует Google.
KGW (red-green watermarking)
У нас есть фиксированный секретный ключ K. При генерации текста смотрим на последние H токенов, и на основании ключа K и этих токенов при помощи хэш функции получаем seed, далее разбиваем словарь на две половины, условно красную и зеленую. Затем ко всем логитам зелёных токенов прибавляем небольшую константу δ, после чего сэмплируем как обычно. Красные токены при этом остаются доступными - если единственный осмысленный токен происходит из красной части, модель его выберет. Смещение δ повышает шанс на выбор зелёного токена, но не запрещает красный.
Дальше переходим к выбору следующего токена. На следующем шаге набор из m последних токенов уже другой, поэтому и раскраска тоже будет другая.
Проверка: зная ключ K, восстанавливаем раскраску на каждой позиции и считаем долю зелёных токенов по всему тексту. У человека она будет около 50%, у модели с вотермаркой - заметно выше. Дальше проводим статистический тест и считаем z-score, p-value и вот это вот всё. Если отличия стат значимы - значит текст вотермаркнутый.
SynthID
SynthID работает несколько иначе.
Также как и в KGW, у нас есть фиксированный секретный ключ K, последние H токенов, которые вместе с ключом задают seed. А также у нас есть m псевдослучайных g-функций (по сути хэш-функций), приписывающих каждому токену словаря значение 0 или 1. При генерации текста из выходного распределения токенов модели вытягивается 2^m кандидатов (в реализации от гугла m = 30), причём с повторениями. Они разбиваются на пары, в каждой паре побеждает набравший большее значение функции g₁, ничьи разрешаются случайно. Дальше победители играют следующий слой, победителя на этом слое определяет функция g₂, и так до финала.
А при проверке текста, зная ключ, восстанавливаем значения g-функции для каждого токена и усредняем их по всему тексту и проводим стат тест. Если среднее находится в районе 0.5, значит с текстом все в порядке. Если значительно выше - значит текст вотермаркнутный.
Более подробно можно почитать здесь.
Теперь по поводу детектора от Anthropic. Как точно он работает, мы не знаем, это закрытая информация. Могу только сослаться на мнение экспертов в этой области, которые склоняются к тому, что в Anthropic используют похожую схему.
Как их обходить
Вполне очевидно, что придется либо жестко редактировать либо переписывать текст другими словами. Что предлагаю я.
Для начала предобработать исходный текст, чтобы удалить самые очевидные признаки сгенерированного ИИ контента: длинные тире, символы нулевой ширины, нестандартные пробелы и т. д.
Следующие три шага направлены на борьбу с самой сутью вотермаркинга - специфическим распределением токенов. Вот как это работает:
Отправить текст в переводчик (например, Google Переводчик) и перевести его на промежуточный язык
Перевести текст обратно с промежуточного языка на исходный
При необходимости переписать текст с помощью LLM, которая гарантированно не добавляет водяные знаки в свои ответы (например, модели с открытыми весами вроде DeepSeek-v4). Это поможет сделать итоговый текст более читаемым (если его качество снизилось в результате двойного перевода) и удалить оставшиеся следы вотермаркинга, если они каким-то образом сохранились
Чтобы проверить эту идею я разработал простое приложение, которое автоматизирует этот процесс. В нём можно выбрать, какие именно шаги использовать, и настроить каждый из них отдельно (например, выбрать конкретный переводчик или модель LLM для перефразирования).
Оно создано на основе Streamlit и LangChain, GUI выглядит вот так:
Просто задаешь нужные настройки, вставляешь текст в поле и нажимаешь кнопочку "Process". Дальше она все сделает сама. Дополнительно напишет, какие символы были удалены из текста, а также покажет промежуточные результаты перевода.
Результаты
На HuggingFace есть несколько моделей, в которые встроен механизм SynthId, например gemma-2b-it. Также оттуда можно достать детектор вотермарок. Я проверил работу приложения для разных вариантов перевода (с английского на немецкий, китайский или русский), в качестве модели для перефразирования использовал DeepSeek-V4-Flash. Результаты представлены ниже.
Как видно из таблички, вотермаркнутый текст детектится на 100%, простой перевод с английского на родственный ему немецкий и обратно не меняет почти ничего, а вот в случае перехода с немецкого на китайский или русский, ситуация улучшается. После дополнительного переписывания нейронки следы вотермарки исчезают почти всегда. Да в принципе можно обойтись совсем без перевода и просто попросить нейронку переписать текст, и это также уничтожит вотермарку.
Выводы
Чтобы победить дракона нейрослоп, нужно самому стать нейрослопом. Или писать все руками. Или просто не париться по поводу вотермарок.
P.S.: В комментариях справедливо отмечают, что по сути ничего не поменялось: AI-слоп на входе, AI-слоп на выходе. На самом деле, кое-что изменилось: я свел более трудную задачу избавления от вотермарок (которая решается жестким редактированием), к более легкой задаче приведения текста в человекоподобный вид (которая решается точечными правками).
Проект с результатами есть на гитхабе, лежит по этой ссылке. Сами результаты можно найти в ноутбуке в папке watermark_detector.