Spacy,在 python 中的大型数据集上使用 nlp.pipe,多处理导致进程进入睡眠状态。如何正确使用所有 CPU 内核?
Posted
技术标签:
【中文标题】Spacy,在 python 中的大型数据集上使用 nlp.pipe,多处理导致进程进入睡眠状态。如何正确使用所有 CPU 内核?【英文标题】:Spacy, using nlp.pipe on large dataset in python, multiprocessing leads to processes going in sleep state. How to proper use all CPU cores? 【发布时间】:2021-06-24 21:39:06 【问题描述】:我正在处理一个大型电子邮件数据库(约 100 万)的 NLP 分类问题。我需要使用 spacy 来解析文本,并且我使用 nlp.pipe() 方法作为nlp.pipe(emails,n_process=CPU_CORES, batch_size=20)
来循环数据集。
该代码有效,但我面临一个(也许不是那么)奇怪的行为:
正在创建进程,但它们都处于 SLEEP 状态,但有一个,随便其中一些进入 RUN 状态几秒钟,然后重新进入睡眠状态。所以我发现自己有一个进程以 100% 使用一个内核,但当然脚本没有使用所有 CPU 内核。
就像进程没有从管道中“获取”输入数据一样。
有人知道如何正确使用 spacy nlp 管道,或者无论如何如何避免这种情况?没有办法在 GPU 上使用 nlp.pipe?
非常感谢! 桑德罗
编辑:我仍然没有解决方案,但我注意到如果我设置batch_size=divmod(len(emails),CPU_CORES)
,所有进程都开始以 100% CPU 运行,几秒钟后它们都切换到睡眠状态,但只有一个。它真的看起来像 spacy 管道中的某些元素在等待某事结束时被锁定....有什么想法吗??
EDIT2:在处理大型数据集时设置 batch_size=divmod(len(emails),CPU_CORES)
不可避免地会导致内存不足的错误:
MemoryError: Unable to allocate array with shape (1232821, 288) and data type float32
*这可能并不奇怪,因为我的机器有 10GB 的 RAM,并且 (1232821×288×32) 位 / 8 = 1.4GB 乘以 6 (CPU_CORES) 导致需要 8.5GB 的 RAM。因此,我想,已经在内存中有其他东西,结果证明是合理的。 *
【问题讨论】:
不是多处理方面的专家,但您是否尝试过将 batch_size 增加到 500 或 1000(可能更多是因为您的大量样本)? 20 似乎相当小,这意味着每 20 个样本流程需要重新安排。或者,您可以在 spacy 模型中 disable 一些管道(我通常只使用 POSTtag) 嗨@ygorg,是的,我尝试将批处理大小设置为许多不同的值( 在 GPU 上,为您的文本长度 + GPU 内存优化batch_size
并使用一个进程可能更容易。根据进程/RAM 的数量,CPU 批量大小可以是 1000+,GPU 批量大小可能需要小很多。此外,如果您使用的是 Transformer 模型,您可能会遇到与 Torch 和 OpenMP(在 CPU 或 GPU 上)相关的问题:github.com/pytorch/pytorch/issues/17199
@aab 感谢您的回复,我不确定如何“强制”spacy nlp.pipe() 使用 GPU?
可能是因为我在for doc in nlp.pipe(...):
循环中所做的事情在执行时间上太慢了,因此 spacy 管道必须以某种方式等待所有批次都被处理?这只是一个猜测,因为我不是 spacy 或多处理专家....
【参考方案1】:
我发现使用 n_process=n 对某些模型效果很好,例如 en_core_web_lg,但对其他模型无效,例如 en_core_web_trf。
无论出于何种原因,en_core_web_trf 似乎使用了只指定了 batch_size 的所有内核,而 en_core_web_lg 只使用了一个,除非给出了 n_process=n。同样,如果指定了 n_process=n,en_core_web_trf 将失败并出现关闭错误。
【讨论】:
我正在使用 en_core_web_lg 但对我来说主要问题是进程将进入睡眠状态并且(显然)随机唤醒而不是一直一起运行。无论如何感谢您的贡献:)【参考方案2】:好的,我认为我找到了改进,但老实说,我并不太清楚这种行为。现在休眠的进程少了很多,大部分稳定运行,少数休眠或在两种状态之间切换。 我所做的是清理和加速 for 循环中的所有代码,并像这样设置 nlp.pipe 参数:
for e in nlp.pipe(emails,n_process=CPU_CORES-1, batch_size=200):
如果有人对此有任何解释或关于如何进一步改进的任何建议,当然非常欢迎:)
【讨论】:
以上是关于Spacy,在 python 中的大型数据集上使用 nlp.pipe,多处理导致进程进入睡眠状态。如何正确使用所有 CPU 内核?的主要内容,如果未能解决你的问题,请参考以下文章