Capitalicoでのchainer 1.1 → 1.5 バージョンアップ事例

Engineering

jun-ya-norimatsu
of 30
Description
Text
為替市場の時系列データ分析へのChainer適用事例 Capitalicoでのchainer 1.1→1.5バージョンアップ事例 JUN-YA NORIMATSU Engineer http://alpaca.ai jnory@alpacadb.com 2015/12/19 Chainer Meetup #01 自己紹介  乗松潤矢(Twitter: arrow_elpis, Github: jnory) Alpaca (Engineer) フリーランス 博士課程在学中(専門:自然言語処理, 統計翻訳) 今日の肩書 Entry Point FXチャートにはパターンがある  Down Trend from Flickr from Flickr すべて同一カテゴリの事象  パターン認識で検出したい プログラミングなしでパターンを発見  Chainerによるモデル学習  入力:為替時系列データ 出力:学習時に指定したパターンっぽさ 今日の発表  弊社環境をChainer 1.5にバージョンアップしました バージョンアップでハマったところは? バージョンアップで良くなったところは? バージョンアップで悪くなったところは? Chainerバージョンアップはどの程度のタスク? 今日の発表  弊社環境をChainer 1.5にバージョンアップしました バージョンアップでハマったところは? バージョンアップで良くなったところは? バージョンアップで悪くなったところは? Chainerバージョンアップはどの程度のタスク? 本題の前に…CapitalicoでのChainerバージョンアップのトラウマ  2015年9月2日 Chainer 1.3リリース 弊社環境もバージョンアップを試みるが… v1.1と比較してモデル学習が約1.5倍遅い バージョンアップ失敗 Chainer 1.3の変更点 CuPyの導入 どうもこれが遅いらしい バージョンアップで良くなったところ  ボトルネックだったCuPyが高速化 速くなりました!!! Chainer 1.1 :約22分 Chainer 1.5 :約16分 (ありがとうございます!!!) 弊社サービス上でのモデル学習時間 Training Loss収束の様子  Chainer 1.1 Chainer 1.5 ほぼ同じ学習ができた 反復回数 反復回数 Chainerの速度で気になっていること  Dropoutが全体の12%の時間 Linearより重い…? モデル学習時のProfileを取った 実行時間に大きな偏りはない 今日の発表  弊社環境をChainer 1.5にバージョンアップしました バージョンアップでハマったところは? バージョンアップで良くなったところは? バージョンアップで悪くなったところは? Chainerバージョンアップはどの程度のタスク? バージョンアップで悪くなったところ  一度GPUメモリを確保すると開放されない 学習終了後もプロセスは起動したまま サーバープログラム内で学習・テスト メモリ解放したい  幾つかのプロセスがGPUを使用 GPUメモリが開放されないと同時起動プロセス数に影響 用途ごとにプロセスを分離 モデル学習 テスト実行 大量のユーザーに対応できない CapitalicoはBtoCなサービス 目標:1万人程度が同時アクセス 数千人が同時にモデル学習を走らせても動くようにしたい [解決策] ちょっとだけChainerを改造  MemoryPoolにこんなコードを追加 (とにかく全部捨てる…という意味) PRしました 今日の発表  弊社環境をChainer 1.5にバージョンアップしました バージョンアップでハマったところは? バージョンアップで良くなったところは? バージョンアップで悪くなったところは? Chainerバージョンアップはどの程度のタスク? バージョンアップでハマったところ  1. インストール 2. FunctionSet → Chain 4. モデルの保存形式をHDF5に変更 5. 過去に学習したモデルを変換 3. その他の非互換を修正 これ バージョンアップの流れ バージョンアップでハマったところ  HDF5からの読込:一部のパラメータが読み込まれない chain.linear = Linear(…, nobias=True) from chainer.serializers.hdf5 import HDF5Deserializer group = h5file["chainer"] serializer = HDF5Deserializer(group) serializer.load(chain) モデルファイルにbiasが書かれていても読まれない 今日の発表  弊社環境をChainer 1.5にバージョンアップしました バージョンアップでハマったところは? バージョンアップで良くなったところは? バージョンアップで悪くなったところは? Chainerバージョンアップはどの程度のタスク? Chainerバージョンアップはどの程度のタスク?  コード修正:5.5人日 動作検証に要した期間:3人日 修正開始 11/26 本番環境適用 12/11 デプロイ等々:2人日 コード修正量 工数 追加:500行(くらい) 削除:100行 コミット回数:30回 Chainerに期待すること  コミュニティが大きくなってほしいと思います Numpy非互換部分が少しずつでも減っていくと嬉しいです CuPyは単体でも十分インパクト大だと思います モデルフォーマットは今後固定していただけるとありがたい! ロゴがあると人に紹介するときにより大きいインパクト まとめ  CapitalicoのChainerをバージョンアップ 学習機能が高速化 メモリ使用効率は悪化 PRしましたm(_ _)m バージョンアップ作業はそこそこ重いタスク ハマりどころもそこそこある おまけ  Chainer 1.5での修正必要箇所一覧 Reference: https://groups.google.com/forum/#!topic/chainer/eXyL11thcNY インストール  pip install cython==0.23.4 pip install h5py==2.5.0 pip install chainer==1.5.0.2 何のつまづきもなくすんなり FunctionSet → Chain  何のつまづきもなくすんなり self.model = FunctionSet(**args) self.model = Chain(**args) API互換性有 その他非互換部分  レイヤー内の変数が(Numpy/gpuarrayから)Variableになった ohlc.W.shape[1] ohlc.W.data.shape[1] 旧FunctionがFunctionとLinkに分離 import chainer.functions as F F.Linear(x_size, self.n_units) import chainer.links as L L.Linear(x_size, self.n_units) 過去に学習したモデルを変換  Chainer 1.1形式のモデル (pickle)を読み込み1.5の形式(HDF5)で出力 import sys from chainer.links.connection import linear sys.modules['chainer.functions.linear'] = linear パッケージの配置が変わっているのでトリックを入れる with open(path) as fp: chain = cPickle.loads(fp.read()) 一応読めるようになる newchain.linear.W.data[...] = model.W[...] newchain.linear.W.grad[...] = model.gW[...] newchain.linear.b.data[...] = model.b[...] newchain.linear.b.grad[...] = model.gb[...] newchain = Chain(linear=linear.Linear(x, y)) 変数の値を淡々とコピー nobias=Trueのとき不要 モデルの保存形式をHDF5に変更  保存:何のつまづきもなくすんなり from chainer.serializers.hdf5 import HDF5Serializer group = h5file.create_group("/chainer”) serializer = HDF5Serializer(group) serializer.save(model) 読込:一部のパラメータが読み込まれなくてハマる model = Linear(…, nobias=True) from chainer.serializers.hdf5 import HDF5Deserializer group = h5file["chainer"] serializer = HDF5Deserializer(group) serializer.load(model) ファイルにbiasが書かれていても読まれない 一応の解決策(おそらく非推奨)  chain.linear = Linear(…, nobias=True) nobias=Trueなレイヤーを無理やりnobias=Falseに書き換える del chain.linear.b out_size = chain.linear.W.data.shape[0] chain.linear.add_param('b', out_size) from chainer.serializers.hdf5 import HDF5Deserializer group = h5file["chainer"] serializer = HDF5Deserializer(group) serializer.load(chain) bをリセット 以下の定義は修正不可とする モデル読み込み (ここを変えられるならnobiasを取るのが正攻法)
Comments
Top