5편에서 SIMD가 매트멀 연산을 8배 빠르게 만든다고 풀었어요. 이번 편은 거기 들어가는 데이터 양 자체를 4배 줄이는 기술이에요. 양자화(Quantization). 두 기법이 곱해져서 32배 효과가 나오니까, LLM 추론이 일반 CPU에서도 돌아가는 거예요.
양자화의 한 줄 요약: 모델 weight를 32비트 float에서 8비트 정수로 압축해도 답이 거의 똑같다. 메모리는 4배 줄고 추론 결과는 미미한 손실. 처음 들으면 “정말 그래?” 싶거든요. 저도 처음엔 의심했어요. 32비트 정밀도가 8비트로 줄어드는데 결과가 같다니. 막상 짜고 측정해 보니 진짜 그래요. 이번 편에서 그 원리를 풀어볼게요.
도시 건축으로 풀면 “정밀 청사진(mm 단위)을 단순화한 청사진(cm 단위)으로 바꿔도 시공 결과는 같다”는 비유예요. 시공 끝난 다음에 청사진을 더 정밀하게 가질 필요가 없거든요. LLM도 학습 끝난 후의 weight는 굳이 32비트 정밀도가 필요 없어요.

모델 weight가 왜 32비트 float인가
LLM 모델 weight는 보통 32비트 부동소수점 (float32, fp32)으로 학습됩니다. 한 weight 값이 4바이트로 표현되는 거예요. 32비트는 약 -3.4e38부터 3.4e38까지 표현 가능. 작은 변화량은 약 1e-7 정도까지 구분 가능.
왜 32비트인가요? 학습 과정의 경사하강법 (gradient descent)이 작은 변화를 누적해서 weight를 조금씩 업데이트하는 방식이라, 표현 가능한 작은 값의 범위가 중요하거든요. 매 학습 step마다 1e-7 단위로 weight가 바뀌는데, 그걸 받아낼 수 있는 정밀도가 32비트 정도예요.
그래서 모델 학습 시점에는 fp32가 거의 표준입니다. 학습이 끝난 모델 파일도 처음엔 fp32로 저장돼요. 다만 최근에는 fp16 또는 bfloat16(16비트)으로 학습하는 경우도 늘었어요. GPU 메모리 부담 줄이고 학습 속도 올리려고.
도시 건축으로 풀면 — 건물을 설계하고 시공할 때는 mm 단위 정밀 청사진이 필요해요. 벽 두께 결정, 배관 곡선 계산, 하중 분포 시뮬레이션 등에서 작은 단위까지 표시돼야 학습(설계)이 정확합니다. 이게 학습 시점의 정밀도 요구.
문제는 그게 너무 크다는 거예요. Qwen2.5-0.5B 모델의 weight 개수가 약 6.3억 개. fp32로 저장하면 6.3억 × 4바이트 = 약 2.5GB. 이건 노트북 RAM의 일부를 잡아먹는 크기예요. 7B 모델이면 28GB라 일반 PC에서는 못 돌려요. 70B 모델이면 280GB.
도시 비유로 풀면 mm 단위 정밀 청사진이 600장(2.5GB)이라 자재 트럭 한 대에 다 못 실어요. 트럭 4대 필요. 더 큰 도시는 트럭 30대.
양자화의 아이디어 – JPEG 압축과 같은 원리
JPEG로 사진을 압축하면 크기가 1/10이 되는데 눈으로 보면 거의 똑같죠. 그게 가능한 이유는 인간의 눈이 작은 색 차이는 못 알아본다는 점을 이용해서 정밀도를 의도적으로 떨어뜨리기 때문이에요.
양자화도 똑같은 아이디어예요. LLM 추론 과정에서 weight의 작은 차이는 답에 거의 영향을 안 줍니다. 그러니까 fp32의 7자리 정밀도를 다 가져갈 필요 없이 8비트 정수(int8) 정도면 충분해요. 메모리는 4배 줄고 답은 거의 같습니다.
도시 비유로 풀면 — 시공이 다 끝난 건물의 청사진은 mm 단위 정밀도가 필요 없어요. mm 단위는 학습(설계·시공) 시점에만 필요. 완성된 건물을 다른 사람에게 보여줄 청사진은 cm 단위 또는 5cm 단위 그리드로 단순화해도 건물 모양은 같습니다. 청사진 종이는 1/4 크기, 정보는 거의 같음.
이게 처음 들으면 마법 같아요. “정밀도를 1/4로 줄이는데 결과가 같다?” 저도 처음엔 의심했어요. 근데 학습 끝난 LLM weight의 분포를 보면 진짜 그래요. 대부분 값들이 -1에서 1 사이의 좁은 범위에 모여 있고, 그 안에서 256가지 단계(int8)로 표현해도 패턴 인식에는 충분한 정보가 남아요.
비유 하나 더. 사진을 흑백으로 만들면 색깔 정보가 사라지지만 사진 안의 사람·물건은 다 알아볼 수 있어요. 색은 부수 정보고 명암이 핵심. 양자화도 비슷해요. weight의 정확한 소수점 7자리는 부수 정보고 256가지 단계의 패턴이 핵심.
32비트 float을 8비트 정수로 변환하는 법
fp32 → int8 변환은 두 단계예요.
1. 범위 결정
한 weight 그룹(예: 32개)에서 가장 큰 절댓값을 찾아요. 예를 들어 {0.12, -0.05, 0.31, …, -0.28} 중에 가장 큰 절댓값이 0.31이라 합시다.
2. 정수 변환
이 0.31을 int8의 최대값(127)에 매핑합니다. 다른 값들은 비례적으로 변환.
0.31 → 127 (int8 max)
0.12 → 49 (= 127 × 0.12 / 0.31)
-0.05 → -20
0.28 → 115
-0.28 → -115
...원래 값을 복원하려면 역으로 곱하면 돼요:
49 × (0.31 / 127) ≈ 0.1196 (원래 0.12였음)미세한 오차(0.12 → 0.1196)가 있지만 0.0004 정도라 LLM 답에는 거의 영향 없습니다.
그룹 크기가 핵심
위에서 “32개씩 그룹”이라고 했는데 이게 양자화 디테일의 핵심이에요. 그룹을 크게 하면 한 그룹 안에 매우 큰 값과 매우 작은 값이 섞일 수 있어요. 큰 값에 맞춰 스케일을 결정하면 작은 값은 0에 가까워져 정밀도 손실이 커집니다.
반대로 그룹을 작게 하면 그룹마다 스케일(0.31 같은 값)을 추가로 저장해야 해서 실질 압축률이 떨어져요. 그룹 크기 4라면 4개 weight마다 스케일 하나, 즉 weight 4개당 추가 2바이트 오버헤드. 그룹 크기 32이면 32개당 2바이트라 오버헤드 거의 무시 가능.
대부분의 양자화 포맷은 그룹 크기 32가 sweet spot이에요. Q8_0 포맷도 이걸 씁니다. 이게 ggml(llama.cpp)에서 처음 정착시킨 표준이고, 거의 모든 양자화 LLM 도구가 이 그룹 크기를 따라요.
Q8_0 포맷 – 양자화의 표준
LLM에서 가장 흔한 양자화는 Q8_0입니다. ggml(llama.cpp)에서 시작해서 사실상 표준이 됐어요. Lumen도 이걸 지원합니다.
Q8_0의 구조:
1 블록 = 32개 weight + 1개 스케일
저장 형태:
- 스케일: fp16 (2바이트)
- 32개 weight: int8 각각 (32바이트)
- 블록 전체: 34바이트한 블록 34바이트로 32개 fp32 weight를 표현해요. 원래 fp32라면 32 × 4 = 128바이트였으니까 약 3.76배 압축이에요(이론상 4배에서 fp16 스케일 오버헤드 0.24배 빼고).
압축률 계산 – Qwen2.5-0.5B 사례
Qwen2.5-0.5B의 weight는 약 6.3억 개예요.
- fp32 형태: 6.3억 × 4바이트 = 2.5GB
- Q8_0 형태: 6.3억 × 1.0625바이트 = 670MB
이게 1편에서 본 “Qwen2.5-0.5B-Q8_0 모델 = 670MB”의 정체예요. fp32 모델의 약 1/4 크기.
670MB도 큰 거 같지만 일반 노트북에서 충분히 다룰 수 있어요. 7B 모델이면 fp32로 28GB지만 Q8_0이면 7.5GB라 32GB RAM 노트북에서 돌릴 수 있어요. 도시 비유로 풀면 정밀 청사진 600장을 cm 단위 단순화로 150장. 자재 트럭 한 대로 한 번에 운반 가능.
이거 처음 알았을 때 진짜 놀랐어요. “Qwen 모델이 무거워서 못 돌릴 줄 알았는데 670MB면 노트북에서도 돌아가네”가 첫 인상. 양자화 한 번이 이 정도 차이를 만든다는 게 진짜 큰 발견 같았어요. 그래서 모든 모던 LLM 추론 도구가 양자화를 기본으로 쓰고, ggml은 양자화 포맷을 표준화한 게 큰 기여인 거예요.
더 강한 압축 – Q4 양자화
Q8_0이 4배 압축이라면 Q4_0은 더 강한 압축이에요. 한 weight를 4비트로 표현하니까 8배 압축(이론상).
Q4_0의 구조:
1 블록 = 32개 weight + 1개 스케일
저장 형태:
- 스케일: fp16 (2바이트)
- 32개 weight: 4비트 각각 = 16바이트 (2개 weight를 1바이트에 packing)
- 블록 전체: 18바이트블록당 18바이트로 32개 weight. fp32 대비 7배 압축이에요.
Qwen2.5-0.5B-Q4_0이면 약 280MB. 더 큰 모델도 같은 비율 압축. 7B Q4_0이면 4GB 정도로 일반 노트북에서 충분히 돌릴 수 있어요. 70B 모델도 Q4면 40GB라 고급 PC에서는 가능.
건축으로 풀면 cm 단위(Q8) 청사진에서 10cm 단위 그리드(Q4)로 더 단순화한 거예요. 청사진 종이가 또 절반 크기. 정보는 살짝 더 거칠어지지만 시공은 가능.
정밀도 손실 – Q4가 Q8보다 답이 안 좋나
Q4가 4비트만 쓰니까 정밀도가 더 떨어집니다. 16가지 값만 표현 가능(2^4). Q8은 256가지. 정밀도 손실이 큰 만큼 답 품질에 영향이 와요.
실제로는 perplexity(언어모델의 표준 평가 지표)가 미세하게 떨어집니다. Q8은 fp32와 거의 동일, Q4_0은 fp32 대비 약 1~2% 품질 저하. 답이 “거의 같지만 가끔 다른 단어 선택” 정도. 일반 채팅 용도로는 거의 구분 안 돼요.
이걸 더 개선한 게 Q4_K_M 같은 변형이에요. Q4_0보다 정교한 양자화 방식이라 같은 4비트 압축률에 품질이 더 좋습니다. 단점은 디코딩 코드가 복잡해진다는 점. 그룹 내 값들이 정규분포를 따른다는 가정으로 더 잘 fit하는 거예요. 통계 트릭이에요.
Lumen은 현재 Q8_0만 native 매트멀 지원이고, Q4_0/Q4_K는 GGUF loader가 fp32로 dequantize한 다음 fp32 매트멀로 처리해요. 즉 디스크 크기만 작아지고 메모리에서는 fp32로 펴진 상태예요. 진짜 native Q4 매트멀은 ROADMAP의 다음 마일스톤이에요. 6주 사이드에 다 못 짠 항목이에요.
양자화된 매트멀 – 어떻게 계산하나
이제 양자화된 행렬로 매트멀을 어떻게 계산하는지 봅니다. 단순한 방법은 이래요.
방법 A – Dequantize first (단순한 방법)
1. Q8 → fp32 변환 (블록당 32개 곱셈)
2. fp32 매트멀 (SIMD로 빠르게)작동은 합니다. 그런데 단점이 있어요. 1단계에서 fp32로 펴진 데이터가 메모리를 다시 차지해요. Q8 모델이 670MB인데 dequantize 후에는 2.5GB가 메모리에 잡혀요. 양자화의 의미가 거의 사라집니다.
도시 비유로 풀면 — cm 단위 청사진을 받자마자 mm 단위 정밀 청사진으로 풀어서 종이에 다시 그린 다음 그걸 보고 시공하는 거예요. cm 단위 청사진 받은 효과 X. 디스크에서 cm 단위로 저장된 의미는 있지만 메모리에서는 mm 단위로 펴져 있어서 압축의 본질을 못 살림.
저도 사이드 초반엔 이 방법으로 짰어요. Phase 5.A에서 GGUF 로더가 Q8 데이터를 읽어서 fp32로 dequantize한 다음 메모리에 저장하고 fp32 매트멀 호출. 작동은 하는데 메모리 사용량이 670MB가 아니라 2.5GB로 부풀어 있었어요. “이건 양자화가 아니라 단순히 디스크 압축”이라는 사실을 깨달은 게 그 때.
방법 B – Fused matmul (진짜 양자화)
1. Q8 weight + fp32 activation 입력 받기
2. 매트멀 inner loop 안에서 그 자리에서 dequantize + 곱셈
3. 결과는 fp32이게 Lumen이 채택한 방식이에요. dequantize한 값을 메모리에 저장하지 않고 SIMD 레지스터 안에서만 잠깐 쓰고 버려요. weight는 메모리에 Q8 그대로 670MB만 차지해요.
도시 비유로 풀면 — cm 단위 청사진을 그대로 들고 현장에 가요. 시공팀이 청사진을 보면서 “이 cm 단위 표시는 실제로 몇 mm” 같은 변환을 머릿속에서 그 자리에서 하고 시공. 별도 mm 단위 청사진을 그리지 않아요. 메모리(종이)는 cm 단위 청사진 한 장만 유지.
이 방식은 메모리 활용은 최적인데 코드가 복잡해져요. 일반 fp32 매트멀 inner loop이 5줄이라면 fused Q8 매트멀은 10~15줄. 그래도 메모리 부담 4배 줄어드는 게 더 중요한 가치라서 LLM 추론에서는 fused 방식이 표준이에요.

Fused matmul – cm 청사진 그대로 시공
Phase 7.D에서 fused Q8 native matmul을 도입했어요. 측정 결과는 충격적이었어요.
측정 결과 (Phase 7.D, 8 thread):
- Before: 4.43 tok/s (Q8 dequantize first 방식)
- After: 17.97 tok/s (fused matmul)
→ 약 4배 가속왜 4배 빨라졌을까요? 메모리 운송 비용이 4배 줄었기 때문이에요. 670MB만 운반하면 되니까, 2.5GB를 운반하는 것보다 4배 빠른 거예요. 이게 1편에서 본 “자재 운송이 진짜 병목”의 측정 근거였어요.
이건 직관이 정확히 맞은 케이스. “dequantize 단계 없애면 메모리 부담 4배 줄어 빠를 것” → 측정으로 4배 확정. 사이드에서 만난 가장 큰 single win 중 하나였어요. 11번 가설 중 win 3번 중 1번이 이 7.D.
Lumen의 fused Q8 매트멀 inner loop
실제 어셈블리 패턴은 이런 모양이에요.
loop: # 한 블록 (32개 weight) 처리
# Q8 weight 32개 로드, fp32로 변환
vpmovsxbd ymm4, [w + offset] # 8 i8 → 8 i32
vcvtdq2ps ymm4, ymm4 # 8 i32 → 8 fp32
vmulps ymm4, ymm4, ymm_scale # 스케일 곱하기
# fp32 activation과 매트멀 (FMA)
vfmadd231ps ymm_acc, ymm4, [act + offset]
# 32개 블록은 4 chunk (각 8개) 단위로 반복
...vpmovsxbd가 핵심 명령이에요. 8개 int8을 SIMD 레지스터에 로드하면서 동시에 i32로 부호 확장합니다. 이거 없으면 한 byte씩 따로 변환해야 해서 매우 느려요. SIMD 명령어 50개 인코딩 짤 때 이 명령어 처음 알았는데, 진짜 잘 디자인된 명령이라는 인상을 받았어요.
이 inner loop이 Phase 7.G에서 4-accumulator 패턴(5편)과 결합돼서 큰 가속을 만들었어요. Q8 native matmul + 4-acc SIMD가 Lumen v0.2.0의 핵심 가속이었어요. 두 기법(양자화 fused + SIMD 4-acc)이 합쳐져서 17.97 → 29.10 tok/s 가속. 첫 호출에서 4.43 tok/s였던 게 그 사이클 끝에 30 tok/s 가까이 갔어요. 약 6.5배.
VNNI – 양자화 매트멀 전용 명령어
Intel과 AMD는 양자화 매트멀이 너무 흔해서 아예 전용 SIMD 명령어를 추가했어요. VNNI (Vector Neural Network Instructions)라고 부릅니다. 핵심 명령은 vpdpbusd 한 개:
vpdpbusd ymm_acc, ymm_a, ymm_b이 한 명령으로 32개 int8 곱셈 + 누적 합을 처리해요. 일반 SIMD로 짜면 5~10 명령이 필요한 작업을 단 한 명령으로.
도시 비유로 풀면 — 양자화 청사진(cm 단위) 전용 시공 명령이에요. 일반 시공팀은 “cm 표시를 mm 단위로 변환 → 자재 결정 → 시공”의 3단계를 거치는데, VNNI 시공팀은 “cm 표시 바로 보고 시공” 한 단계로 끝.
지원 CPU:
- Intel Cascade Lake (2019) 이후
- AMD Zen 4 (2022) 이후
Lumen은 VNNI가 있는 CPU에서 자동으로 활용해요(Phase 7.N/7.O/7.P). 그런데 재미있는 측정 결과가 있어요. VNNI가 항상 빠른 게 아닙니다.
VNNI의 함정 – 짧은 K는 win, 긴 K는 loss
VNNI 인프라 짜는 데 약 일주일 걸렸어요. 다 짜고 단순한 비교 측정.
Phase 7.N - VNNI single-acc:
baseline (AVX2 4-acc) 대비 -3.6% 회귀
Phase 7.O - VNNI 4-acc:
baseline 대비 -2.7% 회귀VNNI가 더 빨라야 하는 게 책 상식인데 측정은 -2.7%. 또 부정. “왜 이러지” 한참 디버깅하다가 측정을 더 세분화. 형상별로 분리해서 측정해 보니:
측정 결과 (형상별):
- 짧은 K (~896, 28 블록): VNNI가 약 10~20% 빠름 (win!)
- 긴 K (~4864, 152 블록): VNNI가 약 27% 느림 (loss)이유: VNNI는 명령당 일하는 양이 많아서 외부 메모리 의존성 체인이 길어요. 짧은 K에서는 OoO(Out-of-Order) window에 잘 맞지만 긴 K에서는 의존성이 너무 길어 stall이 늘어납니다.
도시 비유로 풀면 — VNNI 시공팀은 한 번에 많은 자재를 처리하는 강력한 팀이지만, 시공 사이클이 길어서 자재 도착이 한 번이라도 늦으면 팀 전체가 멈춰요. 짧은 시공 (28 블록)에서는 자재 도착 타이밍 맞추기 쉬워서 win, 긴 시공(152 블록)에서는 중간에 자재 늦으면 손해. 일반 SIMD 시공팀은 한 사이클이 짧아서 자재 늦어도 영향 작음.
이걸 측정으로 확인 후 Lumen은 shape-aware dispatch를 도입했어요(Phase 7.P). 매트멀 형상별로 VNNI 사용 여부 자동 결정. 짧은 K는 VNNI, 긴 K는 fp32 4-acc. 같은 모델 안에서도 매트멀별로 다른 커널 호출.
이게 v0.4.0 release의 핵심 기능이었어요. 직관(VNNI는 항상 빠르다)이 측정으로 부정된 좋은 예시예요. 그래서 9편의 측정-주도 의사결정 패턴이 중요해요.
인프라 살린 결정의 가치
7.N과 7.O에서 VNNI가 회귀였을 때, “이 코드 다 폐기”가 일반적인 결정이에요. 1주일 작업 헛수고로 돌리는 거죠. 그래도 Lumen은 코드를 살려뒀어요. “혹시 형상별로 다를 수도?” 같은 의심.
그 결정이 7.P에서 부활. shape-aware dispatch는 VNNI 인프라 없이 짤 수 없는 기능이었어요. 즉 7.N과 7.O의 1주일 작업이 7.P에서 가치를 발휘한 거예요. 60 → 65 tok/s @ 8t.
이 패턴이 2편에서 “사이드 자산”의 메타 패턴이에요. 부정 후에도 인프라 유지하는 결정이 미래 win의 근거. 사이드 직접 짜본 사람만 얻는 직관이에요. 책에서 “부정도 자산”이라고 적혀 있어도 그게 가슴에 안 박히는데, 7.O → 7.P 부활을 한 번 체험하면 그 다음부터는 자연스러워져요.
양자화 안 되는 부분도 있다
모든 weight를 양자화하면 좋겠지만 일부는 안 됩니다.
1. Bias 벡터
매트멀 결과에 더하는 작은 vector. 크기가 작아 압축 효과 미미하고 정밀도 손실이 답 품질에 영향을 줘서 fp32 그대로 유지해요. Qwen2.5-0.5B는 bias 자체가 거의 없는 모델인데, 다른 모델(Llama 등)에서는 한 동(layer)당 약 수 KB 정도. 전체 모델의 1% 미만.
2. Layer norm scale
정규화 단계의 스케일 파라미터. 역시 작고 민감해서 fp32. 한 동당 약 수 KB. 전체 모델의 0.5% 미만.
3. Activation
Weight는 학습이 끝나서 변하지 않으니 양자화 가능하지만, activation은 매 입력마다 새로 계산되는 값이라 사전 양자화 불가능. 추론 시점에 양자화하는 방식이 있긴 한데(activation quantization) 정밀도 손실이 커서 신중히 사용해야 해요. Lumen은 activation은 fp32 그대로.
도시 비유로 풀면 — 청사진(weight)은 시공 끝나면 cm 단위로 단순화 가능. 그런데 “공사 현장 일별 자재 사용량(activation)”은 매일 바뀌니까 미리 cm 단위로 만들 수 없어요. 정확한 mm 단위로 매번 새로 계산.
그래서 실제 모델 파일은 weight 대부분(99%+)이 양자화돼 있고, 나머지 작은 부분은 fp32로 남아 있어요. 그래도 전체 모델 크기의 1% 미만이라 압축 효과는 그대로 유지됩니다.
6편 정리
- 양자화는 fp32 weight를 더 작은 표현으로 압축하는 기법. JPEG 사진 압축의 행렬 버전. mm 단위 정밀 청사진을 cm 단위로 단순화. 답에 큰 영향 없이 메모리 4~8배 절약.
- Q8_0은 표준 양자화 포맷. 32개 weight + 1개 fp16 스케일 = 34바이트. 약 3.76배 압축. Lumen이 기본 지원.
- Q4_0은 더 강한 압축(7배)이지만 정밀도 손실 1~2%. 10cm 단위 그리드. 큰 모델(7B+) 실행에 거의 필수.
- Fused matmul이 핵심 기술. dequantize한 값을 메모리에 저장하지 않고 SIMD 레지스터 안에서만 쓰고 버림. cm 단위 청사진을 mm으로 다시 그리지 않고 머릿속 변환만으로 시공. Phase 7.D에서 4배 가속.
- VNNI는 양자화 매트멀 전용 SIMD 명령어. 짧은 K 매트멀에 win, 긴 K에 loss. “한 번에 많은 자재 처리하지만 사이클 길어서 자재 늦으면 전체 멈춤”. 직관과 다른 측정 결과로 shape-aware dispatch 도입(Phase 7.P).
양자화가 LLM 추론을 일반 노트북에서 가능하게 만든 핵심 기술이에요. ggml이 양자화 포맷 표준화한 게 진짜 큰 기여였구나 — 직접 짜보고 그 가치를 알게 됐어요. 시리즈에서 가장 “직관적이지 않은데 효과는 큰” 영역이 양자화. JPEG 압축 비유 하나로 이 직관이 잡혀요.
다음 편 미리보기
7편은 Transformer 한 layer를 통과하는 전체 과정을 다룹니다. 1편에서 본 “도시 한 동(洞)을 통과 = 매트멀 5개 + 작은 계산들”의 세부 동작. attention이 정확히 무엇이고 RMSNorm, RoPE, SiLU 같은 부수 op들은 왜 필요한지. 도시의 한 동 안에서 일어나는 일들을 단계별로 풀어 봅니다.
attention 부분에서는 건축 비유로는 약간 추상도가 높아져서 칵테일 파티 효과 같은 인지심리학 비유를 잠깐 보조로 빌려와요. 한 단락만 보조로 쓰고 다시 건축 비유로 돌아옵니다.
이 시리즈 본문 전체는 GitHub에도 정리해 뒀어요. github.com/redchupa/lumen/docs/tutorial에서 원문 격으로 보실 수 있어요.
그럼 다음 편에서 뵐게요. 양자화 관련 질문 있으시면 댓글 남겨주세요.