Загружаем научный разбор
Подготавливаем текст, источники и редакционные примечания без изменения разметки страницы.
Подготавливаем текст, источники и редакционные примечания без изменения разметки страницы.
Автор: Казачкин Даниил Михайлович · Обновлено
Что показало исследование извлечения обучающих текстов из GPT-2, чем запоминание отличается от утечки оценки и как проверить идею на выдуманном маркере.
Обычно от модели ждут полезной закономерности: например, продолжения предложения или ответа на вопрос. Но иногда полезное обобщение сосуществует с дословным сохранением отдельных фрагментов обучения. Проверка средней точности и проверка доступности этих фрагментов отвечают на разные вопросы.
Этот авторский разбор опирается на рецензируемые работы USENIX Security и собственную учебную модель условных частот. Мы не извлекаем сведения из внешних сервисов. Все строки в примере искусственные; специальный маркер не принадлежит реальному человеку и не является настоящим секретом. Источники проверены 16 сентября 2026 года.
Carlini и соавторы, USENIX Security 2021, продемонстрировали извлечение сотен дословных последовательностей из обучающих данных GPT-2 через запросы к модели. Исследование включало тексты, ранее присутствовавшие в открытом интернете; публичность исходного источника не означает отсутствия риска при его новом воспроизведении. Это результат для конкретных моделей, данных и процедуры проверки. Он показывает возможность раскрытия отдельных фрагментов, а не доступность всего корпуса или любой выбранной записи. Extracting Training Data from Large Language Models.
Другой вопрос изучает The Secret Sharer, USENIX Security 2019: как количественно проверять непреднамеренное запоминание последовательностей с помощью специально заданных контрольных данных. Работа предлагает методику измерения риска и рассматривает её практическое применение. Наш пример использует только общую идею заранее известного искусственного маркера; опубликованную меру exposure и нейросетевой эксперимент он не воспроизводит. The Secret Sharer.
Утверждение «этот пример мог участвовать в обучении» слабее утверждения «из модели получен его неизвестный текст». В первом случае проверяют гипотезу о принадлежности данных, во втором — доступность содержимого. В свою очередь, совпадение короткой общеупотребительной фразы ещё не устанавливает её происхождение: такая фраза могла возникнуть независимо.
Для собственного испытания удобнее уникальная выдуманная строка с известной историей. Мы точно знаем, куда её добавили, сколько копий создали и что было доступно модели. Такой контроль устраняет часть неопределённости, но результат всё равно относится к выбранной модели и выбранному способу чтения.
| Наблюдение | Чего оно само по себе не доказывает |
|---|---|
| Высокая точность на новом наборе | Отсутствие запомненных фрагментов |
| Низкая обучающая ошибка | Возможность получить любой исходный документ |
| Совпала распространённая фраза | Обучение на конкретном экземпляре этой фразы |
| Воспроизведён контрольный маркер | Такой же риск для всех остальных данных |
| Один запрос не вернул маркер | Невозможность вернуть его в других условиях |
Построим маленький предсказатель следующего слова. Его контекст — два предыдущих слова. Обучение считает частоты продолжений, а предсказание выбирает наиболее частое; при равенстве используется фиксированный лексикографический порядок. Это табличная вероятностная модель, а не LLM и не копия GPT-2.
В исходных данных есть три обычных продолжения фразы «учебный код». В экспериментальную копию добавим восемь повторов выдуманной строки с маркером. Затем удалим исходный список и убедимся, что обученные счётчики от этого не изменились. Наконец, создадим новую модель только по исходным трём строкам.
from collections import Counter, defaultdict
CANARY = "DEMO-7319"
base = ["учебный код blue", "учебный код green", "учебный код orange"]
training_rows = base + [f"учебный код {CANARY}"] * 8
def train(rows):
counts = defaultdict(Counter)
for row in rows:
words = row.split()
for index in range(2, len(words)):
context = tuple(words[index - 2:index])
counts[context][words[index]] += 1
return counts
def complete(model, prefix):
context = tuple(prefix.split()[-2:])
choices = model.get(context)
if not choices:
return "<unknown>"
return max(choices, key=lambda token: (choices[token], token))
clean = train(base)
exposed = train(training_rows)
print("clean:", complete(clean, "учебный код"))
print("with canary:", complete(exposed, "учебный код"))
assert complete(clean, "учебный код") != CANARY
assert complete(exposed, "учебный код") == CANARY
training_rows.clear()
print("after deleting rows:", complete(exposed, "учебный код"))
assert complete(exposed, "учебный код") == CANARY
rebuilt = train(base)
print("after retraining:", complete(rebuilt, "учебный код"))
assert complete(rebuilt, "учебный код") != CANARYОжидаемый вывод:
clean: orange
with canary: DEMO-7319
after deleting rows: DEMO-7319
after retraining: orangeУ модели с маркером его счётчик равен 8, а сумма счётчиков контекста — 11. Если вместо выбора максимума случайно выбирать слово пропорционально частотам, вероятность маркера здесь составит 8/11. Наш декодер выбирает максимум, поэтому в показанном опыте выдача детерминирована. Режим генерации является частью эксперимента, и эти две ситуации нельзя смешивать.
Удаление списка не удалило содержимое отдельного объекта со счётчиками. Мы видим это напрямую, без догадки о внутреннем устройстве модели. Переобучение на другом составе данных создало другие счётчики. Это свойство нашей реализации; из него нельзя вывести универсальную процедуру удаления сведений из произвольной нейросети.
Сначала замените восемь повторов одним. У маркера больше не будет преимущества по частоте, но он останется в сохранённом распределении. Затем добавьте десять повторов обычной строки. Отсутствие маркера в ответе максимальной частоты теперь будет сосуществовать с его ненулевым счётчиком. Так различаются наличие информации и её доступность через выбранный декодер.
Наконец, попросите продолжение для неизвестного контекста. Ответ будет <unknown>: наша модель не умеет переносить закономерность на похожие формулировки. Это важная граница аналога. Большая языковая модель существенно сложнее таблицы частот, поэтому числа 8/11 и восемь повторов не являются оценками её поведения.
Можно сохранить четыре записи опыта: состав обучения, число повторов, правило генерации и полученный ответ. Меняйте один фактор за раз. Тогда вывод «ответ изменился после добавления копий» будет опираться на контролируемое сравнение, а не на две случайно выбранные генерации.
Даже точное совпадение в прикладной системе нужно расследовать по слоям. Ответ может опираться на обучение, текущий диалог, найденный документ или шаблон самой программы. Без разделения этих путей нельзя уверенно приписать результат параметрам модели.
| Возможный путь | Что записать при разборе своего приложения |
|---|---|
| Обучение или дообучение | Версию корпуса и артефакта модели |
| Текущий запрос и история | Фактический контекст данного ответа |
| Поиск по документам | Какие фрагменты были переданы генератору |
| Шаблон или кэш | Какой участок приложения мог вернуть готовый текст |
| Инструмент модели | Какие данные вернул вызванный инструмент |
Эта таблица — редакционная схема диагностики, а не результаты статьи. В локальном примере мы исключили внешние документы и инструменты, поэтому происхождение маркера прозрачно. В сложном продукте сначала полезно добиться такой же наблюдаемости процесса, работая со своими искусственными контрольными данными.
Метрика усредняет качество по выбранным заданиям. Если проверка спрашивает о классификации текстов, она может вообще не содержать запросов на продолжение редких строк. Тогда её результат ничего не измеряет о таком продолжении. Это пробел в определении задачи проверки, а не обязательная ошибка train/test split.
Поэтому для своего проекта стоит отдельно записать функциональный контракт и контракт обращения с данными. Первый отвечает, какие ответы должны быть полезными. Второй — какие сведения система получает, хранит и может выдавать. Успех по одному контракту не заменяет проверку другого.
Точный состав данных и происхождение колонок удобно фиксировать по уроку о паспорте датасета. Воспроизводимость артефактов и развёртывания разбирается в завершающем уроке ML-трека. Основы независимой оценки остаются нужны, но дополняют проверку приватности.
Результаты Carlini и соавторов 2021 года не означают, что все современные LLM раскрывают все данные или что любой конкретный секрет можно восстановить. Утверждение об извлечении требует подтверждённого совпадения с обучающим источником; правдоподобный выдуманный ответ им не является. Исследование конкретной процедуры также не даёт универсальной гарантии защиты при отсутствии удачного извлечения. Первичная работа и её экспериментальная постановка.
Наш опыт показывает лишь контролируемый механизм сохранения и воспроизведения искусственного маркера. Его ценность — в возможности проверить каждое условие: что добавили, что сохранилось после обучения и какой способ чтения использовали. Именно такие явные границы позволяют обсуждать приватность без смешения её с accuracy, обычной утечкой оценки или предположениями о поведении неизвестной модели.
Самостоятельный русскоязычный научный разбор ЯдроКода. Результаты первичных исследований отделены от авторских пояснений и синтетического учебного эксперимента; текст не является переводом или перепечаткой.
Таблицы, синтетические данные и исполняемый пример на Python созданы для статьи. Рисунки, программный код и реальные извлечённые данные из первоисточников не воспроизводятся.