joblib Parallel 函数如何管理内存?

How does joblib Parallel function manage the memory?

我正在编写一个将 PDF 转换为 PNG 图像的函数,它看起来像这样:

import os
from wand.image import Image

def convert_pdf(filename, resolution):
    with Image(filename=filename, resolution=resolution) as img:
        pages_dir = os.path.join(os.path.dirname(filename), 'pages')
        page_filename = os.path.splitext(os.path.basename(filename))[0] + '.png'
        os.makedirs(pages_dir)
        img.save(filename=os.path.join(pages_dir, page_filename))

当我尝试并行化时,内存在增长,我无法完成 PDF 文件的处理:

def convert(dataset, resolution):
    Parallel(n_jobs=-1, max_nbytes=None)(
        delayed(convert_pdf)(filename, resolution) for filename in glob.iglob(dataset + '/**/*.pdf', recursive=True)
    )

当我串行调用函数时,内存保持不变。

joblib 如何管理每个并行实例的内存分配?

如何修改我的代码,以便在 运行 并行时内存保持不变?

Joblib 将使用序列化技术将数据传递给您的所有工作人员。当然内存会随着worker的数量增长。

来自docs

By default the workers of the pool are real Python processes forked using the multiprocessing module of the Python standard library when n_jobs != 1. The arguments passed as input to the Parallel call are serialized and reallocated in the memory of each worker process.

没有办法用 1 个内存并行处理 2 个文件(如果你真的想要加速的话)!

文档还提到了内存映射,它通常用于数字数据以及当这些工作人员共享数据时(OS 负责缓存)。这在这里无济于事,因为您的案例中没有共享数据。但是由于内存映射在缓存方面自动保持内存友好,因此在这种情况下不应发生基于内存的程序崩溃,但当然完成此 IO(与缓存相反)会降低性能。

简而言之:

  • 使用 X 核,预计内存使用量增加 X 倍
    • 你无能为力
  • 如果您观察到比预期的线性消耗更多的内存消耗,则似乎有问题
  • 我不确定你有多少核心,但你可以尝试用 n_jobs=4 来限制它
  • 这种 IO 密集型处理不适合并行处理
    • IO 主导计算!!!