~15 min · memory, fleet, bandwidth-per-gb, working-set, decode-ceiling, measured
Level 0스펙 시트 훑는 사람
0 XP0/91 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete
"맥 아홉 대, 칸 아홉 개. 그중 어느 기계에서든 언어 모델이 할 모든 일이 돌리기 전에 이 표 안에 있어."
표
칸마다 증거 라벨이 있어. 스펙 대역폭은 애플 거야. 달성 대역폭은 GPU 트랙의 스트리밍 측정값으로, 실험실 맥 넷에만 있고 나머진 추측 대신 빈칸으로 뒀어. GPU 권장 작업 집합은 2026-09-15에 아홉 대 전부에서 읽었어. GB당 GB/s는 스펙으로 한 산수야. 디코드 상한은 달성 수치가 있으면 그걸 쓰고, 없으면 스펙 기반 예측이라고 표시해.
별칭
칩
메모리
스펙 GB/s
달성 GB/s
GB당 GB/s
GPU 작업 집합
상한, 9B (토큰당 4.47 GB)
상한, 27B (14.42)
office
M3 Ultra
512 GB
819
635–638
1.6
464.0 GiB (90.6%)
142 (달성)
44 (달성)
server
M3 Ultra
512 GB
819
—
1.6
464.0 GiB (90.6%)
183 (스펙)
57 (스펙)
worker
M2 Ultra
192 GB
800
—
4.2
161.3 GiB (84.0%)
179 (스펙)
55 (스펙)
music
M2 Ultra
192 GB
800
734–740
4.2
161.3 GiB (84.0%)
165 (달성)
51 (달성)
macbook
M5 Max
128 GB
614
— (규칙상 미측정)
4.8
107.5 GiB (84.0%)
137 (스펙)
43 (스펙)
pro2024
M4 Max
128 GB
546
—
4.3
107.5 GiB (84.0%)
122 (스펙)
38 (스펙)
pro2023
M3 Max
128 GB
400
359–391
3.1
107.5 GiB (84.0%)
87 (달성)
27 (달성)
mini
M4 Pro
64 GB
273
—
4.3
51.8 GiB (81.0%)
61 (스펙)
19 (스펙)
air
M3
24 GB
100
93–97
4.2
17.8 GiB (74.0%)
22 (달성)
7 (달성. 짧은 컨텍스트에서만 들어감)
줄을 가로로 읽기
office를 봐. 스펙 819, 달성 635. GPU 트랙의 78%야. 4비트 27B 모델은 토큰당 14.4 GB를 읽으니까 달성 수치로 한 상한은 초당 44토큰이야. 실험 트랙은 32.6을 쟀고, 남은 차이는 물리 트랙이 설명해(토큰당 고정 오버헤드, KV 캐시, 런타임). 464 GiB 작업 집합이 이 기계를 제일 큰 오픈 체크포인트를 아예 담을 수 있는 이 집의 두 맥 중 하나로 만들어. GB당 GB/s 1.6은 함대에서 제일 낮아. 제일 많이 담는 기계가 자기가 담을 수 있는 제일 큰 모델을 제일 느리게 디코드해. 결함이 아니라 LPDDR의 모양이야.
air를 봐. 스펙 100, 달성 97. 메모리가 시트에 적힌 대로 내줘. GB당 GB/s 4.2는 office보다 높아서, Air를 채우는 모델은 자기 크기에 비해 office를 채우는 모델보다 빠르게 디코드해. 하지만 작업 집합이 17.8 GiB라서 'Air를 채우는 모델'은 짧은 프롬프트에선 16 GB 모델이고 진짜 컨텍스트에선 9B 모델이야. 두 기계는 같은 표의 반대편 구석이고, 이 집은 둘을 반대의 도구로 써.
칸을 세로로 읽기
이 퀘스트를 놀라게 한 건 작업 집합 칸이야. 운영체제가 자기 몫으로 남기는 예약분은 풀과 함께 커지는데 비례하진 않아. 24에서 6.2 GiB, 64에서 12.2, 128에서 20.5, 192에서 30.7, 512에서 48. 'GPU는 약 75%를 받는다'고 하는 모든 구매 가이드는 제일 작은 줄을 설명하고 있는 거야. 달성 칸엔 자기 놀라움이 있어. M2 Ultra의 92% 대 M3 Ultra의 78%. 이 퀘스트는 설명 없이 보고해. 사용자 공간의 무엇도 설명 못 하니까. 상한 칸들은 실험 트랙이 기계 하나씩, 예측을 먼저 적어두고 시험하는 것들이야.
Code
fleet_memory.py — 라이브 읽기와 실측 달성 수치로 생성하는 표·python
#!/usr/bin/env python3
"""Per-Mac memory columns. Spec GB/s from Apple; achieved from stream.py where
measured (None elsewhere — never guessed); working set read live over ssh."""
import subprocess
SPEC = {"office": 819, "server": 819, "worker": 800, "music": 800, "macbook": 614,
"pro2024": 546, "pro2023": 400, "mini": 273, "air": 100}
ACHIEVED = {"office": 638, "music": 740, "pro2023": 391, "air": 97} # stream.py sum, 2026-09-15
BYTES_PER_TOKEN = {"9B": 4.47e9, "27B": 14.42e9}
READ = ("for p in ~/miniconda3/envs/silicon-lab/bin/python ~/miniconda3/envs/mlx/bin/python ~/miniconda3/envs/cwk-asr/bin/python ~/miniconda3/bin/python /opt/homebrew/bin/python3; do "
"[ -x $p ] && $p -c 'import mlx.core as mx; i=(mx.device_info() if hasattr(mx,\"device_info\") else mx.metal.device_info()); "
"print(i[\"memory_size\"], i[\"max_recommended_working_set_size\"])' 2>/dev/null && break; done")
print(f"{'alias':8} {'GB':>4} {'spec':>5} {'achieved':>9} {'GB/s/GB':>8} {'working set GiB':>16} {'9B ceiling':>11} {'27B ceiling':>12}")
for alias, spec in SPEC.items():
out = subprocess.run(["ssh", "-o", "ConnectTimeout=8", alias, READ], capture_output=True, text=True).stdout.split()
phys, rec = (int(out[0]), int(out[1])) if len(out) == 2 else (None, None)
bw = ACHIEVED.get(alias)
basis = bw or spec
tag = "" if bw else " (spec)"
ws = f"{rec/2**30:6.1f} ({rec/phys:.0%})" if rec else " n/a"
print(f"{alias:8} {phys//2**30 if phys else '?':>4} {spec:5d} {str(bw or '—'):>9} {spec/(phys/2**30) if phys else 0:8.1f} {ws:>16} "
f"{basis*1e9/BYTES_PER_TOKEN['9B']:8.0f}{tag:>7} {basis*1e9/BYTES_PER_TOKEN['27B']:8.0f}{tag}")
네 맥을 완전한 줄로 추가해. 칸 아홉 개 전부, 달성은 네 stream.py 실행에서. 그다음 표에서 GB당 GB/s가 너보다 높고 작업 집합은 더 작은 맥을 골라서, 거기서 더 나은 워크로드 하나와 거기선 불가능한 워크로드 하나를 설명해. 마지막으로 네 줄에서 실험 트랙이 곧 시험할 두 칸을 표시해.
Hint
두 칸은 상한이야. 실험은 그걸 적어두고, 모델을 돌리고, 차이를 설명해. 작은 기계에서 더 나은 워크로드는 높은 초당 토큰의 작은 모델이고, 불가능한 건 네 컨텍스트에서의 피크가 그 기계의 작업 집합을 넘는 모든 것이야.
Progress
Progress is local-only — sign in to sync across devices.