Transformerモデルの高速化

Cheif Research Officerの西鳥羽 (Jiro Nishitoba (@jnishi) | Twitter) です。

前回はONNX runtimeを利用した高速化を紹介いたしました。今回はさらなる高速化をしたいと思います。 NVIDIA社のTensorRTおよびIntel社のOpenVINOを利用します。

onnxruntimeのインストール

OpenVINOやTensorRTを用いる場合*1、onnxruntimeをソースからビルドしてインストールします。なお、OpenVINOやTensorRTは既にインストールされているものとします。これらのインストールはOpenVINOのinstallation instructionやTensorRTのInstallation Guideを参考にしてください。

以下のコマンドでonnxruntimeの取得とビルドを行います。詳しくはBuild ONNX Runtime for inferencing及びBuild ONNX Runtime with Execution Providersを参考にしてください。

git clone --recursive git@github.com:microsoft/onnxruntime.git
cd onnxruntime
source  /opt/intel/openvino_2021/bin/setupvars.sh # OpenVINOの有効化
./build.sh --use_cuda --cuda_home /usr/local/cuda --cudnn_home /usr/lib/x86_64-linux-gnu --use_tensorrt --tensorrt_home /usr --use_openvino CPU_FP32 --config RelWithDebInfo  --build_shared_lib --use_openmp --build_wheel --parallel

なお、--cuda_home --cudnn_home --tensorrt_home で指定しているディレクトリはUbuntu 20.04にてDebパッケージでインストールした際のデフォルトのパスになります。ご自身の環境に合わせて変更してください。

OpenVINOを用いたCPUでの推論の高速化

CPUのモデルの推論をOpenVINOを利用して高速化します。OpenVINOはIntel社がオープンソースで提供している推論用ライブラリです。IntelのCPU、GPUおよびFPGA上での計算に特化して高速な推論を行います。

OpenVINOを用いる場合には providers["OpenVINOExecutionProvider"] を指定します。 前回のブログでCUDAの指定を行っていた部分を以下のように変更します。

# ONNX形式のモデルから推論用モデルを作成
session = InferenceSession(args.onnx_path, providers=["OpenVINOExecutionProvider"])

以上でOpenVINOを用いた推論が行われます。

以下に速度比較を行っています。前回のブログと同じように事前学習済みモデルとして cl-tohoku/bert-large-japanese を利用し、livedoorニュースコーパスの記事を学習データ:評価データを4:1に分割し、カテゴリ推定でファインチューニングを行いました。Hugging Face Transformersのモデル、ONNXのCPU実行、ONNXのOpenVINO実行における推論時間を測定しています。評価データ全件に対して推論を行いその1件当たりの平均時間で比較しています。なおOpenVINOでの推論において、8秒近く時間のかかっている推論が4件あり、それらは異常値として平均からは取り除いています。

f:id:Christopher-727:20220329115244p:plain
CPUにおける推論時間の比較

Hugging Face Transformersでの実行よりもOpenVINOによる実行の方が高速ですが、ONNXのCPU実行よりも速度が低下しています。8秒以上かかる例も含めてOpenVINOをうまく扱えてないような感じがします。

TensorRTを用いたGPUでの推論の高速化

GPUモデルの推論をTensorRTを利用して高速化します。TensorRTはNVIDIA社がオープンソースで提供しているGPU上での推論ライブラリです。INT8やFP16への量子化やNeural Networkの最適化などを行い、GPU上での推論を高速化します。

TensorRTを用いる場合には providers["TensorRTExecutionProvider"] を指定します。 前回のブログでCUDAの指定を行っていた部分を以下のように変更します。

# ONNX形式のモデルから推論用モデルを作成
session = InferenceSession(args.onnx_path, providers=["TensorRTExecutionProvider"])

以上でTensorRTでの推論が行われます。注意点としては sessionを用いた推論の初回実行時にはTensorRT向けのモデルのビルドが行われるため、実行に数十秒くらいの時間がかかります。2回目以降の推論は高速に行われます*2

以下に速度比較を行っています。こちらも同じように事前学習済みモデルとして cl-tohoku/bert-large-japanese を利用し、livedoorニュースコーパスの記事を学習データ:評価データを4:1に分割し、カテゴリ推定でファインチューニングを行いました。Hugging Face Transformersのモデル、ONNXのCUDA実行、ONNXのTensorRT実行における推論時間を測定しています。評価データ全件に対して推論を行いその1件当たりの平均時間で比較しています。なおTensorRTでの推論において、1秒以上時間のかかっている推論は推論だけでなくモデルのビルドが行われていると思われるので平均からは取り除いています。

f:id:Christopher-727:20220329115311p:plain
GPUにおける推論時間の比較

Hugging Face TransformersのモデルとONNX CUDAでの実行を比較すると、前回のブログでもふれたとおり約2.4倍の高速化となっています。TensorRTを用いるとCUDAでの実行から更に1.35倍の高速化となっています。Neural Networkの最適化が行われるタイミングを管理しないといけない課題はありますが、効果は出ているようです。

まとめ

CPUのメーカーおよびGPUのメーカーが公開している高速化ライブラリを通じて推論がどれだけ早くなるかを試してみました。NVIDIA社のTensorRTを利用したところ初回や、何度も実行していると偶にビルドで時間がかかる時があるものの、CUDA実行と比較して1.35倍の高速化となりました。Intel社のOpenVINOの方は処理が速くはなりませんでしたが、こちらはうまく扱えていない様子なので今後何かわかりましたら続報を上げたいと思います。

*1:TensorRTだけを用いる場合はpypyにて公開されているパッケージでも利用可能です。onnxruntime-gpuパッケージで利用できます。

*2:ただ、推論を何度も実行しているとまたモデルのビルドが行われるようです。後述の実験の際に初回推論以外にも1回数秒かかる実行が存在しました。

社Dへの道 ~折り返し地点~

こんにちは。レトリバの飯田(@meshidenn)です。TSUNADE事業部 研究チームのリーダーをしており、マネジメントや論文調査、受託のPOCを行なっています。

2020年4月から、東京工業大学(東工大)の岡崎研究室に社会人博士課程で所属しており、論文が一本出せた段階です。折り返し地点でちょうど良いタイミングと思いますので、社会人博士で何を学べているのか、仕事との兼ね合いはどうなのかなど書いていきたいと思います。

続きを読む

音響学会2022年春季研究発表会に参加しました

こんにちは。リサーチャーの古谷(@kk_fry_)です。

レトリバでは、研究動向・業界動向の把握のため、積極的に学会参加をしています。3/9~11にオンラインで開催された日本音響学会2022年春季研究発表会にも参加しました。

今回の記事では、気になった発表をいくつかピックアップして紹介します。

各項目に講演番号を記載しているので、しばらくの間、研究発表会のページで公開されている講演要旨を確認することができます。

続きを読む

深層学習の量子化に入門してみた 〜BERTをDynamic Quantization〜

こんにちは。 リサーチャーの勝又です。 私はレトリバで自然言語処理、とくに要約や文法誤り訂正に関する研究の最新動向の調査・キャッチアップなどを行っております。

前回、深層学習の量子化について簡単な解説記事を公開しました。 今回は、深層学習の量子化、とくにDynamic Quantizationを実際に試してみようと思います。

続きを読む

Huggingface transformersモデルのONNX runtimeによる推論の高速化

Chief Research Officerの西鳥羽 (Jiro Nishitoba (@jnishi) | Twitter) です。 今回はHugging Face TransformersのモデルのONNX runtimeで実行を試してみました。それにより特にCUDAでの実行では2.4倍近い高速化が行えました。 Hugging Face TransformersのモデルのONNX形式への変換方法から、ONNX runtimeでの実行も含めて紹介したいと思います。

続きを読む

深層学習の量子化に入門してみた 〜理論編〜

こんにちは。 リサーチャーの勝又です。 私はレトリバで自然言語処理、とくに要約や文法誤り訂正に関する研究の最新動向の調査・キャッチアップなどを行っております。

最近、深層学習の量子化について勉強する機会があったので、この記事では量子化の理論的な話をまとめてみようと思います。

続きを読む

BERTでの語彙追加~add_tokenに気をつけろ!~

こんにちは。レトリバの飯田(@meshidenn)です。TSUNADE事業部 研究チームのリーダーをしており、マネジメントや論文調査、受託のPOCを行なっています。

みなさんは、BERTなどの学習済み言語モデルに対して語彙を追加したくなることはありませんか? 諸々の論文(こちらこちらこちら)により、特定ドメインやrare-wordの語彙を追加することによって、性能が上がることが知られています。

そこで、語彙を追加しようと思い、TransformersのTokenizerの仕様を見ると、add_tokens という関数があります。これを使えば、tokenizerに語彙を追加できるので、あとはembedding側にも新しい語彙を受け取れるようにすれば万事解決です!

とは、うまくいかないので、今回はこの辺りについて、ちょっとした解説をします。

続きを読む

CTC 誤差関数を完全に理解したい(後編)

こんにちは、リサーチャーの古谷(@kk_fry_)です。 私は普段、音声認識の研究開発をしています。 前回の記事から、End-to-End 音声認識で用いられる Connectionist Temporal Classification (CTC) 誤差関数の解説をしています。 本記事はその後編となります。

前回は、CTC 誤差関数の定義と計算方法を解説し、その偏導関数を導出しました。 今回は、CTC 誤差関数の勾配降下法による学習について解説し、その解釈を考えてみます。

続きを読む

事前学習モデルT5とTransformersを使ってお手軽日本語文書要約をやってみた

こんにちは。 カスタマーサクセス部リサーチャーの勝又です。 私はレトリバで自然言語処理、とくに要約や文法誤り訂正に関する研究の最新動向の調査・キャッチアップなどを行っております。

今回の記事では、事前学習モデルであるT5を使って日本語文書要約を行った話を紹介します。

続きを読む