不确定这是否是预期发生的情况,还是我自己的误解。我假设是误解,所以我选择了文档报告。
Language (nlp)
类有一个 max_length
参数,对于日语等语言似乎表现不同。
我目前正尝试通过考虑 max_length 并将文本拆分为基于该值的块来对过长的文本进行分块。例如,英语文本在这种情况下似乎没有任何问题。
基本方法代码:
if len(content) > nlp.max_length:
for chunk in __chunk_text(content, nlp.max_length-100):
doc = nlp(chunk)
#....
然而,对于配置字符串 ja_core_news_sm
,这不起作用。
经过一些分析,我注意到不是长度而是字节量需要考虑。
def __utf8len(s:str):
return len(s.encode('utf-8'))
if __utf8len(content) > nlp.max_length:
#...
然而,即使采用字节方法,我也遇到了一个错误,看起来像是与 max_length 相关的,但也许不是?
稍微减少的错误跟踪:
doc = nlp(content)
File "/usr/local/lib/python3.9/site-packages/spacy/language.py", line 1014, in __call__
doc = self._ensure_doc(text)
File "/usr/local/lib/python3.9/site-packages/spacy/language.py", line 1105, in _ensure_doc
return self.make_doc(doc_like)
File "/usr/local/lib/python3.9/site-packages/spacy/language.py", line 1097, in make_doc
return self.tokenizer(text)
File "/usr/local/lib/python3.9/site-packages/spacy/lang/ja/__init__.py", line 56, in __call__
sudachipy_tokens = self.tokenizer.tokenize(text)
Exception: Tokenization error: Input is too long, it can't be more than 49149 bytes, was 63960
我还仔细检查了 max_length(1000000)、字符串长度(63876)和字节长度(63960)的值。
手动将 max_length 设置为 1100000 没有改变错误信息,所以我假设可能是其他东西(也许是 Sudachi 本身?)定义了输入太长的错误信息。
实际问题是什么以及如何解决它(用于查找大小限制)对于文档来说会很有趣。
此问题与哪个页面或部分相关?
不确定在哪里添加,因为如果直接与日语有关的话就不确定了。然而,在 https://spacy.io/models/ja 或者 https://spacy.io/usage/models#japanese 中添加一条注解可能会很有意义。此外,关于 max_length 的一般说明可能需要扩展(如果正确地假设的话,也许类似于 character length isn't the classic python len(<string>) function but the byte size (e.g. letter "I" - len 1 - byte 1 & kanji "私" - len 1 - byte 3)
)。
4条答案
按热度按时间pxy2qtax1#
nlp.max_length
不是一个硬性的内部约束,而是一种笨拙的方式来保护用户免受令人困惑的OOM错误的困扰。它是用 "核心" 管道和一个并不特别新的消费级笔记本电脑设置的。如果你的系统实际上并没有内存耗尽,你可以放心地增加它,尤其是对于像分词这样的简单任务。另一方面,核心管道中的任何组件都不会从非常长的上下文中受益(通常,一个段落或一页就足够了),因此拆分文本通常是最佳方法。非常长的文本可能会占用大量RAM,尤其是对于
parser
或ner
。这个日语限制与
nlp.max_length
完全分开,直接来自 sudachipy(我之前实际上没有遇到过)。他们的错误信息似乎还不错(比带有令人困惑的解析器中间的OOM消息要好得多),所以我不知道是否有必要在 spacy 日本分词器中添加另一个检查,这可能会在未来与上游 sudachipy 约束不同步。
但你是对的,
nlp.max_length
不会直接帮助限制字节长度,除非你将其设置得非常低。但再次,较低的限制在实践中可能没问题。我们会考虑将其添加到文档中!
j2cgzkjk2#
感谢您的解释,这帮助我消除了困惑,我知道如何为我的用例继续进行。
如果有人偶然遇到这个问题,以下是我使用的字节拆分代码(尽管可能仍然有很多优化潜力)
14ifxucb3#
现有文档
"""
...
max_length (int): 用于处理的文本的最大允许长度。
...
"""
更新后的文档
"""
...
max_length (int): 用于处理的文本的最大允许长度。max_length的行为可能因不同的语言而有所不同。请参阅针对特定语言的文档以获取更多详细信息。
...
tgabmvqs4#
感谢您的建议!我认为这个描述对用户来说有些困惑,因为
nlp.max_length
本身对所有语言的行为都是相同的。我们需要强调的是,一些单独的分词器或组件,尤其是那些 Package 第三方库的组件,可能有自己的内部长度限制。