第7回 MLOps勉強会に参加してみた

MLOpsに興味があったので参加してみた。今回初参加。

mlops.connpass.com

下記は参加したときのメモ。メモなので正確性はないです。


Data CentricなMLOps概論

Data-centriはAndrew先生が提唱し始めた。今回はAndrew先生の提唱している内容を中心に話す。

  • Model-Centricとは、データは固定してアルゴリズム変更してPerformance向上。
  • Data-Centricはアルゴリズム固定して、データを変更してPerformanceを向上させる。

Annotationの正確さ(ノイズデータ)がPerformanceに与える影響が大きい。

実践編

  • エラーデータ発見
    推論結果と教師データを比較することで、エラーデータ(Annotationミス)を見つける試み。
  • データ不足
    人混みでの認識精度が悪いことがわかれば、人混みのデータを集める。
  • 誤検出
    歩行者検知したいのに、自転車に乗る人も検出してしまう。新たにサイクリスト(自転車に乗る人)というクラスを作り、検出対象に追加する。

Q&A

  • ハイパーパラメータチューニングでは厳しいのか?
    -> Model-centricを最初にやって、modelをFixして、データ改善をしていったほうがいいのではないか。
  • 訓練データ作成に有用なツールあるか?
    -> labelmeとかいろいろあるよ。
  • データのバージョン管理はFastlabelでやってるか?
    -> Fastlabelではちゃんとやってます。

特徴量の品質向上の施策

メモなし。資料公開されたらあとでリンク貼っとく。

www.slideshare.net

onnxruntimeのグラフ最適化1

onnxruntimeではどんなグラフ最適化がされているか観てみる。

概要はonnxrutimeのドキュメントにまとまっている。

Graph Optimization Levels

ここをみてみるとグラフ最適化は以下の3つのレベルに分けられるとある。

  • Basic
    冗長なノードや計算を削除する操作(ConstantFolding, Redundant node eliminations等)
  • Extended 複雑なノード融合が含まれ、cuda,cpuに割り当てられたノードに適用される(GEMM Activation fusion, Attention Fusion等)

  • Layout Optimization データレイアウトを最適化する。CPUに割り当てられたノードに適用される

    • NCHWc optimizer NCHWの代わりに、NCHWcレイアウトを適用する。

Online/Offline Mode

Online mode

推論を実行する前にInferenceSessionを初期化し、このときに有効になっているグラフ最適化を適用する。Sessionを起動するたびに最適化を適用するので、モデルの起動時間にオーバーヘッドが生じ、本番環境では問題になる可能性がある。

Offline mode

最適化下グラフをディスクに保存しとくことによって、次に推論をするときに最適化後のモデルを読み込むことができる。

次はソースコードで対応する部分を観てみる。 読む箇所メモ:

  • onnxruntime/onnxruntime/core/optimizer/graph_transformer_utils.cc
  • onnxruntime/onnxruntime/core/session/inference_session.cc

Ubuntuでイヤホンが認識しなくなる問題

たまによく起こる

Ubuntuでイヤホンを抜き差ししていると、たまにイヤホンを認識しなくなる。 Outputdeviceにイヤホンのインターフェースが表示されなくなる。 これの対処法。

pulseaudio

pulseAudioで以下のようにHD Audio Controllerの設定をする。 pulseaudoが入ってなければsudo apt-get install pavucontrol

f:id:kuroko1t:20210516142417p:plain

alsamixer

alsamixerでLoopbackが設定されちゃってると、ハウリングがすごいことになったので、これをDisableにする。

f:id:kuroko1t:20210516142617p:plain

Jetson Xavierの全CPUのonline化

下書きにあって公開されてなかったから、とりあえず公開しておく。

CPUコアの設定

全CPUのonline化

8コア搭載されているが、デフォルトだと4コアしかonlineになっていなかった.

➜  ~ sudo /usr/bin/jetson_clocks --show                                                                                                                                                                        
SOC family:tegra194  Machine:Jetson-AGX                                                                                                                                                                        
Online CPUs: 0-3                                                                                                                                                                                               
CPU Cluster Switching: Disabled                                                                                                                                                                                
cpu0: Online=1 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0                                                                                                    
cpu1: Online=1 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0
cpu2: Online=1 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0                                                                                                    
cpu3: Online=1 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0
cpu4: Online=0 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0
cpu5: Online=0 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0
cpu6: Online=0 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0
cpu7: Online=0 Governor=schedutil MinFreq=1190400 MaxFreq=1190400 CurrentFreq=1190400 IdleStates: C1=0 c6=0
GPU MinFreq=675750000 MaxFreq=675750000 CurrentFreq=675750000                    
EMC MinFreq=204000000 MaxFreq=1331200000 CurrentFreq=1600000000 FreqOverride=1  
Fan: speed=255                                                                 
NV Power Mode: MODE_15W   

8コア全部使うにはofflineのコアをonlineにする必要がある。以下のように1つ1つchcpuコマンドを利用してonlineに変更した。

➜  ~ sudo chcpu -e 4                                                            
CPU 4 enabled 

Swin Transformerってのがあるんだと(object detectionのSOTAモデル)

短くてもいいから、気軽にブログ書くようにしていかないとやらないと気づいた。きれいに書くことより、とりあえず書く。

最近のobject detectionですごいモデルって何なのか調べていたら出会った。 code with paperのobject detection on COCOを見てみると下記のようにSwin Transformerが1位でした。

f:id:kuroko1t:20210516130222p:plain
coco test-dev benchでSOTAとってる

論文リンク

Swin TransformerはMicrosoft Researchが開発発表した画像認識モデルで名前の通りTransformerを使っています。 この画像認識モデルをObjectDetectionモデル(MASK-RCNNとかの)のバックボーンで利用してSOTAをとったようです。 DETRっていうObjectDetectionのモデルとかもそうだけど、Transformerの利用が最近の流行りですな。

swin transformerはpytorchベースの公式実装Microsoftが公開してるのと、mmdetectionをforkして実際にobjectdetectionに組み込んだモデルというのも利用できる形になっています。

Optunaの最適化手法

Optunaの最適化手法

最近Optunaを触る機会が増えてきたので、Optunaを通して最適化手法に関して勉強していきたい。 まずはOptunaのサポートしている最適化手法に何があるのか見てみる。 Optunaがサポートしている最適化手法はいくつかあり、Sampler classで定義されている。 実際にOptunaで利用するときはcreate_studyの引数で指定して使用する。

study = optuna.create_study(sampler=RandomSampler())                                                                               
study.optimize(objective, direction='minimize')    

Optunaのサポートしている最適化手法

optuna.samplers.RandomSampler

単純なRandomサンプリング

optuna.samplers.TPESampler

TPEを利用したサンプリング。 Samplerを何も指定しなければ、defaultでこのTPESamplerが選ばれる。

optuna.integration.CmaEsSampler

バックエンドでcma(Covariance Matrix Adaptation)ライブラリを利用したサンプリングを行う。

以下CMA-ESの説明(wikipedia)

ES は進化戦略(evolution strategy)の事で、確率を使用したメタヒューリスティックスの乱択アルゴリズム。多変量正規分布に基づいて新しいサンプルが選ばれる。分布は同じ平均値になるように設定され、突然変異は平均値を変えないように導入される。変数間の依存関係は共分散行列によって扱われる。

CMA は共分散行列適応(covariance matrix adaptation)の事で、分布に基づいて共分散行列を更新する。関数にノイズが多い時にこの手法は有効である。CMAは準ニュートン法の逆ヘッセ行列を使用する方法に似ていて、目的関数を二次関数で近似する。古典的な手法と比べると、目的関数に対する仮定がより少ない。

実装に関する説明もありました。

cyberagent.ai

optuna.integration.SkoptSampler

scikit-opimizeを利用したサンプリングを行う。 scikit-optimizeとはOptunaのようなハイパーパラメータを最適化するライブラリのよう。参照

感想

hyperoptでもTPE使われてたから、今のところTPEが一番最適化アルゴリズムの中で一番良いのかな? 理解していきたい。

ALBert (A Lite BERT) 論文の序文

arxiv.org

Abstruct

自然言語表現の事前トレーニング時にモデルを大きくすることは、多くの場合精度を向上させます。 ただし、GPU/TPUのメモリ制限や予期せぬ精度劣化によってモデルを大きくすることが難しくなっていきています。 この問題に対処するために、BERTのメモリ消費を抑え、かつトレーニング速度を向上させるための2つの手法を紹介します。 また、self-supervised lossを利用することにより複数文が入力のときのTaskに役立つ事を示しました。 GLUE、RACE、およびSQuADベンチマークでいい結果を残しつつ、BERTよりメモリ削減することに成功しました。

Introduction

NLPのモデルをよりよい精度にするために、よくモデルを大きくする手法を用いることがありますが、これ以上モデルを大きくするのはハードのメモリ制限等により難しくなってきています。現在の最新モデルだと数億から数十億のパラメータがあるため、この制限に引っかかってしまします。 また、BERT-Largeモデルを単純に大きくするとパフォーマンスが劣化することがわかっています。下図はBERT-Largeのhidden sizeを2倍に増やしたBERT-xlargeモデルでパフォーマンスが劣化した例になります。 f:id:kuroko1t:20191215173730p:plain f:id:kuroko1t:20191215204253p:plain

このメモリ不足に対応する手法としては、モデル並列化、clever memory managementが考えられます。しかし、これらの手法はデバイス間通信のオーバーヘッドと、モデルの性能劣化には対応してません。 この論文ではBERTより大幅に少ないパラメータの”A Lite BERT”(ALBERT)により前述したすべての問題に対応します。 ALBERTにはメモリ削減のための2つのパラメータ削減手法が取り入れられています。 1. factorized embedding parameterization 大きなボキャブラリ埋め込みマトリックスを2つの小さなマトリックスに分解し、ボキャブラリー埋め込みからhidden layerを分離します.この分離により,hidden sizeを簡単に大きくすることができます。 2. cross-layer parameter sharing この手法はネットワークの深さとともにパラメータが大きくなるのを防ぎます。レイヤ間のパラメータ共有はTransformerのときに検討はされていたそうですが、事前トレーニングの観点ではなく、通常のエンコーダ、デコーダに焦点を当てていたそうです。

どちらの手法もパフォーマンスを大幅に低下させずに、BERTのパラメーター数を大幅に削減し、パラメータの効率を改善します。BERT−Largeと同じ構成のALBERTでは18倍少ないパラメータになり、1.7倍トレーニング速度が上昇しました。パラメーターの削減はトレーニングも安定させます。 また、パフォーマンスをさらに改善するために文の順序予測(sentence-order prediction : SOP)のself-supervised lossを導入します。SOPの主な目的は文章間の一貫性で、BERTの文章予測の問題に対処しています。

3.2 MODEL SETUP

ALBERT-LargeはBERT-Largeに比べてパラメータが約18倍少なく、18M vs 334Mとなります。 f:id:kuroko1t:20191215210004p:plain

4.8 WHAT IF WE TRAIN FOR THE SAME AMOUNT OF TIME?

BERT-largeとALBERT-xxlargeを同じ時間トレーニングさせた時のパフォーマンスの比較。 f:id:kuroko1t:20191215220622p:plain

Discussion

ALBERT-xxlargeはBERT-largeよりもパラメーターが少なく、結果が大幅に向上しますが、構造が大きいため計算量が多くなります。したがって、重要な次のステップは、スパースアテンション(Child et al.,2019)やブロックアテンション(Shen et al.,2018)などの方法により、ALBERTのトレーニングと推論の速度を上げることです。