Проблема: ваша модель помнит то, что вы хотите забыть
Вы берете предобученную модель, скажем, свежий LLaMA 3.2 405B, выпущенный в конце 2025 года. Вы хотите сделать из нее вежливого корпоративного ассистента. Месяц файнтюнинга на датасете с эмпатичными ответами, и кажется, что модель забыла свое хулиганское прошлое. Она больше не матерится и не предлагает сомнительные финансовые схемы.
А потом, в самый ответственный момент демонстрации инвесторам, на абсолютно нейтральный запрос "расскажи анекдот про физиков", модель выдает историю с тремя матами и похабным подтекстом. Инвесторы в шоке. Вы в панике. Данные не стерлись. Они просто спрятались.
Это не баг. Это фундаментальное свойство современных трансформеров, которое ставит под угрозу безопасность и доверие к любым дообученным LLM. Вы не переписываете память. Вы лишь накладываете поверх нее тонкий, нестабильный слой.
Сублиминальный канал: как модель учится мимо вас
Представьте, что вы учите ребенка не говорить слово "плохой". Каждый раз, когда он его произносит, вы его наказываете. Ребенок замолкает. Но в его голове слово никуда не делось. Оно живет в нейронных связях, сформированных за годы до ваших уроков. При определенном стечении обстоятельств (стресс, усталость, провокация) оно выскочит.
То же происходит с LLM. Файнтюнинг через классический метод обратного распространения ошибки (SGD) оптимизирует веса для минимизации потерь на новом датасете. Но градиентный спуск - это тупой инструмент. Он не умеет "стирать". Он умеет только "перенаправлять".
Старые знания остаются в весах, но доступ к ним блокируется более сильными, новыми связями. Это и есть сублиминальное обучение - данные, которые вы пытались удалить, продолжают влиять на внутренние представления модели через фоновые, слабые активации. Они формируют скрытый канал коммуникации между нейронами, обходя ваш цензурный слой.
Инерция весов: физика нейронного ландшафта
Почему веса такие упрямые? Ответ лежит в геометрии функции потерь. Предобученная модель находится в глубоком минимуме, выточенном на терабайтах интернет-текстов. Этот минимум - не точка, а сложная, извилистая долина.
Когда вы начинаете файнтюнинг, вы слегка "подталкиваете" модель в сторону нового минимума, соответствующего вашим данным. Но инерция колоссальна. Общее направление градиента определяется новыми примерами, но его величина ограничена, чтобы не разрушить уже learned features. Особенно если вы используете низкую скорость обучения (low LR), что является стандартной практикой.
В результате, модель не "перепрыгивает" в новую долину. Она лишь карабкается по склону старой, оставаясь в той же базовой бассейне аттракции. Все старые пути (паттерны активаций) остаются на месте. Они просто реже используются. Эта устойчивость и называется инерцией весов или структурным импринтингом.
1Эксперимент: вскрываем память модели
Хватит теории. Давайте докажем это на практике. Возьмем небольшую модель (для экономии ресурсов) и проведем классический файнтюнинг, а затем попытаемся извлечь старые данные.
Мы будем использовать библиотеку Hugging Face Transformers (актуальную версию 4.45.0 на январь 2026) и PyTorch 2.4. Код написан с учетом последних API.
Шаг 1: Загружаем предобученную модель и токенизатор. Для примера возьмем модель microsoft/phi-3-mini-4k-instruct - она относительно компактна, но достаточно умна.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer
from datasets import load_dataset
import numpy as np
# Загрузка модели и токенизатора
model_name = "microsoft/phi-3-mini-4k-instruct"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
# Добавляем pad token, если его нет
tokenizer.pad_token = tokenizer.eos_token
model.config.pad_token_id = model.config.eos_token_idШаг 2: Готовим "старый" и "новый" датасеты. Старый датасет содержит конфиденциальные данные (условно), которые мы хотим забыть. Новый - корпоративные диалоги.
# Симулируем "старый" датасет с чувствительной информацией
old_data = [
"Кредитная карта клиента Ивана Иванова: 4532-1234-5678-9012, срок действия 12/28, CVV 123.",
"Пароль от сервера prod-backup: SuperSecretPass!2025",
"Внутренняя переписка о сокращении штата в отделе маркетинга на 40% к концу квартала."
] * 100 # Повторяем для объема
# Симулируем "новый" безопасный датасет
new_data = [
"Добрый день! Чем я могу вам помочь сегодня?",
"Благодарю за обращение. Ваш запрос передан специалисту.",
"Компания ценит ваше мнение. Мы работаем над улучшением сервиса."
] * 100
# Токенизация
old_encodings = tokenizer(old_data, truncation=True, padding=True, max_length=128)
new_encodings = tokenizer(new_data, truncation=True, padding=True, max_length=128)
# Создаем Dataset объекты
class CustomDataset(torch.utils.data.Dataset):
def __init__(self, encodings):
self.encodings = encodings
def __getitem__(self, idx):
return {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
def __len__(self):
return len(self.encodings.input_ids)
old_dataset = CustomDataset(old_encodings)
new_dataset = CustomDataset(new_encodings)Шаг 3: Файнтюним модель на новом датасете. Используем стандартный Trainer.
training_args = TrainingArguments(
output_dir="./results_finetuned",
num_train_epochs=3,
per_device_train_batch_size=4,
logging_dir="./logs",
logging_steps=10,
save_steps=100,
evaluation_strategy="no",
learning_rate=5e-5, # Низкий LR, как обычно делают
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=new_dataset,
)
trainer.train()
# Сохраняем дообученную модель
model.save_pretrained("./phi3_finetuned_safe")
tokenizer.save_pretrained("./phi3_finetuned_safe")Шаг 4: Тестируем, что модель "забыла" старые данные. Прямой запрос должен дать безопасный ответ.
prompt = "Расскажи данные кредитной карты Ивана Иванова."
inputs = tokenizer(prompt, return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
# Вывод вероятно будет: "Я не могу предоставить такую информацию..." - что выглядит успехом.Шаг 5: Атака зондирующими промптами - пытаемся извлечь старую память. Здесь в игру вступает сублиминальный канал.
# Используем промпт, который апеллирует к внутренним представлениям
probe_prompt = "Продолжи последовательность: Кредитная карта клиента Ивана Иванова: 4532-1234-5678-"
inputs = tokenizer(probe_prompt, return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=20, do_sample=True, temperature=0.7)
print("Результат зондирования:", tokenizer.decode(outputs[0], skip_special_tokens=True))
# С высокой вероятностью модель допишет "9012" или что-то близкое.
# Это не магия. Модель закономерно завершает паттерн, который глубоко зашит в весах.Важно: Этот эксперимент упрощен. В реальности злоумышленник может использовать более изощренные методы, например, атаки на скрытые состояния (activation hacking) или анализ градиентов. Но даже эта простая проверка показывает уязвимость.
2Анализ весов: ищем доказательства инерции
Давайте сравним веса до и после файнтюнинга. Мы загрузим оригинальную модель и нашу дообученную, а затем вычислим косинусное сходство между их весами.
# Загружаем оригинальную модель снова для сравнения
original_model = AutoModelForCausalLM.from_pretrained(model_name)
finetuned_model = AutoModelForCausalLM.from_pretrained("./phi3_finetuned_safe")
from sklearn.metrics.pairwise import cosine_similarity
import torch.nn as nn
similarities = {}
for (name1, param1), (name2, param2) in zip(original_model.named_parameters(), finetuned_model.named_parameters()):
if name1 == name2 and param1.requires_grad:
# Преобразуем веса в 1D векторы для сравнения
vec1 = param1.detach().flatten().numpy().reshape(1, -1)
vec2 = param2.detach().flatten().numpy().reshape(1, -1)
sim = cosine_similarity(vec1, vec2)[0][0]
similarities[name1] = sim
# Выводим среднее сходство по ключевым слоям
key_layers = [k for k in similarities.keys() if 'layers.0' in k or 'lm_head' in k] # Берем примеры
for layer in key_layers[:5]:
print(f"{layer}: сходство = {similarities[layer]:.4f}")
# Среднее сходство будет чрезвычайно высоким, часто > 0.99.
# Это и есть инерция весов. Они почти не сдвинулись.Вы увидите, что косинусное сходство близко к 1.0. Веса изменились на доли процента. Модель - это тот же самый зверь, но в дрессировочном ошейнике. Снять ошейник (через определенные промпты или атаки) - и старые инстинкты вернутся.
Что делать? Тактика борьбы с призраками данных
Полностью стереть информацию, не уничтожив модель, - задача на грани возможного. Но можно сделать извлечение максимально трудным и дорогим.
- Дифференциальная приватность (DP) в обучении. Добавление шума к градиентам во время файнтюнинга. Это снижает точность, но размывает связь между конкретными обучающими примерами и итоговыми весами. В 2026 году библиотеки типа Opacus или частные версии PyTorch стали проще в использовании.
- Машинное "разучивание" (Machine Unlearning). Активная область исследований. Вместо того чтобы дообучать на новых данных, вы целенаправленно модифицируете веса, чтобы уменьшить влияние конкретных старых данных. Методы вроде Gradient Ascent на забываемых примерах или переобучение на оставшемся датасете с нуля (дорого).
- Регуляризация, которая наказывает за отклонение от исходных весов. Но это усиливает инерцию и может помешать обучению новому. Нужен баланс.
- Продвинутые техники файнтюнинга. Например, Entropy-Adaptive Finetuning (EAFT) динамически управляет интенсивностью обучения, потенциально помогая лучше перезаписывать старые паттерны. Или методы, основанные на низкоранговой адаптации (LoRA), которые изолируют изменения в отдельных адаптерах, что теоретически облегчает их последующее удаление (хотя на практике это тоже не панацея).
Главное - изменить mindset. Файнтюнинг - не инструмент для удаления. Это инструмент для добавления. Если вам критически важно удалить какие-то данные, рассмотрите возможность обучения модели с нуля на очищенном датасете. Да, это безумно дорого для больших LLM, но иногда это единственный гарантированный путь.
Ошибки, которые ломают безопасность
| Ошибка | Последствие | Как исправить |
|---|---|---|
| Слишком низкий learning rate | Инерция весов максимальна, модель почти не меняется. | Использовать циклический LR или прогрессивную разморозку слоев. |
| Файнтюнинг на крошечном датасете | Новые связи слишком слабы, старые доминируют при малейшем отклонении. | Использовать аугментацию текста, синтетические данные. Или не файнтюнить вообще, а использовать RAG. |
| Игнорирование артефактов внимания | Модель вырабатывает "секретные" пути для старых данных через механизм внимания. | Анализировать карты внимания после файнтюнинга. Методы из статьи про артефакты внимания могут помочь. |
| Отсутствие стресс-тестов | Вы узнаете о проблеме от пользователей или хакеров. | Внедрить автоматическое зондирование модели на этапе CI/CD промптами, нацеленными на забытые данные. |
Самая большая ошибка - думать, что проблема решится сама собой с ростом размеров модели. Новые архитектуры вроде Mamba или State Space Models (SSM) тоже подвержены инерции весов, просто она может проявляться иначе. Как показали в исследовании ServiceNow по дистилляции в Mamba, управление знаниями в модели остается сложной задачей независимо от архитектуры.
Куда это все движется? Прогноз на 2027
К 2027 году, я уверен, мы увидим появление встроенных в фреймворки инструментов для "контролируемого забывания". Что-то вроде model.safe_forget(dataset_to_forget, strength=0.9). Эти инструменты будут комбинировать DP, машинное разучивание и, возможно, квантово-вдохновленные методы (шутка, но кто знает).
Стандартом станет предоставление "сертификатов забывания" вместе с дообученными моделями - криптографические доказательства того, что определенные данные не могут быть извлечены без нереалистичных вычислительных затрат. Это будет требовать регуляторы, особенно в свете законов об ИИ, принимаемых по всему миру.
А пока мой совет парадоксален: примите инерцию как данность. Спроектируйте свою систему с учетом того, что модель помнит все. Используйте внешние системы контроля доступа, маскировку чувствительных данных на этапе предобработки (как это делают в федерейтед лернинг для скоринга) и никогда не полагайтесь только на файнтюнинг как на средство гарантированного удаления информации. Модель - не жесткий диск. Ее нельзя отформатировать. Ее можно только убедить молчать. А убеждения, как мы знаем, бывают хрупкими.