Бенчмарк скорости LLM: реальное время ожидания vs pp/tg | Практический гайд 2026 | AiManual
AiManual Logo Ai / Manual.
07 Фев 2026 Гайд

Скорость LLM: Почему pp/tg вас обманывает и как тестировать реальное время ожидания

Полное руководство по тестированию реальной скорости LLM: как измерить время ожидания, автоматизировать бенчмаркинг и избежать ошибок pp/tg. Инструменты и метод

Проблема: Почему ваша модель "быстрая" в тестах и медленная на практике

Вы скачали свежую версию Llama 4 8B (да, на февраль 2026 она уже существует), запустили стандартный бенчмарк, получили 45 tokens/sec и радостно пошли показывать коллегам. А потом пользователь ждет ответ 8 секунд и спрашивает: "Это нормально?"

Вот в чем подвох: pp/tg (prompt processing / token generation) измеряет только активную генерацию. А реальное время ожидания включает:
1. Загрузку модели в память (если не держать постоянно)
2. Подготовку контекста
3. Сетевую задержку (для API)
4. Очередь запросов
5. И только потом - генерацию

Представьте, что вы тестируете автомобиль, измеряя только скорость на прямой. А потом едете по городу с пробками, светофорами и поиском парковки. Разница примерно такая же.

Решение: Измеряем не то, что легко, а то, что важно

Вместо pp/tg мы считаем E2E (end-to-end) время - от момента отправки промпта до получения полного ответа. Это то, что чувствует пользователь. Это то, что влияет на UX. Это реальная скорость.

💡
Ключевая идея: пользователю все равно, сколько токенов в секунду генерирует ядро модели. Ему важно, сколько секунд ждать ответа. Если модель загружается 15 секунд и генерирует со скоростью 100 tokens/sec - это хуже, чем модель, которая загружается мгновенно и генерирует 50 tokens/sec для типичных запросов.

Пошаговый план: Как тестировать реальную скорость

1 Подготовка тестового стенда

Сначала уберите все переменные. Те же настройки, что и в продакшене. Если в продакшене модель загружается при старте и живет в памяти - тестируйте так. Если перезагружается для каждого запроса - тестируйте так.

# Пример подготовки для llama.cpp
# НЕПРАВИЛЬНО (только генерация):
./main -m llama-4-8b.Q4_K_M.gguf -p "Тестовый промпт" --no-display-prompt

# ПРАВИЛЬНО (полный цикл с измерением):
time (echo "Тестовый промпт" | ./main -m llama-4-8b.Q4_K_M.gguf -n 256 --no-display-prompt)

Для облачных моделей (GPT-5, Claude 4, Gemini 2.5) добавьте сетевую составляющую. Используйте тот же регион, что и пользователи.

2 Создание реалистичного набора промптов

Не используйте один промпт. Создайте корпус из 50-100 запросов, которые отражают реальное использование:

  • Короткие запросы ("Переведи слово 'hello'")
  • Средние ("Напиши email коллеге о переносе встречи")
  • Длинные ("Проанализируй этот код и предложи оптимизации" + 200 строк кода)
  • Цепочки (несколько связанных запросов)

Если вы тестируете специализированную модель (кодирование, анализ документов), используйте соответствующие промпты. Универсальный совет по созданию тестовых промптов есть в статье "Промпт для сравнения LLM: как тестировать модели, а не свои вопросы".

3 Автоматизация измерений

Ручные замеры бесполезны. Нужен скрипт, который:

import time
import subprocess
from datetime import datetime

class LLMBenchmark:
    def __init__(self, model_path):
        self.model_path = model_path
        self.results = []
    
    def measure_e2e(self, prompt, max_tokens=256):
        """Измеряет полное время от отправки до получения"""
        start = time.time()
        
        # Здесь ваш код вызова модели
        # Для llama.cpp:
        cmd = [
            "./main",
            "-m", self.model_path,
            "-p", prompt,
            "-n", str(max_tokens),
            "--no-display-prompt"
        ]
        
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            check=True
        )
        
        end = time.time()
        total_time = end - start
        
        # Считаем реальные метрики
        output_text = result.stdout
        tokens_generated = len(output_text.split())  # упрощенно
        
        return {
            "total_time": total_time,
            "tokens": tokens_generated,
            "time_per_token": total_time / tokens_generated if tokens_generated > 0 else 0,
            "timestamp": datetime.now().isoformat()
        }

4 Запуск тестов в разных условиях

Один прогон - это не статистика. Запустите каждый промпт:

  1. 10 раз подряд (измерение стабильности)
  2. С холодным стартом (модель не в памяти)
  3. С горячим стартом (модель уже загружена)
  4. При разной нагрузке на систему

Для GPU-тестирования важны температурные режимы. Современные карты (RTX 5090, AMD 8900 XTX) троттлят при перегреве, и скорость падает на 20-30% после 10 минут непрерывной работы. Если вы тестируете на eGPU или нестандартных конфигурациях, посмотрите реальные цифры в статье "AMD 7900 XTX + ROCm: полный бенчмарк llama.cpp vs vLLM на eGPU".

5 Анализ результатов

Не усредняйте слепо. Посмотрите на распределение:

Метрика Что показывает Целевое значение
P95 total_time 95% запросов быстрее этого значения < 2 секунды для коротких ответов
Time to first token Сколько ждать начала ответа < 0.5 секунды
Cold start penalty Насколько медленнее холодный старт < 2x от горячего
Memory usage growth Утечки памяти при долгой работе Не более 5% за час

Типичные ошибки и как их избежать

Ошибка 1: Тестирование на "чистой" системе

В продакшене на сервере крутятся мониторинг, логи, бэкапы. Выделите 20% ресурсов на фоновые задачи при тестировании. Или тестируйте прямо на продакшен-сервере в часы минимальной нагрузки.

Ошибка 2: Игнорирование длины контекста

Модель с 128K контекстом (как Claude 4 или свежие версии Qwen 3 на начало 2026) ведет себя по-разному при 1K и 100K токенах. Если вы планируете работать с длинными документами, тестируйте именно такие сценарии. Подробнее о подводных камнях длинных контекстов - в материале "Когда 512k токенов — это не хвастовство, а боль".

Ошибка 3: Забыть про батчинг

Если вы обслуживаете несколько пользователей, посмотрите, как ведет себя модель при параллельных запросах. Некоторые реализации (особенно самописные) линейно замедляются. Другие (vLLM, TensorRT-LLM) хорошо масштабируются. Хотите понять разницу? Посмотрите, как работает батчевая обработка в самописном vLLM.

Важный нюанс на 2026 год: многие новые модели используют mixture-of-experts (MoE) архитектуру. Их скорость НЕЛИНЕЙНО зависит от промпта. Простые запросы летают, сложные - тормозят. Тестируйте оба сценария.

Готовые инструменты и автоматизация

Не пишите велосипеды. Используйте:

  • Locust или k6 - для нагрузочного тестирования API
  • Prometheus + Grafana - для мониторинга метрик в реальном времени
  • Встроенные бенчмарки в llama.cpp (с флагом --benchmark)
  • Специализированные фреймворки вроде lm-evaluation-harness (обновленная версия на 2026 поддерживает все актуальные модели)

Для полной автоматизации подбора параметров есть интересный подход с AI-агентом, который сам ищет оптимальные настройки. Если хотите сэкономить недели ручной настройки, посмотрите как автоматически настраивать llama.cpp.

Что делать с результатами

Вы получили цифры. И что теперь?

Если P95 total_time > 3 секунды для основных сценариев - пользователи будут раздражаться. Варианты:

  1. Выбрать другую модель (меньше параметров, другая архитектура)
  2. Оптимизировать загрузку (держать в памяти, использовать кэширование)
  3. Увеличить hardware (но сначала прочитайте про ограничения видеопамяти)
  4. Использовать streaming ответов (пользователь видит первые токены сразу)

Если cold start penalty > 5x - подумайте, можно ли держать модель загруженной. Или используйте предзагрузку при старте приложения.

Если разброс времени большой (одни запросы 0.5с, другие 10с) - возможно, проблема в конкретных типах промптов. Проанализируйте, какие медленные, и либо оптимизируйте их, либо предупредите пользователей.

Секрет профессиональных бенчмарков

Теперь вы понимаете, почему коммерческие провайдеры показывают красивые цифры pp/tg, а на практике все медленнее. Они тестируют в идеальных условиях. Вы же тестируете в реальных.

Хотите увидеть, как это делают (или не делают) в индустрии? Разбор методологий крупных компаний есть в статье "Как на самом деле проводят бенчмарки: коммерческие модели против локальных".

💡
Фишка: добавьте в тесты "плохие" промпты - с опечатками, на другом языке, бессвязные. В продакшене они будут, и модель может обрабатывать их дольше (больше времени на "понимание").

Дальнейшие шаги

Реальная скорость - только одна метрика. Дальше можно:

  1. Измерить энергоэффективность (токены на ватт) - особенно для мобильных и edge-устройств. Актуальные методики есть в гайде по оптимизации энергопотребления.
  2. Протестировать влияние PCIe версии на multi-GPU setups (актуально для серверных решений).
  3. Добавить измерение качества ответов (перплексия, точность) - потому что самая быстрая модель бесполезна, если она генерирует ерунду.

И помните: бенчмаркинг - не разовое мероприятие. Каждое обновление модели, каждой библиотеки (CUDA 13.5, ROCm 7.0, torch 3.5), каждого драйвера может изменить производительность на 10-30%. Сделайте тесты частью CI/CD.

Последний совет: если вы публикуете результаты сравнения моделей - показывайте не только pp/tg, но и P95 total_time для типичных сценариев. Это сделает ваши бенчмарки честными. И возможно, заставит индустрию двигаться в сторону измерения того, что действительно важно для пользователей.