Spaces:
Paused
ONNX๋ก ๋ด๋ณด๋ด๊ธฐ [[export-to-onnx]]
๐ค Transformers ๋ชจ๋ธ์ ์ ํ ํ๊ฒฝ์์ ๋ฐฐํฌํ๊ธฐ ์ํด์๋ ๋ชจ๋ธ์ ์ง๋ ฌํ๋ ํ์์ผ๋ก ๋ด๋ณด๋ด๊ณ ํน์ ๋ฐํ์๊ณผ ํ๋์จ์ด์์ ๋ก๋ํ๊ณ ์คํํ ์ ์์ผ๋ฉด ์ ์ฉํฉ๋๋ค.
๐ค Optimum์ Transformers์ ํ์ฅ์ผ๋ก, PyTorch ๋๋ TensorFlow์์ ๋ชจ๋ธ์ ONNX์ TFLite์ ๊ฐ์ ์ง๋ ฌํ๋ ํ์์ผ๋ก ๋ด๋ณด๋ผ ์ ์๋๋ก ํ๋ exporters
๋ชจ๋์ ํตํด ์ ๊ณต๋ฉ๋๋ค. ๐ค Optimum์ ๋ํ ์ฑ๋ฅ ์ต์ ํ ๋๊ตฌ ์ธํธ๋ฅผ ์ ๊ณตํ์ฌ ํน์ ํ๋์จ์ด์์ ๋ชจ๋ธ์ ํ๋ จํ๊ณ ์คํํ ๋ ์ต๋ ํจ์จ์ฑ์ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
์ด ์๋ด์๋ ๐ค Optimum์ ์ฌ์ฉํ์ฌ ๐ค Transformers ๋ชจ๋ธ์ ONNX๋ก ๋ด๋ณด๋ด๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. TFLite๋ก ๋ชจ๋ธ์ ๋ด๋ณด๋ด๋ ์๋ด์๋ TFLite๋ก ๋ด๋ณด๋ด๊ธฐ ํ์ด์ง๋ฅผ ์ฐธ์กฐํ์ธ์.
ONNX๋ก ๋ด๋ณด๋ด๊ธฐ [[export-to-onnx]]
ONNX (Open Neural Network eXchange)๋ PyTorch์ TensorFlow๋ฅผ ํฌํจํ ๋ค์ํ ํ๋ ์์ํฌ์์ ์ฌ์ธต ํ์ต ๋ชจ๋ธ์ ๋ํ๋ด๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ณตํต ์ฐ์ฐ์ ์ธํธ์ ๊ณตํต ํ์ผ ํ์์ ์ ์ํ๋ ์คํ ํ์ค์ ๋๋ค. ๋ชจ๋ธ์ด ONNX ํ์์ผ๋ก ๋ด๋ณด๋ด์ง๋ฉด ์ด๋ฌํ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ฒฝ๋ง์ ํตํด ๋ฐ์ดํฐ๊ฐ ํ๋ฅด๋ ํ๋ฆ์ ๋ํ๋ด๋ ๊ณ์ฐ ๊ทธ๋ํ(์ผ๋ฐ์ ์ผ๋ก _์ค๊ฐ ํํ_์ด๋ผ๊ณ ํจ)๊ฐ ๊ตฌ์ฑ๋ฉ๋๋ค.
ํ์คํ๋ ์ฐ์ฐ์์ ๋ฐ์ดํฐ ์ ํ์ ๊ฐ์ง ๊ทธ๋ํ๋ฅผ ๋ ธ์ถํจ์ผ๋ก์จ, ONNX๋ ํ๋ ์์ํฌ ๊ฐ์ ์ฝ๊ฒ ์ ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, PyTorch์์ ํ๋ จ๋ ๋ชจ๋ธ์ ONNX ํ์์ผ๋ก ๋ด๋ณด๋ด๊ณ TensorFlow์์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค(๊ทธ ๋ฐ๋๋ ๊ฐ๋ฅํฉ๋๋ค).
ONNX ํ์์ผ๋ก ๋ด๋ณด๋ธ ๋ชจ๋ธ์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค:
- ๊ทธ๋ํ ์ต์ ํ ๋ฐ ์์ํ์ ๊ฐ์ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ ์ถ๋ก ์ ์ํด ์ต์ ํ๋ฉ๋๋ค.
- ONNX Runtime์ ํตํด ์คํํ ์ ์์ต๋๋ค.
ORTModelForXXX
ํด๋์ค๋ค์ ํตํด ๋์ผํAutoModel
API๋ฅผ ๋ฐ๋ฆ ๋๋ค. ์ด API๋ ๐ค Transformers์์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํฉ๋๋ค. - ์ต์ ํ๋ ์ถ๋ก ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ ๐ค Transformers์ [
pipeline
] ํจ์์ ๋์ผํ API๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๐ค Optimum์ ๊ตฌ์ฑ ๊ฐ์ฒด๋ฅผ ํ์ฉํ์ฌ ONNX ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์ง์ํฉ๋๋ค. ์ด๋ฌํ ๊ตฌ์ฑ ๊ฐ์ฒด๋ ์ฌ๋ฌ ๋ชจ๋ธ ์ํคํ ์ฒ์ ๋ํด ๋ฏธ๋ฆฌ ์ค๋น๋์ด ์์ผ๋ฉฐ ๋ค๋ฅธ ์ํคํ ์ฒ์ ์ฝ๊ฒ ํ์ฅํ ์ ์๋๋ก ์ค๊ณ๋์์ต๋๋ค.
๋ฏธ๋ฆฌ ์ค๋น๋ ๊ตฌ์ฑ ๋ชฉ๋ก์ ๐ค Optimum ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
๐ค Transformers ๋ชจ๋ธ์ ONNX๋ก ๋ด๋ณด๋ด๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ฌ๊ธฐ์์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ชจ๋ ๋ณด์ฌ์ค๋๋ค:
- ๐ค Optimum์ ์ฌ์ฉํ์ฌ CLI๋ก ๋ด๋ณด๋ด๊ธฐ
optimum.onnxruntime
์ ์ฌ์ฉํ์ฌ ๐ค Optimum์ผ๋ก ONNX๋ก ๋ด๋ณด๋ด๊ธฐ
CLI๋ฅผ ์ฌ์ฉํ์ฌ ๐ค Transformers ๋ชจ๋ธ์ ONNX๋ก ๋ด๋ณด๋ด๊ธฐ [[exporting-a-transformers-model-to-onnx-with-cli]]
๐ค Transformers ๋ชจ๋ธ์ ONNX๋ก ๋ด๋ณด๋ด๋ ค๋ฉด ๋จผ์ ์ถ๊ฐ ์ข ์์ฑ์ ์ค์นํ์ธ์:
pip install optimum[exporters]
์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ์ธ์๋ฅผ ํ์ธํ๋ ค๋ฉด ๐ค Optimum ๋ฌธ์๋ฅผ ์ฐธ์กฐํ๊ฑฐ๋ ๋ช ๋ น์ค์์ ๋์๋ง์ ๋ณด์ธ์.
optimum-cli export onnx --help
์๋ฅผ ๋ค์ด, ๐ค Hub์์ distilbert-base-uncased-distilled-squad
์ ๊ฐ์ ๋ชจ๋ธ์ ์ฒดํฌํฌ์ธํธ๋ฅผ ๋ด๋ณด๋ด๋ ค๋ฉด ๋ค์ ๋ช
๋ น์ ์คํํ์ธ์:
optimum-cli export onnx --model distilbert-base-uncased-distilled-squad distilbert_base_uncased_squad_onnx/
์์ ๊ฐ์ด ์งํ ์ํฉ์ ๋ํ๋ด๋ ๋ก๊ทธ๊ฐ ํ์๋๊ณ ๊ฒฐ๊ณผ์ธ model.onnx
๊ฐ ์ ์ฅ๋ ์์น๊ฐ ํ์๋ฉ๋๋ค.
Validating ONNX model distilbert_base_uncased_squad_onnx/model.onnx...
-[โ] ONNX model output names match reference model (start_logits, end_logits)
- Validating ONNX Model output "start_logits":
-[โ] (2, 16) matches (2, 16)
-[โ] all values close (atol: 0.0001)
- Validating ONNX Model output "end_logits":
-[โ] (2, 16) matches (2, 16)
-[โ] all values close (atol: 0.0001)
The ONNX export succeeded and the exported model was saved at: distilbert_base_uncased_squad_onnx
์์ ์์ ๋ ๐ค Hub์์ ์ฒดํฌํฌ์ธํธ๋ฅผ ๋ด๋ณด๋ด๋ ๊ฒ์ ์ค๋ช
ํฉ๋๋ค. ๋ก์ปฌ ๋ชจ๋ธ์ ๋ด๋ณด๋ผ ๋์๋ ๋ชจ๋ธ์ ๊ฐ์ค์น์ ํ ํฌ๋์ด์ ํ์ผ์ ๋์ผํ ๋๋ ํ ๋ฆฌ(local_path
)์ ์ ์ฅํ๋์ง ํ์ธํ์ธ์. CLI๋ฅผ ์ฌ์ฉํ ๋์๋ ๐ค Hub์ ์ฒดํฌํฌ์ธํธ ์ด๋ฆ ๋์ model
์ธ์์ local_path
๋ฅผ ์ ๋ฌํ๊ณ --task
์ธ์๋ฅผ ์ ๊ณตํ์ธ์. ์ง์๋๋ ์์
์ ๋ชฉ๋ก์ ๐ค Optimum ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์. task
์ธ์๊ฐ ์ ๊ณต๋์ง ์์ผ๋ฉด ์์
์ ํนํ๋ ํค๋ ์์ด ๋ชจ๋ธ ์ํคํ
์ฒ๋ก ๊ธฐ๋ณธ ์ค์ ๋ฉ๋๋ค.
optimum-cli export onnx --model local_path --task question-answering distilbert_base_uncased_squad_onnx/
๊ทธ ๊ฒฐ๊ณผ๋ก ์์ฑ๋ model.onnx
ํ์ผ์ ONNX ํ์ค์ ์ง์ํ๋ ๋ง์ ๊ฐ์๊ธฐ ์ค ํ๋์์ ์คํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ONNX Runtime์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ๋ก๋ํ๊ณ ์คํํ ์ ์์ต๋๋ค:
>>> from transformers import AutoTokenizer
>>> from optimum.onnxruntime import ORTModelForQuestionAnswering
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert_base_uncased_squad_onnx")
>>> model = ORTModelForQuestionAnswering.from_pretrained("distilbert_base_uncased_squad_onnx")
>>> inputs = tokenizer("What am I using?", "Using DistilBERT with ONNX Runtime!", return_tensors="pt")
>>> outputs = model(**inputs)
Hub์ TensorFlow ์ฒดํฌํฌ์ธํธ์ ๋ํด์๋ ๋์ผํ ํ๋ก์ธ์ค๊ฐ ์ ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, Keras organization์์ ์์ํ TensorFlow ์ฒดํฌํฌ์ธํธ๋ฅผ ๋ด๋ณด๋ด๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
optimum-cli export onnx --model keras-io/transformers-qa distilbert_base_cased_squad_onnx/
optimum.onnxruntime
์ ์ฌ์ฉํ์ฌ ๐ค Transformers ๋ชจ๋ธ์ ONNX๋ก ๋ด๋ณด๋ด๊ธฐ [[exporting-a-transformers-model-to-onnx-with-optimumonnxruntime]]
CLI ๋์ ์ optimum.onnxruntime
์ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๐ค Transformers ๋ชจ๋ธ์ ONNX๋ก ๋ด๋ณด๋ผ ์๋ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์งํํ์ธ์:
>>> from optimum.onnxruntime import ORTModelForSequenceClassification
>>> from transformers import AutoTokenizer
>>> model_checkpoint = "distilbert_base_uncased_squad"
>>> save_directory = "onnx/"
>>> # Load a model from transformers and export it to ONNX
>>> ort_model = ORTModelForSequenceClassification.from_pretrained(model_checkpoint, export=True)
>>> tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)
>>> # Save the onnx model and tokenizer
>>> ort_model.save_pretrained(save_directory)
>>> tokenizer.save_pretrained(save_directory)
์ง์๋์ง ์๋ ์ํคํ ์ฒ์ ๋ชจ๋ธ ๋ด๋ณด๋ด๊ธฐ [[exporting-a-model-for-an-unsupported-architecture]]
ํ์ฌ ๋ด๋ณด๋ผ ์ ์๋ ๋ชจ๋ธ์ ์ง์ํ๊ธฐ ์ํด ๊ธฐ์ฌํ๋ ค๋ฉด, ๋จผ์ optimum.exporters.onnx
์์ ์ง์๋๋์ง ํ์ธํ ํ ์ง์๋์ง ์๋ ๊ฒฝ์ฐ์๋ ๐ค Optimum์ ๊ธฐ์ฌํ์ธ์.
transformers.onnx
๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ ๋ด๋ณด๋ด๊ธฐ [[exporting-a-model-with-transformersonnx]]
tranformers.onnx
๋ ๋ ์ด์ ์ ์ง๋์ง ์์ต๋๋ค. ์์์ ์ค๋ช
ํ ๋๋ก ๐ค Optimum์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ๋ด๋ณด๋ด์ธ์. ์ด ์น์
์ ํฅํ ๋ฒ์ ์์ ์ ๊ฑฐ๋ ์์ ์
๋๋ค.
๐ค Transformers ๋ชจ๋ธ์ ONNX๋ก ๋ด๋ณด๋ด๋ ค๋ฉด ์ถ๊ฐ ์ข ์์ฑ์ ์ค์นํ์ธ์:
pip install transformers[onnx]
transformers.onnx
ํจํค์ง๋ฅผ Python ๋ชจ๋๋ก ์ฌ์ฉํ์ฌ ์ค๋น๋ ๊ตฌ์ฑ์ ์ฌ์ฉํ์ฌ ์ฒดํฌํฌ์ธํธ๋ฅผ ๋ด๋ณด๋
๋๋ค:
python -m transformers.onnx --model=distilbert-base-uncased onnx/
์ด๋ ๊ฒ ํ๋ฉด --model
์ธ์์ ์ ์๋ ์ฒดํฌํฌ์ธํธ์ ONNX ๊ทธ๋ํ๊ฐ ๋ด๋ณด๋ด์ง๋๋ค. ๐ค Hub์์ ์ ๊ณตํ๋ ์ฒดํฌํฌ์ธํธ๋ ๋ก์ปฌ์ ์ ์ฅ๋ ์ฒดํฌํฌ์ธํธ๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค. ๊ฒฐ๊ณผ๋ก ์์ฑ๋ model.onnx
ํ์ผ์ ONNX ํ์ค์ ์ง์ํ๋ ๋ง์ ๊ฐ์๊ธฐ ์ค ํ๋์์ ์คํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ONNX Runtime์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ๋ก๋ํ๊ณ ์คํํ ์ ์์ต๋๋ค:
>>> from transformers import AutoTokenizer
>>> from onnxruntime import InferenceSession
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
>>> session = InferenceSession("onnx/model.onnx")
>>> # ONNX Runtime expects NumPy arrays as input
>>> inputs = tokenizer("Using DistilBERT with ONNX Runtime!", return_tensors="np")
>>> outputs = session.run(output_names=["last_hidden_state"], input_feed=dict(inputs))
ํ์ํ ์ถ๋ ฅ ์ด๋ฆ(์: ["last_hidden_state"]
)์ ๊ฐ ๋ชจ๋ธ์ ONNX ๊ตฌ์ฑ์ ํ์ธํ์ฌ ์ป์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, DistilBERT์ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
>>> from transformers.models.distilbert import DistilBertConfig, DistilBertOnnxConfig
>>> config = DistilBertConfig()
>>> onnx_config = DistilBertOnnxConfig(config)
>>> print(list(onnx_config.outputs.keys()))
["last_hidden_state"]
Hub์ TensorFlow ์ฒดํฌํฌ์ธํธ์ ๋ํด์๋ ๋์ผํ ํ๋ก์ธ์ค๊ฐ ์ ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ์์ํ TensorFlow ์ฒดํฌํฌ์ธํธ๋ฅผ ๋ด๋ณด๋ ๋๋ค:
python -m transformers.onnx --model=keras-io/transformers-qa onnx/
๋ก์ปฌ์ ์ ์ฅ๋ ๋ชจ๋ธ์ ๋ด๋ณด๋ด๋ ค๋ฉด ๋ชจ๋ธ์ ๊ฐ์ค์น ํ์ผ๊ณผ ํ ํฌ๋์ด์ ํ์ผ์ ๋์ผํ ๋๋ ํ ๋ฆฌ์ ์ ์ฅํ ๋ค์, transformers.onnx ํจํค์ง์ --model ์ธ์๋ฅผ ์ํ๋ ๋๋ ํ ๋ฆฌ๋ก ์ง์ ํ์ฌ ONNX๋ก ๋ด๋ณด๋ ๋๋ค:
python -m transformers.onnx --model=local-pt-checkpoint onnx/