Hugging Face Optimum으로 Transformers를 ONNX로 변환하기
Hugging Face는 Transformers 모델을 Open Neural Network Exchange (ONNX) 형식으로 변환하는 세 가지 뚜렷한 경로를 제공하여 사용자가 세밀한 제어와 고수준 추상화 중에서 선택할 수 있도록 합니다. 가장 간편한 방법은 Optimum 라이브러리를 이용하는 것으로, 변환 과정을 자동화하면서 Hugging Face 파이프라인과의 호환성을 유지합니다.
Hugging Face Optimum을 사용한 고수준 변환
Optimum 라이브러리는 ORTModelForXxx 클래스를 통해 ONNX 변환을 가장 사용자 친화적으로 제공합니다. from_pretrained() 메서드에서 from_transformers=True 플래그를 설정하면 Optimum이 자동으로 기본 Transformers 모델을 로드하고 내부적으로 transformers.onnx 패키지를 사용해 ONNX로 변환합니다.
구현 예시:
from optimum.onnxruntime import ORTModelForSequenceClassification
model = ORTModelForSequenceClassification.from_pretrained("distilbert-base-uncased-finetuned-sst-2-english", from_transformers=True)
Optimum을 통해 변환된 모델은 즉시 예측에 사용할 수 있거나 Hugging Face 파이프라인에 직접 통합할 수 있습니다.
transformers.onnx를 사용한 중간 수준 변환
transformers.onnx 모듈은 구성 객체를 활용하여 변환 과정을 단순화하고, 사용자가 dynamic_axes와 같은 복잡한 매개변수를 수동으로 정의할 필요를 없앱니다.
구현 예시:
from pathlib import Path
import transformers
from transformers.onnx import FeaturesManager
from transformers import AutoConfig, AutoTokenizer, AutoModelForSequenceClassification
model_id = "distilbert-base-uncased-sst-2-english"
feature = "sequence-classification"
model = AutoModelForSequenceClassification.from_pretrained(model_id)
tokenizer = AutoTokenizer.from_pretrained(model_id)
model_kind, model_onnx_config = FeaturesManager.check_supported_model_or_raise(model, feature=feature)
onnx_inputs,
preprocessor=tokenizer,
model=model,
config=onnx_config,
opset=13,
output=Path("trfs-model.onnx")
)
torch.onnx를 사용한 저수준 변환
torch.onnx API는 가장 세밀한 제어를 제공하지만 input_names, output_names, dynamic_axes 등 여러 매개변수를 수동으로 지정해야 합니다.
구현 예시:
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
model_id = "distilbert-base-uncased-finetuned-sst-2-english"
model = AutoModelForSequenceClassification.from_pretrained(model_id)
tokenizer = AutoTokenizer.from_pretrained(model_id)
dummy_model_input = tokenizer("This is a sample", return_tensors="pt")
torch.onnx.export(
model,
tuple(dummy_model_input.values()),
f="torch-model.onnx",
input_names=['input_ids', 'attention_mask'],
output_names=['logits'],
dynamic_axes={'input_ids': {0: 'batch_size', 1: 'sequence'},
'attention_mask': {0: 'batch_size', 1: 'sequence'},
'logits': {0: 'batch_size', 1: 'sequence'}},
do_constant_folding=True,
opset_version=13,
)