如何初始化具有共享状态的python多处理工作者池?

Posted

技术标签:

【中文标题】如何初始化具有共享状态的python多处理工作者池?【英文标题】:How to initialize a pool of python multiprocessing workers with a shared state? 【发布时间】:2018-11-12 11:45:45 【问题描述】:

我正在尝试并行执行some machine learning algorithm。

当我使用多处理时,它比不使用要慢。我的疯狂猜测是,我使用的模型的pickle 序列化减慢了整个过程。所以问题是:如何使用初始状态初始化池的工作程序,这样我就不需要为每次调用模型进行序列化/反序列化?

这是我当前的代码:

import pickle
from pathlib import Path
from collections import Counter
from multiprocessing import Pool

from gensim.models.doc2vec import Doc2Vec

from wikimark import html2paragraph
from wikimark import tokenize


def process(args):
    doc2vec, regressions, filepath = args
    with filepath.open('r') as f:
        string = f.read()
    subcategories = Counter()
    for index, paragraph in enumerate(html2paragraph(string)):
        tokens = tokenize(paragraph)
        vector = doc2vec.infer_vector(tokens)
        for subcategory, model in regressions.items():
            prediction = model.predict([vector])[0]
            subcategories[subcategory] += prediction
    # compute the mean score for each subcategory
    for subcategory, prediction in subcategories.items():
        subcategories[subcategory] = prediction / (index + 1)
    # keep only the main category
    subcategory = subcategories.most_common(1)[0]
    return (filepath, subcategory)


def main():
    input = Path('./build')
    doc2vec = Doc2Vec.load(str(input / 'model.doc2vec.gz'))
    regressions = dict()
    for filepath in input.glob('./*/*/*.model'):
        with filepath.open('rb') as f:
            model = pickle.load(f)
        regressions[filepath.parent] = model

    examples = list(input.glob('../data/wikipedia/english/*'))

    with Pool() as pool:
        iterable = zip(
            [doc2vec] * len(examples),  # XXX!
            [regressions] * len(examples),  # XXX!
            examples
        )
        for filepath, subcategory in pool.imap_unordered(process, iterable):
            print('*  -> '.format(filepath, subcategory))


if __name__ == '__main__':
    main()

标有XXX! 的行指向我调用pool.imap_unodered 时序列化的数据。至少有 200MB 的数据被序列化。

如何避免序列化?

【问题讨论】:

【参考方案1】:

解决方案就像对doc2vecregressions 使用全局一样简单。

【讨论】:

以上是关于如何初始化具有共享状态的python多处理工作者池?的主要内容,如果未能解决你的问题,请参考以下文章

多处理池 - 大多数工作人员已加载但仍处于空闲状态

如何使Python多处理池工作以写入相同的日志文件

Python多处理:如何在异常时关闭多处理池

python多处理池:我怎么知道池中的所有工作人员何时完成?

具有多个参数的Python多处理池映射[重复]

Python 多处理:最大。池工作进程的数量?