【问题标题】:Why parallel processing taking longer than usual code?为什么并行处理比普通代码花费更长的时间?
【发布时间】:2021-02-14 17:02:40
【问题描述】:

这个想法是用不同的新语料库更新特定的预训练 word2vec 模型。我有以下

# c1, c2 are each a list of 100 files
filelist = [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10]

def update_model(files):
    # loading a pre-trained model
    trained_model = gensim.models.Word2Vec.load("model_both_100")
    # Document feeder is an iterable
    docs = DocumentFeeder(files)
    trained_model.build_vocab(docs, update=True)
    trained_model.train(docs, total_examples=trained_model.corpus_count, epochs=trained_model.epochs)

with Pool(processes=10) as P:
    P.map(update_model, filelist)

运行大约需要 13 分钟。但是非并行版本(循环filelist)需要大约 11 分钟。为什么会这样?在 12 核 cpu 上运行。

【问题讨论】:

    标签: parallel-processing nlp python-multiprocessing gensim word2vec


    【解决方案1】:

    Gensim 的Word2Vec 训练已经使用了多个线程——这取决于模型创建时的workers 参数。 (默认使用workers=3,但您的模型可能已经初始化为使用更多。)

    因此,您将启动 10 个(重量级)进程,每个进程分别加载一个全尺寸模型。这很容易触发大量内存使用,从而导致虚拟内存交换。

    然后,每个模型都进行自己的(单线程)词汇扩展,然后进行(一个管理线程和 3 个或更多工作线程)训练。如果它们都在同时训练,则意味着在 12 个核心处理器上的 10 个操作系统进程内有 40 个线程处于活动状态。在这种情况下,没有理由期望加速,线程多于内核的争用,以及所有争用完全不同的加载模型内存范围的竞争,都可以很容易地解释减速。

    您真的要创建 10 个独立的增量更新模型吗? (更新训练后它们会被重新保存为 10 个不同的文件名吗?)

    【讨论】:

    • 是的。我正在尝试这样做。我将保存 10 个单独的增量更新模型(但只是键向量)。实际上我必须这样做超过 1000 次,我将发布一个关于如何优化空间的单独问题。
    • 那么,怎样才能让这个过程更快呢?我正在研究高性能计算集群,并且对云也有一些预算。平行化/加快流程的最佳解决方案是什么?
    • 作为一个单独的问题,这种增量训练充满了原始模型与增量更新之间平衡和兼容性的难题。我不知道您的完整设置和目标,但我怀疑对同一基本模型的这种数十(或数千)次交替增量更新无法提供您希望的价值。
    • 为了速度,在完全相同的机器上尝试多进程并行需要非常仔细地考虑我提到的交换、内存争用和核心争用问题。根据您的完整集群资源,最有意义的是尽可能快地弄清楚单个模型的更新 - 参数,工作线程等 - 然后在 N 完全独立的机器上重复此操作(没有争用) .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多