[ML Model Convert] Pytorch -> TFLite Convert

eetocs·2022년 9월 23일
2

ML Model Convert

목록 보기
1/2

들어가기 앞서, 우리 모두 Pinto0309님께 큰절 한번씩 합시다.

문제 1 : 대부분 SOTA 모델은 Pytorch인데, Mobile inference 최적화는 TFLite가 잘되어 있음
문제 2 : Pytorch->TFlite의 공식 지원은 없으며, 개개인이 구현한 convert 방법들은 지원하는 Layer가 매우 한정적임

해결책 : Pinto0309님이 만들어논 openvino2Tensorflow가 그나마 낫다. (완벽하진 않음)

Convert 순서

Pytorch -> onnx -> onnx-simplify -> openvino -> TFLite

Pytorch -> onnx

onnx -> onnx-simplify

  • https://github.com/daquexian/onnx-simplifier
  • onnx export를 하면 잡다한 shape, gather 연산같은게 덕지덕지 붙어있는 경우가 있음
    다음과 같은 연산이 convert과정에 문제 발생 가능성 높음
  • onnx-simplify로 말끔하게 해결(좌측 : onnx-simplify 전, 우측 : onnx-simplify 후)

onnx-simplify -> openvino

  • Intel에서 만든 Deep learning Inference Toolkit으로 Intel CPU에서 최적이다.
  • openvino는 (xml, mapping, bin)으로 구성되어짐

onnx -> openvino convert 방법 1

  1. 해당 링크(https://www.intel.com/content/www/us/en/developer/tools/openvino-toolkit/download.html) 가서 openvino 설치
  2. onnx2openvino convert
python3 mo.py --input_model <INPUT_MODEL>.onnx ##openvino 파일 생성(xml, bin, mapping)

onnx -> openvino convert 방법 2

  1. 어차피 openvino2tensorflow docker에 openvino 환경 구성까지 되어있음
docker pull ghcr.io/pinto0309/openvino2tensorflow:latest
docker run -it --rm \
  -v `pwd`:/home/user/workdir \
  ghcr.io/pinto0309/openvino2tensorflow:latest
  1. onnx2openvino convert
python3 mo.py --input_model <INPUT_MODEL>.onnx ##openvino 파일 생성(xml, bin, mapping)
  • openvino 최종 output(xml, bin, mapping) 확인
  • openvino 모델도 Netron 보는게 용이함

openvino -> TFLite

  1. docker run
docker pull ghcr.io/pinto0309/openvino2tensorflow:latest
docker run -it --rm \
  -v `pwd`:/home/user/workdir \
  ghcr.io/pinto0309/openvino2tensorflow:latest
  1. openvino2TFlite
openvino2tensorflow \
  --model_path <input_model>.xml \
  --output_saved_model \                             #saved model True
  --output_pb \                                      #pb model True
  --output_float16_quant_tflite \                    #float16 Quantize
  --output_no_quant_float32_tflite \                 #float32
  ##########################################################################
  #-weight_replacement_config=config.json            #아래에서 자세하게 설명
  #########################################################################

가장 기본적인 convert 명령어로 다음과 같은 모델이 output으로 나옴.

  • saved model, pb model, tflite-fp16, tflite-fp32

참고사항(weight_replacement_config 옵션)

  • openvino-> TFlite convert가 한번에 잘되면 좋겠지만, 그렇지 않는 경우에 사용해야하는 config
  • 예상대로 동작하지 않는 부분을 해당 옵션을 통해 강제로 할당 시킴
    example json
    {
      "format_version": 2,
      "layers": [
          {
              "layer_id": "660",                      #openvino의 660번째 layer가 문제가 되서
              "type": "Reshape",                      #Reshape layer를 
              "replace_mode": "insert_after",         #660번째 layer 뒤에
              "values": [                             #다음과 같은 값으로 지정해줘
                  2100,
                  85
              ]
          }
      ]
    }
  • pinto가 지속적으로 버그 (5d transpose 제대로 동작안하던 문제) 수정을 해서 많은 부분 해결되었지만, 그럼에도 불구하고 tensorflow 태생적인 문제 때문에 해당 기능은 필요함

Tensorflow의 태생적인 문제 상황 예시

  • top-k layer : feature에서 특정 dim을 기준으로, k개의 상위 value와 그 index를 계산하는 layer로 딥러닝 모델에 종종 쓰이는 layer이다.

  • 우리 착한 pytorch에서는 다음과 같이 dimension을 지정할수 있게 지원해주는 반면

  • 우리의 Tensorflow는 그런거 모름 ㅋㅋㅋㅋㅋㅋ.

    • 돌려보면 아시겠지만, 마지막 끝 dimension(dim=-1)으로 강제 할당 되어 있습니다.

  • 이러한 Tensorflow의 구조를 고려하지 않으면, 딥러닝 모델의 Dimension이 깨지는 현상이 발생하게 됨
    • 모델의 최종 output shape이 이상하거나, convert 도중에 에러를 뿜게 되는 불상사가 발생...
  • 이러한 문제를 해결하기 위해서는, top-k layer 들어가기전에 강제로 transpose(target dim을 맨 뒤에 가도록)를 삽입해주는게 필요함!!

Pinto0309의 openvino2tensorflow는 사용한지 1년쯤 되어가는거 같은데요. 꾸준하게 계속 버그 수정 및 업데이트를 하시는걸 보면 정말 존경스럽다는 생각이 절로 듭니다...

profile
ML 잡부

0개의 댓글