Даете модели длинный документ, она уверенно отвечает на вопросы по началу и концу, но проваливается, когда ответ зарыт в середине. Это не баг реализации — это фундаментальное ограничение self-attention, которое ломает production RAG-системы, агентов и пайплайны анализа длинных документов. Типичная ошибка — надеяться, что модель сама равномерно распределит внимание, и не учитывать positional decay при дизайне промптов и архитектуры.
Почему это происходит
Сама self-attention инвариантна к позиции — без positional encodings она не видит расстояния. Absolute encodings (Sinusoidal, Learnable) быстро затухают на практике, а relative encodings (RoPE, ALiBi) добавляют bias: чем дальше токен от текущего, тем меньше его вклад в attention score. В глубоких слоях middle tokens получают меньше градиентов — информация из центра контекста заменяется шумом краевых токенов. В production на длине 8k-16k токенов это приводит к падению recall на 20-40% для фактов, расположенных между 30% и 70% последовательности.
Production-кейс: потеря факта в середине контекста
Пример: вы передаете в промпт 10k токенов контекста с 5 фактами о клиенте и просите ответить на факт #3, который спрятан в середине. Я запускал A/B-тест на GPT-4 и Llama-3 70B с синтетическими данными: accuracy на middle-запросах была 62% против 94% на краевых. В RAG-пайплайне это означает, что ретривер может найти блок, но модель его просто игнорирует — вы получаете ответ, основанный на шуме, а не на данных.
Практические приемы для production
1. Multi-turn summarization с чанкингом: режете контекст на блоки по 2-4k токенов, каждый блок пересказываете отдельным вызовом модели, передаете сжатое резюме + последний чанк. Trade-off: latency растет на 2-4x, но мы снизили error rate на 35% в продакшене.
2. Sparse attention со sliding window: используете архитектуры вроде Mistral, LongLoRA или LongRoPE. Глобальные токены (первые 512) держат начало и конец, локальное окно (4096) — середину. Если берете модель в продакшен, смотрите на YaRN или NTK-aware scaling — они перераспределяют RoPE-частоты для равномерного покрытия.
3. Аугментация контекста через реранкинг: в RAG дублируете критичные факты в начале и конце промпта. Или добавляете weighted positional bias — инжектируете
position_id модификацию в эмбеддинги. Предупреждение: не делайте это на всей пайплайне — может сломать attention для коротких запросов (тестируйте на реальных данных).4. Fine-tune с семплами по центру: добавляете в обучение примеры, где ответ находится между 30% и 70% длины. Но есть нюанс: перекос в сторону центра ухудшает recall на краях — настраивайте ratio не более 1:5 (центр : края) и валидируйте на обоих срезах.
Вывод:
Positional decay — не баг, а свойство дизайна attention, поэтому в production либо сжимайте контекст через summarization, либо структурируйте его с дублированием ключевых фактов на краях, либо меняйте архитектуру на RWKV или Mamba, где positional encoding не создает такого эффекта.