如何将Jupyter中训练的微调BERT模型部署到Ubuntu 20.04服务器解决长文本推理报错
问题根源定位
你遇到的触发报错的原文为:
At most 4 tokens in tensor([ 2, 2, 2, 2, 44763, 44763, 2, 44763]) can be equal to
eos_token_id: 2. Make sure tensor([ 2, 2, 2, 2, 44763, 44763, 2, 44763]) are corrected.
这个报错不是长文本输入触发的模型能力问题,是跨环境依赖版本差、模型文件迁移不全导致的解码逻辑异常:
- 短文本输入时解码路径短,序列中累计出现的eos token(id为2)数量达不到校验阈值,所以能正常生成
- 长文本输入时解码步长更长,累计的eos数量一旦超过新版本transformers里写死的4个的默认上限,就会直接抛错
可落地解决方案
1. 优先对齐两边环境的依赖版本
本地Jupyter环境运行正常,迁移到Ubuntu服务器出问题的第一诱因几乎都是依赖版本不匹配:
- 在本地可正常运行的环境执行命令查询版本号:
pip show simpletransformers transformers torch - 在Ubuntu服务器上安装完全相同版本号的三个依赖,不要直接装最新版
原因:transformers从4.40版本开始,在seq2seq生成流程里新增了硬编码的eos token数量校验,默认仅允许生成序列中最多保留4个eos token,本地运行的旧版本没有这段校验逻辑,自然不会触发报错
2. 无法降级依赖时的快速修复
如果因为服务器环境限制没法把依赖降到本地兼容版本,直接在初始化模型时自定义生成参数,把eos校验的阈值调高即可,不需要修改源码:
from simpletransformers.seq2seq import Seq2SeqModel # 自定义模型参数,覆盖默认生成配置 custom_args = { # 对应生成逻辑里的max_eos_to_keep参数,把阈值拉到大于最大生成长度即可,不会触发校验报错 "max_eos_to_keep": 1024, # 同步对齐训练时的最大生成长度,避免长文本解码时出现截断乱码 "max_length": 128, # 替换为实际微调时设置的最大生成长度 } model = Seq2SeqModel( encoder_decoder_type="bart", encoder_decoder_name="PATHOFMODEL", use_cuda=False, args=custom_args )
注意:你描述中提到微调的是BERT模型,但代码中加载的是bart架构的seq2seq模型,记得核对模型路径下的权重文件是否为实际训练生成的,避免错用其他架构的模型权重
3. 排查迁移遗漏的模型文件
如果调整参数后还是出现序列中无意义连续输出eos token的问题,需要检查模型目录下的文件是否拷贝完整:
- 必须把本地模型目录下的
tokenizer.json、vocab.txt、special_tokens_map.json、tokenizer_config.json全量拷贝到服务器的模型路径下,不能只拷贝模型权重文件pytorch_model.bin - 长文本输入时不要超过训练时设置的最大输入截断长度,比如训练时最大输入长度设为512token,传入更长的文本时前处理会发生token位置错位,把普通token错误识别为eos id,触发异常输出
内容的提问来源于stack exchange,提问作者Scorp Amelia
相关产品推荐
相关产品推荐

