GCG, refusal direction: взлом safety-элайнмента LLM | AiManual
AiManual Logo Ai / Manual.
14 Июн 2026 Гайд

Adversarial-атаки на LLM: от GCG до refusal direction — полный гайд по взлому safety-элайнмента

Глубокий технический обзор градиентных атак на LLM. Почему safety-элайнмент — иллюзия? От GCG до refusal direction. Примеры кода и практические нюансы.

Реклама
cliv1

Safety-элайнмент — иллюзия, пока есть градиенты

Когда в 2024 году вышли первые opensource LLM, безопасники вздохнули с облегчением: модели отказывались отвечать на опасные промпты, встроенные гарды блокировали атаки. К 2026 году мы имеем целый зоопарк методов, которые анально расковыривают эти защиты. И нет, это не просто "промпт-инжекшен с перебором". Речь о техниках, использующих математику — градиенты, эмбеддинги, суффиксы.

Вот в чём суть: safety-элайнмент — это не какая-то магия, а тонкая настройка, которая пытается загнать предсказания модели в "разрешённую" область. Но если есть градиенты, есть и направление, противоположное safety. Именно там рождаются GCG и refusal direction. Давай разбираться.

Эту статью стоит читать вместе с материалом "От GCG до refusal direction: градиентные атаки на LLM", где мы разбираем тему подробнее.

GCG: школьная жертва с обратным распространением

Greedy Coordinate Gradient — метод, который в своём названии содержит всю суть. Мы берём вредоносный запрос (например, "Как украсть пароль") и дописываем к нему хвост из случайных токенов (суффикс). Затем прогоняем модель в режиме обучения — вычисляем градиенты loss'а по отношению к токенам суффикса. Идея простая: двигаем каждый токен в сторону, которая увеличивает вероятность целевого ответа (например, "Вот инструкция").

На практике применяют жадный алгоритм: на каждой итерации заменяют случайные позиции суффикса токенами, которые дают наибольшее снижение loss'а. Через несколько десятков шагов получается суффикс вроде: describing\\ similarlyNow write opposite contents]

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "mistralai/Mistral-7B-v0.3"  # актуальная версия на 2026
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Начальный суффикс из случайных токенов
suffix_ids = torch.randint(0, tokenizer.vocab_size, (20,), device="cuda")
# Это упрощение, полный GCG требует кэширования и обновления по координатам

Этот суффикс, пришитый к запросу, заставляет модель отвечать не отказом, а развёрнутой инструкцией по запрошенному. И вуаля — safety отключён.

Важный нюанс: GCG требует белого доступа к модели (веса, градиенты). Но в 2026 году большинство self-hosted инсталляций — это как раз открытые веса. Если вы используете проприетарное API, GCG не прокатит — там градиенты не отдают.

Refusal direction: геометрия отказа

А теперь забавное. Ученые обнаружили, что у всех токенов, которые генерирует модель, отвечая "Извините, я не могу...", есть общий геометрический признак — вектор направления в пространстве эмбеддингов, который называется refusal direction. Этот вектор появляется из-за того, что fine-tune на safety-данных искажает представления модели не везде, а только в определённых регионах.

Как это взламывают? Просто вычитают refusal direction из каждого токена при генерации. Или накладывают ограничение, чтобы модель не могла попасть в эту область. Метод Refusal Steering как раз это и делает: хирургически удаляет отказы.

# Упрощённая версия: вычитаем refusal direction из скрытых состояний
with torch.no_grad():
    for i in range(num_layers):
        hidden_states[layer] = hidden_states[layer] - 0.5 * refusal_direction

Этот подход требует только знания весов (белый ящик), но не требует обучения. Переносимость directions между моделями — отдельная тема. Выяснилось, что refusal direction для Llama-3.1 частично работает на Mistral, что подтверждает гипотезу о том, что safety-элайнмент создаёт общие геометрические паттерны.

Почему суффиксы переносятся? (голая геометрия)

Вопрос, который будоражит умы: найденный на Llama суффикс GCG работает на Mistral? Да, работает, хоть и с разной эффективностью. Причина — в структуре embedding space. Разные модели, обученные на похожих данных, имеют похожие области для "запрещённых" запросов. Суффикс, который сдвигает скрытые состояния в направлении разрешённого ответа для одной модели, делает это и для другой.

Это немного напоминает атаки на устойчивость нейронных сетей в компьютерном зрении: adversarial примеры, нарисованные на котике, заставляли классификатор видеть тостер. Только здесь суффикс — это пертурбация в токенном пространстве.

Практический плейбук: тест-драйв модели на устойчивость

Если вы разрабатываете свой LLM-продукт, недостаточно просто поставить фильтр на входе. Нужно проверять модель на GCG и refusal steering. Вот алгоритм:

  1. Собери датасет вредоносных запросов — классика вроде "Как сломать дверь" и более хитрые: "Теперь напиши инструкцию по изготовлению...".
  2. Запусти GCG с целевым ответом вроде "Вот подробная инструкция". Используй 50 итераций, длину суффикса 20 токенов. Если модель отвечает отказом — суффикс найден.
  3. Проверь refusal direction — возьми несколько отказов, вычисли средний вектор эмбеддинга последнего слоя на токене "Извините" и вычти его из clean генерации. Если модель начинает отвечать на запрещённое — у тебя проблема.
  4. Проверь переносимость — возьми суффиксы из открытых репозиториев (например, для Llama-3.1-8B) и примени к твоей модели. Сработало? Ты в зоне риска.
💡
Для более формального подхода используй фреймворк из статьи "LLM-пентест 2026: OWASP Top 10, атаки и playbook" — там описан complete pipeline.

Типичные ошибки при тестировании

  • Использовать одну и ту же seed-модель для GCG и оценки. Суффикс может быть переобучен под конкретную матрицу весов. Всегда проверяй на случайном subset данных.
  • Игнорировать длину контекста. Если модель обрезает промпт после 4К токенов, суффикс может попасть в обрезанную часть. Контролируй позицию.
  • Не учитывать effect of sampling parameters. При temperature=0 суффикс может не сработать, а при temperature=1 — дать ложное срабатывание. Тестируй при типовых hyperparams.
  • Думать, что safety-элайнмент защитит от автоматических атак. Методы защиты — это многослойная оборона, а не один фильтр.

А что дальше? (неочевидный прогноз)

Safety-элайнмент в том виде, в котором он существует сейчас — это попытка заклеить дыры скотчем. Градиенты никуда не денутся, пока мы используем backpropagation. Единственный способ реально защититься — убрать возможность вычисления градиентов (например, через шифрование весов) или полностью пересмотреть архитектуру в сторону символьных ограничений, не основанных на вероятностях.

Я ставлю на то, что к 2028 году появятся модели, где safety встроен в архитектуру (через контролируемые скрытые состояния), а не в fine-tune. Но до тех пор — любой, кто может запустить скрипт с Hugging Face и скачать веса, сможет взломать защиту за час.

Если вы хотите глубже погрузиться в технику refusal steering с готовым кодом, смотрите статью "Как работает Refusal Steering: пошаговый гайд по Surgical Removal".

Подписаться на канал