如何使用mBERT对泰米尔UD数据集pandas列生成词嵌入并解决token id错误
问题核心原因
mBERT采用WordPiece分词规则,会将你提前拆分好的单token进一步拆分为多个子词,单个原token对应多个token id,因此直接转换会出现原token与依存标签无法对齐的错误。
解决方案
方案1:使用分词器原生预分词适配逻辑(推荐)
HuggingFace Transformers库的BertTokenizer已内置对预分词输入的支持,通过is_split_into_words参数即可实现原token与子词的自动映射,对齐步骤如下:
- 预分词输入编码
from transformers import BertTokenizer, BertModel import torch import pandas as pd # 加载mBERT分词器与模型 tokenizer = BertTokenizer.from_pretrained("bert-base-multilingual-cased") model = BertModel.from_pretrained("bert-base-multilingual-cased") # 假设你的预处理后数据集存储在df变量中,tokens列为单样本分词结果列表 sample_tokens = df["tokens"].iloc[0] # 传入预分词列表,开启is_split_into_words参数 encoded_input = tokenizer( sample_tokens, is_split_into_words=True, padding="max_length", truncation=True, max_length=128, return_tensors="pt" ) # 获取每个子词对应的原token索引 word_ids = encoded_input.word_ids()
- 词嵌入对齐
得到模型输出后,可选择两种常用策略将子词嵌入聚合为原token对应的嵌入:
- 取原token对应第一个子词的嵌入作为整体表示
- 取原token对应所有子词嵌入的平均值作为整体表示
示例代码(取首子词策略):
with torch.no_grad(): model_output = model(**encoded_input) # 提取序列最后一层隐藏状态,去掉batch维度 last_hidden = model_output.last_hidden_state[0] aligned_embeds = [] prev_word_idx = None for sub_idx, word_idx in enumerate(word_ids): # 跳过<[BOS_never_used_51bce0c785ca2f68081bfa7d91973934]>、[SEP]等特殊标记 if word_idx is None: continue # 仅保留每个原token对应的第一个子词嵌入 if word_idx!= prev_word_idx: aligned_embeds.append(last_hidden[sub_idx]) prev_word_idx = word_idx # aligned_embeds长度与原sample_tokens长度完全一致,可匹配对应依存标签使用
方案2:替换适配低资源语言的预训练模型
泰米尔语属于印度语系低资源语言,mBERT对其的子词拆分粒度通常较碎,若上述方案效果达不到预期,可替换为针对印度语系优化的多语言预训练模型ai4bharat/indic-bert,该模型的词表覆盖更多泰米尔语常用词,子词拆分更合理,可降低对齐误差。
内容的提问来源于stack exchange,提问作者Ayush Shyam
相关产品推荐
相关产品推荐

