Python调用MarianMT实现回译报index out of range in self错误
错误原因
这个索引越界错误由两个核心问题共同触发:
- 代码逻辑冗余重复:你在调用翻译函数前,已经手动给原始文本拼接了一次
>>es<<前缀,而perform_translation函数内部会再次执行前缀拼接逻辑,最终传入模型的文本会出现>>es<< >>es<< 原文的重复前缀,无意义的特殊标记堆叠直接导致分词结果异常。 - 模型用法错误:你加载的
Helsinki-NLP/opus-mt-en-es是固定方向的英翻西单语对模型,这类模型训练时从未使用>>目标语言代码<<作为前缀提示,额外添加的前缀属于模型训练阶段没见过的特殊字符,分词后会生成超出词表/位置嵌入表范围的异常id,查表时直接触发越界。 - 额外触发场景:如果单条待翻译文本长度超过模型支持的最大序列长度(opus-mt系列默认最大支持512token),也会触发同类位置嵌入索引越界错误。
修复方法
单语对Marian翻译模型不需要额外添加语言前缀,删掉冗余的格式化逻辑,同时在分词阶段增加超长文本截断即可,修正后的可运行代码如下:
# 安装依赖 !pip install transformers !pip install sentencepiece from transformers import MarianMTModel, MarianTokenizer # 加载双向翻译模型 # 英译西模型 en2es_model_name = 'Helsinki-NLP/opus-mt-en-es' en2es_tokenizer = MarianTokenizer.from_pretrained(en2es_model_name) en2es_model = MarianMTModel.from_pretrained(en2es_model_name) # 西译英模型 es2en_model_name = 'Helsinki-NLP/opus-mt-es-en' es2en_tokenizer = MarianTokenizer.from_pretrained(es2en_model_name) es2en_model = MarianMTModel.from_pretrained(es2en_model_name) # 翻译函数 def perform_translation(batch_texts, model, tokenizer, max_seq_len=512): # 分词阶段自动padding、截断超长文本,从根源避免长度越界 model_inputs = tokenizer( batch_texts, return_tensors="pt", padding=True, truncation=True, max_length=max_seq_len ) # 生成翻译结果 gen_tokens = model.generate(**model_inputs) # 转换为自然文本 result = [tokenizer.decode(t, skip_special_tokens=True) for t in gen_tokens] return result # 回译流程示例 if __name__ == "__main__": # 替换成你自己的原始英文数据集 raw_en_texts = ["Back translation is a common data augmentation method for NLP tasks.", "The weather is nice today."] # 第一步:英译西 es_trans = perform_translation(raw_en_texts, en2es_model, en2es_tokenizer) print("英译西结果:", es_trans) # 第二步:西译英,完成回译 back_en_trans = perform_translation(es_trans, es2en_model, es2en_tokenizer) print("回译英文结果:", back_en_trans)
补充说明:
>>目标语言代码<<前缀仅适用于多语言Marian模型(比如支持英语翻译到多种罗曼语的Helsinki-NLP/opus-mt-en-roa),作用是指定具体目标语言;固定方向的单语对模型不需要加任何前缀,直接输入原始文本即可。
内容的提问来源于stack exchange,提问作者Laura Vázquez
相关产品推荐
相关产品推荐

