02. bit, byte, parameter, tensor
이 장의 핵심 연결: 01장의 data path에 "무엇이 흐르는가"를 채웁니다. 그 흐름의 정체는 결국 숫자 덩어리입니다.
다음 질문: 파라미터를 담는 데 최소 얼마의 storage가 필요한가? 그리고 그 "최소"는 실제 메모리 사용량과 같은가?
목표:
- bit·byte·parameter·tensor를 정확히 정의하고 단위 표기를 못 박는다.
- 파라미터 수 × 비트 폭으로 weight-only storage 하한을 직접 계산한다.
- 그 하한을 런타임 메모리 전체와 반드시 구분한다.
일상 비유: 서랍장과 서랍
숫자를 담는 저장 공간을 서랍장이라고 합시다.
- bit(비트)는 가장 작은 칸. 0 또는 1, 딱 두 상태만 담습니다.
- byte(바이트)는 8칸(8 bit)을 한 묶음으로 본 것. 관례적으로 저장·전송의 기본 단위입니다.
- parameter(파라미터)는 모델이 학습으로 정한 숫자 하나. 서랍장에 든 물건 하나에 해당합니다.
- tensor(텐서)는 그 숫자들을 정해진 모양(행·열·…)으로 담은 다차원 배열. 서랍이 격자로 정렬된 서랍장 한 짝입니다.
핵심 질문은 이겁니다. "물건 하나(파라미터 하나)를 담는 데 칸(bit)을 몇 개 쓰느냐"에 따라 서랍장 전체 크기가 정해집니다. 이 "칸 수"가 바로 03장의 정밀도(precision)입니다.
정확한 정의와 단위 표기 (여기서 못 박기)
- bit(비트, 기호 b): 정보의 최소 단위. 0/1.
- byte(바이트, 기호 B): 8 bit. 표기 주의 — 소문자 b는 bit, 대문자 B는 byte. 예:
8 b = 1 B. - parameter(파라미터): 학습으로 정해진 모델의 숫자값 하나. 흔히 가중치(weight)라 부릅니다.
- tensor(텐서): 같은 자료형(dtype)의 숫자들을 다차원 격자에 담은 배열. 스칼라(0차원)·벡터(1차원)·행렬(2차원)·그 이상.
- dtype(data type, 자료형): 숫자 하나를 몇 bit로, 어떤 형식으로 담는지의 규칙. 03장의 주제.
⚠️ 단위·접두어 함정 — 처음 나올 때 못 박기
"1억 파라미터가 몇 GB냐?"에서 GB의 뜻이 두 가지입니다.
- 10진 접두어: 1 KB = 1,000 B, 1 MB = 1,000,000 B, 1 GB = 10⁹ B.
- 2진 접두어: 1 KiB = 1,024 B, 1 MiB = 1,024² B, 1 GiB = 1,024³ B.
이름도 다릅니다: KiB/MiB/GiB(2진, "키비·메비·기비")와 KB/MB/GB(10진). 그런데 현실에선 GB라 써 놓고 2진(GiB)을 뜻하는 자료가 흔합니다. 어느 쪽 접두어인지 확인하지 않으면 약 7%(GiB vs GB) 오차가 조용히 섞입니다. 이 안내서는 계산에서 어느 쪽을 쓰는지 매번 밝힙니다.
또 하나: 대역폭은 흔히 GB/s(초당 바이트), 네트워크는 Gb/s(초당 비트)로 표기하기도 합니다(07장). b와 B를 놓치면 8배 차이납니다.
시각적 직관: 비트에서 텐서까지
flowchart LR
BIT["bit (b)<br/>0 또는 1"]:::mem --> BYTE["byte (B)<br/>= 8 bit"]:::mem
BYTE --> PARAM["parameter<br/>숫자 하나<br/>(= N bit, dtype이 결정)"]:::mem
PARAM --> TENSOR["tensor<br/>파라미터들을<br/>격자 모양으로"]:::mem
TENSOR --> MODEL["모델<br/>= 수많은 tensor의 모음"]:::compute
classDef mem fill:#ede9fe,stroke:#7c3aed,color:#4c1d95
classDef compute fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
계산: weight-only storage 하한
이제 핵심 계산입니다. 가중치만 담는 데 필요한 최소 바이트를 구합니다.
입력 → 식 → 산술
CODE
입력: P = 파라미터 수 (개) w = 파라미터 하나당 비트 폭 (bit/parameter) ← dtype이 결정 (03장) 식: storage_하한(byte) = P × w / 8 (÷8 은 bit → byte 변환. 8 bit = 1 byte) 기호의 뜻: P … 몇 개의 숫자를 담는가 w … 숫자 하나를 몇 bit로 담는가 /8 … bit를 byte로 바꾸는 나눗셈
산술 예시 (가상의 조건 명시 모델)
파라미터 수 P = 7 × 10⁹(70억), 비트 폭 w = 16 bit(예: BF16 — 03장)라고 합시다.
CODE
storage_하한 = 7×10⁹ × 16 / 8
= 7×10⁹ × 2 byte
= 14 × 10⁹ byte
= 14 GB (10진, GB 기준)
≈ 13.04 GiB (2진, ÷1024³ 하면 14×10⁹ / 1.0737×10⁹)
- 비트 폭을 절반(8 bit)으로 낮추면 하한도 절반(약 7 GB)이 됩니다. 이것이 03장에서 볼 정밀도-메모리 절충의 산술적 뿌리입니다.
- 10진(GB)과 2진(GiB)을 같이 적은 이유를 보세요. 같은 14×10⁹ byte가 "14 GB"이자 "약 13 GiB"입니다. 어느 접두어인지 안 밝히면 이 차이가 숨습니다.
⚠️ 가장 중요한 구분: 하한 ≠ 런타임 메모리 전체
방금 구한 14 GB는 "가중치만"의 "하한"입니다. 실제로 요청을 처리할 때 가속기 메모리에 올라가는 것은 그보다 많습니다.
flowchart TB
subgraph RUNTIME["런타임 메모리 전체 (실제 사용량)"]
W["가중치 storage 하한<br/>P×w/8 ← 방금 계산한 것"]:::mem
A["활성값(activation)<br/>계산 중간 산물"]:::compute
K["KV 캐시<br/>생성이 길수록·동시요청 많을수록 증가"]:::mem
O["기타: 작업 버퍼,<br/>단편화, 런타임 오버헤드"]:::warn
end
classDef mem fill:#ede9fe,stroke:#7c3aed,color:#4c1d95
classDef compute fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef warn fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
📌 핵심: P × w / 8은 "가중치를 담는 데 필요한 최소 바이트"일 뿐입니다. 런타임 메모리 전체 = 가중치 + 활성값 + KV 캐시 + 각종 버퍼·오버헤드. 하한을 실제 사용량으로 착각하면, "14 GB 가속기면 70억 파라미터 모델이 딱 들어간다"는 식의 잘못된 결론에 빠집니다. 실제로는 캐시·활성값 자리가 없어 안 들어갈 수 있습니다.
KV 캐시가 왜 메모리를 쓰는지, 왜 요청 길이·동시성에 따라 커지는지는 06장에서 다룹니다. 지금은 "하한은 바닥이지, 천장이 아니다"만 챙기면 됩니다.
조건 명시: 이 계산이 성립하는·성립하지 않는 범위
| 내용 | |
|---|---|
| 성립하는 조건 | P × w / 8은 모든 파라미터가 동일한 dtype으로 촘촘히(밀집) 저장된다고 가정할 때의 가중치 storage 하한입니다. 산술 자체는 dtype·하드웨어와 무관하게 정확합니다(calculated). |
| 성립하지 않는 결론 | 이 값은 런타임 메모리 사용량이 아닙니다. 또한 dtype이 섞이거나(혼합 정밀도), 양자화가 블록 단위 스케일·메타데이터를 동반하거나, 저장 포맷이 압축·정렬 오버헤드를 가지면 실제 파일/메모리 크기는 하한과 달라집니다. "하한 = 실제"로 읽으면 안 됩니다. |
🔬 증거 읽기: 이 수치는 어떤 유형인가
storage_하한 = P × w / 8으로 나온 14 GB는 calculated(계산값)입니다 — 공개 입력(P, w)과 식을 남긴 산술이므로 누구나 재현 가능합니다.- 반면 "이 모델은 실제로 메모리를 XX GB 쓴다"는 주장은 measured(측정값)여야 하며, 측정 조건(생성 길이·동시 요청 수·런타임)을 밝혀야 합니다.
- calculated와 measured를 같은 표에 나란히 놓고 순위 매기면 안 됩니다. 하한(계산)과 실사용(측정)은 다른 축입니다.
이 장에서 배운 것
- bit(b) ≠ byte(B), 10진(GB) ≠ 2진(GiB) — 표기·접두어를 매번 확인한다.
- 가중치 storage 하한 = P × w / 8. 비트 폭을 절반으로 낮추면 하한도 절반.
- 이 하한은 가중치만·최소치다. 런타임 메모리 전체 = 가중치 + 활성값 + KV 캐시 + 버퍼·오버헤드.
- 하한은 calculated, 실사용은 measured — 다른 축이므로 섞어 순위 매기지 않는다.
🔎 이 장의 '지지하지 않는 결론'
P × w / 8으로 "이 가속기에 이 모델이 들어간다/안 들어간다"를 단정할 수 없다. 그건 런타임 메모리 전체를 알아야 하고, 이 장은 하한만 다룬다.- 이 계산으로 "어느 정밀도가 더 낫다"를 말할 수 없다. 메모리 하한이 준다고 품질·수치 범위까지 좋아지는 건 아니다(03장).
✍️ 확인 문제
P = 3×10⁹,w = 8 bit일 때 가중치 storage 하한을 GB(10진)로 계산하세요. 식과 산술을 남기세요.- "storage 하한이 14 GB이니, 16 GB 메모리 가속기면 이 모델로 추론이 된다"는 주장의 빠진 전제는 무엇인가요? 무엇을 더 알아야 하나요?
- [peak/measured/calculated/inferred 묻기]
P × w / 8로 얻은 14 GB는 measured/calculated/inferred 중 무엇인가요? 그 이유는? 반대로 "실측 메모리 20 GB"는 무엇이며, 왜 둘을 같은 표에서 순위 매기면 안 되나요?
다음 장: 03 · FP32, FP16, BF16, INT8, INT4 — 이 장의 "비트 폭 w"를 선택지로 엽니다. 정밀도를 낮추면 무엇을 얻고(storage·대역폭) 무엇을 바꾸는지(수치 범위·품질·커널 지원)를 절충으로 읽습니다.