如何复现行为
下载 https://www.gutenberg.org/files/1342/1342-0.txt — 《傲慢与偏见》,大约0.8MB。
然后运行:
import spacy
nlp = spacy.load("en_core_web_sm")
with open("./1342-0.txt") as f:
book = f.read()
result = nlp.tokenizer(book)
使用 Fil memory profiler ( fil-profile run example.py
)运行此代码显示分词器使用30MB的RAM处理输入文件(最右边的列)。换句话说,内存使用量是原始文件大小的15-30倍,考虑到 _realloc
中引入的双倍逻辑所带来的不确定性。
您的环境
- spaCy版本: 3.4.1
- 平台: Linux-5.18.10-76051810-generic-x86_64-with-glibc2.35
- Python版本: 3.10.4
- Pipelines: en_core_web_sm (3.4.0)
关于解决这个问题的一些想法
基本上,内存使用量似乎与 tokens
数组中的 TokenC
对象有关。缩小 TokenC
是直接的方法:
- 更改字段的顺序,使字段按大小递减的顺序排列,这样对齐要求就不会添加不必要的填充。例如,查看 https://lwn.net/Articles/335942/ 以了解填充如何增加内存。
TokenC
上的一些字段可能可以切换为较小的类型,例如 uint32_t(或者在某些情况下甚至可以是16或8),而不是 uint64_t。- 我模糊的印象是,一个
TokenC
可以存储不同类型的令牌的不同信息。因此,它有一些字段用于一种类型,但不用于另一种类型,反之亦然。切换到联合体而不是一个大结构可以减少从所有变体的总和到所有变体的最大值的内存使用量。
这是个严重的问题吗?
我不确定。但我想象有时人们会尝试对大型文档进行分词,例如一个100MB的输入可能会占用3GB的RAM,这开始变得越来越多。用户可以在分词之前自行拆分文档,但考虑到分词器的作用,这有点奇怪😁
1条答案
按热度按时间ldioqlga1#
感谢报告和建议!这确实是我们希望在spaCy的下一个主要版本中进行调查的事情,在那里我们有更多的余地对库进行ABI破坏性更改。