【DL】淺談模型Inference優化

最近又被一週一更的flag打臉,一是拉來了外援助陣專欄(之後會愈來愈多的!),二是本身想探索新的故事線(好比NLP+CV的任務),三是工做太忙(懶)。git

最近開始接觸BERT Inference的優化,這篇文章主要總結一下知識點github

1. 簡介

Inference提速的重要性就沒必要說了,目前主流的優化方式有如下幾種:網絡

  1. 分佈式計算(CPU):將底層的矩陣運算並行化
  2. 混合精度(GPU):理論上INT8優化可提高4倍、FP16可提高2倍
  3. 重寫Kernel(GPU):使用GPU計算時,每次運算(好比TF中的operation)都要通過幾個流程:CPU在GPU上分配顯存 -> CPU把數據發送給GPU -> CPU啓動GPU kernel -> CPU把數據取回 -> CPU釋放GPU顯存。複雜的模型每每須要大量的operation,形成屢次顯存讀寫。而若是把多個kernel合併重寫就能夠避免這種額外開銷

接下來會介紹一下Pytorch、Tensorflow、C++配合不一樣設備可用的優化方案,各位能夠根據業務須要和經濟實力選擇適合本身團隊的。多線程

另外在開始正文前先介紹一些周邊名詞,方便以後的理解:分佈式

  • BLAS:Basic Linear Algebra Subprograms,一個線性代數計算的API標準,Netlib用fortran語言編寫了一個BLAS計算庫
  • LAPACK:基於BLAS,Netlib用fortran語言編寫的計算庫,優於BLAS
  • Intel MKL:基於BLAS、LAPACK和另一些計算庫編寫的數學計算庫,C++和Fortran語言編寫,基於OpenMP可進行多線程優化。後來針對深度神經網絡又出了一個MKL-DNN。Pytorch就是基於MKL的
  • Eigen:基於BLAS、LAPACK和另一些計算庫編寫的數學計算庫,C++語言編寫,基於OpenMP可進行多線程優化。支持MKL做爲底層,支持CUDA。MKL和Eigen是兩個經常使用的高級計算庫,其中MKL的速度更快一些,但Eigen更容易上手,並且隨着優化速度也在逼近MKL。Tensorflow就是基於Eigen的
  • CuDNN:用於深度神經網絡的GPU加速庫,支持並行計算,Pytorch的GPU實現基於CuDNN,TF也有提供基於cudnn的實現
  • CuBLAS:用cuda實現的GPU BLAS計算庫

2. 優化方案(以BERT爲例)

2.1 經濟CPU

  1. Tensorflow提供C++,Java API,建議把訓練好的模型用更高效的語言部署。由於是基於eigen,應該能夠設置線程數並行化矩陣運算。
  2. Pytorch好像只有C++ API,經過torchlib調用,能夠設置線程數並行化矩陣運算。
  3. 厲害的大佬能夠基於MKL或者Eigen本身擼一份,好比知乎的幾個大牛就寫了一個CuBERT,支持load pb格式的BERT,看性能比Tensorflow提高很多。

2.2 土豪GPU

  1. Tensorflow XLA,能夠在編譯階段合併OpKernel
  2. Tensorflow、Pytorch都支持FP16優化
  3. TensorRT是NVDIA提供的庫,也是對OpKernel進行融合,同時支持INT8和FP16優化
  4. Faster Transformer是NVIDIA專門針對transformer寫的Kernel,極速爆表,支持FP16和TensorRT,提供C++、TF接口,若是擁有GPU的話你還在等什麼:

3. 建議

對線上要求很高的話,仍是用GPU+faster transformer,若是不高,那也不用本身手擼一份純C++的代碼,用TF、Pytorch的C++ API就能夠了性能

相關文章
相關標籤/搜索