我正在学习 Bert,它只处理少于 512 个标记的文本,并且遇到了这个 answer,它说在中间截断文本(而不是在开头或结尾)可能对 Bert 很有效。我想知道是否有任何库可以进行这种类型的截断,因为据我了解,一个单词可以由多个 Bert 令牌组成,所以我不能简单地获取中间的 512 个单词。预先感谢
该帖子引用了一篇论文,其中指出应保留前 128 个代币和最后 382 个代币(不包括 CLS 和 SEP 代币)。
对于标记化,您可以使用 HuggingFace 的 Transformers 库中的 Bert Tokenizer 对整个字符串进行标记化,然后删除除前 129 个和最后 383 个标记之外的所有内容。 129 是因为我们包含了初始的 CLS 代币,383 是因为我们包含了结尾的 SEP 代币。
代码:
# Generate sample text
from string import ascii_lowercase
sample_text = ""
for c1 in ascii_lowercase:
for c2 in ascii_lowercase:
sample_text += f"{c1}{c2} "
# Get tokenizer
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
# Perform tokenization
tokenized = tokenizer(sample_text)
# Trim tokens
if len(tokenized["input_ids"]) > 512:
for k,v in tokenized.items():
tokenized[k] = v[:129] + v[-383:]
# Verify result
print(tokenizer.decode(tokenized["input_ids"]))
print(len(tokenized["input_ids"]))