본문 바로가기
C.W.K.
Lesson 02 of 06 · published

디코드 속도에서 네 대역폭을 재

~15 min · lab, regression, bandwidth, fixed-overhead, stream, measured

Level 0스펙 시트 훑는 사람
0 XP0/91 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete
"모델 다섯, 점 다섯, 선 하나. 기울기는 네 런타임이 보는 버스고, 절편은 네 런타임이 하는 일 중 읽기가 아닌 전부야."

맞춤

물리 트랙의 디코드 공식엔 항이 둘이야. 토큰당 초 = 고정 비용 + 토큰당 바이트 ÷ 대역폭. 같은 가족, 같은 양자화의 밀집 모델 사다리를 한 기계에서 돌리고, x축에 토큰당 바이트, y축에 토큰당 초를 놓으면 점들이 선 위에 떨어져. 고정 비용은 바이트에 관심이 없고 대역폭 항은 바이트에 선형이니까. 보통 최소제곱이 어떤 벤치마크 표도 출력하지 않는 숫자 둘을 줘. 절편, 모델 하나만큼의 커널을 띄우고 샘플링하고 루프를 도는 토큰당 비용. 그리고 기울기, 그 역수가 런타임이 풀에서 실제로 끌어온 대역폭. 혼합 전문가 모델은 일부러 뺐어. 토큰당 바이트는 작고 커널 수는 작지 않아서 선 위쪽에 앉고, 전문가 레슨이 이미 왜인지 설명했어.

맥, 2026-09-15칩, 스펙 GB/s토큰당 고정 비용맞춤 대역폭맞춤 ÷ 스펙최악 잔차증거
airM3, 1001.45 ms89 GB/s89%0.92 ms실측, 밀집 모델 5
pro2023M3 Max, 4001.12 ms347 GB/s87%0.30 ms실측, 5
officeM3 Ultra, 8191.67 ms497 GB/s61%0.73 ms실측, Llama-1B 포함 6
musicM2 Ultra, 8001.80 ms546 GB/s68%0.51 ms실측, 5

두 숫자 읽기

고정 비용은 어느 맥에서든 토큰당 1.1에서 1.8밀리초고, 단일 다이 Max에서 가장 낮아. Ultra 둘은 다이 둘을 먹이느라 토큰당 더 치르고, 그게 가장 작은 모델이 M3 Max에서 가장 빨리 도는 이유의 전부야. 27B의 30밀리초짜리 토큰에 대해선 잡음이고, 0.8B의 3밀리초짜리 토큰에 대해선 시간의 절반이야. 앞 레슨의 상한 대비 비율 칸의 모양이 그거야. 맞춤 대역폭이 더 놀라운 숫자야. 기본 M3와 M3 Max는 디코드 커널에 스펙의 87–89%를 전달해. M3 Ultra는 61%, 한 세대 오래된 같은 메모리 시스템의 M2 Ultra는 68%. 읽고 더하기만 하는 스트리밍 커널, GPU 트랙의 스트림 테스트는 M3 Ultra에서 78%, M2 Ultra에서 92%를 얻어. 그러니 M3 Ultra에선 격차 일부가 메모리 시스템이고 일부가 다이 둘에서 코어 80개를 먹이는 디코드 커널 자체의 비효율인데, 92%를 스트림해서 단일 다이 대역에 있는 M2 Ultra에선 격차가 거의 전부 커널 몫이야. 실험실은 사용자 공간에서 그 둘을 갈라 놓을 수 없어. 두 숫자와 그 사이의 격차를 보고해.

이 숫자의 쓸모

예측해. 네 맥의 a와 BW가 있으면 아직 안 받은 어떤 밀집 모델의 디코드 속도든 1 ÷ (a + 바이트 ÷ BW)고, 이 네 기계에서 사다리 전체의 최악 오차는 토큰당 1밀리초 아래야. 버스에 대해선 상한이 아니라 바닥이야. 더 좋은 커널은 더 끌어올 수 있고(여정 트랙의 PyTorch 행렬-벡터 곱은 이 맞춤의 497에 대해 office에서 605 GB/s를 끌어왔어), 스펙보다 많이 끌어올 수 있는 건 없어. 그리고 추측 디코딩을 드러내. 스트림한 대역폭보다 많이 함의하는 속도는 패스당 토큰 하나 넘게고, Ollama 레슨이 그걸 찾았어. 카드엔 두 숫자와 날짜가 들어가. 런타임 릴리스가 어느 쪽이든 움직일 수 있으니까.

Code

lab_fit.py — 토큰당 바이트에 대한 토큰당 초, 맥마다 맞춤·python
#!/usr/bin/env python3
"""Bandwidth from decode speed. Over the dense models of one machine's ladder,
fit seconds-per-token = a + bytes-per-token / BW. The slope's reciprocal is the
bandwidth your runtime actually pulled; the intercept is its fixed cost per token.
Standard library only. Usage: lab_fit.py ladder-office.jsonl [more.jsonl ...]"""
import json, sys


def dense_rows(path):
    for line in open(path):
        r = json.loads(line)
        if r.get("experiment") == "ladder" and r.get("experts", 0) == 0:     # dense only: experts break the straight line
            yield r


def fit(xs, ys):                                                              # ordinary least squares, y = a + b x
    n = len(xs); mx = sum(xs) / n; my = sum(ys) / n
    b = sum((x - mx) * (y - my) for x, y in zip(xs, ys)) / sum((x - mx) ** 2 for x in xs)
    return my - b * mx, b


for path in sys.argv[1:]:
    rs = list(dense_rows(path))
    xs = [r["weight_bytes_per_token"] for r in rs]                           # bytes read per token
    ys = [1.0 / r["generation_tps"] for r in rs]                              # seconds per token
    a, b = fit(xs, ys)
    bw, spec = 1.0 / b, rs[0].get("spec_gbps")
    worst = max(abs(y - (a + b * x)) for x, y in zip(xs, ys))
    print(f"{rs[0]['alias']:8} {rs[0]['device']:16} {len(rs)} dense models: "
          f"fixed {a*1e3:.2f} ms/token + bytes / {bw/1e9:.0f} GB/s"
          + (f"  ({bw/1e9/spec*100:.0f}% of spec {spec:.0f})" if spec else "")
          + f"   worst residual {worst*1e3:.2f} ms")
    for r, x, y in zip(rs, xs, ys):
        print(f"    {r['model'].split('/')[-1]:30} {x/1e9:6.2f} GB  measured {1/y:7.1f} tok/s  fit {1/(a+b*x):7.1f}")

# office   Apple M3 Ultra   6 dense models: fixed 1.67 ms/token + bytes / 497 GB/s  (61% of spec 819)   worst residual 0.73 ms
# pro2023  Apple M3 Max     5 dense models: fixed 1.12 ms/token + bytes / 347 GB/s  (87% of spec 400)   worst residual 0.30 ms
# music    Apple M2 Ultra   5 dense models: fixed 1.80 ms/token + bytes / 546 GB/s  (68% of spec 800)   worst residual 0.51 ms
# air      Apple M3         5 dense models: fixed 1.45 ms/token + bytes / 89 GB/s   (89% of spec 100)   worst residual 0.92 ms

External links

Exercise

네 맥에서 한 가족, 한 양자화의 밀집 모델 최소 넷으로 사다리를 돌리고, 결과 파일에 lab_fit.py를 돌려. 고정 비용과 맞춤 대역폭을 날짜와 함께 카드에 적고, 받기 전에 아직 없는 모델 하나의 디코드 속도를 예측해. 그다음 받아서 돌리고 오차를 기록해.
Hint
토큰당 1밀리초 아래의 오차가 실험실의 경험이야. 더 큰 오차는 보통 새 모델이 다른 아키텍처라는 뜻이고(하이브리드에 대한 순수 트랜스포머, 혹은 혼합 모델), 그게 고정 비용을 바꿔. 선의 실패가 아니라 모델에 대한 발견이야.

Progress

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

댓글 0

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

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