質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
並列処理

複数の計算が同時に実行される手法

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3591閲覧

(python)(Ray)pickleをリモート関数内でloadできない

kaneko_

総合スコア10

並列処理

複数の計算が同時に実行される手法

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/08/27 10:05

前提・実現したいこと

rayという並列分散処理のライブラリを用いています。pickleを用いてクラスを並列化し、rayによって並列処理を行いたいのですが、そこで、@ray.remoteデコレータをつけた関数内でpickle.loadをしようとすると、エラーが起きてしまいます(attribution error)。何が間違っているのか検討がつかないので、もしわかる方がいましたら、そもそもの設計があっているのかどうかも含めて、少しでも教えていただけるとありがたいです。

発生している問題・エラーメッセージ

RayTaskError(AttributeError): ray::output() (pid=62562, ip=133.34.30.175) File "python/ray/_raylet.pyx", line 484, in ray._raylet.execute_task File "<ipython-input-12-539c228b28bd>", line 12, in output AttributeError: Can't get attribute 'encoding' on <module '__main__' from '/Users/masayukikaneko/.pyenv/versions/3.7.10/lib/python3.7/site-packages/ray/workers/default_worker.py'> --------------------------------------------------------------------------- RayTaskError(AttributeError) Traceback (most recent call last) <ipython-input-12-539c228b28bd> in <module> 15 16 result=output.remote(dumped) ---> 17 codeword=ray.get(result) 18 print(codeword.shape) ~/.pyenv/versions/3.7.10/lib/python3.7/site-packages/ray/worker.py in get(object_refs, timeout) 1424 worker.core_worker.dump_object_store_memory_usage() 1425 if isinstance(value, RayTaskError): -> 1426 raise value.as_instanceof_cause() 1427 else: 1428 raise value RayTaskError(AttributeError): ray::output() (pid=62562, ip=133.34.30.175) File "python/ray/_raylet.pyx", line 484, in ray._raylet.execute_task File "<ipython-input-12-539c228b28bd>", line 12, in output AttributeError: Can't get attribute 'encoding' on <module '__main__' from '/Users/masayukikaneko/.pyenv/versions/3.7.10/lib/python3.7/site-packages/ray/workers/default_worker.py'>

該当のソースコード

クラスencodingのメソッドを呼び出して、結果を出力することを試してみています。

python

1ec=encoding() 2#普通にクラス内の関数を呼び出してみる 3information,codeword=ec.encode()#NO ERROR 4print(codeword.shape)#(1000,) 5 6#一度dumpしてからloadし、関数を呼び出してみる 7dumped=pickle.dumps(ec) 8a=pickle.loads(dumped) 9information,codeword=a.encode()#NO ERROR 10print(codeword.shape)#(1000,) 11 12#ray 内の関数でloadし、関数を呼び出してみる 13@ray.remote 14def output(dumped): 15 b=pickle.loads(dumped) 16 information,codeword=b.encode()#ERROR!!! 17 return codeword 18 19result=output.remote(dumped) 20codeword=ray.get(result) 21print(codeword.shape)

一応、クラスencodingを以下に示しておきます。(簡略化しております)

import pickle import numpy as np import ray if __name__=="__main__": ray.init() class coding(): def __init__(self,tG): self.N=1000 self.K=500 #self.K=self.N*(self.Wr-self.Wc)//self.Wr self.Wc=3 self.Wr=6 self.tG=tG class encoding(coding): def generate_information(self): #generate information information=np.random.randint(0,2,self.K) return information def encode(self): information=self.generate_information() codeword=self.tG@information%2 return information,codeword

試したこと

  • pickleの代わりにdillを用いたところ、name 'np' is not definedとでた
  • @ray.remoteデコレータのついた関数は、別ファイルの扱いになる?かもしれない?と考察したが、よくわからなかった。

補足情報(FW/ツールのバージョンなど)

  • VScodeのjupyterで記述(python 3.7.10 64-bit)
  • ray 0.9.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

https://docs.python.org/ja/3/library/pickle.html#id3

関数 (組込みおよびユーザー定義) は、値ではなく、"完全修飾" された名前参照で pickle 化されます。
(略)
クラスも同様に名前参照で pickle 化されるので、unpickle 化環境には同じ制限が課せられます。

https://docs.python.org/ja/3/library/main.html#module-main

'__main__' はトップレベルのコードが実行されるスコープの名前です。モジュールが、標準入力から読み込まれたとき、スクリプトとして実行されたとき、あるいはインタラクティブプロンプトのとき、__name__ には '__main__' が設定されます。

なので、実行したファイル(python hogehoge.pyで実行した時のhogehoge.py)で定義されたクラスをpickle化した時、pickle化されたデータに入っているクラス名は(hogehoge.encodingではなく)__main__.encodingになります。
(Jupyterのnotebookやconsoleもインタラクティブプロンプトと同様で、スコープ名は__main__です)

非pickle化する時に別の実行ファイルで起動していて、その中でfrom hogehoge import encodingしてクラスを参照していると、encodingクラスの完全修飾名はhogehoge.encodingです。かつ、__main__は実行に指定したファイルになっています。
そのため、pickle化されたデータに入っているクラス名の__main__.encodingが解決できません。

エラーから逆算するとそういうことと推測します。

分散処理のワーカープロセスを実行していて、そちらで非pickle化されていると想像しました。
encodingの定義をモジュールに分離する必要があるかと思います。

投稿2021/08/27 11:27

編集2021/08/27 12:09
quickquip

総合スコア11202

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaneko_

2021/08/27 12:17

別ファイルからインポートしてみたところ、うまくいきました!! 本当にありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問