批量运行spaCy nlp()管道以处理大型文档

8
我试图在由20,211,676个字符组成的一系列文本记录上运行nlp()管道。我使用了一台配备8GB RAM的计算机进行操作。虽然我对Python和spaCy都很陌生,但是现在正在工作的论文所需的语料库比较工具和句子切块功能非常完美。 我尝试的方法 我首先导入英语管道,并删除'ner'以提高速度。
nlp = spacy.load('en_core_web_lg', disable = ['ner'])

然后我将语料库分成800,000个字符的片段,因为spaCy建议每GB处理100,000个字符。

split_text = [text[i:i+800000] for i in range(0, len(text), 800000)]

将这些代码块通过流水线循环处理,创建NLP对象列表。

nlp_text = []
for piece in split_text:
    piece = nlp(piece)
    nlp_text.append(piece)

需要经过长时间等待才能正常工作。 注意: 我尝试通过'nlp.max_length'提高阈值,但是超过1,200,000后,我的Python会话就崩溃了。

现在,我已经将所有内容传输完毕,需要将它们拼接起来,因为最终需要将整个文档与另一个(大小大致相当)进行比较。此外,我还想找出整个文档中最常见的名词短语,而不仅仅是在人为分割的800,000字符片段中。

nlp_text = ''.join(nlp_text)

然而我收到了以下错误信息:

TypeError:序列项0:期望str实例, 找到spacy.tokens.doc.Doc

我意识到我可以将其转换为字符串并进行连接,但这将违背使用“token”对象的目的。

我需要什么

除了使用昂贵的AWS CPU时间外,是否有其他方法(分割文档,运行nlp()管道,然后加入标记以重建完整的文档作为研究对象)? 我是否对大型文档运行管道有误?我是否注定要在某个地方获得64GB RAM?

编辑1:对Ongenz的回复

(1) 这是我收到的错误消息

ValueError:长度为1071747的文本超过了1000000的最大值。 v2.x解析器和NER模型需要每100,000个字符输入大约1GB的临时内存。 这意味着长文本可能会导致内存分配错误。 如果您没有使用解析器或NER,则可能可以安全地增加nlp.max_length限制。 限制是字符数,因此您可以通过检查len(text)来检查输入是否太长。

我无法找到直接涉及此问题的文档部分。

(2) 我的目标是进行一系列措施,包括(但不限于如有需要):单词频率,tfidf计数,句子计数,最常见名词短语的计数,使用w2v或d2v策略比较两个语料库。 为此,我理解我需要spaCy管道的每个部分,除了NER。

(3) 您完全正确关于切割文档,在完美的世界中,我将在换行符上切割。但正如您所提到的,我不能使用join来重新组合我的拆开的语料库,因此可能无关紧要。


你好,您想做什么处理?只是句子分词?词语分词?还是需要进行词性标注和依存句法分析?您能否发布一下 spaCy 文档中建议 "spaCy 建议每 GB 处理的字符数为 100,000" 的相关部分?此外,join 函数(文档)以可迭代对象(例如字符串或字符串对象列表)作为参数,并且您传递了一个 spaCy 的 Doc 对象列表。您在这里要做的事情取决于您想要做的处理方式(我猜您不想使用 join)。 - ongenz
将文档按固定长度的字符序列进行拆分可能会将单词拆分成两部分 - 这对您有影响吗?如果您的文本确实太大,您可以尝试使用较少“粗暴”的方法(例如,在换行符上进行切割)预处理为较小的文件。 - ongenz
感谢您的回答 ongenz:我编辑了帖子以反映您的问题。 - Gabriel Varela
1个回答

2
您需要使用Doc.from_docs方法将生成的Doc连接起来:
docs = []
for piece in split_text:
    doc = nlp(piece)
    docs.append(doc)
merged = Doc.from_docs(docs)

请参阅此处的文档了解更多细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接