모델 양자화#

캘리브레이션 데이터는 MBLT -> MXQ 단계에서 사용하는 대표 입력 데이터입니다. qb Compiler는 이 데이터를 이용해 활성값 범위를 관찰하고 컴파일된 모델의 양자화 파라미터를 결정합니다.

좋은 캘리브레이션 데이터는 형상만 맞는 데이터가 아닙니다. 실제 추론에서 컴파일러가 기대하는 입력과 같은 분포, 데이터 타입, 레이아웃, 스케일링, 전처리를 가져야 합니다.

양자화 개요#

양자화 흐름#

양자화는 MBLT 모델의 수치 범위를 MXQ 산출물에서 사용하는 표현으로 변환하는 단계입니다. qb Compiler에서는 이 과정이 MBLT -> MXQ 단계에 포함됩니다. 양자화는 메모리 이동량을 줄이고 NPU 실행 효율을 높이지만, 모델의 수치 동작도 바꿉니다.

일반적인 흐름은 다음과 같습니다.

원본 모델 -> MBLT -> 캘리브레이션 (값 분포 계산) -> 양자화 -> MXQ

컴파일러는 캘리브레이션 단계에서 캘리브레이션 샘플로 활성값 범위를 관찰해 값 분포를 계산하고, 이 값 분포로부터 활성값과 가중치의 스케일을 결정하는 양자화를 수행한 뒤, 선택한 target device에 맞는 MXQ 패키지를 생성합니다. 일부 설정은 수치 품질에만 영향을 주지만, 일부 설정은 생성되는 연산 그래프나 NPU 실행 특성에도 영향을 줄 수 있습니다.

튜닝은 다음 순서로 진행하는 것을 권장합니다.

  1. 실제 추론 전처리를 사용해 캘리브레이션 데이터를 생성했는지 확인합니다.

  2. 기본 프리셋으로 검증을 수행합니다.

  3. 캘리브레이션, bit 정책 같은 전역 양자화 설정을 조정합니다.

  4. 민감한 것으로 확인된 레이어에만 레이어별 재정의를 추가합니다.

  5. 단순한 조정으로 부족할 때 탐색 또는 최적화 설정을 사용합니다.

아래 섹션에서는 세부 양자화 기법과 설정 제어 방법을 다룹니다.

캘리브레이션이 필요한 이유#

대부분의 원본 모델은 floating point로 학습됩니다. MXQ 산출물은 모빌린트 NPU 실행에 맞게 최적화되며 내부적으로 양자화된 텐서를 사용하는 경우가 많습니다. 캘리브레이션은 floating-point 동작을 양자화 실행으로 옮길 때 필요한 활성값의 수치 범위를 추정합니다.

캘리브레이션 샘플이 실제 추론 입력과 다르면 관찰된 범위도 달라집니다. 그 결과 컴파일된 모델에서 값이 포화되거나 작은 신호가 사라지거나, 실제로 거의 쓰지 않는 범위에 정밀도가 낭비될 수 있습니다.

캘리브레이션 데이터#

캘리브레이션 데이터 형식#

캘리브레이션 데이터는 NumPy 배열, PyTorch 텐서, 이미지 파일을 디렉터리에 저장하거나 샘플 경로를 나열한 텍스트/JSON 메타데이터 파일로 저장할 수 있습니다. 각 샘플은 qb Compiler가 캘리브레이션하는 모델 입력과 일치해야 합니다.

  • 같은 입력 개수

  • 컴파일 경로가 기대하는 입력 이름 또는 순서

  • 컴파일러가 기대하는 형상

  • 같은 데이터 타입과 수치 범위

  • HWC, NHWC, NCHW 같은 레이아웃

단일 이미지 입력에서는 컴파일러 측 전처리용 원본 이미지 또는 전처리된 이미지 텐서 하나가 캘리브레이션 샘플이 되는 경우가 많습니다. 다중 입력 모델에서는 한 캘리브레이션 샘플 안에 같은 추론 예시에 해당하는 모든 입력이 함께 있어야 합니다.

프리셋과 캘리브레이션 데이터#

프리셋은 원본 모델 입력 앞에 전처리를 추가할 수 있습니다. 캘리브레이션 샘플은 원본 부동소수점 모델 입력만을 기준으로 준비하지 말고, 컴파일 설정이 정의하는 입력 형식에 맞춰야 합니다.

프리셋

컴파일러 측 전처리

제공할 캘리브레이션 데이터

classification

없음

내보낸 모델 입력과 일치하도록 준비한 텐서

classification_torchvision

3채널 uint8 입력, bilinear 보간의 256 x 256 크기 변경, 224 x 224 가운데 자르기, [0, 255]에서 [0.0, 1.0]으로 스케일링, mean [0.485, 0.456, 0.406] 및 standard deviation [0.229, 0.224, 0.225] 정규화

크기 변경과 가운데 자르기를 적용한 뒤 정규화 이전의 224 x 224 3채널 uint8 이미지; fuseIntoFirstLayer는 정규화를 결합하므로 크기 변경/자르기는 MXQ 모델 밖에서 적용해야 합니다

detection

없음

내보낸 모델 입력과 일치하도록 준비한 텐서

yolo_640

3채널 uint8 입력, padding value 114를 사용하는 640 x 640 letterbox

Letterbox 이전의 원본 3채널 uint8 이미지; Letterbox를 다시 적용하지 않습니다

yolo_1280

3채널 uint8 입력, padding value 114를 사용하는 1280 x 1280 letterbox

Letterbox 이전의 원본 3채널 uint8 이미지; Letterbox를 다시 적용하지 않습니다

vision_transformer

없음

내보낸 모델 입력 및 모델별 전처리와 일치하도록 준비한 텐서

llm / llm_fast

Tokenizer 또는 embedding 전처리 없음

컴파일 흐름이 요구하는 token, embedding, mask, position, cache 텐서; 설정한 sequence/cache length와 일치해야 합니다

multimodal

Image/text 전처리 없음

내보낸 모델이 요구하는 모든 준비된 vision/language 입력

모델의 학습/내보내기 전처리가 프리셋 파이프라인과 다르면 해당 프리셋을 사용하지 않습니다. 사용자 설정을 사용하고 그 설정이 기대하는 입력 형식에 맞춰 캘리브레이션 데이터를 준비해야 합니다.

이미지 모델 캘리브레이션#

컴파일러 측 전처리가 없는 모델의 이미지 캘리브레이션은 대표 원본 이미지에서 시작해 추론과 같은 크기 변경, 자르기, 색상 변환, 스케일링, 레이아웃 변환, 정규화를 적용한 뒤 텐서로 저장합니다.

예를 들어 외부 TorchVision 스타일 ImageNet 전처리는 보통 다음 흐름입니다.

  1. 이미지를 RGB로 디코딩

  2. 학습 레시피의 보간법으로 크기 변경

  3. 모델 입력 크기로 가운데 자르기

  4. uint8 픽셀을 부동소수점으로 변환하고 보통 255로 나누어 스케일링

  5. 학습 평균과 표준편차로 정규화

  6. qb Compiler가 기대하는 레이아웃으로 저장

컴파일러 측 YOLO 전처리 프리셋을 쓰지 않는 경우에는 일반적으로 RGB 변환, 종횡비 유지 크기 변경, letterbox 패딩, 스케일링을 외부에서 적용한 뒤 640 x 640 또는 1280 x 1280 같은 고정 정사각형 입력 텐서를 제공합니다. qb Compiler는 이 입력 크기에 대응하는 yolo_640, yolo_1280 설정 프리셋도 제공합니다. 내보낸 모델 입력이 640 x 640이면 yolo_640 프리셋을 사용하고, 1280 x 1280이면 yolo_1280 프리셋을 사용합니다. 이 프리셋에서는 컴파일러가 letterbox를 수행하므로 외부에서 letterbox를 적용한 텐서가 아니라 원본 3채널 uint8 이미지를 제공합니다. 프리셋과 캘리브레이션 데이터의 입력 형식이 서로 맞지 않으면 양자화 결과가 올바르지 않습니다.

캘리브레이션 데이터 형상#

캘리브레이션 텐서 형상은 컴파일러가 보는 모델 입력과 대응해야 합니다.

일반적인 예시는 다음과 같습니다.

모델 계열

일반적인 샘플 형상

설명

classification_torchvision

(224, 224, 3)

크기 변경/자르기 이후 결합된 정규화 이전의 3채널 uint8 이미지입니다.

컴파일러 측 전처리가 없는 분류 모델

(224, 224, 3)

컴파일러가 보는 입력이 HWC인 경우의 전처리된 RGB 이미지입니다.

채널 우선 모델 입력이 유지되는 ONNX 또는 프레임워크 흐름

(1, 3, 224, 224) 또는 (3, 224, 224)

모델 입력 또는 compile API의 기대 형식에 맞춥니다.

yolo_640

(H, W, 3)

프리셋 letterbox로 640 x 640이 되기 전 원본 3채널 uint8 이미지.

yolo_1280

(H, W, 3)

프리셋 letterbox로 1280 x 1280이 되기 전 원본 3채널 uint8 이미지.

다중 입력 모델

입력마다 하나의 텐서

이름, 순서, 형상, 데이터 타입, 샘플 정렬을 유지합니다.

LLM

컴파일 흐름이 요구하는 토큰, 임베딩, 마스크, 위치, 캐시 관련 텐서

HuggingFace/transformers 전처리와 시퀀스/캐시 길이에 맞춥니다. 컴파일 흐름이 RoPE, ALiBi 같은 위치 인코딩을 별도 텐서로 요구하면 캘리브레이션 데이터에도 포함해야 합니다.

일부 흐름은 CPU head를 제외한 NPU body를 캘리브레이션하고, CPU 오프로딩 흐름은 원본 모델에서 보이는 입력을 캘리브레이션할 수 있습니다. CPU 오프로딩을 사용할 때는 캘리브레이션 형상이 원본 모델 기준인지 추출된 NPU body 기준인지 확인합니다.

다중 입력 캘리브레이션#

다중 입력 모델에서는 컴파일 도구가 명시적으로 다른 레이아웃을 요구하지 않는 한 입력 스트림을 서로 독립적으로 저장하지 않습니다. 모든 입력의 캘리브레이션 샘플 0은 같은 실제 예시에서 나온 값이어야 합니다.

예를 들어 멀티모달 모델은 이미지 텐서, 토큰 ID, 어텐션 마스크를 함께 받을 수 있습니다. 이 이미지는 같은 샘플의 프롬프트/텍스트와 대응해야 합니다. 이미지와 텍스트를 임의로 조합하면 실제 추론에서 나타나지 않는 활성값 범위를 만들 수 있습니다.

LLM 캘리브레이션#

LLM 캘리브레이션은 배포 작업 부하를 대표하는 텍스트와 추론에서 사용할 토크나이저, 시퀀스 길이 정책, 어텐션 마스크 동작, 위치 처리, KV 캐시 설정을 그대로 사용해야 합니다.

일부 컴파일 흐름은 임베딩 레이어를 CPU에서 실행하고 NPU 본문만 캘리브레이션합니다. 이 경우 캘리브레이션 입력은 원본 토큰 ID가 아니라 임베딩 레이어를 거친 텐서입니다. 이 임베딩된 텐서를 생성할 때는 컴파일 스크립트와 같은 모델 가중치 및 데이터 타입 가정을 사용합니다. 배치 크기, 시퀀스 길이, 캐시 길이도 선택한 llm 또는 llm_fast 프리셋과 일치해야 합니다.

무작위 캘리브레이션#

무작위 캘리브레이션은 스모크 테스트, 파서 확인, 컴파일 경로 동작 검증에는 유용할 수 있습니다. 하지만 정확도가 중요한 MXQ 산출물에는 대표 캘리브레이션 데이터를 대체할 수 없습니다.

무작위 캘리브레이션은 빌드 검증 목적일 때만 사용합니다. 배포용 산출물에는 예상 추론 분포의 샘플을 사용해야 합니다.

추론 전처리와 일치#

캘리브레이션 전처리는 추론 전처리와 반드시 일치해야 합니다. 캘리브레이션은 MXQ 산출물이 사용할 수치 범위를 결정하기 때문입니다. 추론은 원본 RGB uint8 이미지를 보내는데 캘리브레이션은 정규화된 float32로 수행했거나, 캘리브레이션은 BGR이고 추론은 RGB라면 서로 다른 모델 입력을 기준으로 캘리브레이션한 것입니다.

이는 양자화 정확도 저하의 가장 흔한 원인입니다. 가능하면 캘리브레이션 생성과 런타임 추론에서 전처리 구현을 공유합니다. 정규화를 컴파일된 모델 안으로 결합한다면, 캘리브레이션 데이터는 필요한 공간 전처리 이후 정규화 이전의 형식으로 제공하고 정규화를 다시 적용하지 않습니다.

캘리브레이션 데이터 준비 시 주의사항#

밝기, 객체 크기, 배경, LLM 프롬프트 길이처럼 실제 배포 시나리오에서 나타나는 입력 분포를 충분히 대표하는 샘플을 사용합니다. 손상된 파일, 섞인 색상 형식, 예상하지 못한 채널 수가 있는 샘플은 제외합니다.

생성한 캘리브레이션 데이터와 함께 프리셋 이름, target device, 원본 모델 내보내기 명령, 캘리브레이션 스크립트 버전, 전처리 파라미터를 기록합니다. 이 정보가 있어야 MXQ 산출물을 재현할 수 있습니다.

양자화 설정#

프리셋, 설정 파일, Python 하위 설정 객체를 통한 설정 전달 방법은 컴파일 설정을 참고합니다. 전체 CompileConfig 스키마는 참조 — CompileConfig 스키마를 참고합니다.

CalibrationConfig#

CalibrationConfig는 qb Compiler가 캘리브레이션 샘플에서 활성값의 값 분포를 수집하는 방식을 제어합니다.

모델 출력이 활성값 범위에 민감하거나, 캘리브레이션 샘플 수가 적거나, 캘리브레이션 분포가 배포 환경의 입력 분포와 다를 때 사용합니다. 비전 모델, 탐지 모델, 멀티모달 인코더, LLM 프롬프트 캘리브레이션에서 가장 먼저 확인할 설정입니다.

이 설정은 샘플 텐서에서 범위를 추정하는 방식을 바꿉니다. 예를 들어 더 보수적인 범위를 선택하거나, 드문 이상값을 완화하거나, 절대 최댓값 대신 백분위수 계열 추정을 사용할 수 있습니다. 보수적인 범위는 클리핑 위험을 줄이지만 양자화 레벨을 낭비할 수 있습니다. 공격적인 이상값 처리는 평균 정확도를 올릴 수 있지만, 실제로 큰 활성값이 필요한 드문 입력에서는 손실을 만들 수 있습니다.

추론 속도 영향은 미미하지만 정확도 영향은 클 수 있습니다. 생성된 MXQ가 같은 NPU operator로 실행되므로 런타임 속도는 크게 바뀌지 않지만, 좋은 범위 선택은 런타임 정밀도를 올리지 않고도 수치 오차를 줄일 수 있습니다. 더 많은 캘리브레이션 샘플이나 추가 통계를 사용하면 컴파일 시간은 늘어날 수 있습니다.

실무 기준:

  • 추론과 같은 전처리 파이프라인에서 만든 대표 캘리브레이션 샘플을 사용합니다.

  • 고급 양자화 옵션을 조정하기 전에 캘리브레이션 샘플 다양성을 먼저 늘립니다.

  • 무작위 캘리브레이션은 정확도 평가용으로 사용하지 말고, 컴파일 스모크 테스트 용도로만 사용합니다.

  • 다중 입력 모델은 입력 간 관계가 실제와 같도록 모든 입력을 함께 캘리브레이션합니다.

BitConfig#

BitConfig는 텐서와 가중치에 적용되는 양자화 bit-width 정책을 제어합니다.

정확도와 더 작고 빠른 실행 사이의 절충점을 조정해야 하거나, 특정 모델 계열의 일부 연산 그래프에 더 높은 정밀도가 필요하다는 것을 알고 있을 때 사용합니다. 낮은 bit-width는 메모리 대역폭을 줄이고 처리량을 높일 수 있지만 수치 해상도를 낮춥니다. 높은 bit-width는 대개 정확도를 높이지만 메모리 사용량이 늘고, target device와 연산자에 따라 성능이 낮아질 수 있습니다.

이 설정은 활성값, 가중치, 선택한 layer output에 할당되는 정밀도를 바꿉니다. 전역 bit 정책은 단순하고 예측하기 쉽습니다. 반면 mixed 정책은 민감한 레이어만 높은 정밀도로 유지하고 나머지는 더 빠른 낮은 정밀도 경로를 사용할 수 있어 정확도와 성능을 함께 맞추기 좋습니다.

정확도 영향은 첫 레이어, 마지막 레이어, 정규화 주변 레이어, 어텐션 projection, 탐지 head에서 큰 경우가 많습니다. 성능 영향은 변경한 연산자에 따라 달라집니다. 큰 합성곱이나 행렬 곱셈 레이어를 많이 바꾸면 작은 출력 head를 바꾸는 것보다 런타임 영향이 큽니다.

HessianQuantConfig#

HessianQuantConfig는 최적화 기반 양자화를 활성화합니다. 기본 스케일 선택은 유효하지만 검증에서 남은 정확도 차이가 확인될 때 사용합니다.

캘리브레이션 데이터를 확인했고, 단순한 전역 설정도 시도한 뒤에 사용하는 것이 좋습니다. 큰 행렬 연산이 많은 모델, transformer block, 가중치 양자화 오차가 활성값 범위 오차보다 큰 레이어에 특히 유용합니다.

이 설정은 양자화 파라미터를 최적화하는 방식을 바꿉니다. 일반적으로 샘플 활성값이나 레이어 재구성 기준을 사용해 부동소수점 동작과 양자화 동작의 차이를 줄입니다. 런타임 정밀도를 높이지 않고도 정확도를 회복할 수 있습니다.

민감한 레이어에서는 정확도 개선 폭이 클 수 있습니다. 최적화는 컴파일 시점에 수행되므로 런타임 성능은 선택한 bit 정책과 거의 같습니다. 대신 컴파일 시간과 임시 메모리 사용량이 증가할 수 있으므로 가능하면 필요한 범위에만 적용합니다.

ModConfig#

ModConfig는 학습(gradient) 기반 MOD(Minimize Output Difference) 최적화를 활성화합니다. 이 방법은 양자화된 출력과 부동소수점 출력의 차이를 직접 줄입니다. 기본 스케일 선택과 HessianQuantConfig 같은 재구성 기반 보정을 모두 거친 뒤에도 검증에서 정확도 차이가 남을 때 마지막 단계로 사용합니다.

대표성 있는 캘리브레이션/학습 데이터가 준비되어 있어야 하며, 단순한 전역 설정과 HessianQuant를 먼저 시도한 뒤에 사용하는 것이 좋습니다. 양자화에 특히 민감한 모델, 출력 품질이 소수 레이어의 오차에 크게 좌우되는 탐지·transformer 계열, 활성값 범위 보정만으로는 회복되지 않는 레이어에 특히 유용합니다.

이 설정은 양자화 파라미터(활성값 스케일, zero-point, 가중치 스케일)를 학습 가능한 값으로 두고, 필요하면 가중치와 바이어스도 함께 조정합니다. 그런 다음 epoch, learning rate schedule, 출력 차이 기준 loss를 사용해 최적화기로 학습합니다. 필요한 경우 재구성 loss나 작업 loss를 결합할 수 있습니다. 부동소수점 모델을 teacher로 삼아 양자화 출력이 그에 가까워지도록 맞추므로, 런타임 정밀도를 높이지 않고도 정확도를 회복할 수 있습니다.

가장 어려운 경우에는 정확도 개선 폭이 가장 클 수 있습니다. 학습은 컴파일 시점에 수행되므로 런타임 성능은 선택한 bit 정책과 거의 같습니다. 대신 실제 학습 루프를 돌기 때문에 컴파일 시간, GPU 메모리, 데이터 준비 부담이 다른 방법보다 크게 늘 수 있으므로, 적용 범위를 레이어 단위로 좁히고 학습 관련 설정은 필요한 만큼만 키우는 것이 좋습니다.

EquivalentTransformationConfig#

EquivalentTransformationConfig는 모델의 수학적 기능은 유지하면서 양자화하기 쉬운 형태로 바꾸는 동등 변환을 제어합니다.

인접 레이어 사이의 스케일 불균형이 큰 모델에서 사용합니다. 예를 들어 합성곱/배치 정규화 패턴, 정규화에 민감한 연산 앞뒤의 선형 레이어, 채널 크기가 고르지 않은 transformer projection이 있습니다. 부동소수점 모델은 정확하지만 양자화 오차가 일부 레이어에 집중될 때 특히 유용합니다.

이 설정은 동등한 계산을 연산 그래프 안에서 재분배합니다. 예를 들어 스케일 계수를 인접 연산 사이로 이동해 가중치와 활성값 범위가 더 양자화하기 좋은 상태가 되도록 만들 수 있습니다. 부동소수점 기능은 동등하게 유지하는 것이 목적이지만, 범위 조건이 좋아지면서 양자화 근사가 개선될 수 있습니다.

이상값 채널이나 불균형 가중치가 있는 모델에서는 정확도 개선 효과가 자주 나타납니다. 추론 속도에는 영향이 거의 없지만, 연산 그래프 변경이 결합과 스케줄링에 영향을 줄 수 있습니다. 컴파일 시간은 다소 증가할 수 있습니다.

SearchWeightScaleConfig#

SearchWeightScaleConfig는 기본 휴리스틱보다 나은 가중치 스케일 값을 탐색합니다.

검증 결과 가중치 양자화가 주요 오차 원인으로 보일 때 사용합니다. 합성곱, fully connected, 어텐션 projection 레이어에서 특히 유용합니다. 캘리브레이션 품질을 먼저 확인한 뒤, 모델 전체 정밀도를 넓게 올리기 전에 시도하기 좋은 단계입니다.

이 설정은 가중치 스케일 선택 방식을 바꿉니다. 기본 범위 추정을 그대로 사용하는 대신, 컴파일러가 후보 스케일을 평가하고 설정된 목적에 따라 양자화 오차를 줄이는 값을 선택합니다.

가중치에 민감한 레이어에서는 정확도 영향이 클 수 있습니다. 결과 MXQ는 같은 양자화 실행 경로를 사용하므로 추론 속도에는 영향이 거의 없습니다. 대신 컴파일 시간이 눈에 띄게 늘 수 있으므로 문제가 되는 레이어가 일부라면 레이어별 재정의로 탐색 범위를 제한합니다.

SaveSampleConfig#

SaveSampleConfig는 캘리브레이션 샘플 또는 중간 샘플 정보를 저장합니다.

정확도 저하를 디버깅하거나, 재현 가능한 양자화 조사 환경을 만들거나, 다른 엔지니어와 최소 캘리브레이션 사례를 공유해야 할 때 사용합니다. 더 무거운 최적화/탐색 흐름을 실행하기 전에 같은 샘플 집합으로 실험을 고정하는 데도 유용합니다.

이 설정은 모델 실행 자체가 아니라 캘리브레이션 과정에서 생성되는 산출물을 바꿉니다. 저장된 데이터는 부동소수점 텐서와 양자화된 텐서 비교, 이상값 샘플 조사, 스케일 생성 재현에 사용할 수 있습니다.

정확도와 런타임 성능을 직접 바꾸지는 않습니다. 큰 입력이나 많은 중간 텐서를 저장하면 디스크 사용량과 빌드 시간이 증가할 수 있습니다.

RuntimeOptions#

RuntimeOptions는 생성된 패키지가 사용하는 런타임 메타데이터를 기록합니다. 일반적으로 양자화 동작을 조정할 때 가장 먼저 만질 설정은 아닙니다.

수치 품질은 캘리브레이션, bit, 최적화, 레이어별 재정의 설정으로 조정합니다. 런타임 메타데이터는 문서화된 작업 흐름이나 런타임 통합에서 요구할 때만 변경하고, 배포에 사용하는 qb Compiler/runtime 버전과 맞춥니다.

레이어별 재정의#

레이어별 재정의는 양자화 설정을 모델 전체가 아니라 특정 레이어에만 적용합니다.

검증 차이, 텐서 비교, 모델 구조 지식으로 소수의 민감한 레이어를 찾았을 때 사용합니다. 입력 stem, 출력 head, 어텐션 projection, 정규화 주변 레이어, 탐지 head만 특별 처리가 필요할 때 전역 설정을 바꾸는 것보다 낫습니다.

대표적인 사용 예:

  • 선택한 레이어만 더 높은 bit-width로 유지합니다.

  • 채널 범위가 고르지 않은 레이어에 채널별 가중치 양자화를 적용합니다.

  • 불안정해지는 레이어에서 연산 그래프 변경 또는 탐색 패스를 끕니다.

  • 재구성 오차가 큰 레이어에만 가중치 스케일 탐색을 적용합니다.

  • 후처리가 작은 수치 차이에 민감한 출력 레이어의 동작을 보수적으로 유지합니다.

레이어별 재정의는 전역 변경보다 성능 비용을 줄이면서 정확도를 회복할 수 있습니다. 대신 유지보수 비용이 있습니다. 원본 모델 내보내기 방식이 바뀌면 레이어 이름도 바뀔 수 있으므로 재정의 설정은 모델 버전과 함께 관리하고, 다시 내보낸 뒤에는 다시 확인해야 합니다.

정확도 튜닝#

정확도 저하 대응#

양자화 정확도 저하는 여러 옵션을 한꺼번에 바꾸기보다, 데이터와 원인 위치를 먼저 확인하는 문제로 다룹니다.

권장 순서:

  1. 전처리를 비교합니다. 캘리브레이션 입력의 정규화, 레이아웃, 데이터 타입, 크기 변경, 패딩, 토큰화, 시퀀스 길이가 실제 추론과 같아야 합니다.

  2. 몇 개 샘플 출력이 아니라 대표 지표로 검증합니다.

  3. 손실이 전체적으로 발생하는지, 특정 클래스, 박스, 토큰, 레이어에 집중되는지 확인합니다.

  4. 캘리브레이션 분포가 약하면 샘플을 늘리거나 재구성합니다.

  5. 활성값 클리핑이나 이상값 문제가 보이면 CalibrationConfig를 조정합니다.

  6. 민감한 레이어가 있으면 BitConfig 또는 레이어별 재정의를 조정합니다.

  7. 남은 오차가 특정 위치에서 반복되면 EquivalentTransformationConfig, SearchWeightScaleConfig, HessianQuantConfig를 사용합니다.

  8. 실험을 재현해야 하면 SaveSampleConfig로 샘플을 고정합니다.

대표 증상과 첫 대응:

증상

가능한 원인

첫 대응

거의 모든 샘플에서 정확도가 낮음

전처리 또는 캘리브레이션 불일치

추론 파이프라인에서 캘리브레이션 데이터를 다시 생성

드문 입력에서 크게 실패

활성값 이상값 클리핑

더 보수적인 캘리브레이션 범위 사용 또는 해당 샘플 추가

특정 head 또는 클래스만 퇴행

민감한 출력 레이어

해당 head에 레이어별 재정의 추가

Transformer 품질이 여러 block 뒤에서 하락

projection/attention 오차 누적

Projection 레이어에 가중치 스케일 탐색 또는 HessianQuant 적용

빌드마다 품질이 다름

캘리브레이션/탐색 입력이 불안정

검증된 스케일 또는 샘플 저장 후 재사용

추천 설정 예시#

가능하면 프리셋에서 시작하고, 관찰된 문제와 직접 관련된 양자화 하위 설정만 바꿉니다.

기본 프로덕션 빌드#

프리셋으로 검증이 통과할 때 사용합니다.

from qbcompiler import CompileConfig

config = CompileConfig(preset="classification")
# 캘리브레이션 데이터는 일반 compile 또는 quantize command에 전달합니다.

영향: 유지보수가 가장 쉽고 튜닝 시간이 짧습니다. 정확도와 성능은 검증된 프리셋 기본값을 따릅니다.

더 안정적인 활성화 캘리브레이션#

출력이 전반적으로 비슷하지만 일부 샘플에서 클리핑처럼 보이는 오류가 있을 때 사용합니다.

from qbcompiler import CalibrationConfig, CompileConfig

config = CompileConfig(
    preset="detection",
    calibration=CalibrationConfig(
        # 사용하는 qb Compiler 버전에서 지원하는 range/값 분포 정책을 선택합니다.
        # Quantization 복잡도를 높이기 전에 대표 sample 확보를 우선합니다.
    ),
)

영향: 런타임 정밀도를 바꾸지 않고 정확도를 회복할 수 있습니다. 더 많은 샘플이나 통계를 사용하면 컴파일 시간은 늘어날 수 있습니다.

가중치에 민감한 트랜스포머 또는 큰 선형 모델#

캘리브레이션은 맞지만 행렬 연산이 많은 블록에 품질 손실이 집중될 때 사용합니다.

from qbcompiler import CompileConfig, HessianQuantConfig, SearchWeightScaleConfig

config = CompileConfig(
    preset="llm",
    search_weight_scale=SearchWeightScaleConfig(),
    hessian_quant=HessianQuantConfig(),
)

영향: 런타임 bit-width를 바꾸지 않고 정확도를 개선할 수 있습니다. 컴파일 시간과 메모리 사용량은 증가할 수 있으므로 문제가 일부 레이어에만 있다면 범위를 좁힙니다.

재현 가능한 양자화 실험#

컴파일러 버전, 프리셋, 모델 내보내기 차이를 비교할 때 사용합니다.

from qbcompiler import CompileConfig, SaveSampleConfig

config = CompileConfig(
    preset="vision_transformer",
    save_sample=SaveSampleConfig(),
)

영향: 같은 샘플 집합으로 실험을 고정해 재현성을 높입니다. 큰 입력이나 많은 중간 텐서를 저장하면 디스크 사용량과 빌드 시간이 증가할 수 있습니다.