티스토리 뷰

지난 시간에 양자화가 무엇이고 Tensorflow 프레임워크 내에 있는 TFLite를 이용해서 양자화가 가능한 방법에 대해서 설명했었는데요.

https://hero-space.tistory.com/146

 

AI 모델 경량화의 지름길 TFLite Quantization

다양한 AI 모델이 시시각각 나오는 시대에서 경량화에 대한 이슈도 그만큼 높아져 가고 있는데요. 모델이 작으면서 정확도가 좋다면 그만큼 리소스를 절약할 수 있기 때문에 다양한 산업군에서

hero-space.tistory.com

실제 AI 사용모델을 가지고 학습 완료된 모델 파일에 대한 양자화를 진행해 보도록 하겠습니다.

Float16 Post Quantization [Default]

from __future__ import absolute_import, division, print_function
import tensorflow as tf
import numpy as np

new_model = tf.keras.models.load_model('./saved')
new_model.summary()

# tflite converter
converter = tf.lite.TFLiteConverter.from_keras_model(new_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]

tflite_model = converter.convert()
open("quant_model_2.tflite", "wb").write(tflite_model)

print("Model successfully converted into tflite file.")

Float16 Post Quantization [Optimze For Latency]

from __future__ import absolute_import, division, print_function
import tensorflow as tf
import numpy as np

new_model = tf.keras.models.load_model('./saved')
new_model.summary()

# tflite converter
converter = tf.lite.TFLiteConverter.from_keras_model(new_model)
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_LATENCY]
converter.target_spec.supported_types = [tf.float16]

tflite_model = converter.convert()
open("quant_model_2.tflite", "wb").write(tflite_model)

print("Model successfully converted into tflite file.")

Int8 Post Quantization [Default]

from __future__ import absolute_import, division, print_function
import tensorflow as tf
import numpy as np

new_model = tf.keras.models.load_model('./saved')
new_model.summary()

# tflite converter
converter = tf.lite.TFLiteConverter.from_keras_model(new_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.uint8]

tflite_model = converter.convert()
open("quant_model_3-1.tflite", "wb").write(tflite_model)

print("Model successfully converted into tflite file.")

Int8 Post Quantization [Optimze For Latency]

from __future__ import absolute_import, division, print_function
import tensorflow as tf
import numpy as np

new_model = tf.keras.models.load_model('./saved')
new_model.summary()

# tflite converter
converter = tf.lite.TFLiteConverter.from_keras_model(new_model)
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_LATENCY]
converter.target_spec.supported_types = [tf.uint8]

tflite_model = converter.convert()
open("quant_model_3-1.tflite", "wb").write(tflite_model)

print("Model successfully converted into tflite file.")

Dynamic Range Convert

from __future__ import absolute_import, division, print_function
import tensorflow as tf
import numpy as np

new_model = tf.keras.models.load_model('./saved')
new_model.summary()

# tflite converter
converter = tf.lite.TFLiteConverter.from_keras_model(new_model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]

tflite_model = converter.convert()
open("quant_model_3-1.tflite", "wb").write(tflite_model)

print("Model successfully converted into tflite file.")

각 케이스별에 대한 정의는 타입에 따라서 이해되실 거라 생각하고 Dynamic Range에 대해서만 간략히 설명하면 아래와 같습니다.

Dynamic Range 양자화는 학습이 완료된 모델을 변환할 때 32비트 부동 소수점인 가중치를 8비트의 정밀도로 정적으로 양자화 합니다. 따라서 모델의 크기가 1/4정도로 줄어들며 추론할 때에는 8비트 값을 다시 32비트 부동 소수점으로 변환하고 부동 소수점 커널을 사용하여 계산합니다. 만약 수행할 연산이 양자화된 커널을 지원한다면 활성화는 계산 전에 동적으로 8비트 정수형으로 변환한 후 양자화된 커널을 사용하여 계산하고, 계산이 끝나면 다시 32비트 역양자화(de-quantization) 됩니다. 성능을 위해 한 번 변환한 값은 캐싱하여 재사용하게됩니다.

Insight

  • Raspberry Pi 3B+ 기준, Float16 양자화한 결과가 INT8 양자화보다 FPS, Latency는 더 좋고, 사이즈는 INT8 양자화 후 사이즈가 더 작았음
    • 이는 양자화 선택 가이드 플로우 다이어그램에 나오듯, 모델이 정수 연산을 진행하는데, 영상의 이미지 픽셀은 float으로 제공되는 문제 때문에 발생하는 것으로 예측할 수 있음 (만약 int8로 연산할 수 없는 상황이라면 다시 float32로 연산하기 때문)

 

텐서플로우 라이트를 사용해서 학습 후 생성된 모델 파일을 양자화 하여 각각 테스트를 진행해보았는데요, 아주 작게 줄인다고 해서 무조건 적으로 좋은 것이 아니라 정확도도 같이 수반되어야 하니 테스트를 반드시 해보는 것이 좋습니다. 그렇다고 리니어하게 경량화와 정확도가 상관관계가 아닐 수 도 있으니 반드시 확인하시면 좋겟습니다. 이어서, 다른 경량화 방법도 공유하도록 하겠습니다.

댓글