Внимание разбегается по углам: как трансформеры теряют информацию
Откройте визуализацию внимания в любом современном ViT (Vision Transformer) - например, в DINOv2. Смотрите на эти красивые карты, где модель якобы "фокусируется" на объектах? Забудьте. Половина этого внимания - артефакт архитектуры, а не реальное понимание.
Когда вы видите, что LLM генерирует наукообразный бред или ViT странно сегментирует изображение - это может быть не недостаток данных, а фундаментальный изъян в механизме внимания. Вайб-физика иногда рождается именно здесь.
Что такое attention sinks на самом деле?
Представьте трансформерный слой. У вас есть запросы (Q), ключи (K) и значения (V). Softmax распределяет внимание. В теории - всё идеально. На практике - появляются "регистры-губки", которые поглощают внимание просто потому, что имеют аномально высокую норму.
Эти регистры становятся attention sinks - точками, куда стекается внимание независимо от семантической релевантности. Они работают как гравитационные колодцы в пространстве внимания: всё падает туда, даже если должно лететь мимо.
| Тип артефакта | Где встречается | Симптомы |
|---|---|---|
| High-norm spikes | DINOv2, ViT-Large | Внимание к пустым патчам |
| Позиционные sinks | Qwen3-Next, Llama 3 | Предпочтение первых/последних токенов |
| Семантические аттракторы | Все LLM с длинным контекстом | Interpretation drift и нестабильность |
Почему это происходит? Механика катастрофы
Всё начинается с инициализации. Некоторые регистры получают случайно высокие нормы. Softmax их замечает - ведь он экспоненциально усиливает различия. Дальше - петля положительной обратной связи:
- Регистр с высокой нормой притягивает больше внимания
- Градиенты обновляют его, делая норму ещё выше
- На следующей эпохе он доминирует ещё сильнее
- Остальные регистры фактически отключаются
Это похоже на проблему, описанную в эффекте Манделы в ИИ, но на уровне архитектуры. Модель не "галлюцинирует" - она просто следует математическому императиву, заложенному в softmax.
Как обнаружить sinks в своей модели?
Для ViT (DINOv2 и подобные):
- Визуализируйте нормы регистров по слоям - ищите выбросы
- Проверьте attention maps для пустых патчей (например, чёрный квадрат)
- Если внимание распределено не по объектам, а по каким-то фиксированным позициям - это sinks
Для LLM (Qwen3-Next и другие):
- Анализируйте attention weights для разных позиций в контексте
- Первые 10 токенов получают непропорционально много внимания? Это sink
- Сравните качество генерации при разной длине контекста - если падает, виноваты sinks
Исправляем без переобучения: 3 практических метода
Исследование на NeurIPS 2025 показало - можно исправить sinks без дополнительного обучения. Zero overhead. Вот как.
1 Нормализация регистров онлайн
Вместо того чтобы бороться с последствиями, атакуйте причину - высокие нормы. Добавьте слой нормализации прямо перед softmax:
# Вместо стандартного внимания:
# attention = softmax(Q @ K.T / sqrt(d_k))
# Делаем так:
def safe_attention(Q, K, V):
# Нормализуем ключи по последнему измерению
K_norm = K / (torch.norm(K, dim=-1, keepdim=True) + 1e-8)
# Масштабируем запросы, но сохраняем их оригинальные нормы
scale = torch.norm(Q, dim=-1, keepdim=True)
Q_scaled = Q / (scale + 1e-8)
# Внимание с нормализованными ключами
scores = Q_scaled @ K_norm.T / math.sqrt(Q.size(-1))
attention = F.softmax(scores, dim=-1)
# Восстанавливаем масштаб для output
return attention @ V * scale
Этот трюк ломает петлю положительной обратной связи. Высокие нормы ключей больше не дают им преимущества. Внимание распределяется по семантике, а не по математическому артефакту.
2 Temperature annealing для softmax
Проблема в экспоненте softmax. Он превращает небольшие различия в огромные. Решение - динамическая температура:
def adaptive_softmax(scores, current_layer, total_layers):
"""
Температура зависит от глубины слоя.
В ранних слоях - более высокая температура (менее "пиковое" распределение)
В поздних слоях - более низкая (более уверенные предсказания)
"""
# Базовый коэффициент
base_temp = 1.0
# Ранние слои получают bonus к температуре
if current_layer < total_layers // 3:
temperature = base_temp * 2.0 # Более равномерное внимание
elif current_layer < 2 * total_layers // 3:
temperature = base_temp * 1.5
else:
temperature = base_temp # Оригинальная температура
return F.softmax(scores / temperature, dim=-1)
Почему это работает? Ранние слои формируют представления. Если там появится sink - он испортит всё дальнейшее обучение. Высокая температура в начале предотвращает это.
Этот подход особенно эффективен для моделей с tuneable attention, где механизм внимания уже подвергается модификациям. Можно комбинировать методы для синергетического эффекта.
3 Патч для существующих моделей (DINOv2, Qwen3-Next)
Если у вас уже есть предобученная модель с sinks, не нужно её переучивать. Добавьте post-processing слой:
class SinkCorrector(nn.Module):
def __init__(self, hidden_dim, num_heads):
super().__init__()
self.hidden_dim = hidden_dim
self.num_heads = num_heads
# Детектор sinks - учится находить аномальные паттерны
self.sink_detector = nn.Sequential(
nn.Linear(hidden_dim, hidden_dim // 4),
nn.ReLU(),
nn.Linear(hidden_dim // 4, num_heads)
)
def forward(self, attention_weights, layer_output):
"""
attention_weights: [batch, heads, seq_len, seq_len]
layer_output: [batch, seq_len, hidden_dim]
"""
batch_size, seq_len, _ = layer_output.shape
# Детектируем sinks по статистике внимания
attention_entropy = -torch.sum(
attention_weights * torch.log(attention_weights + 1e-8),
dim=-1
) # [batch, heads, seq_len]
# Низкая энтропия = пиковое распределение = возможный sink
sink_mask = (attention_entropy < 0.5).float()
# Пересчитываем attention без sinks
corrected_attention = attention_weights * (1 - sink_mask.unsqueeze(-1))
# Перенормируем
corrected_attention = corrected_attention / (
corrected_attention.sum(dim=-1, keepdim=True) + 1e-8
)
return corrected_attention
Этот корректор можно вставить после каждого трансформерного слоя. Он работает онлайн, почти не добавляя вычислительной сложности.
Что будет, если проигнорировать проблему?
Краткий список катастроф, которые уже происходят в продакшене:
- DINOv2 для сегментации: Модель "видит" границы там, где их нет. Потому что attention застрял в каком-то sink-регистре, который активируется на текстурах, похожих на границы.
- Qwen3-Next для длинных документов: Качество анализа падает после 4К токенов. Не из-за ограничений контекста, а из-за того, что sinks поглощают внимание, нужное для середины документа.
- Нестабильность fine-tuning: Вы делаете LoRA-адаптацию, а модель начинает вести себя непредсказуемо. Потому что sinks взаимодействуют с новыми весами непредвиденным образом. Датасет для LoRA может быть идеальным, но sinks всё испортят.
Самое опасное - sinks создают иллюзию работы. Модель проходит метрики на стандартных датасетах, но в реальных задачах даёт сбой. Это тот случай, когда нейросети понимают вашу боль, но всё равно дают опасный совет - потому что механизм принятия решений сломан на фундаментальном уровне.
FAQ: Ответы на неочевидные вопросы
Вопрос: Attention sinks - это баг или фича?
И то, и другое. В некоторых задачах sinks могут работать как "память" или "буфер". Но в 95% случаев это баг, который нужно фиксить. Разработчики часто не знают о их существовании, поэтому не документируют.
Вопрос: Почему sinks не обнаруживают при тестировании?
Потому что стандартные бенчмарки используют короткие последовательности. Sinks проявляются на длинных контекстах или специфических паттернах. Нужно специальное тестирование - например, тест (c/t)^n для семантического заземления.
Вопрос: Можно ли использовать sinks для ускорения?
Теоретически - да. Если знать, какие регистры становятся sinks, можно предвычислять их вклад. Но на практике это слишком нестабильно. Лучше исправить sinks, а для ускорения использовать другие методы.
Вопрос: Как sinks связаны с эпистемической асимметрией?
Прямо. Sinks создают "предвзятость внимания" - модель обращает внимание не на то, что важно, а на то, что математически удобно. Это форма внутренней асимметрии: у модели есть доступ ко всей информации, но механизм выбора сломан.
Что делать прямо сейчас?
- Проверьте свои ViT/LLM модели на наличие sinks (код выше)
- Если используете DINOv2 или Qwen3-Next - обязательно добавьте нормализацию регистров
- Для новых проектов закладывайте защиту от sinks в архитектуру с самого начала
- Делитесь находками с комьюнити - это системная проблема, а не особенность конкретной модели
И последнее: не верьте красивым визуализациям внимания. Они часто показывают артефакты, а не понимание. Настоящее внимание скрыто в динамике градиентов, в нормах регистров, в статистике, которую обычно не показывают в статьях.
Проверьте свою модель сегодня. Скорее всего, вы найдёте sinks. И когда исправите их - качество вырастет на те самые проценты, которых вам не хватало для production.