Torch Vocab方法更新(stoi/itos变更)后翻译模型代码报错求助
问题解决方案
1. 核心问题定位
你遇到的Counter object has no attribute 'get_stoi'错误,根源是你的src_vocab不是TorchText的Vocab实例,而是直接返回了Counter对象。旧文章的build_vocab函数只统计了词频,没有用TorchText的Vocab类封装,导致无法调用新版本的get_stoi()方法。
2. 修正build_vocab函数
基础修正版(兼容原逻辑)
将统计后的Counter包装成TorchText的Vocab实例,确保返回合法的Vocab对象:
from collections import Counter from torchtext.vocab import Vocab def build_vocab(sentences, tokenizer): counter = Counter() for sentence in sentences: tokens = tokenizer.encode(sentence, out_type=str) counter.update(tokens) # 用Counter构建Vocab,添加特殊标记 vocab = Vocab( counter, specials=['<unk>', '<pad>', '<bos>', '<eos>'], # 对应你的BOS/EOS/PAD/UNK标记 special_first=True ) return vocab
优化版(推荐,适配TorchText新版本)
使用TorchText官方推荐的build_vocab_from_iterator函数,更高效且节省内存,适合大规模数据集:
from torchtext.vocab import build_vocab_from_iterator # 定义迭代器生成器,逐句返回token def yield_tokens(sentences, tokenizer): for sentence in sentences: yield tokenizer.encode(sentence, out_type=str) def build_vocab(sentences, tokenizer, min_freq=2): vocab = build_vocab_from_iterator( yield_tokens(sentences, tokenizer), min_freq=min_freq, # 过滤出现次数少于min_freq的词,减少词汇表大小 specials=['<unk>', '<pad>', '<bos>', '<eos>'], special_first=True ) # 设置未登录词默认映射到<unk>的索引 vocab.set_default_index(vocab['<unk>']) return vocab
3. 修正translate函数的token转换代码
将原代码中的src_vocab.stoi替换为src_vocab.get_stoi(),同时添加未登录词的容错处理:
# 原错误代码 # tokens = [BOS_IDX] + [src_vocab.stoi[tok] for tok in src_tokenizer.encode(src, out_type=str)]+ [EOS_IDX] # 修正后代码 src_stoi = src_vocab.get_stoi() unk_idx = src_vocab['<unk>'] tokens = [BOS_IDX] + [src_stoi.get(tok, unk_idx) for tok in src_tokenizer.encode(src, out_type=str)] + [EOS_IDX]
get_stoi()返回词汇到索引的字典get(tok, unk_idx)确保遇到未收录的词时,自动映射到的索引,避免KeyError
4. 关于itos的替代方案
原代码中的src_vocab.itos需要替换为src_vocab.get_itos(),比如获取索引对应的token:
# 原代码:token = src_vocab.itos[idx] # 修正后: token = src_vocab.get_itos()[idx]
内容的提问来源于stack exchange,提问作者BoostMatch
相关产品推荐
相关产品推荐

