В Claude Code есть кнопка /fast: тот же самый Клод начинает печатать в 2,5 раза быстрее — а стоит ровно в 2 раза дороже. Это не магия и не «модель поменьше». За 10 минут заглянем под капот датацентра: как модель выбирает слова, что она помнит — и почему «быстрый режим» вообще существует.
Когда Claude Code или Codex отвечает, текст рождается по маленьким кусочкам — токенам. Токен — это примерно половинка слова: привет. Модель выдаёт их строго по одному: выбрала кусочек → добавила к ответу → начала выбирать следующий.
Поэтому «скорость модели» меряют в токенах в секунду. Обычный Opus 4.8 в API выдаёт ≈59 токенов/с, fast mode — примерно 148. Но сперва главный вопрос: как модель вообще решает, какой кусочек поставить следующим?
Откуда модель знает, что после «Маша уронила стакан, и он…» идёт «разбился», а не «улетел»? Она оглядывается на все слова, что уже написаны, и решает, какие из них сейчас важнее. Это и называется вниманием.
Представь прожектор. Перед тем как выбрать следующее слово, модель светит им назад по всей фразе: на важные слова — ярко, на неважные — еле-еле. Из самых освещённых слов и рождается ответ. Нажми — увидишь, куда падает свет:
Нажми «Посветить», чтобы модель выбрала следующее слово.
Прожектор смотрит только назад, на уже написанное, — будущего модель не видит. И так перед каждым новым словом заново.
Сначала — вся модель одним взглядом, потом залезем внутрь прожектора и разберём, из чего складывается его свет.
Глянем на всю модель разом — по-простому.
Прожектор — лишь первая из двух работ на каждом этаже. Сейчас встанем на один этаж и разглядим под лупой, откуда берётся его яркость. ↓
Трансформер — нейросеть над последовательностью токенов. Каждый токен сперва переводится в вектор чисел — эмбеддинг (embedding). Дальше идёт стопка из N одинаковых по устройству слоёв (layers) — в больших моделях их десятки. Каждый слой делает две вещи: слой внимания (self-attention), где каждый токен смотрит на предыдущие токены (каузальная маска) и подмешивает их информацию, и полносвязный блок (feed-forward / MLP), где каждый токен обрабатывается отдельно. Вокруг обоих — остаточные связи (residual connections): результат прибавляется к входу, а не заменяет его. После всех слоёв числа последнего токена превращаются в логиты — по одному на каждый возможный следующий токен, — а softmax делает из них вероятности. Модель авторегрессивная: сгенерировала токен → дописала к входу → повторила.
В прошлом шаге прожектор просто «светил ярче на важное». Но откуда берётся яркость? Заглянем внутрь — окажется, что у каждого слова есть три кусочка.
Представь класс на перекличке. У каждого уже написанного слова на груди висит значок (key) — коротко, про что оно: у «стакан» — «хрупкий, стеклянный». А в кармане лежит записка (value) — что слово подкинет в ответ, если его осветят: у «стакан» — «легко бьётся».
Новое слово «он» — последнее, что мы написали, — ничего не носит. Оно светит лучом-вопросом: «к чему я отношусь и что с ним случилось?». Это запрос (query), и это ровно тот самый прожектор из прошлого шага — просто теперь видно, что это конкретный вопрос слова «он». Луч бежит назад по фразе и цепляется за значки: насколько вопрос совпал со значком — настолько ярко и горит слово.
⚠ На значке и в записке на самом деле не слова, а числовой отпечаток слова — буквами рисуем лишь для наглядности. И «совпал» значит по смыслу, а не по буквам: у «стакан» совпало сильнее всех — 10 из 10, у «уронила» — 6 из 10, у «Маша» — 1 из 10. Никакой высшей математики, просто «сколько из десяти».
Нажимай кнопки по порядку — слева направо.
А ответ — не одно самое яркое слово. Модель берёт по кусочку записки (value) у всех: у ярких кусок большой, у тусклых крошечный, но не ноль, и смешивает всё в одно новое слово. Больше всех подкинул «стакан», рядом «уронила» — вместе выходит «разбился».
В self-attention из вектора каждого токена тремя обучаемыми матрицами получают три вектора: запрос Q (query), ключ K (key) и значение V (value). Веса внимания токена i ко всем токенам j — это softmax (нормировка по всем j) от скалярных произведений Qi·Kj, делённых на корень из размерности ключа («scaled dot-product attention»). Выход для токена i — взвешенная сумма всех Vj с этими весами; веса неотрицательны и в сумме дают 1 — поэтому «яркости делят один прожектор». В декодере внимание каузальное: токен видит только позиции ≤ своей (маска). И всё это считают параллельно несколько «голов» (multi-head), каждая со своими Q/K/V; их выходы конкатенируют и линейно проецируют.
И вот главное — отсюда прямая дорога в следующий шаг. Значок и записка слова застывают навсегда по простой причине: слова смотрят только назад, а будущее не меняет прошлое. «Стакан» уже написан — что мы допишем после него, ему всё равно; значит, его значок и записка потом уже не поменяются. А раз прошлые слова не переписывают — их значки и записки одни и те же на каждом шаге. Поэтому их считают один раз и складывают в блокнот. Это и есть KV-кэш — он и назван по буквам K и V. Ровно эти сохранённые значки и записки — те «пометки», что в следующем шаге считают один раз (сейчас увидишь: без блокнота 15 пересчётов, а с ним всего 5 — в 15 ÷ 5 = три раза меньше).
А вопрос-луч (query) не хранят. Он принадлежит не старому слову, а тому, что светит прямо сейчас. Свой вопрос по разу светит каждое слово — когда оно самое новое: посветило назад, собрало ответ — и луч больше не нужен. На следующем шаге самым новым станет «разбился» и посветит уже своим, свежим вопросом. Значок и записку того же слова при этом кладут в блокнот, а вопрос выбрасывают: одноразовое хранить незачем.
Держи в голове разницу: одно дело — работа, которую делают именно на этом шаге (свежий вопрос-луч и только что посчитанные значок с запиской нового слова), другое — то, что уже лежит в блокноте с прошлых шагов. Значок и записку (key, value) сохраняют, а вопрос выбрасывают. В следующем шаге это видно прямо: новое слово считают заново, а прошлые берут из блокнота готовыми.
При авторегрессивной генерации на каждом новом токене нужно снова посчитать внимание ко всем прошлым. Но Kj и Vj прошлого токена зависят только от него и того, что стоит левее (каузальность), и не меняются, когда мы дописываем справа. Поэтому их считают один раз и держат в памяти — это KV-кэш. Без него объём работы на шаг растёт как O(n²) по длине контекста, с ним — линейно, O(n). Вопрос-луч (Q) кэшировать незачем: на шаге генерации нужен только query самого свежего токена, а старые лучи больше не участвуют. Ровно этот кэш — «рюкзак» каждого запроса в следующих шагах про «автобус».
Эти сохранённые значки и записки — те самые «пометки», что в следующем шаге кладут в блокнот. Идём смотреть, сколько работы это экономит ↓
Чтобы посветить прожектором на слово, модель заранее считает про него пару пометок (по-умному — ключ и значение, KV). Пометки нужны на каждом шаге. Считать их заново для всех старых слов каждый раз? Посмотри, сколько выходит лишней работы — и нажми «С блокнотом»:
У каждого слова теперь есть блокнотик-пометка. Но чтобы выбрать слово, кроме блокнота модель читает кое-что огромное — свою библиотеку знаний. Вот где главная тяжесть. Едем туда ↓
Все «знания» модели хранятся в её весах — гигантской таблице чисел. У современных флагманов это триллионы чисел, порядка терабайта — как библиотека из миллиона толстых книг.
А теперь главное, самое контринтуитивное: чтобы выбрать один следующий токен, чипу нужно прогнать через себя практически всю эту библиотеку. Не главу. Не полку. Всю. И для следующего токена — снова всю.
Веса лежат в сверхбыстрой памяти HBM прямо рядом с чипом. Между ними — «труба», которая качает данные с конечной скоростью: у одного GPU это единицы терабайт в секунду, у целой стойки из 72 GPU — сотни.
И вот весь секрет скорости токена в одной строчке:
Меньше — физически нельзя: нельзя выбрать токен, не дочитав веса. Покрути сам:
Постойте. Если каждый токен — это терабайт чтения, почему цены не космические? Трюк: датацентр отвечает не тебе одному. Он собирает в один «автобус» сотни и тысячи запросов — это называется batch — и читает библиотеку один раз сразу для всех. Расход на чтение делится на всех пассажиров.
Но у автобуса есть цена: каждый пассажир везёт «рюкзак» — тот самый KV-блокнот из шага 4, память своего разговора. Чем больше пассажиров, тем больше рюкзаков едет через ту же трубу — и каждый шаг автобуса становится медленнее для всех.
Модель для графиков: флагман ~2,4 ТБ весов, стойка NVL72 (труба 576 ТБ/с), рюкзак пассажира ~3,6 ГБ. Ось «пассажиры» — логарифмическая.
Совсем без пассажиров тоже нельзя: при batch = 1 вся стоимость чтения терабайта ложится на одного человека — Райнер Поуп в лекции у Дваркеша называет это «экономикой в ~1000 раз хуже». Поэтому лаборатории держат автобусы большими — около 2000 запросов — так выгоднее всего.
Обе кривые — это roofline-модель из лекции. Время одного «шага автобуса» (один токен сразу для всего батча) = (веса + пассажиры × рюкзак) ÷ труба памяти. Из него всё и следует: скорость на пассажира = 1 ÷ шаг (больше пассажиров → тяжелее шаг → каждый медленнее), а цена места ∝ шаг ÷ пассажиры (веса читают один раз на всех — поэтому чем больше батч, тем дешевле место). При одном пассажире цена улетает вверх (весь терабайт на него одного), при огромных батчах упираемся в компьют. Числа под графиком — это те самые веса / труба / рюкзак, подставленные в формулу.
Уточнение к «читаем всю библиотеку». На один токен модель считает только через активные параметры — в MoE-моделях это лишь ~3–5% весов (выбранные эксперты). Но из памяти на каждом шаге батча перекачиваются практически все веса: по целому батчу из тысяч разных токенов задействованы почти все эксперты. Поэтому декод и упирается в память, а не в вычисления. Отсюда и оптимум: batch ≈ 300 × разреженность (полные ÷ активные параметры) ≈ 2000 последовательностей — оценка Райнера Поупа: больше — упрёшься в компьют, меньше — в память.
Теперь у тебя есть всё, чтобы разгадать fast mode самостоятельно. Anthropic официально говорит: «та же модель, более быстрая конфигурация инференса, интеллект не меняется». Та же модель — значит, ту же библиотеку читаем через ту же трубу. Что остаётся крутить? Главный рычаг — число пассажиров.
Fast mode — это места в маленьком автобусе: меньше попутчиков → меньше чужих «рюкзаков» в трубе и меньше ожидания → твои токены приходят в ~2,5 раза быстрее. Но чтение библиотеки теперь делится на меньшее число мест — поэтому место стоит дороже. Anthropic берёт ровно 2×: $10/$50 вместо $5/$25 за миллион токенов.
Красивое подтверждение из мира открытых моделей, где веса и цены видны насквозь: у Kimi (Moonshot) есть официальный тир K2.7-highspeed — та же самая модель, ~2,5× скорость (≈72 → ≈180 токенов/с)… ровно за 2× цены. Другая компания, другая страна, другое железо — а арифметика та же, потому что физика одна.
Кстати, в самой лекции у Дваркеша этот режим описан жёстче — «6× цена за 2,5× скорость». Со временем лаборатории научились нарезать «маленькие автобусы» дешевле, и сегодня наценка ближе к 2×. И обрати внимание: ускоряется только печать токенов (throughput), а не «время на подумать» до первого токена.