본문 바로가기
C.W.K.
Lesson 04 of 07 · published

왜 90% 컨텍스트가 정직한 벤치마크인가

~15 min · llm-physics, context-curve, ttft, decode, benchmark, measured

Level 0스펙 시트 훑는 사람
0 XP0/91 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete
"의미 있는 벤치마크는 90% 컨텍스트에서의 디코드 초당 토큰과 첫 토큰까지 시간뿐이야. 그리고 아무도 그걸 공개하지 않아." — 아빠, 2026-08-26

빈 컨텍스트 숫자

네가 볼 거의 모든 초당 토큰 수치, 벤더 것이든 리뷰어 것이든 포럼 것이든, 짧은 프롬프트와 빈 캐시에서 잰 거야. 실험 트랙의 사다리도 그런 숫자고, 일부러 그래. 가중치를 분리해 주니까. 하지만 아무도 모델을 그렇게 쓰지 않아. 진짜 세션은 긴 시스템 프롬프트, 문서, 저장소, 대화를 지고 다녀. 쓸모 있는 첫 토큰이 나오기 전에 캐시는 이미 크고, 기계가 쓸 만한지를 정하는 두 숫자는 첫 토큰을 얼마나 기다리느냐(지금까지 것 전부의 프리필)와 답이 시작되면 얼마나 빨리 흘러나오느냐(꽉 찬 캐시로 디코드)야. 집주인의 규칙은 거의 꽉 찬 윈도우에서 둘 다 보고하지 않는 벤치마크는 워크로드를 재는 게 아니라는 거야. 이 레슨이 그걸 재.

곡선, 실측

office에서, 32,768토큰 윈도우, 그 10, 50, 90%에서의 프롬프트, 200토큰 생성, 캐시 대 가중치 비율을 가로지르도록 고른 모델 셋.

모델컨텍스트프롬프트 토큰TTFT프리필 tok/s디코드 tok/s피크 GB증거
Llama-3.2-1B (순수 GQA, 토큰당 32 KB)10%3,2540.56 s6,572343.61.63실측, office, 2026-09-15
50%16,3022.54 s6,562237.41.97실측
90%29,4065.82 s5,105208.52.38실측
Qwen3.5-9B (하이브리드, 토큰당 32 KB)10%3,2332.69 s1,27794.46.77실측
50%16,33713.12 s1,25986.38.13실측
90%29,38524.90 s1,18778.19.39실측
Qwen3.5-27B (하이브리드, 토큰당 64 KB)10%3,2338.96 s36732.318.21실측
50%16,33745.94 s35729.320.46실측
90%29,38590.38 s32627.522.57실측

두 곡선 읽기

디코드는 10%에서 90%로 가면서 1B는 39%, 9B는 17%, 27B는 15% 떨어져. 앞 레슨은 캐시 대 가중치 비율에서 기울기를 예측했어. (가중치 + 캐시) ÷ 가중치로, 1B는 바이트 2.3배, 9B는 1.21배, 27B는 1.13배. 9B와 27B는 예측에 떨어져(실측 1.21배와 1.17배). 1B는 2.3배에 못 미치는데, 토큰당 1.5밀리초쯤의 고정 오버헤드가 3밀리초짜리 토큰을 희석하기 때문이야. 그러니 방향과-때 원칙에서 나온 집주인의 문장, 대역폭은 기울기를 나눌 뿐 곡선의 모양을 바꾸지 않는다는 말은 정확하고, 이 퀘스트가 보정 하나를 더해. 모양은 캐시 대 가중치 비율이고, 하이브리드 아키텍처는 토큰당 캐시가 같은 순수 트랜스포머보다 훨씬 평평한 모양을 가져.

첫 토큰까지 시간이 세션을 실제로 바꾸는 숫자야. 32K 윈도우의 90%에서 27B는 90초, 9B는 25초. 그리고 이건 한 번짜리 프리필이야. 매 턴 전체 이력을 다시 보내는 채팅 클라이언트는 런타임이 턴 사이에 캐시를 유지하고 늘리지 않는 한 매 턴 그 정도의 청구서를 내. 여기서 물리는 봐주지 않아. 프리필은 연산에 묶이니까 처방은 더 많은 행렬 처리량이고, 애플 M5의 Neural Accelerator가 정확히 그걸 위한 거고, 이 퀘스트가 정확히 측정하지 않은 거야.

Code

context_curve.py — 실험의 곡선 실험, 압축판·python
#!/usr/bin/env python3
"""Decode and TTFT at fractions of a context window. Build a prompt of the
target token count, generate, and record what mlx-lm reports. This is the
`curve` experiment of silicon_lab.py, trimmed to its essentials."""
import sys, time
import mlx.core as mx
from mlx_lm import load, stream_generate
from mlx_lm.sample_utils import make_sampler

repo = sys.argv[1] if len(sys.argv) > 1 else "mlx-community/Qwen3.5-9B-4bit"
window = int(sys.argv[2]) if len(sys.argv) > 2 else 32768
FILLER = "Decode re-reads the weights for every generated token, which is why its ceiling is bandwidth divided by bytes per token. "
QUESTION = "Explain the passage in detail, in at least 400 words."

model, tok = load(repo)


def prompt_of(target: int) -> list[int]:
    reps = max(1, target // 24)                          # ~24 tokens per filler sentence
    ids = tok.apply_chat_template([{"role": "user", "content": FILLER * reps + QUESTION}], add_generation_prompt=True)
    while len(ids) > target and reps > 1:
        reps -= 1
        ids = tok.apply_chat_template([{"role": "user", "content": FILLER * reps + QUESTION}], add_generation_prompt=True)
    return ids


for frac in (0.1, 0.5, 0.9):
    ids = prompt_of(int(window * frac))
    mx.reset_peak_memory(); t0 = time.perf_counter(); first = None
    for r in stream_generate(model, tok, ids, max_tokens=200, sampler=make_sampler(temp=0.0)):
        if first is None:
            first = time.perf_counter() - t0
    print(f"{frac:.0%} of {window}: prompt {r.prompt_tokens:6d}  TTFT {first:6.2f}s  prefill {r.prompt_tps:7.1f} tok/s  "
          f"decode {r.generation_tps:6.2f} tok/s  peak {r.peak_memory:5.2f} GB")

# office, mlx 0.32.2, 2026-09-15, Qwen3.5-9B-4bit:
# 10%: prompt 3233  TTFT  2.69s  prefill 1277  decode 94.38  peak 6.77
# 50%: prompt 16337 TTFT 13.12s  prefill 1259  decode 86.31  peak 8.13
# 90%: prompt 29385 TTFT 24.90s  prefill 1187  decode 78.10  peak 9.39

External links

Exercise

네 맥에서 네가 실제로 쓰는 모델과 윈도우로 context_curve.py를 돌려(작업 집합이 담을 수 있는 윈도우를 골라. 앞 트랙의 피크 표가 안내야). 90% 줄을 정직한 벤치마크로 카드에 추가해. 그다음 네가 잰 디코드 기울기를 앞 레슨 연습에서 예측한 비율과 비교하고, 차이가 있으면 한 문장으로 설명해.
Hint
기울기가 비율 예측보다 완만하면 고정 오버헤드가 희석하고 있거나(작은 모델) 런타임이 캐시로 뭔가 영리한 걸 하는 거야. 더 가파르면 기계가 작업 집합 근처일 수 있고 피크 메모리 칸이 그걸 보여줄 거야. 그건 캐시가 아니라 스왑 절벽이야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인 — 댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.