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

묶음별 양자화와 혼합 정밀도

~14 min · quantization, group-size, mixed-precision

Level 0호기심
0 XP0/51 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

가중치마다 양자화 민감도가 달라

Transformer의 모든 가중치가 정밀도 손실에 똑같이 반응하지는 않아. 임베딩 층, 어휘로 다시 투영하는 LM head, 어텐션 출력 투영은 보통 피드포워드 MLP 가중치보다 민감해. 전부 4비트로 줄이는 건 단순하지만, 민감한 층만 높은 정밀도로 남기고 나머지를 낮추면 비슷한 평균 비트 수로 품질 손실을 줄일 수 있어.

그게 혼합 정밀도 양자화야. mlx-lm은 --quant-predicate로 미리 정한 방식을 제공해.

제공되는 방식

  • mixed_2_6 — 대부분은 2비트, 민감한 층은 6비트야. 가장 작지만 품질 손실도 눈에 띄어.
  • mixed_3_4 — 대부분은 3비트, 민감한 층은 4비트야. 전체 Q4보다 작으면서 품질 경쟁력이 있어.
  • mixed_3_6 — 대부분은 3비트, 민감한 층은 6비트야. 공격적으로 줄이되 중요한 층에 여유를 줘.
  • mixed_4_6 — 대부분은 기본 Q4인 4비트, 민감한 층은 6비트야. 더 안전한 Q4에 가장 가까워.

mixed_X_Y에서 X는 대부분 층의 비트 수, Y는 민감한 층의 비트 수야. 어느 층을 올릴지는 mlx-lm의 predicate registry에 정해져 있어.

묶음 크기는 별개로 정해

--q-group-size는 혼합 정밀도와 독립된 선택이야. 32는 파일을 키우고 품질을 얻으며, 128은 품질을 조금 내주고 파일을 줄여. 64가 합리적인 중간값이야. 혼합 정밀도에서는 보통 64로 두고 비트 선택 규칙이 층을 구분하게 해.

혼합 정밀도를 꺼낼 때

  • 메모리 천장에 닿았을 때 — 전체 Q4보다 조금 큰 모델을 넣으려면 mixed_3_4mixed_2_6으로 평균 비트 수를 더 낮출 수 있어.
  • 특정 작업에서 Q4 품질이 부족할 때 — Q8까지 가지 않고 일부 정확도를 되찾으려면 mixed_4_6이 자연스러운 다음 단계야.
  • 많은 기계에 배포할 때 — 모델 하나의 작은 절약도 기계 수만큼 쌓여.

사용자 한 명짜리 노트북 배포는 전체 Q4면 대개 충분해. 혼합 정밀도는 측정으로 필요가 드러났을 때 꺼내는 조절값이지 기본 출발점이 아니야.

Code

혼합 정밀도 방식으로 변환하기·bash
# 4-bit base, 6-bit on sensitive layers — the "safer Q4" recipe.
python -m mlx_lm convert \
  --hf-path meta-llama/Llama-3.2-3B-Instruct \
  --mlx-path ./Llama-3.2-3B-Instruct-Mixed-4-6 \
  --quantize \
  --quant-predicate mixed_4_6 \
  --q-group-size 64

# Aggressive size reduction — 3-bit base, 4-bit on sensitive layers.
python -m mlx_lm convert \
  --hf-path meta-llama/Llama-3.2-3B-Instruct \
  --mlx-path ./Llama-3.2-3B-Instruct-Mixed-3-4 \
  --quantize \
  --quant-predicate mixed_3_4 \
  --q-group-size 64
결과 모델의 양자화 설정 살피기·python
import json, glob, os

# After conversion, the config records exactly how each layer was quantized.
for path in glob.glob("./Llama-3.2-3B-Instruct-Mixed-*"):
    with open(os.path.join(path, "config.json")) as f:
        cfg = json.load(f)
    print(f"--- {path} ---")
    print("group_size :", cfg["quantization"].get("group_size"))
    print("bits       :", cfg["quantization"].get("bits"))
    # Mixed-precision configs have per-layer overrides; check for them.
    qmap = cfg.get("quantization_config") or cfg["quantization"].get("model.layers", {})
    if qmap:
        # Show the first few per-layer overrides if present
        sample = list(qmap.items())[:4] if isinstance(qmap, dict) else []
        print("first per-layer entries:", sample)
    print()

External links

Exercise

3B급 모델을 전체 Q4(--quant-predicate 없음), mixed_4_6, mixed_3_4로 각각 변환해. 세 폴더의 크기를 비교하고 같은 프롬프트를 탐욕 샘플링으로 실행해. 크기와 품질의 맞바꿈이 어디까지 괜찮은지는 한 번 나란히 돌려봐야 감이 와.

Progress

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

댓글 0

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

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