NVIDIA AI Tech Workshop at NIPS 2018 -- Session3: Inference and Quantization


youtube link

What is quantization for inference?

4-bit Quantization

$$ \begin{pmatrix} -1.54 & 0.22 \ -0.026 & 0.65 \end{pmatrix} \times \begin{pmatrix} 0.35 \ -0.51 \end{pmatrix} = \begin{pmatrix} -0.65 \ -0.423 \end{pmatrix}$$

스크린샷 2019-02-06 오전 9.16.19

위와 같이 각각을 Quantization하게 된다.
각각의 행렬을 다른 범위로 양자화해도 상관 없다.
이 때 중요한것은 FP범위로 봤을 때 [-2, 2)인 것을 정밀하게 분포로 표현하고 해당 눈끔을 8개로 쪼개서 [-8, 8)로 표현한다. 그다음 각각을 가장 근접한 INT8 숫자로 변환하면 된다. 왜냐하면 4bit로 표현할 수 있는 숫자의 범위가 [-8, 8)이기 때문이다.

1bit: signed
3bit: number

스크린샷 2019-02-06 오전 9.35.44

위와 같이 나머지들도 각각 변환해 준다. 두 번째 matrix의 경우 [-1,1)의 범위 레인지를 잡고 양자화 시켰다.

결국 두 행렬은 각각 스케일 x4, x8을 한 것이다. 연산을 수행하고 나온 결과를 다시 복구 하기위해서 32의 최종 스케일 값으로 나누면 된다.
결과가 약간 다르지만 얼추 비슷하면 딥러닝에선 잘 동작하게 된다.

Important takeaways

  • A centered quantization scheme is equivalent to sacle, then round
  • An uncentered quantization scheme is equivalent to scale-plus-shift, then round
  • It is possible to take the output and either dequantize-to-float or directly requantize at the appropirate scale for the next operation
    • This is straightforward for scale-only, a little tricky for scale-and-shift
      However, the output must initially have a wider type than the inputs

Quantizing for accuracy and speed

Quantized Network Accuracy
스크린샷 2019-02-06 오전 10.18.28

Sacle-only quantization
스크린샷 2019-02-06 오전 10.20.01

Per-channel scaling
스크린샷 2019-02-06 오전 10.20.41

Training for Quantization
스크린샷 2019-02-06 오전 10.21.22

Conclusion

  • Quantization is not magic, but instead simply a matter of choosing min/max values and mapping weights/activation to index of nearest presentable value
  • Turing has extensive support for accelerating INT8 networks and experimental support for really accelerating INT4 and INT1 models
  • Prefer sacle-only (centered) quantization for performance
  • Fine-grained (per-channel) scaling of wieghts is good for accuracy

Post-Training calibration

자동을 통해서 잘 처리 한다. 하지만 아래와 같은 특수한 상황이 존재 한다면:

  • You already know the dynamic range?
  • You only want to quantize part of the network?
  • It dosn't work?

A Harder case

Yolov1을 가지고 실험 했을 때 int8로 단순히 Quantization을 수행하면 아래와 같은 문제가 발생함.

스크린샷 2019-02-06 오전 9.51.34

정확도 Drop이 발생했음을 분석함

스크린샷 2019-01-11 오전 11.25.26

  • 먼저 각각의 tensor에서의 activiation의 분포를 분석
  • 그리고 어디서 cutoff할지를 파악한다. 최대한 original distribution과 최대한 비슷한지를 파악하게 됨. metric으론 KL Divergence를 이용하게 됨.
    • 근데 이 때 각각의 tensor에 따라 loss를 최소로 하는 Dynamic-Range를 적용하게 됨.
    • 이것이 각각 Calibration-Cache에 저장되게 됨.
    • 이러한 값들은 tensor별로 저장되며 hex로 저장됨. 이것은 Human-Readable 하지는 않다. 그렇다고 심하게 obfuscation되어 있지도 않다.

Mixed Precision networks
하나의 전략은 앞쪽레이어에서는 INT 8을 쓰고 뒤로 갈수록 높은 precision을 사용 한다. 왜냐하면, Later Layers are more sensitive to Noise 이기 때문이다.

for(<all lauers)
  layer -> setprecision(DataType::INT8)

fc25 -> setPrecision(DataType:FP16)
fc26 -> setPrecision(DataType::FP16)

이렇게 해도 잘 안나와서 디버깅을 해보면
First layer의 dynamic range는
Calibration cache

  • conv1: 18.1006
  • relu1: 13.2026
    이건 예상치 못한 결과이다. 왜냐하면 tensorRT는 scale-only calibration을 사용하게 된다.

이때 리키 렐루를 사용하게 되면 마이너스 값이 생기고
이게 비대칭이기 때문에 레프트 사이드가 아래와 같이 왜곡되어 버린다.
스크린샷 2019-02-06 오전 9.53.01
위 그래프 처럼 conv의 경우 nice bell-shaped을 나타낸다.
하지만 ReLU의 경우 모든 negative value들이 squashed되어 왼쪽에 몰려 있는것을 볼 수 있다.

YOLOv1에서 사용하는 Leaky ReLU (Parametric ReLU)의 값은 0.1을 가진다. 즉, 나누기 10을 한 것과 같다.
참조: https://medium.com/tinymind/a-practical-guide-to-relu-b83ca804f1f7

원하는 ReLU의 분포가 다르게 나타난다.

TensorRTv5에서 지원하는 것이 Bring your own Calibration

for(<each leaky relu){
  float c = <conv dynamic range>;
  leakyRelu->setDynamicRange(-c,c);
}

이렇게 각각의 렐루를 다르게 quant.하면 아래와 같이 어느정도 복구가 된다.
스크린샷 2019-02-06 오전 9.58.46

요약
Getting the bset from INT8

  • Dynamic Range from Training:
    • ITensor::setDynamicRange()
  • Mixed Precision is easy to try
    • IBuilder::setStrictTypeConstraints()
    • ILayer:setPrecision()
  • TRT Calibration makes local decisions
  • Improve using insights from:
    • Calibration Cache
    • Network structure
    • Operator properties
  • Try the Legacy Calibrator (requires a parameter sweep, but then works for YOLOv1.)

Also In TensorRT
TensorRT 5:

  • New Python API
  • Global Plugin Registry
  • Integrated ONNX Parser
  • Devices: Xavier, Turing
  • DLA FP16
  • Windows

Comming Soon:

  • Reinforcement Learning Support
  • Plugins & Parsers --> OSS
  • DLA INT8

TensorFlow backend with tensorRT 공식 Github: https://github.com/tensorflow/tensorrt

TensorRT 부분

스크린샷 2019-01-11 오후 12.09.33

스크린샷 2019-01-11 오후 3.49.37

스크린샷 2019-01-11 오후 4.03.54


+ Recent posts