[안드로이드 앱 생성]PyTorch 모델을 TensorFlow Lite모델로 변환
2024. 6. 3. 14:08ㆍ컴퓨터과학
728x90
반응형
[작업 개요]
ㆍ 텍스트 분류 기능을 파이썬으로 코딩하여 PyTorch모델을 만들었다.
- pytorch_model.bin [679MB]
- BERT 자연어처리 분류모델로 작성
- 안드로이드 앱에서 해당 모델 기능 사용하기 위해 파일 형식 변환이 필요
- 변환 후에 사이즈 경량화가 필요한 경우 추가작업이 필요
[ 모델 파일 변환 계획 ]
- 모델파일 형식 변경(경량화는 아직 안함)
- (필요시)변경된 파일에 추가 경량화
- 경량화된 모델파일 생성하고 경량화 추가작업 수행
ㆍ 계획 ① 모델파일 형식 변경
- PyTorch 모델인 pytorch_model.bin 파일은 안드로이드에서 직접 구동되지 않는 파일 형식입니다. 따라서, 이 모델을 TensorFlow Lite 포맷인 tflite 파일로 변환하는 작업은 안드로이드에서 구동 가능한 모델로 만들기 위한 변환 작업입니다.
- 모델 포맷 변환: PyTorch 모델을 안드로이드 환경에서 사용할 수 있는 TensorFlow Lite 모델로 변환.
- 경량화: 변환 과정에서 모델을 경량화하여 안드로이드 디바이스에서 효율적으로 실행될 수 있도록 함.
- ONNX 변환: PyTorch 모델을 ONNX 포맷으로 변환하여 다양한 프레임워크와 호환성을 높임.(model.onnx)
- TensorFlow 변환: ONNX 모델을 TensorFlow 포맷으로 변환하여 TensorFlow Lite로 변환할 준비를 함. (saved_model.pb)
- TensorFlow Lite 변환: TensorFlow 모델을 TensorFlow Lite 포맷으로 변환하여 모바일 환경에서 실행 가능하게 함. (bert_model.tflite)
- 작업 환경 : 구글 Colab
연결된 런타임:
Python 3 Google Compute Engine 백엔드 (GPU)
RAM: 10.09 GB/12.67 GB
디스크: 31.70 GB/78.19 GB
[모델 변환]
▶변환을 왜해?
1. Android 호환성: TensorFlow Lite는 Android 및 iOS와 같은 모바일 및 임베디드 장치에서 기계 학습 모델을 실행하기 위해 설계되었습니다. PyTorch 모델(pytorch_model.bin)은 직접적으로 Android에서 실행할 수 없기 때문에 TensorFlow Lite 형식으로 변환해야 합니다. 2. 성능 최적화: TensorFlow Lite는 모델을 모바일 장치에서 효율적으로 실행할 수 있도록 최적화된 인터프리터를 제공합니다. 이는 메모리 사용량을 줄이고, 추론 시간을 단축시킵니다. 3. 경량화: TensorFlow Lite 모델은 경량화되어 모바일 장치에서 빠르고 효율적으로 실행할 수 있습니다. 이는 배터리 소모와 같은 자원 소비를 줄여줍니다. 4. 에코시스템 통합: TensorFlow Lite는 TensorFlow 에코시스템의 일부로, Android에서 쉽게 통합할 수 있는 다양한 도구와 라이브러리를 제공합니다. |
▶변환 파이썬 코드
ㆍPyTorch to ONNX
*PyTorch가 뭔데
더보기
1. PyTorch 모델 (pytorch_model.bin)
- 구조: PyTorch 모델은 .bin 형식으로 저장됩니다. 이는 PyTorch 프레임워크에서 모델의 가중치와 구조를 포함하는 바이너리 파일입니다.
- 유연성: PyTorch는 동적 연산 그래프를 사용하여 유연한 모델 정의와 디버깅을 지원합니다.
- 학습 및 추론: 주로 학습(Training)과 추론(Inference)에 사용되며, 연구 및 프로토타입 개발에 적합합니다.
- 호환성 문제: PyTorch 모델은 Android와 같은 모바일 장치에서 직접 실행하기 어렵습니다.
* ONNX가 뭔데
더보기
2. ONNX 모델 (bert_model.onnx)
- 구조: ONNX(Open Neural Network Exchange) 모델은 다양한 딥러닝 프레임워크 간의 상호 운용성을 제공하기 위해 설계된 오픈 형식입니다.
- 변환: PyTorch 모델을 ONNX 형식으로 변환하여 다른 프레임워크(TensorFlow 등)에서 사용할 수 있습니다.
- 유연성: 다양한 딥러닝 프레임워크에서 모델을 사용할 수 있도록 지원합니다.
- 중간 형식: ONNX는 주로 모델 변환의 중간 형식으로 사용됩니다.
*변환 코드
더보기
# 1.PyTorch 모델을 조각으로 나누어 ONNX로 변환:
import torch
import torch.onnx
import onnx
from transformers import BertForSequenceClassification, BertConfig, BertTokenizer
# 모델 경로 및 설정
model_dir = '/content/gdrive/MyDrive/Uplus/bert/module/model240423_ver6.6.5_현장등록용_epoch5'
model_path = f'{model_dir}/pytorch_model.bin'
onnx_model_path = '/content/gdrive/MyDrive/Uplus/AndroidStudio/lite_model1/model.onnx'
# Bert 모델 구성 로드
config = BertConfig.from_pretrained(model_dir)
tokenizer = BertTokenizer.from_pretrained(model_dir)
# PyTorch 모델 로드
state_dict = torch.load(model_path, map_location=torch.device('cpu'))
# BertForSequenceClassification 인스턴스 생성 및 state_dict 로드
pytorch_model = BertForSequenceClassification(config)
pytorch_model.load_state_dict(state_dict)
# 사용자 정의 래퍼 함수
class CustomModel(torch.nn.Module):
def __init__(self, model):
super(CustomModel, self).__init__()
self.model = model
def forward(self, input_ids):
outputs = self.model(input_ids)
return outputs.logits
wrapped_model = CustomModel(pytorch_model)
# PyTorch 모델을 ONNX로 변환
dummy_input = torch.randint(0, config.vocab_size, (1, 128)).to('cpu') # 모델에 맞는 입력 크기로 설정 (BertModel은 일반적으로 1, 128)
torch.onnx.export(wrapped_model, dummy_input, onnx_model_path,
input_names=["input_ids"], output_names=["logits"], opset_version=14)
print("ONNX model conversion completed successfully.")
ㆍONNX to TensorFlow
* TensorFlow가 뭔데
더보기
3. TensorFlow 모델 (bert_model.pb)
- 구조: TensorFlow 모델은 .pb 형식(Protocol Buffers)으로 저장됩니다. 이는 모델의 그래프 구조와 가중치를 포함합니다.
- 광범위한 사용: 연구, 프로덕션, 모바일 등 다양한 환경에서 사용됩니다.
- 성능 최적화: TensorFlow는 모델 최적화 및 배포를 위한 다양한 도구와 라이브러리를 제공합니다.
- 변환 용이성: TensorFlow 모델은 TensorFlow Lite 모델로 쉽게 변환할 수 있습니다.
*변환 코드
더보기
# 2.ONNX 모델을 조각으로 나누어 TensorFlow로 변환:
import onnx
import tensorflow as tf
from onnx_tf.backend import prepare
# ONNX 모델 로드
onnx_model_path = '/content/gdrive/MyDrive/Uplus/AndroidStudio/lite_model1/model.onnx'
onnx_model = onnx.load(onnx_model_path)
# ONNX 모델을 TensorFlow 모델로 변환
tf_rep = prepare(onnx_model)
tf_model_dir = '/content/gdrive/MyDrive/Uplus/AndroidStudio/lite_model1/model_tf'
tf_rep.export_graph(tf_model_dir)
print("TensorFlow model conversion completed successfully.")
ㆍTensorFlow to TensorFlow Lite
*TensorFlow Lite가 뭔데
더보기
4. TensorFlow Lite 모델 (bert_model.tflite)
- 구조: TensorFlow Lite 모델은 .tflite 형식으로 저장됩니다. 이는 경량화되고 최적화된 모델 형식입니다.
- 모바일 최적화: 모바일 및 임베디드 장치에서의 빠르고 효율적인 추론을 위해 최적화되었습니다.
- 성능: 메모리 사용량이 적고, 빠른 추론 시간을 제공합니다.
- 경량화: 모델의 크기가 작아 배포 및 실행 시 자원 소모를 최소화합니다.
- 에코시스템 통합: TensorFlow Lite는 Android 및 iOS와 같은 플랫폼에서 쉽게 통합하고 사용할 수 있는 도구와 라이브러리를 제공합니다.
*변환 코드
더보기
# 3.TensorFlow 모델을 조각으로 나누어 TensorFlow Lite로 변환:
import tensorflow as tf
# TensorFlow 모델을 TFLite로 변환
converter = tf.lite.TFLiteConverter.from_saved_model(tf_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS, # Enable default ops.
tf.lite.OpsSet.SELECT_TF_OPS] # Enable TensorFlow ops.
tflite_model = converter.convert()
# TFLite 모델 저장
tflite_model_path = '/content/gdrive/MyDrive/Uplus/AndroidStudio/lite_model1/bert_model.tflite'
with open(tflite_model_path, "wb") as f:
f.write(tflite_model)
print("TFLite model conversion completed successfully.")
ㆍ 계획 ② (필요시)변경된 파일에 추가 경량화
- tflite파일 사이즈가 커서(100MB보다 작아야 한다고 함) 앱에서 구동이 안됨. 추가 경량화가 필요함.
- 모델 경량화 방안은 여러가지임.
▽ 간략히 비교글 ▽
더보기
모델 경량화 방안 정리 각 단계와 사용된 방법, 생성된 파일, 그리고 해당 방식의 특징
- Quantize 방식
입력 파일: saved_model.pb
출력 파일: quantized_model.tflite
특징: 모델의 파라미터 값을 32비트에서 8비트로 줄여 모델 크기를 줄이고 속도 향상. - Prune 방식
입력 파일: saved_model.pb
출력 파일: pruned_model.tflite
특징: 모델의 불필요한 파라미터를 제거하여 경량화. - Simplified 방식
입력 파일: model.onnx
출력 파일: model_simplified.onnx
특징: 모델의 불필요한 연산을 제거하여 경량화. - Sliced 방식
입력 파일: model.onnx
출력 파일: model_sliced.onnx
특징: 모델의 일부 레이어를 제거하여 경량화. - Hybrid 방식
입력 파일: model.onnx
출력 파일: hybrid_model.tflite
특징: Prune와 Quantize 방식 등을 혼합하여 경량화를 시도.
- 프루닝작업 수행
더보기
# [추가] 프루닝(Pruning): 가중치의 일부를 제거하여 모델 크기를 줄이는 방법
# !pip install tensorflow_model_optimization
import tensorflow as tf
import numpy as np
from transformers import TFBertForSequenceClassification, BertConfig
import tensorflow_model_optimization as tfmot
# 모델 디렉토리 및 경로
model_dir = '/content/gdrive/MyDrive/Uplus/bert/module/model240423_ver6.6.5_현장등록용_epoch5'
model_path = f'{model_dir}/pytorch_model.bin'
saved_model_dir = '/content/gdrive/MyDrive/Uplus/AndroidStudio/lite_model1/model_tf'
tflite_model_path = '/content/gdrive/MyDrive/Uplus/AndroidStudio/lite_model1/bert_model_pruned.tflite'
# Bert 모델 구성 로드
config = BertConfig.from_pretrained(model_dir)
model = TFBertForSequenceClassification.from_pretrained(model_dir, from_pt=True)
# 프루닝 적용 함수 정의
prune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude
pruning_params = {
'pruning_schedule': tfmot.sparsity.keras.PolynomialDecay(initial_sparsity=0.50,
final_sparsity=0.80,
begin_step=0,
end_step=1000)
}
# 프루닝 적용 가능 여부를 확인하는 함수
def is_prunable(layer):
return isinstance(layer, tf.keras.layers.Dense) or isinstance(layer, tf.keras.layers.Conv2D)
# 모델의 프루닝을 적용한 레이어를 반환하는 함수
def apply_pruning_to_layers(model):
for i, layer in enumerate(model.layers):
if is_prunable(layer):
model.layers[i] = prune_low_magnitude(layer, **pruning_params)
if hasattr(layer, 'layers'):
model.layers[i] = apply_pruning_to_layers(layer)
return model
# 프루닝 적용된 모델 생성
model = apply_pruning_to_layers(model)
# 모델 컴파일
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# 프루닝 동안 모델 훈련
logdir = "/content/gdrive/MyDrive/Uplus/AndroidStudio/logs"
callbacks = [
tfmot.sparsity.keras.UpdatePruningStep(),
tfmot.sparsity.keras.PruningSummaries(log_dir=logdir),
]
# 여기서는 예제 데이터셋을 사용했으나 실제 데이터셋으로 대체해야 함
# 데이터 타입을 int32로 설정
input_ids = np.random.randint(0, config.vocab_size, (32, 128), dtype=np.int32)
labels = np.random.randint(0, 2, (32,), dtype=np.int32) # 레이블 데이터가 None이 아닌지 확인
train_data = tf.data.Dataset.from_tensor_slices((input_ids, labels))
train_data = train_data.batch(8)
model.fit(train_data, epochs=2, callbacks=callbacks)
# 프루닝 스트립 함수
def strip_pruning_from_layers(model):
for layer in model.layers:
if isinstance(layer, tfmot.sparsity.keras.PruneLowMagnitude):
model = tfmot.sparsity.keras.strip_pruning(layer)
if hasattr(layer, 'layers'):
strip_pruning_from_layers(layer)
return model
# 프루닝 스트립 및 저장
model = tf.keras.models.clone_model(model)
model.save(saved_model_dir, save_format='tf')
# TFLite 변환자 생성 (양자화 적용)
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
# TFLite 모델 변환
tflite_model = converter.convert()
# TFLite 모델 저장
with open(tflite_model_path, 'wb') as f:
f.write(tflite_model)
print("Pruned TFLite model conversion completed successfully.")
결과 : 170M로 경량화됨
ㆍ 계획 (번외) ③ 경량화된 모델파일 생성하고 경량화 추가작업 수행
- tflite파일 사이즈가 커서(100MB보다 작아야 한다고 함) 앱에서 구동이 안됨. 추가 경량화가 필요함.
- 채택 방식 : 기존의 BERT모델을 아예 다시만든다. 처음부터 경량화BERT를 만들고 그 다음에 경량화작업을 또 한다.
- 모델 자체를 작게하는 방법을 수행한 뒤 경량화를 진행하는 것임.
ㆍ경량화BERT..? 그게 뭔데
더보기
BERT 모델과 DistilBERT의 차이 및 선택 이유
BERT와 DistilBERT의 차이
- BERT (Bidirectional Encoder Representations from Transformers):
- BERT는 Google에서 개발한 대규모 사전 학습 언어 모델로, 자연어 처리(NLP) 작업에서 뛰어난 성능을 보입니다.
- 많은 매개변수(약 110M~340M 파라미터)를 가지고 있으며, 여러 NLP 태스크에서 우수한 성능을 보여줍니다.
- 그러나 대규모 모델이므로 훈련 및 추론 시 많은 계산 자원과 시간이 필요합니다.
- DistilBERT:
- DistilBERT는 BERT의 경량화 버전으로, Hugging Face에서 개발하였습니다.
- BERT의 약 60%의 파라미터와 계산량을 가지면서도 성능의 약 97%를 유지합니다.
모델 크기가 작아 추론 속도가 빠르고, 계산 자원이 적게 들기 때문에 모바일 및 임베디드 시스템에 적합합니다.
ㆍ파일 용량 변화 비교
- BERT 모델 변환 과정
- BERT 모델 (700MB) -> TensorFlow Lite 모델 (170MB)
- DistilBERT 모델 변환 과정
- DistilBERT 모델 (517MB) -> TensorFlow Lite 모델 (65.5M)
끝.
728x90
반응형
'컴퓨터과학' 카테고리의 다른 글
접근성 서비스(Accessibility Service): 안드로이드의 접근성 보조 기능 (0) | 2024.08.22 |
---|---|
[현장 개발용어 기초개념]현장 담당자가 DevOps를 말하는 의도는 무엇인가 (0) | 2024.06.28 |
AndroidStudio로 APK만들기 (계획짜기) (0) | 2024.06.03 |
[AndroidStudio]Manifest merger failed with multiple errors, see logsDuplicate class 오류Java heap space 문제 (0) | 2024.05.30 |
AWS로 서비스 배포하기(3) _DB연결하기(PuTTY, sqlDeveloper, eclipse) (0) | 2021.08.19 |