使用gensim WikiCorpus处理维基百科Dump时遇MemoryError求解决方案
尝试从19GB的.bz2格式维基百科Dump文件构建语料库,运行以下Python代码时触发MemoryError:
import warnings warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim') from gensim.corpora import WikiCorpus import sys def make_corpus(in_f, out_f): output = open(out_f, 'w') print("File Created!") wiki = WikiCorpus(in_f) print("Wiki Opened!") i = 0 for text in wiki.get_texts(): output.write(bytes(' '.join(text).encode('utf-8')).decode('utf-8') + '\n') i = i + 1 if (i % 10000 == 0): print('Processed ' + str(i) + ' articles...') output.close() print('Processing Completed!') if __name__ == '__main__': if len(sys.argv) !=3: sys.exit(1) in_f = sys.argv[1] out_f = sys.argv[2] make_corpus(in_f, out_f)
报错回溯信息:
回溯(最近的调用最后):
文件 "", 第1行, in
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\multiprocessing\spawn.py", 第105行, in spawn_main
exitcode = _main(fd)
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\multiprocessing\spawn.py", 第114行, in _main
prepare(preparation_data)
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\multiprocessing\spawn.py", 第225行, in prepare
fixup_main_from_path(data['init_main_from_path'])
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\multiprocessing\spawn.py", 第277行, in fixup_main_from_path
run_name="mp_main")
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\runpy.py", 第263行, in run_path
pkg_name=pkg_name, script_name=fname)
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\runpy.py", 第96行, in run_module_code
mod_name, mod_spec, pkg_name, script_name)
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\runpy.py", 第85行, in run_code
exec(code, run_globals)
文件 "d:/LeongJC/FYP_Code/Code/wikipedia_transformation.py", 第3行, in
import gensim
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim_init.py", 第11行, in
from gensim import parsing, corpora, matutils, interfaces, models, similarities, utils # noqa:F401
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora_init.py", 第6行, in
from .indexedcorpus import IndexedCorpus # noqa:F401 must appear before the other classes
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\indexedcorpus.py", 第14行, in
from gensim import interfaces, utils
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\interfaces.py", 第19行, in
from gensim import utils, matutils
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\matutils.py", 第19行, in
from scipy.stats import entropy
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\scipy\stats_init.py", 第388行, in
from .stats import *
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\scipy\stats\stats.py", 第174行, in
from scipy.spatial.distance import cdist
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\scipy\spatial_init.py", 第101行, in
from .procrustes import procrustes
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\scipy\spatial_procrustes.py", 第9行, in
from scipy.linalg import orthogonal_procrustes
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\scipy\linalg_init.py", 第194行, in
from .misc import *
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\scipy\linalg\misc.py", 第4行, in
from .lapack import get_lapack_funcs
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\scipy\linalg\lapack.py", 第783行, in
from scipy.linalg import _flapack
ImportError: DLL load failed: 分页文件太小,无法完成此操作。
multiprocessing.pool.RemoteTraceback:
"""
回溯(最近的调用最后):
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\multiprocessing\pool.py", 第119行, in worker
result = (True, func(*args, **kwds))
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\wikicorpus.py", 第530行, in _process_article
token_max_len=token_max_len, lower=lower,
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\wikicorpus.py", 第490行, in process_article
result = tokenizer_func(text, token_min_len, token_max_len, lower)
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\wikicorpus.py", 第361行, in tokenize
utils.to_unicode(token) for token in utils.tokenize(content, lower=lower, errors='ignore')
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\utils.py", 第264行, in tokenize
text = text.lower()
MemoryError
"""
上述异常是导致以下异常的直接原因:
回溯(最近的调用最后):
文件 "d:/LeongJC/FYP_Code/Code/wikipedia_transformation.py", 第31行, in
make_corpus(in_f, out_f)
文件 "d:/LeongJC/FYP_Code/Code/wikipedia_transformation.py", 第11行, in make_corpus
wiki = WikiCorpus(in_f)
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\wikicorpus.py", 第639行, in init
self.dictionary = Dictionary(self.get_texts())
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\dictionary.py", 第78行, in init
self.add_documents(documents, prune_at=prune_at)
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\dictionary.py", 第196行, in add_documents
for docno, document in enumerate(documents):
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\site-packages\gensim\corpora\wikicorpus.py", 第693行, in get_texts
for tokens, title, pageid in pool.imap(_process_article, group):
文件 "C:\Users\asus\anaconda3\envs\tensorflow\lib\multiprocessing\pool.py", 第735行, in next
raise value
MemoryError
1. 禁用自动字典构建
WikiCorpus默认会在初始化时构建全量词汇字典,这会占用大量内存。初始化时指定dictionary=None跳过字典生成,只做文本提取:
wiki = WikiCorpus(in_f, dictionary=None)
2. 限制多进程数量
多进程并发处理会叠加内存占用,通过workers参数减少进程数,建议设为CPU核心数的一半:
wiki = WikiCorpus(in_f, dictionary=None, workers=2) # 根据自身CPU配置调整
3. 优化文本写入逻辑
原代码中的编码解码操作完全多余,直接拼接字符串写入,减少临时内存对象:
output.write(' '.join(text) + '\n')
4. 扩大系统虚拟内存
报错明确提到“分页文件太小”,Windows系统可按以下步骤调整:
- 右键「此电脑」→「属性」→「高级系统设置」→「高级」→「性能」→「设置」→「高级」→「虚拟内存」→「更改」
- 取消「自动管理所有驱动器的分页文件大小」,选中系统盘,设置「自定义大小」:初始大小设为物理内存的1.5倍,最大值设为物理内存的3倍
- 重启电脑生效
5. 分块处理Dump文件
如果以上方法仍无法解决,可先解压.bz2文件,再分割成小文件逐个处理:
- 解压:用7-Zip或命令行
bzip2 -d 文件名.bz2 - 分割:用
split命令按行数分割,比如split -l 100000 解压后的.xml 文件前缀_ - 修改代码循环处理每个分割后的小文件
6. 升级物理内存
这是最彻底的解决方案,处理19GB级别的语料,建议物理内存至少16G,32G以上会更流畅。
内容的提问来源于stack exchange,提问作者Ethan Leong

