1

Cython で書かれたNoAho ライブラリを使用しています。その内部トライはピクルできません。マスターノードにロードすると、ワーカーで実行される操作に一致するものは得られません。

各 Spark エグゼキュータで同じトライを使用したいので、このspaCy on Spark issueに触発されて、トライを遅延ロードする方法を見つけました。

global trie

def get_match(text):
    # 1. Load trie if needed
    global trie
    try:
        trie
    except NameError:
        from noaho import NoAho

        trie = NoAho()
        trie.add(key_text='ms windows', payload='Windows 2000')
        trie.add(key_text='ms windows 2000', payload='Windows 2000')
        trie.add(key_text='windows 2k', payload='Windows 2000')
        ...

    # 2. Find an actual match to get they payload back
    return trie.findall_long(text)

これが機能している間、すべての.add()呼び出しがすべての Spark ジョブに対して実行されます。これには約 1 分かかります。「Spark ジョブ」が正しい用語であるかどうかわからないので、より明確に説明します。私は Jupyter ノートブックで Spark を使用しており、get_match()関数を必要とするセルを実行するたびに、トライはキャッシュされず、1 つ取得されます。これは、実行時間を支配します。

トライが確実にキャッシュされるようにするためにできることはありますか? または、私の問題に対するより良い解決策はありますか?

4

1 に答える 1

1

試してみることができることの 1 つは、シングルトン モジュールを使用して をロードして初期化することtrieです。基本的に必要なのは、次のような別のモジュールだけです。

  • trie_loader.py

    from noaho import NoAho
    
    def load():
        trie = NoAho()
        trie.add('ms windows', 'Windows 2000')
        trie.add('ms windows 2000', 'Windows 2000')
        trie.add('windows 2k', 'Windows 2000')
        return trie
    
    trie  = load()
    

これを標準の Spark ツールを使用して配布します。

sc.addPyFile("trie_loader.py")
import trie_loader

rdd = sc.parallelize(["ms windows", "Debian GNU/Linux"])
rdd.map(lambda x: (x, trie_loader.trie.find_long(x))).collect()
## [('ms windows', (0, 10, 'Windows 2000')),
##  ('Debian GNU/Linux', (None, None, None))]

これにより、データがアクセスされたときにロードするのではなく、Python プロセス エグゼキュータが開始されるたびに必要なデータをロードする必要があります。ここで役立つかどうかはわかりませんが、試してみる価値はあります。

于 2016-02-19T12:55:09.787 に答える