在大型数据集上运行BERT嵌入遇代码错误,求解决方案
解决BERT文本分块时的AttributeError问题
你的AttributeError: 'list' object has no attribute 'split'是因为代码里误对列表对象调用了字符串专属的split()方法。这种情况通常出现在数据读取或预处理环节:要么是把单部小说的内容存成了段落/句子列表,要么是之前的步骤把字符串转成了列表,却直接用它来调用split()。
核心修复步骤
- 定位变量类型:找到报错代码行,检查调用
split()的变量实际是列表还是字符串。比如打印type(your_variable)确认。 - 统一数据格式:如果变量是列表(比如按段落拆分的小说内容),先合并成单字符串:
# 假设novel_content是段落列表 full_text = ' '.join(novel_content) - 用BERT Tokenizer做分块(更可靠):不要用普通
split()分块——BERT的token是子词结构,普通拆分会破坏语义,直接用Tokenizer处理分块更准确,还能自动适配512token限制:
修正后的完整分块代码示例
from transformers import BertTokenizer # 初始化BERT分词器 tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') # 假设你的数据集是:每个元素是一部小说的内容(可能是列表或字符串) novel_dataset = [["第一章 雨下了一整夜...", "第二章 他推开木门..."], "第三章 风穿过小巷..."] for novel in novel_dataset: # 第一步:确保处理的是字符串 if isinstance(novel, list): full_text = ' '.join(novel) else: full_text = novel # 第二步:用Tokenizer编码文本为token序列 tokens = tokenizer.encode(full_text, add_special_tokens=False) # 第三步:按496个token分块(预留16个位置给[CLS]和[SEP]) chunk_size = 496 token_chunks = [tokens[i:i+chunk_size] for i in range(0, len(tokens), chunk_size)] # 可选:将token块转回文本(如果需要文本形式的分块) text_chunks = [tokenizer.decode(chunk) for chunk in token_chunks] # 后续处理每个分块的BERT嵌入 for chunk in token_chunks: # 添加BERT要求的特殊token input_ids = tokenizer.build_inputs_with_special_tokens(chunk) # 这里可以传入BERT模型获取嵌入 # outputs = bert_model(torch.tensor([input_ids])) # embeddings = outputs.last_hidden_state
关键注意事项
- 分块时必须给
[CLS]和[SEP]留位置,所以每个块的最大token数设为496-500(避免加上特殊token后超过512)。 - 不要用
split(' ')这种方式分块,会导致子词拆分错误,影响BERT嵌入的准确性。 - 如果是读取数据时生成了列表,调整读取逻辑:比如用
open(file_path).read()直接读取整个小说为单字符串,而不是按行拆分存成列表。
内容的提问来源于stack exchange,提问作者Dez Miller
相关产品推荐
相关产品推荐

