FinCodeCow · Обзор AI-инфраструктуры

Профилирование, отладка и настройка инференса LLM в масштабе

Обзор шестнадцатой главы книги Chris Fregly «AI Systems Performance Engineering» (O'Reilly, 2026) — с изложением содержания, проверкой прогнозов и систематизацией ключевых положений
Об источнике

Настоящий материал представляет собой обзор шестнадцатой главы книги Chris Fregly, «AI Systems Performance Engineering: Optimizing Model Training and Inference Workloads with GPUs, CUDA, and PyTorch», O'Reilly Media, 2026 (Copyright © 2026 Flux Capacitor, LLC).

Прямые цитаты из книги выделены отдельными блоками с пометкой «Цитата из книги». Остальной текст — систематизированное изложение содержания главы, сопоставление с актуальными данными, проверка прогнозов по открытым источникам, а также дополнительные замечания, выходящие за пределы текста главы. Цитаты приводятся в ограниченном объёме в целях обзора и критического анализа.

Блок 01 · Контекст

Контекст главы

Шестнадцатая глава книги Fregly посвящена профилированию, отладке и настройке производительности инференса LLM в масштабе. Глава охватывает полный цикл: от мониторинга и сбора метрик до конкретных техник оптимизации — динамического батчинга, планирования, квантования и оптимизаций на уровне приложений. Значительное внимание уделяется практическим аспектам эксплуатации inference-кластеров: диагностике неполадок, работе с KV-кэшем, управлению памятью и обеспечению качества обслуживания (QoS).

Цитата из книги · Глава 16

«Эксплуатация крупного кластера для инференса LLM требует инструментов мониторинга и отладки, которые гарантируют, что всё работает как ожидается. Они также помогают быстро выявлять узкие места, когда производительность отклоняется от целевой».

Изложение содержания

Глава построена как практическое руководство по эксплуатации inference-кластеров. Сначала рассматриваются инструменты профилирования и мониторинга (Nsight Systems, Nsight Compute, Prometheus, Grafana, DCGM), затем — методология диагностики неполадок и рецепты устранения типовых проблем. Далее следуют конкретные техники оптимизации: динамический батчинг, непрерывное планирование, чанковый префилл, перекрытие коммуникаций и вычислений, управление памятью и KV-кэшем, квантование для инференса и оптимизации на уровне приложений. Завершается глава вопросами QoS, раннего отклонения запросов и fault tolerance.

Ключевая идея главы: производительность inference-системы — это не только скорость отдельных ядер, но и эффективность планирования, управления памятью и обработки запросов на всех уровнях стека. Инженер по производительности должен уметь измерять, диагностировать и оптимизировать каждый из этих уровней.

Итоги блока 01
Ключевое положение главы

Производительность инференса LLM — это многоуровневая задача, охватывающая мониторинг, планирование, управление памятью и оптимизацию на уровне приложений.

Практическое следствие

Инженер должен уметь работать с инструментами профилирования (Nsight, DCGM, PyTorch Profiler) и применять техники оптимизации на каждом уровне стека.

• • •
Блок 02 · Методология

Итеративный цикл настройки: наблюдение — гипотеза — действие

Фундаментальная методология настройки производительности инференса — итеративный цикл:

  1. Наблюдение. Сбор метрик: загрузка SM GPU, использование памяти, перцентили задержки (p50, p95, p99), доля попаданий в кэш, частота преемпций KV-кэша, загрузка copy-движков, пропускная способность NVLink. Без измерений любая оптимизация — лотерея.
  2. Гипотеза. Формулирование конкретного предположения о первопричине. Не «модель медленная», а «загрузка SM ниже 50% из-за маленьких батчей в фазе декодирования» или «p99 задержка растёт из-за преемпции KV-кэша при пиковом трафике».
  3. Исправление. Внесение изменения: увеличение размера батча, включение prefix caching, применение квантования FP8, перераспределение памяти GPU. Одно изменение за раз — иначе невозможно понять, что сработало.
  4. Проверка. Прогон на staging-окружении с репрезентативной нагрузкой, затем выкатка в продакшен через канареечный релиз на 5–10% трафика. Слежение за Grafana: если пропускная способность выросла, а p99 задержка осталась в рамках SLO — оптимизация успешна.
  5. Повтор. Устранив одно узкое место, обнаруживается следующее. Этот цикл никогда не заканчивается, потому что характеристики трафика меняются, модели обновляются, а оборудование стареет.
Канареечные выкатки

Развёртывание новой версии движка инференса или квантованной модели на всём кластере одновременно — это риск превратить 5-минутную оптимизацию в часовой даунтайм. Инкрементальный подход ограничивает «радиус поражения» и позволяет откатить изменение до того, как оно затронет всех пользователей.

Итоги блока 02
Ключевое положение главы

Настройка производительности — непрерывный цикл: наблюдение → гипотеза → исправление → проверка → повтор. Каждое исправление вскрывает следующее узкое место.

Практическое следствие

Изменения вносятся по одному, с измерением эффекта каждого. Канареечные выкатки ограничивают риск.

• • •
Блок 03 · Профилирование

Профилирование: Nsight Systems и Nsight Compute

Nsight Systems — макроуровень

NVIDIA Nsight Systems — это профилировщик уровня системы, который показывает временную шкалу работы CPU и GPU с микросекундным разрешением. Видны потоки CPU, ядра GPU, события CUDA, коммуникации NCCL, операции memcpy — всё на единой шкале времени.

Ключевая техника — аннотация NVTX (NVIDIA Tools Extension). Пометка регионов кода метками вроде «Prefill», «Decode», «All-to-all» даёт цветные блоки на временной шкале, по которым сразу видно, сколько времени занимает каждая фаза и где возникают простои.

#include <nvtx3/nvToolsExt.h>
#include "my_model.hpp"
#include <vector>

#define NVTX_PUSH(name, argb) \
  do { \
    nvtxEventAttributes_t a{}; \
    a.version = NVTX_VERSION; \
    a.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE; \
    a.colorType = NVTX_COLOR_ARGB; \
    a.color = (unsigned int)(argb); \
    a.messageType = NVTX_MESSAGE_TYPE_ASCII; \
    a.message.ascii = (name); \
    nvtxRangePushEx(&a); \
  } while (0)

#define NVTX_POP() do { nvtxRangePop(); } while (0)

void run_inference(
    const std::vector<Token>& prompt_tokens,
    Model& model,
    int num_generate_steps) {

  NVTX_PUSH("Prefill", 0xFF4F86F7);
  model.encode(prompt_tokens);
  NVTX_POP();

  for (int t = 0; t < num_generate_steps; ++t) {
    NVTX_PUSH("Decode", 0xFFFF8C00);
    Token next_token = model.decode_next();
    NVTX_POP();
  }
}

Для многопоточных сценариев критически важно именовать потоки CUDA и оборачивать каждый в отдельные диапазоны NVTX. Без именования потоков дорожки GPU на временной шкале выглядят как бессмысленная мешанина — с именованием сразу видно, перекрываются ли передача данных и вычисления.

Nsight Compute — микроуровень

Nsight Compute профилирует отдельные ядра CUDA. Можно сосредоточиться на конкретных частях ядра — например, на транзакциях памяти — через профилирование по секциям.

Менее известная, но крайне полезная функция — CUDA Program Counter (PC) Sampling. Она сэмплирует счётчики программы и выявляет горячие точки внутри ядер с минимальными накладными расходами. В отличие от полной трассировки, PC Sampling можно запускать на живых продакшен-серверах, не деградируя обслуживание.

Схема 1. CUDA Program Counter Sampling

Сэмплирование счётчика команд для поиска горячих инструкций

Описание: Nsight Compute сэмплирует счётчик команд и подсвечивает «горячие» инструкции ядра с минимальными накладными расходами. Это первый инструмент при производственном расследовании: локализуйте горячую точку с PC Sampling, и только если она указывает на конкретное ядро, запускайте полную трассировку Nsight Systems.

PyTorch Profiler

PyTorch Profiler, основанный на библиотеке Kineto, предоставляет разбивку на уровне операторов для CPU и GPU. Он записывает формы тензоров, снимки памяти и поддерживает экспорт трассировок в Chrome Tracing / Perfetto для совместного анализа.

with torch.profiler.profile(
    activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
    record_shapes=True,
    profile_memory=True,
    with_stack=True
) as prof:
    with profiler.record_function("train_step"):
        torch.cuda.nvtx.range_push("forward")
        outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
        loss = outputs.loss
        torch.cuda.nvtx.range_pop()

        torch.cuda.nvtx.range_push("backward")
        loss.backward()
        torch.cuda.nvtx.range_push("optimizer_step")
        optimizer.step()
        torch.cuda.nvtx.range_pop()
        optimizer.zero_grad()
        torch.cuda.nvtx.range_pop()

print(prof.key_averages().table(
    sort_by="self_cuda_time_total",
    row_limit=10,
    fields=["self_cuda_time_total", "calls"]
))
Итоги блока 03
Ключевое положение главы

Профилирование — двухэтапный процесс: Nsight Systems для общей картины и поиска горячих ядер, Nsight Compute для детального анализа. NVTX-аннотации делают временную шкалу читаемой.

Практическое следствие

PyTorch Profiler (на базе Kineto) даёт op-уровневую разбивку и поддерживает экспорт в Chrome Tracing / Perfetto. PC Sampling в Nsight Compute позволяет локализовать горячие инструкции с минимальными накладными расходами.

• • •
Блок 04 · Мониторинг

Мониторинг: Prometheus, Grafana и DCGM

В продакшене постоянный мониторинг важнее эпизодического профилирования. Стек Prometheus + Grafana + DCGM — стандарт де-факто для GPU-кластеров.

Схема 2. DCGM, Prometheus, Grafana

Поток метрик от GPU-узлов к дашбордам

DCGM Prometheus Grafana
Описание: DCGM собирает метрики с GPU-узлов Kubernetes, Prometheus их накапливает, Grafana визуализирует в реальном времени. Для vLLM workloads загрузка GPU обычно составляет 80–95%; внезапное падение до 0% указывает на сбой serving-процесса, а устойчивое падение до 30–40% — на проблемы с маршрутизацией трафика.

Ключевые метрики GPU

МетрикаDCGM-счётчикЧто означает
Загрузка SMDCGM_FI_DEV_GPU_UTILПроцент времени, когда SM заняты
Загрузка copy-движкаDCGM_FI_DEV_MEM_COPY_UTILАктивность движков копирования памяти
Использование памятиDCGM_FI_DEV_FB_USEDЗанятая память фреймбуфера
ТемператураDCGM_FI_DEV_GPU_TEMPТемпература GPU
ЭнергопотреблениеDCGM_FI_DEV_POWER_USAGEМощность в ваттах
Ошибки ECCDCGM_FI_DEV_ECC_*Корректируемые и неисправимые ошибки
Ошибки NVLinkDCGM_FI_DEV_NVLINK_*Повторы, CRC, восстановление линков

Метрики уровня приложения

  • Запросы в секунду (RPS) — основной индикатор нагрузки.
  • Средняя задержка, p95, p99 — для соответствия SLO.
  • Число активных контекстов — сколько одновременных сессий обслуживается.
  • Пропускная способность в токенах/с — реальная скорость генерации.
  • Использование и размер KV-кэша (общий и по узлам).
  • Доля попаданий в префиксный кэш — vllm:gpu_prefix_cache_queries и vllm:gpu_prefix_cache_hits в vLLM.
  • Частота преемпций KV-кэша — если растёт, памяти GPU не хватает.

Алерты в Alertmanager

МетрикаУсловиеСерьёзностьПримечания
Загрузка GPU< 10% более 60 сПростойНедоиспользование
Загрузка GPU> 90%Узкое местоВозможное насыщение
Использование памяти> 80%ПредупреждениеПриближение к OOM
Использование памяти> 95%КритичноВысокий риск OOM
Температура> 85 °CПредупреждениеПриближение к троттлингу
Температура> 95 °CКритичноРиск повреждения
Ошибки NVLink (повтор)≥ 1КритичноПроблема линка
Ошибки CRC NVLink> 100/сКритичноДеградация линка
Неисправимые ошибки ECC≥ 1КритичноПовреждение данных

Числовые значения — ориентировочные. Фактические пороги зависят от архитектуры GPU, условий охлаждения и SLO. Настраивайте их на основе baseline-измерений.

Корреляция метрик

  • RPS + p99 задержка: всплеск задержки совпадает со всплеском трафика? Возможно, динамический батчинг увеличивает размер батча и задержку.
  • Загрузка SM + загрузка copy-движка: SM простаивает, copy-движок загружен? Скорее всего, движок выгружает и загружает KV-кэш — памяти GPU не хватает.
  • Счётчик ошибок NCCL + загрузка GPU по узлам: один узел на 0%, остальные на 90%? Ищите NCCL_COMM_FAILURE в логах.
  • Доля попаданий в префиксный кэш + TTFT: падение hit-rate совпадает с ростом time-to-first-token? Возможно, кэш слишком мал.

Логи: что мониторить

Пример лога vLLM, указывающего на преемпцию KV-кэша:

WARNING 2025-05-03 14:22:07 scheduler.py:1057 Sequence group 0 is preempted by
PreemptionMode.RECOMPUTE because not enough KV cache space.
total_cumulative_preemption_cnt=1

Это означает, что движку не хватило памяти для KV-кэша, и он вытеснил активную последовательность. Результат — пересчёт KV при повторном планировании, дополнительные вычисления и рост задержки. Если такие сообщения появляются регулярно: увеличьте порог использования памяти GPU, уменьшите максимальное число батчированных токенов, включите PagedAttention или рассмотрите квантование KV-кэша.

Итоги блока 04
Ключевое положение главы

Постоянный мониторинг через Prometheus + Grafana + DCGM — стандарт де-факто для GPU-кластеров. Ключевые метрики: загрузка SM, использование памяти, перцентили задержки, доля попаданий в кэш.

Практическое следствие

Корреляция метрик (RPS + p99, SM + copy-движок, NCCL errors + загрузка GPU) позволяет быстро локализовать первопричину.

• • •
Блок 05 · Диагностика

Рецепты устранения неполадок

СимптомВероятная причинаРекомендуемое действие
Загрузка SM < 50%Маленькие батчи или отсутствие fused-ядерУвеличить размер батча, включить FlashAttention, добавить fused-ядра, профилировать через nsys --trace=cuda
Предупреждения о преемпции KV-кэшаНедостаточно места в KV-кэшеПовысить порог памяти GPU, уменьшить max batch tokens, включить PagedAttention
Высокая хвостовая задержка (p95 > 200 мс)Горячая точка декодирования или блокировка головы очередиПроверить логи маршрутизатора, настроить порог предвыборки, включить спекулятивное декодирование
Доля попаданий в кэш < 60%Несбалансированный шардинг или отсутствие префиксного кэшаПроверить конфигурацию префиксного кэша (LMCache, NIXL), увеличить TTL, добавить реплики
Неожиданный OOMПерегрузка памяти GPUСнизить память на инстанс, включить выгрузку на CPU/NVMe, привязать процессы к сокетам
Нерегулярные выбросыТепловой троттлинг или несогласованные частотыСинхронизировать частоты, следить за температурой, ограничить частоту через nvidia-smi -lgc

Отладка корректности

  • Утечки памяти CUDA: использование памяти растёт монотонно. Используйте compute-sanitizer --tool memcheck your_binary для обнаружения ошибок памяти, гонок данных и выходов за границы.
  • Сбои NCCL: один GPU показывает 0% загрузки, остальные 90%. Включите NCCL_DEBUG=WARN для подробных логов. Используйте ncclCommGetAsyncError с ncclCommAbort для обнаружения и обработки асинхронных ошибок.
  • Аппаратные ошибки: ошибки ECC, повторы NVLink, повторы PCIe. Любое появление неисправимых ошибок ECC — повод немедленно оповестить и запланировать замену узла.
Итоги блока 05
Ключевое положение главы

Диагностика неполадок инференса — систематический процесс: от симптома к вероятной причине и конкретному действию. Таблица рецептов покрывает типовые сценарии.

Практическое следствие

Для отладки корректности используются compute-sanitizer, NCCL_DEBUG и мониторинг аппаратных счётчиков ошибок.

• • •
Блок 06 · Полностековые оптимизации

Полностековые оптимизации

Высокопроизводительный инференс требует скоординированных оптимизаций на каждом уровне стека. Проблема только на одном уровне — это удача. В реальности узкие места мигрируют между уровнями по мере их устранения.

Уровень стекаКлючевые техники
МодельПрунинг, дистилляция, разреженность (MoE), FlashAttention, обучение с учётом квантования (QAT)
ЯдроFused-операции (Linear + GELU + LayerNorm), FlashInfer, Tensor Core, блочный тайлинг, асинхронные передачи (cp.async, TMA)
Среда выполненияДинамический/непрерывный батчинг, PagedAttention, CUDA Graphs, пулинг буферов, многопотоковые CUDA, синхронизация на основе событий
ОркестрацияРазделение префилла и декодирования, интеллектуальная маршрутизация, изоляция мультитенантности, автомасштабирование с тёплыми резервами
РазвёртываниеГеораспределённое граничное обслуживание, умные API-шлюзы с батчингом, CI/CD для вариантов моделей, NVLink/NVSwitch, InfiniBand, NUMA-аффинность
QoS и масштабированиеДинамический батчинг с учётом SLA, изоляция через MIG, дашборды профилирования в реальном времени, динамическое переключение параллелизма (TP, PP, DP)

Ключевая идея — синергии между уровнями. Квантование (модель) снижает потребление памяти, позволяя увеличить размеры батчей (среда выполнения) без OOM, что, в свою очередь, позволяет оркестрации объединять больше запросов на цикл GPU. Одна оптимизация на нижнем уровне может разблокировать несколько оптимизаций на верхних.

Итоги блока 06
Ключевое положение главы

Полностековые оптимизации — необходимое условие для высокопроизводительного инференса. Узкие места мигрируют между уровнями по мере их устранения.

Практическое следствие

Поддерживайте стек ПО в актуальном состоянии. Новые версии CUDA, cuDNN, NCCL, Transformer Engine содержат оптимизации, недоступные на старых версиях.

• • •
Блок 07 · Батчинг

Динамический батчинг и планирование

Статический vs динамический vs непрерывный

Статический батчинг фиксирует размер батча, дополняет все последовательности до самой длинной и ждёт завершения каждого запроса перед возвратом. Результат: неограниченная задержка для ранних прибывших запросов и впустую потраченные циклы GPU на паддинг.

Динамический батчинг собирает батчи на лету. Система накапливает входящие запросы в течение короткого таймаута (обычно 2–10 мс) или до достижения целевого размера батча, затем отправляет батч на GPU.

Схема 3. Static vs Dynamic Batching

Накопление запросов vs мгновенный старт с тем, что пришло

Static batching — ждёт полный батч Dynamic batching — стартует сразу
Описание: Статический батч копит запросы до фиксированного размера; динамический отправляет то, что пришло за короткий таймаут. При низком RPS динамический батчинг добавляет небольшую задержку — запросы ждут в очереди, надеясь, что к ним присоединятся другие. При умеренном и высоком RPS задержка амортизируется: за то же время обрабатывается больше работы, и общее время ожидания в очереди снижается.
АспектСтатическийДинамическийНепрерывный
ТриггерФиксированный размерЦель по размеру или таймаутСобытие завершения токена
Ограничение задержкиНеограниченноеОграничено max_batch_delay_msМинимальное
ПаддингВысокийУмеренныйНизкий
Простой GPUПлохоеЛучшеОтличное
СложностьПростаяУмереннаяСложная

Непрерывный батчинг (batching in-flight, iteration-level scheduling) — следующий шаг. Вместо ожидания завершения полных последовательностей, система пополняет батч на каждой итерации генерации токенов. Завершённые запросы вытесняются, новые немедленно занимают их слоты.

Схема 4. Continuous Batching

Завершённые последовательности уходят, новые встраиваются прямо посреди генерации

GPU batch (итерация за итерацией)
Описание: Continuous batching: завершённые последовательности покидают батч, а новые запросы встраиваются прямо посреди генерации. Батчинг 4–8 запросов часто удваивает или утраивает пропускную способность по сравнению с батчами по 1–2 запроса, потому что математические блоки и конвейеры памяти GPU используются лучше. Дополнительная задержка на запрос — порядка нескольких миллисекунд.

Непрерывное планирование

Непрерывное планирование относится к GPU как планировщик ОС к CPU. Если модель маленькая или размер батча ограничен SLO, одна копия модели может не насыщать GPU. Тогда движок запускает несколько потоков инференса одновременно на одном GPU.

PagedAttention в vLLM — конкретный пример. KV-кэш разбивается на страницы, и вычисления динамически группируются по страницам между активными последовательностями. Под тяжёлой нагрузкой это даёт почти 100% загрузку GPU.

Чанковый префилл

Когда промпты очень длинные (например, 20 000 токенов), можно разбить их на чанки и чередовать работу префилла и декодирования. Это называется чанковым префиллом (chunked prefill) или планированием без простоев.

Размер чанкаЧисло чанковОперации внимания на чанкВсего токенов MLP
20K1200M20K
10K250M + 150M = 200M20K
5K412,5M + 37,5M + 62,5M + 87,5M = 200M20K

Ключевое понимание: чанкирование не уменьшает общее число операций внимания. Self-attention выполняет N(N+1) ÷ 2 скалярных произведений Q × K на слой на голову — стоимость квадратична по N, O(N²). Чанкирование меняет только то, когда работа становится доступной декодеру. Выгода — сглаживание задержки и улучшение перекрытия, а не сокращение вычислений.

Планирование с учётом задержки

Наивный планировщик FIFO может перегрузить один GPU, если порядок прибытия не оптимален. Рассмотрим шесть промптов с длинами 6K, 2K, 6K, 2K, 2K, 2K и два GPU.

  • FIFO: Батч 1 = [6K, 2K, 6K] → GPU 1 (≈38M операций Q×K), Батч 2 = [2K, 2K, 2K] → GPU 2 (≈6M). Критический путь — GPU 1.
  • С учётом задержки: Батч 1 = [2K, 2K, 6K] → GPU 1 (≈22M), Батч 2 = [2K, 2K, 6K] → GPU 2 (≈22M). Критический путь снижается на 42%.
Итоги блока 07
Ключевое положение главы

Непрерывный батчинг и чанковый префилл — ключевые техники для максимизации пропускной способности при сохранении низкой задержки. Планирование с учётом задержки снижает критический путь на 42% в примере с шестью промптами.

Практическое следствие

Чанкирование не уменьшает общее число операций внимания — оно только сглаживает задержку и улучшает перекрытие.

• • •
Блок 08 · Системные оптимизации

Системные оптимизации

Перекрытие коммуникаций и вычислений

В распределённом инференсе перекрытие коммуникаций с вычислениями — критический фактор производительности. Системы вроде GB200/GB300 NVL72 обеспечивают до ~130 ТБ/с агрегированной пропускной способности NVLink внутри стойки, но даже с такими скоростями синхронные коммуникации создают пузыри.

Базовый приём — отдельные потоки CUDA для передачи и вычислений:

cudaStream_t transfer_stream, compute_stream;
cudaStreamCreate(&transfer_stream);
cudaStreamCreate(&compute_stream);

// Передача в transfer_stream
cudaMemcpyAsync(h_logits, d_logits, bytes, 
                cudaMemcpyDeviceToHost, transfer_stream);

// Вычисление в compute_stream — перекрывается с передачей
my_kernel<<<grid, block, 0, compute_stream>>>(...);

// Синхронизация только когда данные нужны
cudaEventSynchronize(transfer_done_event);

Обязательно используйте page-locked (pinned) буферы хоста для передач по PCIe или NIC — драйвер CUDA может выполнять DMA напрямую и перекрывать с вычислениями.

Для MoE-моделей all-to-all можно перекрыть, разделив батч токенов пополам: пока первая половина обрабатывается экспертами, вторая отправляется. К моменту завершения первой половины данные второй уже прибыли на GPU-получатели.

GPUDirect RDMA позволяет сетевым адаптерам (InfiniBand NIC) читать и писать в память GPU напрямую, минуя память хоста. Это снижает задержку кросс-узловых передач KV-кэша или активаций экспертов и освобождает ядра CPU.

CUDA Graphs позволяют захватить асинхронные паттерны и снизить накладные расходы на запуск ядер — особенно полезно для повторяющихся паттернов декодирования.

Энергопотребление и тепловые ограничения

Непрерывная работа GPU на 100% вызовет тепловой троттлинг, если охлаждение недостаточно. Иногда работа на 90% с эффективными ядрами превосходит 100% с троттлингом.

  • Ограничение частот через nvidia-smi -lgc — незначительно снижает пропускную способность, но обеспечивает стабильность.
  • Небольшая задержка между батчами для снижения утилизации.
  • Жидкостное охлаждение — стандарт для современных дата-центр GPU.
  • Повышение лимита мощности через nvidia-smi -pl (если охлаждение адекватно).

Управление памятью

Страничный KV-кэш (PagedAttention в vLLM) разбивает KV-кэш на страницы и динамически выделяет их между последовательностями. Это устраняет фрагментацию памяти, свойственную подходам с фиксированным выделением.

Выгрузка KV-кэша (swap) в память CPU или на NVMe — вариант для редко используемых данных. LMCache в vLLM позволяет регулировать соотношение кэша на GPU и CPU. RadixAttention в SGLang лениво вытесняет наименее недавно использованные префиксы.

Однако выгрузка — не бесплатно: при высокой частоте свопа загрузка copy-движков растёт, а загрузка SM падает. Если виден всплеск copy-движка с одновременным падением SM — система свопит. Решения: применить квантование FP8/FP4 для уменьшения размера KV, увеличить выделение памяти GPU под кэш, изменить стратегию свопа.

Итоги блока 08
Ключевое положение главы

Перекрытие коммуникаций и вычислений — критический фактор производительности распределённого инференса. GPUDirect RDMA и CUDA Graphs помогают скрыть задержки.

Практическое следствие

Управление памятью через PagedAttention, LMCache и RadixAttention устраняет фрагментацию и позволяет обслуживать больше одновременных запросов.

• • •
Блок 09 · Квантование

Квантование для инференса в реальном времени

Спектр точности

ФорматБит на элементУскорение vs FP32След памяти vs FP32Примечания
FP32321×1×Базовая точность
TF3219 (мантисса 10 бит)~1,5×1×Только Tensor Cores
FP16/BF16162×0,5×Стандарт для инференса
FP8 (E4M3/E5M2)84×0,25×Требует калибровки
INT448× (теоретически)0,125×Квантование только весов
FP4 (NVFP4)4 + блок-масштабы~8×~0,18× (с метаданными)Требует микромасштабирования

Схема 5. Transformer Engine: преобразование точности

Анализ диапазона, подбор масштаба, перевод в FP8/FP4

FP16 input range scale FP8 / FP4
Описание: Transformer Engine анализирует диапазон значений, подбирает масштаб и переводит тензор в FP8/FP4, сохраняя точность. NVIDIA's FP4 implementation (NVFP4) uses block-wise microscaling in hardware, поддерживаемое TE.

Квантование только весов: GPTQ и AWQ

Квантование только весов сжимает веса до 4-битных целых, сохраняя активации в более высокой точности (FP8, FP16). Это снижает след памяти весов примерно в 4 раза по сравнению с FP16.

GPTQ применяет приближённый алгоритм второго порядка для послойного квантования весов до 3–4 бит за несколько часов на GPU. Для многих моделей 4-битное GPTQ сохраняет 99%+ точности FP16 с ~2× ускорением инференса.

AWQ (Activation-aware Weight Quantization) идентифицирует небольшую долю «значимых» каналов весов, которые производят большие величины активаций. AWQ применяет масштабирование на конкретный канал перед приведением весов к 4-битной точности.

Квантование активаций: SmoothQuant и W4A8

Квантование активаций сложнее, потому что их распределения сильно варьируются при разных входах. SmoothQuant — метод PTQ для 8-битного квантования активаций без обучения. Он переносит часть ошибки квантования с активаций на веса через простое масштабирование по строкам/столбцам.

Гибридный подход W4A8 сочетает 4-битные веса (INT4) с 8-битными активациями (FP8 или INT8). TensorRT-LLM и другие движки предоставляют этот путь с почти без потерь точности при правильной калибровке.

Практический рабочий процесс

  1. Начните с инференса в FP16/BF16 — это базовая линия.
  2. Оцените 8-битное квантование (FP8 или INT8) — обычно без потерь.
  3. Примените 4-битное квантование только весов (GPTQ или AWQ) — для дополнительного сжатия.
  4. Если нужна максимальная оптимизация — перейдите к W4A8 (INT4 веса + FP8 активации).
  5. Калибруйте на данных, отражающих реальную нагрузку.
  6. Проводите A/B-тестирование ответов квантованной модели против исходной.
Итоги блока 09
Ключевое положение главы

Квантование — один из самых эффективных способов снижения стоимости инференса. GPTQ и AWQ для 4-битных весов, SmoothQuant для 8-битных активаций, W4A8 для максимальной оптимизации.

Практическое следствие

Всегда валидируйте точность на downstream-задачах и проводите A/B-тестирование. 4-битное квантование весов сохраняет 99%+ точности для многих моделей.

• • •
Блок 10 · Уровень приложений

Оптимизации на уровне приложений

Сжатие промптов

Механизм внимания трансформера имеет временную сложность O(n²), где n — размер входа в токенах. Сокращение промпта с 10 000 до 5 000 токенов уменьшает работу self-attention в 4 раза.

  • Удаление избыточности: если пользовательский промпт содержит большой фрагмент текста, не относящийся к вопросу, вышестоящий компонент может суммировать или извлечь релевантные части.
  • Сжатие истории диалога: при превышении 75% максимального контекста суммировать самые старые 25% сообщений.
  • Специальные токены: системный промпт из 200 токенов можно заменить 10 специальными токенами, если модель дообучена распознавать их.
  • Ссылки вместо содержимого: если промпт ссылается на ранее сохранённый документ, заменить полное содержимое ссылкой и обработать через RAG.

Кэширование префиксов

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

Без кэширования: N запросов длины L требуют O(N × L) работы. С кэшированием: O(N + L) — префикс обрабатывается один раз, каждый запрос добавляет только свой уникальный суффикс.

Схема 6. Префикс-кэш как trie

Каждый узел — токен, зелёная подсветка — переиспользование общего префикса

"You are ChatGPT, a friendly assistant..."
Описание: Префикс-кэш хранится как trie: каждый узел — токен, зелёная подсветка — переиспользование общего префикса. В vLLM включается через enable_prefix_caching=True. Движок определяет, совпадают ли первые N токенов входящего промпта с уже кэшированным префиксом, и если да — копирует данные KV-кэша вместо пересчёта.

Схема 7. Эволюция префикс-кэша

Новые узлы, активные узлы, вытеснение по LRU

Описание: Зелёные — новые узлы, синие — активно используемые, вытесненные по LRU при нехватке памяти. Высокая доля попаданий в префиксный кэш (> 80%) означает эффективное переиспользование данных. При доле промахов > 40% нужно настроить размер кэша, изменить политику вытеснения (LRU, LFU), увеличить TTL или проверить логику сопоставления префиксов.

Каскадирование моделей

Не все запросы требуют мощности самой большой модели. Каскадирование — подход, при котором простые запросы направляются к меньшей, более быстрой модели, а сложные — к большой.

  • Эвристическая: короткие фактические запросы → малая модель. Длинные промпты или запросы со словами «объясни», «проанализируй» → большая модель.
  • Спекулятивная: запустить малую модель, оценить уверенность. Высокая уверенность — вернуть ответ. Низкая — вызвать большую модель.
  • По нагрузке: при насыщении кластера большой модели направлять менее критичные запросы к малой.

Маршрутизация 60% запросов к модели в 10 раз меньше может сократить вычислительные затраты в ~5 раз.

Потоковая выдача

Модель генерирует по одному токену за раз (за исключением спекулятивного декодирования EAGLE и много-головного декодирования Medusa). Система группирует токены в батчи по 2–5, сбрасывает поток и отправляет через SSE/WebSockets/HTTP Streaming.

Человек читает со скоростью 4–13 токенов в секунду. Без потоковой выдачи пользователь смотрит на пустой экран 5 секунд, затем получает весь ответ разом. С потоковой выдачей первый батч токенов приходит через 0,25 секунды — и пользователь начинает читать сразу.

Технические детали: TCP_NODELAY для минимизации задержки; потокобезопасные очереди для передачи токенов сетевому потоку; управление контролем потока; HTTP/2 и постоянные соединения.

Схема 8. Debouncing кликов

Короткая пауза после серии кликов перед отправкой запроса

Клики пользователя 2 мс Ответ
Описание: Debouncing ждёт короткую паузу после серии кликов и отправляет только один запрос, отбрасывая дубликаты. Request coalescing объединяет похожие запросы. Токен-лимиты и таймауты предотвращают runaway-генерацию.
Итоги блока 10
Ключевое положение главы

Оптимизации на уровне приложений — сжатие промптов, кэширование префиксов, каскадирование моделей, потоковая выдача — дают значительный эффект без изменения модели или железа.

Практическое следствие

Кэширование префиксов превращает O(N × L) работы в O(N + L). Сжатие промптов уменьшает работу self-attention квадратично.

• • •
Блок 11 · Проверка прогнозов

Проверка прогнозов и актуальные данные

Книга Fregly писалась в 2025 году, когда inference-стек активно развивался. Ниже представлено сопоставление прогнозов главы 16 с открытыми данными.

Подтверждено Прогноз 1: мониторинг через DCGM + Prometheus + Grafana

«DCGM собирает метрики с GPU-узлов Kubernetes, Prometheus их накапливает, Grafana визуализирует».

Подтверждено. DCGM Exporter стал стандартом де-факто для GPU-наблюдаемости в Kubernetes. Для vLLM workloads DCGM метрики интегрируются с Prometheus recording rules для расчёта стоимости. AIPerf и другие инструменты включают DCGM/pynvml метрики в выходные данные бенчмарков.

Подтверждено Прогноз 2: непрерывный батчинг как стандарт

«Continuous batching: завершённые последовательности покидают батч, новые встраиваются прямо посреди генерации».

Подтверждено. Continuous batching реализован в vLLM, SGLang, TensorRT-LLM и стал стандартом для production-инференса. PagedAttention в vLLM и RadixAttention в SGLang обеспечивают динамическое управление KV-кэшем.

Подтверждено Прогноз 3: чанковый префилл и планирование без простоев

«Чанковый префилл: разбить длинные промпты на чанки и чередовать работу префилла и декодирования».

Подтверждено. Chunked prefill реализован в vLLM как stall-free scheduling. Рекомендуемые параметры: --enable-chunked-prefill --max-num-batched-tokens 2048. Это предотвращает блокировку коротких запросов длинными префиллами.

Подтверждено Прогноз 4: GPTQ и AWQ как стандарт квантования

«GPTQ и AWQ для 4-битных весов сохраняют 99%+ точности FP16 с ~2× ускорением».

Подтверждено. GPTQ и AWQ интегрированы в Hugging Face Transformers, vLLM, TensorRT-LLM. W4A8 (INT4 веса + FP8 активации) стал стандартным путём для максимальной оптимизации. SmoothQuant обеспечивает 8-битное квантование активаций.

Подтверждено Прогноз 5: кэширование префиксов

«Кэширование префиксов превращает O(N × L) работы в O(N + L)».

Подтверждено. Prefix caching реализован в vLLM (enable_prefix_caching=True) и SGLang (RadixAttention). Для рабочих нагрузок с общими системными промптами или историей диалога это даёт кратное ускорение.

Подтверждено Прогноз 6: перекрытие коммуникаций и вычислений

«Отдельные потоки CUDA для передачи и вычислений; GPUDirect RDMA; CUDA Graphs».

Подтверждено. Overlap коммуникаций и вычислений — стандартная практика. GPUDirect RDMA используется для кросс-узловых передач KV-кэша. CUDA Graphs интегрированы в inference-движки. NVIDIA Dynamo использует NIXL для асинхронной передачи KV-кэша с перекрытием.

• • •
Блок 12 · Дополнительные выводы

Дополнительные выводы

  1. Производительность инференса — это не только скорость ядер. Глава 16 показывает, что производительность inference-системы определяется совокупностью факторов: эффективностью планирования, управления памятью, обработки запросов и мониторинга. Оптимизация только одного уровня даёт ограниченный эффект.
  2. Мониторинг и профилирование — основа эксплуатации. Без систематического сбора метрик (DCGM, Prometheus, Grafana) и профилирования (Nsight Systems, Nsight Compute, PyTorch Profiler) невозможно выявить узкие места. Инструменты должны быть интегрированы в CI/CD и производственные дашборды.
  3. Непрерывный батчинг и чанковый префилл — ключевые техники. Они максимизируют пропускную способность при сохранении низкой задержки. Continuous batching в сочетании с PagedAttention и chunked prefill стали стандартом для production-инференса.
  4. Квантование — самый эффективный способ снижения стоимости. GPTQ, AWQ, SmoothQuant и W4A8 позволяют снизить потребление памяти и увеличить пропускную способность без значительной потери точности. Начинать следует с FP8, затем переходить к 4-битным весам.
  5. Оптимизации на уровне приложений недооценены. Сжатие промптов, кэширование префиксов и потоковая выдача дают значительный эффект при минимальных затратах на внедрение. Они не требуют изменения модели или железа.
  6. Перекрытие коммуникаций и вычислений — критический фактор масштабирования. GPUDirect RDMA, CUDA Graphs и отдельные потоки CUDA позволяют скрыть задержки передачи данных за вычислениями.
  7. QoS и раннее отклонение запросов необходимы в масштабе. При перегрузке кластера лучше быстро отклонить низкоприоритетные запросы, чем допустить деградацию latency для всех. Mooncake и аналогичные системы реализуют admission control на основе прогнозирования задержки.
• • •
Блок 13 · Ключевые положения

Ключевые положения

  1. Профилирование — двухэтапный процесс. Nsight Systems для общей картины и поиска горячих ядер, Nsight Compute для детального анализа. NVTX-аннотации делают временную шкалу читаемой.
  2. Мониторинг через Prometheus + Grafana + DCGM. Ключевые метрики: загрузка SM, использование памяти, перцентили задержки, доля попаданий в кэш. Корреляция метрик позволяет быстро локализовать первопричину.
  3. Диагностика неполадок — систематический процесс. Таблица рецептов покрывает типовые сценарии: низкая загрузка SM, преемпции KV-кэша, высокая хвостовая задержка, OOM.
  4. Полностековые оптимизации. Узкие места мигрируют между уровнями. Оптимизации на уровне модели, ядра, среды выполнения, оркестрации и развёртывания взаимодополняют друг друга.
  5. Непрерывный батчинг и чанковый префилл. Continuous batching максимизирует пропускную способность. Chunked prefill предотвращает блокировку коротких запросов длинными.
  6. Планирование с учётом задержки. Снижает критический путь на 42% в примере с шестью промптами.
  7. Перекрытие коммуникаций и вычислений. Отдельные потоки CUDA, GPUDirect RDMA и CUDA Graphs скрывают задержки передачи данных.
  8. Управление памятью. PagedAttention, LMCache и RadixAttention устраняют фрагментацию и позволяют обслуживать больше одновременных запросов.
  9. Квантование. GPTQ и AWQ для 4-битных весов, SmoothQuant для 8-битных активаций, W4A8 для максимальной оптимизации. Начинайте с FP8, калибруйте на реальных данных.
  10. Сжатие промптов и кэширование префиксов. Сжатие уменьшает работу self-attention квадратично. Кэширование префиксов превращает O(N × L) в O(N + L).
  11. Каскадирование моделей. Маршрутизация 60% запросов к модели в 10 раз меньше сокращает затраты в ~5 раз.
  12. Потоковая выдача. TCP_NODELAY, потокобезопасные очереди, HTTP/2. Первый батч токенов через 0,25 секунды вместо 5 секунд ожидания.
  13. QoS и раннее отклонение. При перегрузке — быстро отклонить низкоприоритетные запросы, чтобы сохранить latency для остальных.
Общий итог обзора

Шестнадцатая глава книги Fregly — систематическое руководство по профилированию, отладке и настройке инференса LLM в масштабе. Ключевая идея: производительность inference-системы — это многоуровневая задача, охватывающая мониторинг, планирование, управление памятью и оптимизацию на уровне приложений. Для инженера это означает, что понимание методологии профилирования и принципов работы каждого инструмента важнее, чем знание конкретных цифр текущего поколения.

Проверка прогнозов показывает: книга оказалась точной в своих предсказаниях. DCGM + Prometheus + Grafana стали стандартом мониторинга. Continuous batching, chunked prefill, GPTQ/AWQ, prefix caching и overlap коммуникаций с вычислениями — все эти техники реализованы в production-движках (vLLM, SGLang, TensorRT-LLM, NVIDIA Dynamo). Главный вывод остаётся неизменным: инвестиции в методологию профилирования и мониторинга обеспечивают адаптацию к любому стеку.

Источники: Chris Fregly, «AI Systems Performance Engineering» (O'Reilly, 2026), Глава 16 — цитаты приводятся в ограниченном объёме в целях обзора и критического анализа. Документация NVIDIA Nsight Systems, Nsight Compute, DCGM, vLLM, SGLang, TensorRT-LLM; NVIDIA Dynamo Documentation; MLPerf Training/Inference v5.0; Red Hat Developer «Deploying distributed AI inference: Blueprints & troubleshooting» (2026); NVIDIA Technical Blog «Benchmarking LLM Inference at Scale with AIPerf» (2026).

FinCodeCow · AI Infrastructure Review

Profiling, Debugging, and Tuning LLM Inference at Scale

A review of Chapter 16 of Chris Fregly's «AI Systems Performance Engineering» (O'Reilly, 2026) — with exposition of the chapter's content, forecast verification, and systematization of key points
About the source

This material is a review of Chapter 16 of Chris Fregly, «AI Systems Performance Engineering: Optimizing Model Training and Inference Workloads with GPUs, CUDA, and PyTorch», O'Reilly Media, 2026 (Copyright © 2026 Flux Capacitor, LLC).

Direct quotes from the book are marked with separate blocks labeled «Quote from the book». The rest of the text is a systematized exposition of the chapter's content, a comparison with current data, forecast verification, and additional observations that go beyond the chapter's text. Quotes are provided in limited volume for review and critical analysis purposes.

Block 01 · Context

Chapter Context

Chapter 16 of Fregly's book is dedicated to profiling, debugging, and tuning LLM inference at scale. The chapter covers the full cycle: from monitoring and metric collection to specific optimization techniques — dynamic batching, scheduling, quantization, and application-level optimizations. Significant attention is paid to the practical aspects of operating inference clusters: troubleshooting, working with KV cache, memory management, and ensuring quality of service (QoS).

Quote from the book · Chapter 16

«Operating a large LLM inference cluster requires monitoring and debugging tools that make sure everything is running as expected. They also help you quickly identify bottlenecks when performance strays from its target».

Exposition of content

The chapter is structured as a practical guide to operating inference clusters. First, profiling and monitoring tools (Nsight Systems, Nsight Compute, Prometheus, Grafana, DCGM) are examined, followed by troubleshooting methodology and recipes for typical problems. Next, specific optimization techniques are presented: dynamic batching, continuous scheduling, chunked prefill, overlapping communication and computation, memory and KV cache management, quantization for inference, and application-level optimizations. The chapter concludes with QoS, early rejection, and fault tolerance.

The key idea of the chapter: inference system performance is not just the speed of individual kernels but the efficiency of scheduling, memory management, and request handling at every level of the stack. The performance engineer must be able to measure, diagnose, and optimize each of these levels.

Block 01 Summary
Key point of the chapter

LLM inference performance is a multi-level task spanning monitoring, scheduling, memory management, and application-level optimization.

Practical consequence

The engineer must be proficient with profiling tools (Nsight, DCGM, PyTorch Profiler) and apply optimization techniques at every level of the stack.

• • •
Block 02 · Methodology

Iterative Tuning Cycle: Observe — Hypothesize — Act

The fundamental methodology for tuning inference performance is an iterative cycle:

  1. Observe. Collect metrics: GPU SM utilization, memory usage, latency percentiles (p50, p95, p99), cache hit rate, KV-cache preemption frequency, copy engine load, NVLink bandwidth. Without measurements, any optimization is a lottery.
  2. Hypothesize. Formulate a specific hypothesis about the root cause. Not "the model is slow" but "SM utilization is below 50% due to small batches in the decode phase" or "p99 latency grows due to KV-cache preemption at peak traffic".
  3. Fix. Make the change: increase batch size, enable prefix caching, apply FP8 quantization, redistribute GPU memory. One change at a time — otherwise you won't know what worked.
  4. Verify. Run on staging with a representative load, then roll out to production via a canary release to 5–10% of traffic. Watch Grafana: if throughput rose while p99 stayed within SLO, the optimization succeeded.
  5. Repeat. After eliminating one bottleneck, you'll find the next. This cycle never ends because traffic characteristics change, models update, and hardware ages.
Canary rollouts

Deploying a new inference engine version or quantized model across the entire cluster at once risks turning a 5-minute optimization into an hour-long outage. The incremental approach limits the blast radius and lets you roll back before it affects all users.

Block 02 Summary
Key point of the chapter

Performance tuning is a continuous cycle: observe → hypothesize → fix → verify → repeat. Each fix reveals the next bottleneck.

Practical consequence

Changes are made one at a time, with the effect of each measured. Canary rollouts limit risk.

• • •
Block 03 · Profiling

Profiling: Nsight Systems and Nsight Compute

Nsight Systems — Macro Level

NVIDIA Nsight Systems is a system-level profiler showing the CPU and GPU timeline with microsecond resolution. You see CPU threads, GPU kernels, CUDA events, NCCL communications, memcpy operations — all on a single timeline.

The key technique is NVTX (NVIDIA Tools Extension) annotation. Marking code regions with labels like "Prefill", "Decode", "All-to-all" gives colored blocks on the timeline that immediately show how long each phase takes and where stalls occur.

#include <nvtx3/nvToolsExt.h>
#include "my_model.hpp"
#include <vector>

#define NVTX_PUSH(name, argb) \
  do { \
    nvtxEventAttributes_t a{}; \
    a.version = NVTX_VERSION; \
    a.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE; \
    a.colorType = NVTX_COLOR_ARGB; \
    a.color = (unsigned int)(argb); \
    a.messageType = NVTX_MESSAGE_TYPE_ASCII; \
    a.message.ascii = (name); \
    nvtxRangePushEx(&a); \
  } while (0)

#define NVTX_POP() do { nvtxRangePop(); } while (0)

void run_inference(
    const std::vector<Token>& prompt_tokens,
    Model& model,
    int num_generate_steps) {

  NVTX_PUSH("Prefill", 0xFF4F86F7);
  model.encode(prompt_tokens);
  NVTX_POP();

  for (int t = 0; t < num_generate_steps; ++t) {
    NVTX_PUSH("Decode", 0xFFFF8C00);
    Token next_token = model.decode_next();
    NVTX_POP();
  }
}

For multi-threaded scenarios it's critical to name CUDA streams and wrap each in separate NVTX ranges. Without naming, GPU tracks on the timeline look like a meaningless jumble — with naming, you immediately see whether data transfer and computation overlap.

Nsight Compute — Micro Level

Nsight Compute profiles individual CUDA kernels. You can focus on specific kernel parts — for example, memory transactions — via section-based profiling.

A lesser-known but extremely useful feature is CUDA Program Counter (PC) Sampling. It samples program counters and identifies hot spots inside kernels with minimal overhead. Unlike full tracing, PC Sampling can run on live production servers without degrading service.

Diagram 1. CUDA Program Counter Sampling

Sampling the program counter to find hot instructions

Description: Nsight Compute samples the program counter and highlights hot kernel instructions with minimal overhead. This is your first tool in a production investigation: localize the hot spot with PC Sampling, and only if it points to a specific kernel, launch a full Nsight Systems trace.

PyTorch Profiler

PyTorch Profiler, based on the Kineto library, provides op-level breakdowns of CPU and CUDA/GPU runtimes. It records tensor shapes, memory snapshots, and supports trace export to Chrome Tracing / Perfetto for collaborative analysis.

with torch.profiler.profile(
    activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
    record_shapes=True,
    profile_memory=True,
    with_stack=True
) as prof:
    with profiler.record_function("train_step"):
        torch.cuda.nvtx.range_push("forward")
        outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
        loss = outputs.loss
        torch.cuda.nvtx.range_pop()

        torch.cuda.nvtx.range_push("backward")
        loss.backward()
        torch.cuda.nvtx.range_push("optimizer_step")
        optimizer.step()
        torch.cuda.nvtx.range_pop()
        optimizer.zero_grad()
        torch.cuda.nvtx.range_pop()

print(prof.key_averages().table(
    sort_by="self_cuda_time_total",
    row_limit=10,
    fields=["self_cuda_time_total", "calls"]
))
Block 03 Summary
Key point of the chapter

Profiling is a two-stage process: Nsight Systems for the big picture and finding hot kernels, Nsight Compute for detailed analysis. NVTX annotations make the timeline readable.

Practical consequence

PyTorch Profiler (based on Kineto) provides op-level breakdown and supports export to Chrome Tracing / Perfetto. PC Sampling in Nsight Compute allows localizing hot instructions with minimal overhead.

• • •
Block 04 · Monitoring

Monitoring: Prometheus, Grafana, and DCGM

In production, continuous monitoring is more important than ad-hoc profiling. The Prometheus + Grafana + DCGM stack is the de facto standard for GPU clusters.

Diagram 2. DCGM, Prometheus, Grafana

Metric flow from GPU nodes to dashboards

DCGM Prometheus Grafana
Description: DCGM collects metrics from Kubernetes GPU nodes, Prometheus aggregates them, Grafana visualizes in real time. For vLLM workloads, GPU utilization is normally high (80–95%); a sudden drop to 0% indicates the serving process crashed, while a sustained drop to 30–40% indicates a traffic routing issue.

Key GPU Metrics

MetricDCGM counterMeaning
SM utilizationDCGM_FI_DEV_GPU_UTILPercentage of time SMs are busy
Copy engine loadDCGM_FI_DEV_MEM_COPY_UTILMemory copy engine activity
Memory usageDCGM_FI_DEV_FB_USEDFramebuffer memory occupied
TemperatureDCGM_FI_DEV_GPU_TEMPGPU temperature
Power drawDCGM_FI_DEV_POWER_USAGEPower in watts
ECC errorsDCGM_FI_DEV_ECC_*Correctable and uncorrectable errors
NVLink errorsDCGM_FI_DEV_NVLINK_*Replays, CRC, link recovery

Application-Level Metrics

  • Requests per second (RPS) — the primary load indicator.
  • Average latency, p95, p99 — for SLO compliance.
  • Active context count — how many concurrent sessions are served.
  • Throughput in tokens/s — real generation speed.
  • KV-cache usage and size (overall and per node).
  • Prefix cache hit rate — vllm:gpu_prefix_cache_queries and vllm:gpu_prefix_cache_hits in vLLM.
  • KV-cache preemption frequency — if it grows, GPU memory is insufficient.

Alertmanager Alerts

MetricConditionSeverityNotes
GPU utilization< 10% for 60 sIdleUnderutilization
GPU utilization> 90%BottleneckPossible saturation
Memory usage> 80%WarningApproaching OOM
Memory usage> 95%CriticalHigh OOM risk
Temperature> 85 °CWarningApproaching throttling
Temperature> 95 °CCriticalDamage risk
NVLink errors (replay)≥ 1CriticalLink problem
NVLink CRC errors> 100/sCriticalLink degradation
Uncorrectable ECC errors≥ 1CriticalData corruption

The numerical values are indicative. Actual thresholds depend on your GPU architecture, cooling conditions, and SLO. Set them based on baseline measurements.

Metric Correlation

  • RPS + p99 latency: does a latency spike coincide with a traffic spike? Dynamic batching may be increasing batch size and latency.
  • SM utilization + copy engine load: SM idle, copy engine busy? The engine is likely swapping KV cache — GPU memory is insufficient.
  • NCCL error counter + per-node GPU utilization: one node at 0%, others at 90%? Look for NCCL_COMM_FAILURE in logs.
  • Prefix cache hit rate + TTFT: does a hit-rate drop coincide with time-to-first-token growth? The cache may be too small.

Logs: What to Monitor

Example vLLM log indicating KV-cache preemption:

WARNING 2025-05-03 14:22:07 scheduler.py:1057 Sequence group 0 is preempted by
PreemptionMode.RECOMPUTE because not enough KV cache space.
total_cumulative_preemption_cnt=1

This means the engine ran out of memory for the KV cache and evicted an active sequence. Result: KV recomputation on rescheduling, extra compute, and latency growth. If such messages appear regularly: raise the GPU memory threshold, reduce max batched tokens, enable PagedAttention, or consider KV-cache quantization.

Block 04 Summary
Key point of the chapter

Continuous monitoring through Prometheus + Grafana + DCGM is the de facto standard for GPU clusters. Key metrics: SM utilization, memory usage, latency percentiles, cache hit rate.

Practical consequence

Metric correlation (RPS + p99, SM + copy engine, NCCL errors + GPU utilization) allows rapid localization of the root cause.

• • •
Block 05 · Troubleshooting

Troubleshooting Recipes

SymptomLikely causeRecommended action
SM utilization < 50%Small batches or missing fused kernelsIncrease batch size, enable FlashAttention, add fused kernels, profile via nsys --trace=cuda
KV-cache preemption warningsInsufficient KV-cache spaceRaise GPU memory threshold, reduce max batch tokens, enable PagedAttention
High tail latency (p95 > 200 ms)Decode hot spot or head-of-line blockingCheck router logs, tune prefetch threshold, enable speculative decoding
Cache hit rate < 60%Unbalanced sharding or missing prefix cacheCheck prefix cache configuration (LMCache, NIXL), increase TTL, add replicas
Unexpected OOMGPU memory overloadReduce per-instance memory, enable CPU/NVMe offload, pin processes to sockets
Irregular spikesThermal throttling or inconsistent clocksSynchronize clocks, monitor temperature, lock clock via nvidia-smi -lgc

Correctness Debugging

  • CUDA memory leaks: memory usage grows monotonically. Use compute-sanitizer --tool memcheck your_binary to detect memory errors, data races, and out-of-bounds.
  • NCCL failures: one GPU shows 0% utilization, others 90%. Enable NCCL_DEBUG=WARN for detailed logs. Use ncclCommGetAsyncError with ncclCommAbort to detect and handle async errors.
  • Hardware errors: ECC errors, NVLink replays, PCIe replays. Any uncorrectable ECC error warrants immediate alerting and node replacement scheduling.
Block 05 Summary
Key point of the chapter

Inference troubleshooting is a systematic process: from symptom to likely cause and concrete action. The recipes table covers typical scenarios.

Practical consequence

For correctness debugging, use compute-sanitizer, NCCL_DEBUG, and monitoring of hardware error counters.

• • •
Block 06 · Full-Stack Optimizations

Full-Stack Optimizations

High-performance inference requires coordinated optimizations at every level of the stack. A problem at only one level is luck. In reality, bottlenecks migrate between levels as they are removed.

Stack levelKey techniques
ModelPruning, distillation, sparsity (MoE), FlashAttention, quantization-aware training (QAT)
KernelFused ops (Linear + GELU + LayerNorm), FlashInfer, Tensor Cores, block tiling, async transfers (cp.async, TMA)
RuntimeDynamic/continuous batching, PagedAttention, CUDA Graphs, buffer pooling, multi-stream CUDA, event-based sync
OrchestrationPrefill/decode separation, intelligent routing, multi-tenancy isolation, autoscaling with warm reserves
DeploymentGeo-distributed edge serving, smart API gateways with batching, CI/CD for model variants, NVLink/NVSwitch, InfiniBand, NUMA affinity
QoS and scalingSLA-aware dynamic batching, MIG isolation, real-time profiling dashboards, dynamic parallelism switching (TP, PP, DP)

The key idea is cross-level synergies. Quantization (model) reduces memory consumption, allowing larger batch sizes (runtime) without OOM, which in turn lets orchestration pack more requests per GPU cycle. One optimization at a lower level can unlock several at higher levels.

Block 06 Summary
Key point of the chapter

Full-stack optimizations are a necessary condition for high-performance inference. Bottlenecks migrate between levels as they are removed.

Practical consequence

Keep the software stack up to date. New versions of CUDA, cuDNN, NCCL, Transformer Engine contain optimizations unavailable in older versions.

• • •
Block 07 · Batching

Dynamic Batching and Scheduling

Static vs Dynamic vs Continuous

Static batching fixes the batch size, pads all sequences to the longest one, and waits for each request to complete before returning. Result: unbounded latency for early arrivals and wasted GPU cycles on padding.

Dynamic batching assembles batches on the fly. The system accumulates incoming requests within a short timeout (typically 2–10 ms) or until a target batch size is reached, then sends the batch to the GPU.

Diagram 3. Static vs Dynamic Batching

Accumulating requests vs starting immediately with what arrived

Static batching — waits for full batch Dynamic batching — starts immediately
Description: Static batching accumulates requests to a fixed size; dynamic sends what arrived within a short timeout. At low RPS, dynamic batching adds a small latency penalty — requests wait in the queue hoping others will join. At moderate and high RPS, the latency is amortized: more work is done in the same time, and total queue wait decreases.
AspectStaticDynamicContinuous
TriggerFixed sizeSize target or timeoutToken completion event
Latency boundUnboundedBounded by max_batch_delay_msMinimal
PaddingHighModerateLow
GPU idle timePoorBetterExcellent
ComplexitySimpleModerateComplex

Continuous batching (batching in-flight, iteration-level scheduling) is the next step. Instead of waiting for full sequences to complete, the system refills the batch at every token generation iteration. Finished requests are evicted, new ones immediately take their slots.

Diagram 4. Continuous Batching

Finished sequences leave, new ones slide in mid-generation

GPU batch (iteration by iteration)
Description: Continuous batching: finished sequences leave the batch while new requests slide in mid-generation. Batching 4–8 requests often doubles or triples throughput compared to batches of 1–2, because GPU math units and memory pipelines are used better. The added per-request latency is on the order of a few milliseconds.

Continuous Scheduling

Continuous scheduling treats the GPU like an OS scheduler treats the CPU. If the model is small or the batch size is SLO-limited, a single model copy may not saturate the GPU. Then the engine launches multiple inference streams simultaneously on one GPU.

PagedAttention in vLLM is a concrete example. The KV cache is split into pages, and computation is dynamically grouped by page between active sequences. Under heavy load this yields nearly 100% GPU utilization.

Chunked Prefill

When prompts are very long (e.g., 20,000 tokens), you can split them into chunks and interleave prefill and decode work. This is called chunked prefill, or stall-free scheduling.

Chunk sizeChunk countAttention ops per chunkTotal MLP tokens
20K1200M20K
10K250M + 150M = 200M20K
5K412.5M + 37.5M + 62.5M + 87.5M = 200M20K

Key insight: chunking does not reduce the total number of attention operations. Self-attention performs N(N+1) ÷ 2 Q × K dot products per layer per head — cost is quadratic in N, O(N²). Chunking only changes when work becomes available to the decoder. The benefit is latency smoothing and better overlap, not reduced compute.

Latency-Aware Scheduling

A naive FIFO scheduler can overload one GPU if arrival order is suboptimal. Consider six prompts with lengths 6K, 2K, 6K, 2K, 2K, 2K and two GPUs.

  • FIFO: Batch 1 = [6K, 2K, 6K] → GPU 1 (≈38M Q×K ops), Batch 2 = [2K, 2K, 2K] → GPU 2 (≈6M). Critical path is GPU 1.
  • Latency-aware: Batch 1 = [2K, 2K, 6K] → GPU 1 (≈22M), Batch 2 = [2K, 2K, 6K] → GPU 2 (≈22M). Critical path drops by 42%.
Block 07 Summary
Key point of the chapter

Continuous batching and chunked prefill are key techniques for maximizing throughput while maintaining low latency. Latency-aware scheduling reduces the critical path by 42% in the six-prompt example.

Practical consequence

Chunking does not reduce the total number of attention operations — it only smooths latency and improves overlap.

• • •
Block 08 · System Optimizations

System Optimizations

Overlapping Communication and Computation

In distributed inference, overlapping communication with computation is a critical performance factor. Systems like GB200/GB300 NVL72 deliver up to ~130 TB/s aggregate NVLink bandwidth within a rack, but even at such speeds synchronous communication creates bubbles.

A baseline technique is separate CUDA streams for transfer and compute:

cudaStream_t transfer_stream, compute_stream;
cudaStreamCreate(&transfer_stream);
cudaStreamCreate(&compute_stream);

// Transfer on transfer_stream
cudaMemcpyAsync(h_logits, d_logits, bytes, 
                cudaMemcpyDeviceToHost, transfer_stream);

// Compute on compute_stream — overlaps with transfer
my_kernel<<<grid, block, 0, compute_stream>>>(...);

// Sync only when data is needed
cudaEventSynchronize(transfer_done_event);

Always use page-locked (pinned) host buffers for PCIe or NIC transfers — the CUDA driver can DMA directly and overlap with computation.

For MoE models, all-to-all can be overlapped by splitting the token batch in half: while the first half is processed by experts, the second is being sent. By the time the first half completes, the second half has arrived at receiving GPUs.

GPUDirect RDMA lets network adapters (InfiniBand NICs) read and write GPU memory directly, bypassing host memory. This reduces cross-node KV-cache or expert activation transfer latency and frees CPU cores.

CUDA Graphs capture asynchronous patterns and reduce kernel launch overhead — especially useful for repetitive decoding patterns.

Power and Thermal Limits

Continuous 100% GPU operation will cause thermal throttling if cooling is insufficient. Sometimes running at 90% with efficient kernels beats 100% with throttling.

  • Lock clocks via nvidia-smi -lgc — slightly reduces throughput but ensures stability.
  • A small delay between batches to reduce utilization.
  • Liquid cooling — standard for modern data-center GPUs.
  • Raise the power limit via nvidia-smi -pl (if cooling is adequate).

Memory Management

Paged KV cache (PagedAttention in vLLM) splits the KV cache into pages and dynamically allocates them between sequences. This eliminates the memory fragmentation inherent in fixed-allocation approaches.

KV-cache offload (swap) to CPU memory or NVMe is an option for rarely used data. LMCache in vLLM lets you tune the GPU/CPU cache ratio. RadixAttention in SGLang lazily evicts least-recently-used prefixes.

However, offload is not free: at high swap frequency, copy engine load rises while SM utilization drops. If you see a copy engine spike with a simultaneous SM drop — the system is swapping. Solutions: apply FP8/FP4 quantization to shrink KV size, increase GPU memory allocated to the cache, change the swap strategy.

Block 08 Summary
Key point of the chapter

Overlapping communication and computation is a critical factor for distributed inference performance. GPUDirect RDMA and CUDA Graphs help hide transfer latencies.

Practical consequence

Memory management via PagedAttention, LMCache, and RadixAttention eliminates fragmentation and enables serving more concurrent requests.

• • •
Block 09 · Quantization

Quantization for Real-Time Inference

Precision Spectrum

FormatBits per elementSpeedup vs FP32Memory footprint vs FP32Notes
FP32321×1×Baseline precision
TF3219 (10-bit mantissa)~1.5×1×Tensor Cores only
FP16/BF16162×0.5×Inference standard
FP8 (E4M3/E5M2)84×0.25×Requires calibration
INT448× (theoretical)0.125×Weight-only quantization
FP4 (NVFP4)4 + block scales~8×~0.18× (with metadata)Requires micro-scaling

Diagram 5. Transformer Engine: Precision Conversion

Range analysis, scale selection, conversion to FP8/FP4

FP16 input range scale FP8 / FP4
Description: Transformer Engine analyzes the value range, selects a scale, and converts the tensor to FP8/FP4 while preserving accuracy. NVIDIA's FP4 implementation (NVFP4) uses block-wise microscaling in hardware, supported by TE.

Weight-Only Quantization: GPTQ and AWQ

Weight-only quantization compresses weights to 4-bit integers while keeping activations at higher precision (FP8, FP16). This reduces the weight memory footprint roughly 4× compared to FP16.

GPTQ applies an approximate second-order algorithm for layer-wise weight quantization to 3–4 bits in a few hours on GPU. For many models, 4-bit GPTQ retains 99%+ of FP16 accuracy with ~2× inference speedup.

AWQ (Activation-aware Weight Quantization) identifies a small fraction of "salient" weight channels that produce large activation magnitudes. AWQ applies per-channel scaling before quantizing weights to 4-bit precision.

Activation Quantization: SmoothQuant and W4A8

Activation quantization is harder because distributions vary widely across inputs. SmoothQuant is a PTQ method for 8-bit activation quantization without training. It shifts part of the quantization error from activations to weights via simple row/column scaling.

The hybrid W4A8 approach combines 4-bit weights (INT4) with 8-bit activations (FP8 or INT8). TensorRT-LLM and other engines provide this path with nearly no accuracy loss given proper calibration.

Practical Workflow

  1. Start with FP16/BF16 inference — this is the baseline.
  2. Evaluate 8-bit quantization (FP8 or INT8) — usually lossless.
  3. Apply 4-bit weight-only quantization (GPTQ or AWQ) — for additional compression.
  4. If maximum optimization is needed — move to W4A8 (INT4 weights + FP8 activations).
  5. Calibrate on data reflecting your real workload.
  6. A/B test quantized model responses against the original.
Block 09 Summary
Key point of the chapter

Quantization is one of the most effective ways to reduce inference cost. GPTQ and AWQ for 4-bit weights, SmoothQuant for 8-bit activations, W4A8 for maximum optimization.

Practical consequence

Always validate accuracy on downstream tasks and perform A/B testing. 4-bit weight quantization retains 99%+ accuracy for many models.

• • •
Block 10 · Application Level

Application-Level Optimizations

Prompt Compression

Transformer attention has time complexity O(n²), where n is input size in tokens. Reducing a prompt from 10,000 to 5,000 tokens cuts self-attention work by 4×.

  • Redundancy removal: if a user prompt contains a large irrelevant text block, an upstream component can summarize or extract relevant parts.
  • Dialogue history compression: when exceeding 75% of max context, summarize the oldest 25% of messages.
  • Special tokens: a 200-token system prompt can be replaced by 10 special tokens if the model is fine-tuned to recognize them.
  • References instead of content: if a prompt references a previously stored document, replace the full content with a reference and handle via RAG.

Prefix Caching

Prefix caching (prefix memoization) is one of the most effective optimizations. If several requests share a common prefix (system prompt, document, dialogue history), the KV cache for the prefix is computed once and reused.

Without caching: N requests of length L require O(N × L) work. With caching: O(N + L) — the prefix is processed once, each request only adds its unique suffix.

Diagram 6. Prefix Cache as a Trie

Each node is a token, green highlighting shows shared prefix reuse

"You are ChatGPT, a friendly assistant..."
Description: Prefix cache is stored as a trie: each node is a token, green highlighting shows shared prefix reuse. In vLLM it's enabled via enable_prefix_caching=True. The engine checks whether the first N tokens of an incoming prompt match an already cached prefix, and if so, copies KV cache data instead of recomputing.

Diagram 7. Prefix Cache Evolution

New nodes, active nodes, LRU eviction

Description: Green — new nodes, blue — actively used, evicted by LRU under memory pressure. A high prefix cache hit rate (> 80%) means the system is effectively reusing data. With a miss rate > 40% you should: tune cache size, change the eviction policy (LRU, LFU), increase TTL, or check prefix matching logic.

Model Cascading

Not every request requires the largest model. Cascading routes simple requests to a smaller, faster model and complex ones to the large model.

  • Heuristic: short factual requests → small model. Long prompts or requests containing "explain", "analyze" → large model.
  • Speculative: run the small model, assess confidence. High confidence — return the answer. Low — call the large model.
  • Load-based: when the large-model cluster is saturated, route less critical requests to the small model.

Routing 60% of requests to a model 10× smaller can cut compute costs by ~5×.

Streaming Output

The model generates tokens one at a time (except for speculative decoding like EAGLE and multi-head decoding like Medusa). The system groups tokens into batches of 2–5, flushes the stream, and sends via SSE/WebSockets/HTTP Streaming.

Humans read at 4–13 tokens per second. Without streaming, the user stares at a blank screen for 5 seconds, then receives the whole answer at once. With streaming, the first batch of tokens arrives in 0.25 seconds — and the user starts reading immediately.

Technical details: TCP_NODELAY to minimize latency; thread-safe queues for passing tokens to the network thread; flow control; HTTP/2 and persistent connections.

Diagram 8. Debouncing Clicks

Short pause after a burst of clicks before sending a request

User clicks 2 ms Reply
Description: Debouncing waits for a short pause after a burst of clicks and sends only one request, discarding duplicates. Request coalescing combines similar requests. Token limits and timeouts prevent runaway generation.
Block 10 Summary
Key point of the chapter

Application-level optimizations — prompt compression, prefix caching, model cascading, streaming output — deliver significant gains without changing the model or hardware.

Practical consequence

Prefix caching turns O(N × L) work into O(N + L). Prompt compression reduces self-attention work quadratically.

• • •
Block 11 · Forecast Verification

Forecast Verification and Current Data

Fregly's book was written in 2025, when the inference stack was rapidly evolving. Below is a comparison of Chapter 16's forecasts with open data.

Confirmed Forecast 1: monitoring via DCGM + Prometheus + Grafana

«DCGM collects metrics from Kubernetes GPU nodes, Prometheus aggregates them, Grafana visualizes».

Confirmed. DCGM Exporter became the de facto standard for GPU observability in Kubernetes. For vLLM workloads, DCGM metrics integrate with Prometheus recording rules for cost calculation. AIPerf and other tools include DCGM/pynvml metrics in benchmark outputs.

Confirmed Forecast 2: continuous batching as the standard

«Continuous batching: finished sequences leave the batch, new ones slide in mid-generation».

Confirmed. Continuous batching is implemented in vLLM, SGLang, TensorRT-LLM and has become the standard for production inference. PagedAttention in vLLM and RadixAttention in SGLang provide dynamic KV-cache management.

Confirmed Forecast 3: chunked prefill and stall-free scheduling

«Chunked prefill: split long prompts into chunks and interleave prefill and decode work».

Confirmed. Chunked prefill is implemented in vLLM as stall-free scheduling. Recommended parameters: --enable-chunked-prefill --max-num-batched-tokens 2048. This prevents short requests from being blocked by long prefills.

Confirmed Forecast 4: GPTQ and AWQ as the quantization standard

«GPTQ and AWQ for 4-bit weights retain 99%+ of FP16 accuracy with ~2× speedup».

Confirmed. GPTQ and AWQ are integrated into Hugging Face Transformers, vLLM, TensorRT-LLM. W4A8 (INT4 weights + FP8 activations) has become the standard path for maximum optimization. SmoothQuant provides 8-bit activation quantization.

Confirmed Forecast 5: prefix caching

«Prefix caching turns O(N × L) work into O(N + L)».

Confirmed. Prefix caching is implemented in vLLM (enable_prefix_caching=True) and SGLang (RadixAttention). For workloads with shared system prompts or dialogue history, it provides multiplicative speedup.

Confirmed Forecast 6: overlapping communication and computation

«Separate CUDA streams for transfer and compute; GPUDirect RDMA; CUDA Graphs».

Confirmed. Overlap of communication and computation is standard practice. GPUDirect RDMA is used for cross-node KV-cache transfers. CUDA Graphs are integrated into inference engines. NVIDIA Dynamo uses NIXL for asynchronous KV-cache transfer with overlap.

• • •
Block 12 · Additional Conclusions

Additional Conclusions

  1. Inference performance is not just kernel speed. Chapter 16 shows that inference system performance is determined by the combination of scheduling efficiency, memory management, request handling, and monitoring. Optimizing only one level yields limited effect.
  2. Monitoring and profiling are the foundation of operations. Without systematic metric collection (DCGM, Prometheus, Grafana) and profiling (Nsight Systems, Nsight Compute, PyTorch Profiler), bottlenecks cannot be identified. Tools must be integrated into CI/CD and production dashboards.
  3. Continuous batching and chunked prefill are key techniques. They maximize throughput while maintaining low latency. Continuous batching combined with PagedAttention and chunked prefill have become the standard for production inference.
  4. Quantization is the most effective way to reduce cost. GPTQ, AWQ, SmoothQuant, and W4A8 reduce memory consumption and increase throughput without significant accuracy loss. Start with FP8, then move to 4-bit weights.
  5. Application-level optimizations are underappreciated. Prompt compression, prefix caching, and streaming output deliver significant gains with minimal implementation cost. They do not require model or hardware changes.
  6. Overlapping communication and computation is critical for scaling. GPUDirect RDMA, CUDA Graphs, and separate CUDA streams hide data transfer latencies behind computations.
  7. QoS and early rejection are necessary at scale. Under cluster overload, it is better to quickly reject low-priority requests than to allow latency degradation for all. Mooncake and similar systems implement admission control based on latency prediction.
• • •
Block 13 · Key Points

Key Points

  1. Profiling is a two-stage process. Nsight Systems for the big picture and finding hot kernels, Nsight Compute for detailed analysis. NVTX annotations make the timeline readable.
  2. Monitoring via Prometheus + Grafana + DCGM. Key metrics: SM utilization, memory usage, latency percentiles, cache hit rate. Metric correlation allows rapid localization of the root cause.
  3. Troubleshooting is a systematic process. The recipes table covers typical scenarios: low SM utilization, KV-cache preemptions, high tail latency, OOM.
  4. Full-stack optimizations. Bottlenecks migrate between levels. Optimizations at the model, kernel, runtime, orchestration, and deployment levels complement each other.
  5. Continuous batching and chunked prefill. Continuous batching maximizes throughput. Chunked prefill prevents short requests from being blocked by long ones.
  6. Latency-aware scheduling. Reduces the critical path by 42% in the six-prompt example.
  7. Overlapping communication and computation. Separate CUDA streams, GPUDirect RDMA, and CUDA Graphs hide data transfer latencies.
  8. Memory management. PagedAttention, LMCache, and RadixAttention eliminate fragmentation and enable serving more concurrent requests.
  9. Quantization. GPTQ and AWQ for 4-bit weights, SmoothQuant for 8-bit activations, W4A8 for maximum optimization. Start with FP8, calibrate on real data.
  10. Prompt compression and prefix caching. Compression reduces self-attention work quadratically. Prefix caching turns O(N × L) into O(N + L).
  11. Model cascading. Routing 60% of requests to a model 10× smaller cuts costs by ~5×.
  12. Streaming output. TCP_NODELAY, thread-safe queues, HTTP/2. First batch of tokens in 0.25 seconds instead of 5 seconds of waiting.
  13. QoS and early rejection. Under overload, quickly reject low-priority requests to preserve latency for others.
Overall Review Summary

Chapter 16 of Fregly's book is a systematic guide to profiling, debugging, and tuning LLM inference at scale. The key idea: inference system performance is a multi-level task spanning monitoring, scheduling, memory management, and application-level optimization. For an engineer, this means that understanding profiling methodology and the principles behind each tool is more important than knowing specific numbers of the current generation.

Forecast verification shows: the book proved accurate in its predictions. DCGM + Prometheus + Grafana became the monitoring standard. Continuous batching, chunked prefill, GPTQ/AWQ, prefix caching, and overlap of communication with computation — all these techniques are implemented in production engines (vLLM, SGLang, TensorRT-LLM, NVIDIA Dynamo). The main takeaway remains unchanged: investments in profiling and monitoring methodology ensure adaptation to any stack.

Sources: Chris Fregly, «AI Systems Performance Engineering» (O'Reilly, 2026), Chapter 16 — quotes provided in limited volume for review and critical analysis purposes. NVIDIA Nsight Systems, Nsight Compute, DCGM, vLLM, SGLang, TensorRT-LLM documentation; NVIDIA Dynamo Documentation; MLPerf Training/Inference v5.0; Red Hat Developer «Deploying distributed AI inference: Blueprints & troubleshooting» (2026); NVIDIA Technical Blog «Benchmarking LLM Inference at Scale with AIPerf» (2026).