380 секунд. Таким был наш p99 latency на запрос к модели, когда мы впервые попытались скормить ей 120 тысяч токенов сырого текста на инференсе. Скармливать многомегабайтные портянки в контекстное окно под девизом «нейросеть сама разберётся» — самая разрушительная и ленивая практика текущего ML-рынка. Длинный контекст в проде: как обрабатывать тысячи страниц без взрыва памяти и latency — это не абстрактный вопрос выбора фреймворка. Это вопрос физического выживания вашей unit-экономики. Мы усвоили этот урок, когда буквально за несколько дней сожгли бюджет на GPU, пытаясь обслужить запросы реальных пользователей.
Задача выглядела классической. Клиенту требовался анализ массивных юридических досье — корпоративные контракты, приложения, многолетняя переписка. Тысячи страниц на один кейс. Пользователи хотели загружать весь архив целиком и задавать вопросы уровня «кто нарушил обязательства в третьем квартале?». Мы поддались хайпу вокруг моделей с окном в 200 тысяч токенов. Демки выглядели безупречно. Модель бодро вытаскивала факты, красиво оформляла ответы. Мы упаковали это в контейнеры и выкатили в продакшен. И тут нас накрыло.
Как только в систему зашли первые полсотни одновременных пользователей, кластер из A100 на 80GB просто лег. Математику квадратичной сложности self-attention невозможно обмануть красивыми пресс-релизами. Время и память для вычисления матрицы внимания растут как O(N^2) от длины последовательности. 100 тысяч токенов — это десятки миллиардов операций только для механизма внимания на одном слое сети. Метрика TTFT (Time To First Token) улетела в космос. Память фрагментировалась. OOM-killer (Out of Memory) стал самой частой записью в логах. При батчинге запросов с такой длиной контекста размер батча стремится к единице — вы физически не можете параллельно обрабатывать нескольких пользователей на одной карте. Экономика инференса рассыпалась в пыль.
Начались экстренные попытки спасти ситуацию. Первая мысль — вернуть классический RAG с жестким чанкингом. Рынок сейчас любит кидаться из крайности в крайность: то «RAG мертв, да здравствует бесконечный контекст», то наоборот. Наш подход в Morana Labs: это ложная дихотомия. RAG — это дешевая оперативная навигация, а длинный контекст — дорогая оперативная память для сложного синтеза. Когда вы пытаетесь найти конкретный пункт договора, RAG справляется за миллисекунды. Но когда вам нужно проанализировать противоречия между финансовым отчетом на странице 10 и показаниями на странице 500, тупой векторный поиск по кускам текста вытащит вам семантически близкий мусор, потеряв нить повествования.
Мы остановили сервера и начали переписывать пайплайн. Наивная подача всего текста отпала навсегда. Нам требовалось передавать модели знания из тысяч страниц, сохраняя связность, но не взрывая VRAM. Первым рубежом стало кэширование.
Если база знаний или документ статичны, заставлять модель пересчитывать ключи и значения (KV-cache) для одних и тех же 100 тысяч токенов при каждом новом вопросе пользователя — преступление против железа. Мы внедрили агрессивный Prompt Caching. Вычисление контекста гигантского документа происходит ровно один раз. Состояние внимания сохраняется в VRAM или сбрасывается на быстрые NVMe-накопители. Когда пользователь задает следующий вопрос по этому же досье, запрос летит сквозь сеть за миллисекунды, потому что тяжелая часть уже вычислена. Но это тянет за собой сложнейшую логику вытеснения кэша (eviction policies), потому что KV-cache для 70-миллиардной модели на 100k токенов весит гигабайты на одну сессию.
С динамическими документами кэш не спасает. Любое изменение в начале текста инвалидирует весь последующий расчет. Здесь мы перешли на архитектуру иерархического саммари. Вместо того чтобы скармливать сырой текст, пайплайн предварительно сжимает его на нескольких уровнях абстракции. Документ бьется на логические блоки (не по тупому лимиту в 512 токенов, а по границам параграфов и глав). Мелкие быстрые модели делают саммари каждого блока. Затем сводят эти саммари в более крупные узлы. Финальной тяжелой модели подается древовидная структура: верхнеуровневый контекст всего архива плюс подробные ветки только для тех разделов, которые релевантны текущему запросу. Мы искусственно создаем плотность информации, выжимая из нее воду до того, как она попадет в LLM.
Мы тестировали и альтернативы — модели с линейной сложностью внимания (Mamba, архитектуры на основе пространства состояний). Они действительно обещают масштабирование O(N). Память на них не взрывается, и на синтетических тестах они выглядят как спасение. На практике, при глубоком анализе запутанной юридической логики их способность к удержанию неочевидных связей проседает. Они отлично подходят для потокового парсинга логов, но для сложного reasoning'а трансформер все еще держит удар. Его просто нужно заковывать в жесткие рамки оптимизаторов типа FlashAttention-3 и PagedAttention.
Отдельный ад — оценка качества на таких объемах. Классический тест «иголка в стоге сена» (Needle in a Haystack) абсолютно бесполезен для реального бизнеса. Найти случайно вставленный факт на 80-й странице документа может почти любая современная модель. Но реальные пользователи не ищут случайные факты. Они требуют многошагового вывода (multi-hop reasoning). Нам пришлось создавать собственные стенды для оценки, где LLM-судья проверяла, смогла ли система увязать причину из первого тома с последствием из пятого. Выяснилось, что при превышении порога в 60 тысяч токенов даже топовые веса начинают «забывать» критические детали в середине контекста (эффект lost in the middle), скатываясь в галлюцинации.
После всех падений, сгоревших бюджетов и переписанного кода мы вывели строгий инженерный стандарт. Работа с гигантскими текстами в проде не терпит романтики. Сегодня наш пайплайн обработки выглядит так:
- Агрессивная очистка и разметка. Никаких слепых выгрузок PDF. Парсеры извлекают структуру, метаданные и иерархию документа, формируя семантический скелет еще до нейросетей.
- Двухконтурный Retrieval. Смесь векторного поиска для точечных фактов и поиска по графу иерархических саммари для понимания глобального контекста.
- Маршрутизация нагрузки. Простые агрегации уходят на быстрые квантованные 8B модели с длинным окном. Глубокая аналитика отправляется на тяжелые ноды, но только после того, как контекст сжат до 10-15 тысяч токенов высокой плотности.
- Переиспользование KV-кэша. Жесткий контроль за тем, какие префиксы пересчитываются, а какие живут в памяти кластера, распределяясь между нодами через кастомные аллокаторы.
Индустриальный ИИ не строится на красивых цифрах из бенчмарков. Заявленный миллион токенов контекста в документации модели не означает, что вы можете вывалить в нее базу знаний компании и пойти пить кофе. Длинный контекст — это не бездонная мусорная корзина. Это узкое, дорогое и хрупкое горлышко бутылки, в которое данные должны подаваться скальпелем, а не экскаватором. Чудес не бывает, есть только расчет стоимости железа и архитектура, которая способна этот расчет выдержать.