0Pricing
AI Engineering Academy · Lekcja

Pomiar opóźnienia LLM: TTFT i TPOT

Zdefiniuj time to first token i time per output token jako dwa kluczowe wskaźniki opóźnienia, dodaj do aplikacji instrumentację mierzącą oba i ustal docelowe wartości SLA dla poszczególnych endpointów.

Pomiar opóźnienia LLM: TTFT i TPOT to bezpłatna lekcja AI Engineering Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Engineering Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.

Dlaczego opóźnienie LLM ma dwa składniki

Pomiar opóźnienia LLM jako jednej wartości może być mylący. W rzeczywistości występują dwie odrębne fazy: czas do nadejścia pierwszego tokenu (postrzegana responsywność) oraz czas generowania kolejnych tokenów (szybkość generowania). Model może mieć świetne TTFT, ale niskie TPOT, przez co długie odpowiedzi wydają się powolne, mimo że początkowa reakcja była natychmiastowa.

TTFT: czas do pierwszego tokenu

Time to First Token (TTFT) to czas od wysłania żądania API do otrzymania pierwszego tokenu odpowiedzi. Obejmuje opóźnienie sieciowe, czas oczekiwania w kolejce serwera inferencji oraz czas prefill (przetwarzania tokenów wejściowych). TTFT w największym stopniu wpływa na postrzeganą responsywność — użytkownicy zauważają, gdy przez ponad 1–2 sekundy nic się nie pojawia, niezależnie od szybkości późniejszego strumieniowania tokenów.

import time
from openai import OpenAI

client = OpenAI()

def measure_ttft(prompt: str) -> float:
    start = time.perf_counter()
    first_token_time = None
    stream = client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}],
        stream=True
    )
    for chunk in stream:
        if chunk.choices[0].delta.content:
            first_token_time = time.perf_counter()
            break  # stop after first token
    return first_token_time - start

TPOT: czas na token wyjściowy

Time Per Output Token (TPOT) to średni czas między kolejnymi tokenami po rozpoczęciu generowania. Oblicza się go jako całkowity czas generowania podzielony przez całkowitą liczbę tokenów wyjściowych. TPOT określa szybkość czytania — ludzie czytają z prędkością około 250 słów na minutę, dlatego TPOT powyżej 100 ms na token (10 tokenów na sekundę) będzie wyraźnie odczuwalnie powolny w przypadku długich odpowiedzi.

import time
from openai import OpenAI

client = OpenAI()

def measure_tpot(prompt: str) -> dict:
    start = time.perf_counter()
    first_token_time = None
    token_count = 0
    stream = client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}],
        stream=True
    )
    for chunk in stream:
        delta = chunk.choices[0].delta.content or ''
        if delta:
            if first_token_time is None:
                first_token_time = time.perf_counter()
            token_count += 1
    end = time.perf_counter()
    ttft = first_token_time - start
    generation_time = end - first_token_time
    tpot = generation_time / max(token_count, 1)
    return {'ttft_ms': ttft * 1000, 'tpot_ms': tpot * 1000, 'tokens': token_count}

Łączne opóźnienie a TTFT i TPOT

Zależność między tymi metrykami przedstawia wzór: total_latency = TTFT + (output_tokens × TPOT). Dla odpowiedzi zawierającej 500 tokenów przy TPOT wynoszącym 50 ms generowanie trwa 25 sekund. W aplikacjach strumieniowych należy najpierw optymalizować TTFT — użytkownicy lepiej tolerują powolne strumieniowanie niż pusty ekran. W przetwarzaniu wsadowym bez strumieniowania liczy się łączne opóźnienie, dlatego należy optymalizować TPOT, wybierając modele o szybszej inferencji.

# Latency breakdown for a 200-token response
ttft_ms = 450       # half a second to first token
tpot_ms = 25        # 25ms per token = 40 tokens/sec
output_tokens = 200

total_latency = ttft_ms + (tpot_ms * output_tokens)
print(f'TTFT:  {ttft_ms}ms')
print(f'Generation: {tpot_ms * output_tokens}ms')
print(f'Total: {total_latency}ms ({total_latency/1000:.1f}s)')
# Output:
# TTFT:  450ms
# Generation: 5000ms
# Total: 5450ms (5.5s)

Czynniki wpływające na TTFT

Na TTFT największy wpływ ma koszt prefill, który rośnie wraz z liczbą tokenów wejściowych. Prompt systemowy zawierający 10 000 tokenów będzie miał 10 razy wyższy TTFT niż prompt zawierający 1000 tokenów, przy pozostałych warunkach bez zmian. Inne czynniki to obciążenie serwera (czas oczekiwania w kolejce), czas podróży w obie strony do punktu końcowego API oraz to, czy buforowanie promptu zmniejsza efektywną pracę prefill. Aby zmniejszyć TTFT, należy ograniczyć długość promptu systemowego.

# TTFT scales approximately linearly with input tokens
# Measured typical values for gpt-4o (2026):
# 500 input tokens:   ~400ms TTFT
# 2000 input tokens:  ~600ms TTFT
# 10000 input tokens: ~1500ms TTFT
# 32000 input tokens: ~4000ms TTFT

# Use prompt caching to avoid paying for repeated long prefixes:
# Cached tokens: ~200ms saved per 1000 cached tokens

Czynniki wpływające na TPOT

TPOT zależy przede wszystkim od rozmiaru modelu i sprzętu. Mniejsze modele (GPT-4o-mini) dekodują znacznie szybciej niż duże modele (GPT-4o). W przypadku modeli hostowanych samodzielnie głównymi czynnikami są rozmiar partii i przepustowość pamięci GPU. W przypadku modeli hostowanych przez OpenAI TPOT zmienia się wraz z obciążeniem serwera, ale zazwyczaj wynosi 15–40 ms na token. Nie można bezpośrednio kontrolować TPOT w hostowanych interfejsach API — głównym narzędziem pozostaje wybór modelu.

# Typical TPOT benchmarks (approximate, 2026):
# gpt-4o-mini:   15-20ms per token (50-65 tokens/sec)
# gpt-4o:        25-40ms per token (25-40 tokens/sec)
# claude-3.5-haiku: 20-25ms per token
# claude-3.5-sonnet: 30-50ms per token
# local llama-3.1-8B on A100: 8-12ms per token
# local llama-3.1-70B on 4xA100: 25-35ms per token

Ustalanie celów SLA dla poszczególnych punktów końcowych

Nie wszystkie endpointy wymagają takiego samego docelowego opóźnienia. Endpoint czatu ma rygorystyczny SLA dla TTFT (użytkownicy oczekują wartości <500 ms), podczas gdy endpoint do podsumowywania wsadowego może tolerować opóźnienie rzędu kilku sekund. Należy zdefiniować wyraźne cele SLA dla każdego endpointu i mierzyć każdy z nich osobno. Typowe cele: czat interaktywny = p95 TTFT <600 ms, ekstrakcja danych z dokumentów = całkowity p95 <10 s, przetwarzanie wsadowe = brak SLA czasu rzeczywistego.

SLA_TARGETS = {
    'chat':       {'ttft_p95_ms': 600,  'total_p95_ms': 8000},
    'extraction': {'ttft_p95_ms': 1500, 'total_p95_ms': 10000},
    'summary':    {'ttft_p95_ms': 2000, 'total_p95_ms': 30000},
    'batch':      {'ttft_p95_ms': None, 'total_p95_ms': None},
}

Rejestrowanie metryk opóźnienia

Rejestruj TTFT i TPOT dla każdego żądania produkcyjnego za pomocą logowania strukturalnego. Uwzględniaj nazwę modelu, endpoint, liczbę tokenów promptu, liczbę tokenów wyjściowych oraz informację, czy nastąpiło trafienie do pamięci podręcznej. Dzięki temu możesz obliczać rozkłady percentylowe (p50, p95, p99), wykrywać regresje po aktualizacjach modeli oraz korelować skoki opóźnienia z długością kolejki lub incydentami u dostawcy.

import structlog

log = structlog.get_logger()

def log_latency(endpoint: str, model: str, metrics: dict):
    log.info(
        'llm_latency',
        endpoint=endpoint,
        model=model,
        ttft_ms=round(metrics['ttft_ms'], 1),
        tpot_ms=round(metrics['tpot_ms'], 1),
        output_tokens=metrics['tokens'],
        total_ms=round(metrics['ttft_ms'] + metrics['tpot_ms'] * metrics['tokens'], 1)
    )

Obliczanie percentyli na podstawie próbek

Surowe średnie wprowadzają w błąd w przypadku opóźnień — kilka powolnych wartości odstających zawyża średnią, nie wpływając na większość użytkowników. Zawsze raportuj percentyle p50, p95 i p99. P95 to najczęściej używana metryka SLA: oznacza, że 95% żądań zostało ukończonych w podanym czasie. Użyj NumPy lub modułu statistics, aby obliczać percentyle na podstawie zarejestrowanych próbek opóźnienia.

import numpy as np

def compute_percentiles(samples: list, label: str = 'latency_ms'):
    arr = np.array(samples)
    stats = {
        'count': len(arr),
        'p50': np.percentile(arr, 50),
        'p95': np.percentile(arr, 95),
        'p99': np.percentile(arr, 99),
        'mean': np.mean(arr),
        'max': np.max(arr)
    }
    print(f'{label}:')
    for k, v in stats.items():
        print(f'  {k}: {v:.1f}')
    return stats

Zmniejszanie opóźnienia za pomocą max_tokens

Ustawienie odpowiedniego limitu max_tokens zmniejsza maksymalne całkowite opóźnienie, zapobiegając generowaniu nadmiernie długich odpowiedzi. Jeśli w danym zastosowaniu odpowiedzi mają mieć najwyżej 200 tokenów, ustaw max_tokens=250. Ogranicza to również koszty. Połącz to ze strumieniowaniem, aby użytkownicy od razu widzieli dane wyjściowe, podczas gdy pełna odpowiedź jest nadal generowana. W produkcyjnych endpointach nigdy nie pozostawiaj max_tokens bez limitu.

response = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': question}],
    max_tokens=300,  # cap at 300 tokens
    stream=True
)

# With max_tokens=300 and TPOT=30ms:
# worst-case total generation = 9000ms
# Without limit: could run to 4096+ tokens = 123s+

Priorytety optymalizacji opóźnienia

Gdy opóźnienie jest zbyt wysokie, usuwaj wąskie gardła w określonej kolejności. Po pierwsze, włącz strumieniowanie, aby użytkownicy od razu widzieli dane wyjściowe, nawet jeśli całkowite opóźnienie pozostaje wysokie. Po drugie, skróć prompt systemowy, aby zmniejszyć TTFT. Po trzecie, dodaj buforowanie prefiksu promptu, aby rozłożyć koszt prefill na wiele powtarzających się żądań. Po czwarte, przełącz się na mniejszy model, jeśli pozwala na to jakość. Na koniec rozważ wnioskowanie self-hosted, aby uzyskać maksymalną kontrolę zarówno nad TTFT, jak i TPOT.

# Latency optimization checklist (in priority order):
# 1. Enable streaming (perceived latency: immediate)
# 2. Shorten system prompt by 50% (TTFT: -20%)
# 3. Enable prompt prefix caching (TTFT: -40% on cache hits)
# 4. Downgrade to gpt-4o-mini for simple queries (TPOT: -40%)
# 5. Self-host llama-3.1-8B for high-volume simple queries
#    (TPOT: 8ms vs 25ms; TTFT: 100ms vs 450ms)

Szybki sprawdzian

Sprawdź swoją wiedzę na temat TTFT i TPOT jako metryk opóźnienia LLM.

Podsumowanie lekcji

W tej lekcji poznano: TTFT (Time to First Token) mierzy postrzeganą responsywność i rośnie wraz z liczbą tokenów wejściowych, TPOT (Time Per Output Token) określa szybkość generowania i zależy głównie od rozmiaru modelu, a cele SLA dla poszczególnych endpointów wraz z metrykami percentylowymi są właściwym sposobem monitorowania opóźnienia w środowisku produkcyjnym. W następnej części zaimplementujemy równoważenie obciążenia między wieloma kluczami API.

Często zadawane pytania

Czy lekcja „Pomiar opóźnienia LLM: TTFT i TPOT” jest bezpłatna?

Tak — pełny tekst „Pomiar opóźnienia LLM: TTFT i TPOT” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Engineering Academy, przejdź na CoddyKit PRO. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Pomiar opóźnienia LLM: TTFT i TPOT”?

Zdefiniuj time to first token i time per output token jako dwa kluczowe wskaźniki opóźnienia, dodaj do aplikacji instrumentację mierzącą oba i ustal docelowe wartości SLA dla poszczególnych endpointó… Ćwiczysz AI Engineering Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Engineering Academy?

Nie wymagamy żadnego doświadczenia. AI Engineering Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Pomiar opóźnienia LLM: TTFT i TPOT”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Engineering Academy?

Tak. Każda lekcja AI Engineering Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Pomiar opóźnienia LLM: TTFT i TPOT
  2. Równoważenie obciążenia i strategie wielu kluczy
  3. Dostawcy zapasowi i circuit breakers
  4. Budżety czasu oczekiwania i kontrolowana degradacja
← Powrót do AI Engineering Academy