僕はよくbatchsizeを分割して逆伝搬をマルチスレッドで行い、勾配を足し合わせてから重み更新をしています。chainer1.16.0にするとここでエラーが出るようになりました。
AttributeError: '_thread._local' object has no attribute 'default_backprop'
逆伝播のときだけではなく、場合によってはforwardでもエラーが出ます。
import chainer
import numpy
import concurrent.futures
def calc_sigmoid(i):
value = numpy.array(i, dtype=numpy.float32)
return chainer.functions.sigmoid(value)
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
values = list(executor.map(calc_sigmoid, range(4)))
print(values)
# AttributeError: '_thread._local' object has no attribute 'default_backprop'
エラー内容的に1.16で追加されたbackprop_mode
に関係がありそうでした。
no_backprop_mode and force_backprop_mode are added. In no_backprop_mode context, Variables with volatile=’auto’ behave like non-volatile variables. And, in force_backprop_mode context, they behave like volatile variables. (#1521)
中でthreading.local()
が使われていたのでこの部分をglobal
にすると思ったように動作しました。
print(values)
# [<variable at 0x1123329e8>, <variable at 0x112332c88>, <variable at 0x112332ef0>, <variable at 0x11234f160>]
backprop_mode
はVariable
のauto
をon/offどちらにするか強制するもの(だと思う)ですが、別にスレッドセーフにする必要はない(というかこのままだと別スレッドで動かない)のでglobal変数を用いるようなPRを作成しました。(追記)その後、初期値を与える方針に変更しました。
たぶん学習済みモデルを複数プロセスで並列に計算して結果を返すようなwebサービスは軒並み動作不良になっているはず(要出典)で、何より自分のコードが動かないので何とかしたいなぁと思いつつ、PRレビュー待ちです。
(追記)masterにマージされました chainer1.17で修正されるはずなのでとりあえず一件落着、日曜日にも関わらず返信頂きありがとうございました。