LabHub
배우기 러닝패스 코스

AI 다이어트 실패 사건 · 스케일과 영점 · 실습

자를 직접 만든다 — 스케일·영점·왕복 오차

LabHub 에서 이어서 보기

목표

qmath.py 를 만들어 QuantizeLinear·DequantizeLinear 의 정의대로 스케일과 영점을 계산하고, 양자화와 역양자화를 구현하고, 왕복 오차가 스케일의 절반 안에 있는지 확인하고, 대칭과 비대칭 그리고 채널별 스케일과 텐서 전체 스케일을 같은 자료 위에서 견준다.

왜 중요한가

변환 도구가 내놓은 int8 모델의 정확도가 떨어졌을 때 고칠 곳을 고르려면, 그 도구가 안에서 하는 산술을 알아야 한다. 스케일은 관찰 범위를 눈금 수로 나눈 값이고, 영점은 실수 0.0 이 앉을 정수 자리다. 범위에 0 이 없으면 패딩과 ReLU 가 만든 0 이 0 이 아닌 값으로 되살아난다.
왕복 오차에는 상한이 있다. 값이 범위 안에 있는 한 오차는 스케일의 절반을 넘지 않는다 — 양자화가 값을 스케일 간격의 격자로 옮기는 일이기 때문이다. 그래서 오차가 그 절반을 크게 넘었다면 반올림이 아니라 범위가 문제다. 이 한 가지 잣대가 원인 판단을 빠르게 만든다.
자료의 모양도 방식을 정한다. ReLU 뒤의 활성은 전부 0 이상이라 대칭 int8 을 걸면 음수 쪽 눈금이 통째로 놀고 스케일이 두 배 거칠어진다. 가중치 행렬에 이상값이 하나 있으면 텐서 전체 스케일이 그 값에 끌려가 나머지가 전부 뭉개진다 — 채널을 나누면 피해가 그 채널 안에 갇힌다.
채점기는 여러분이 적어 낸 숫자를 믿지 않는다. 매번 다른 씨앗으로 배열을 만들어 여러분의 qmath.py 를 실제로 실행하고, 같은 입력을 ONNX 의 QuantizeLinear·DequantizeLinear 연산자에 그대로 태워 나온 결과와 대조한다.

단계

1. /root/onnxq-scale/gen_data.py 를 만들어 실행해 /root/onnxq-scale/data 아래 배열 세 벌을 만들고, /root/onnxq-scale/qmath.pyparams 를 구현하세요.
2. q 를 더해 실수 배열을 정수 배열로 내리세요.
3. dq 를 더해 정수 배열을 실수로 되돌리세요.
4. roundtrip 을 더해 왕복 오차와 그 상한을 함께 내게 하세요.
5. 범위를 일부러 좁혀 포화를 만들고 결과를 /root/onnxq-scale/saturate.json 에 적으세요.
6. 전부 0 이상인 자료에 대칭과 비대칭을 걸어 /root/onnxq-scale/symmetry.json 에 적으세요.
7. channel 을 더해 채널별 스케일과 텐서 전체 스케일을 견주고 /root/onnxq-scale/channel.json 에 적으세요.
8. /root/onnxq-scale/report.json/root/onnxq-scale/report.md 로 한 장에 정리하세요.

참고

단계 8개

  1. 관찰 범위를 스케일과 영점으로
  2. 실수를 정수 눈금으로 내리기
  3. 정수를 실수로 되돌리기
  4. 왕복 오차와 그 상한
  5. 범위를 좁히면 무엇이 깨지는가
  6. 0 이상만 나오는 자료에 대칭을 걸면
  7. 이상값 하나를 가두기
  8. 잰 것을 한 장으로