大语言模型中一个调皮的EOS token

背景

最近需要做一个微调的培训,所以不可避免地需要上手一下相关的微调,而受限于机器资源,暂时没法做全参数微调,所以就尝试了目前比较火的两种高效微调方式,分别是PTuning和LoRA。模型选择得自然是现在中文做的比较好的ChatGLM2-6B。

微调的代码分别用的是

PTuning

LoRA

在分别尝试了两个结果后,发现LoRA微调出来的结果有点抽风,喜欢疯狂输出,而它就是咱们今天的主角:ChatGLM2-6B的Tokenizer所使用的EOS(end-of-sequence) token。

EOS token 介绍

其实从名字就可以看出来,EOS的作用就是标记一个序列的结束,这样模型就可以知道这个序列已经结束了,不需要再继续输出了。 如果以为例,一般模型在推理的时候,觉得可以结束一句话了,就会输出,但是模型的脑子里肯定没有的概念呀,它只能输出数字,所以我们需要把转换成数字,这个数字就是EOS token ID。在ChatGLM2-6B的Tokenizer中,EOS token ID是2,而模型输出的时候,输出的也是2,而不是

分析BUG

既然模型会输出文字版的,那是不是模型的输入中,给它喂进去了不合适的语料呢?

进一步查找发现所使用的LoRA库中是这么添加EOS的:

medicalGPT

尝试一下直接用喂给tokenizer,看看tokenizer会怎么处理。

tokenize_s

看到这原因的就很明显了,因为这个EOS添加的是字符,而不是token_id,所以tokenizer有时候会把当成了分开的token,比如</和s和>,模型就把这3它当成了三个token,而不是一个token,所以在推理的时候,遇到结尾,有时候就会输出</+s+>。而transformers的库在推理看一个句子是否以EOS结尾,看的是token_id而不是token。就会认为生成还没有结束,就继续生成了,直到某一次推理,模型想起来预训练时的记忆,在遇到结尾的时候输出了2的token id(也就是),transformers库才会认为生成结束,停止生成。

transformers

既然知道了问题的原因,那么就需要解决这个问题,解决的方法也很简单,就是把EOS token_id添加到输入中,而不是字符。具体代码就是按照PTuning的方式,把EOS token_id添加到输入中。

refactor

改完之后重新train一遍LoRA,模型不再疯狂输出了。

尾声

要改这个bug,其实需要挺多tokenization的知识的,最近没有时间好好研究,之后有时间再来补充一下。

相关推荐
腾讯云开发者几秒前
架构火花|产品经理和程序员谁会先被AI淘汰?
人工智能
腾讯云开发者16 分钟前
告别 271 万小时重复劳动:银行数字员工如何再造效率奇迹?
人工智能
xiaoxue..19 分钟前
Vibe Coding之道:从Hulk扩展程序看Prompt工程的艺术
前端·人工智能·prompt·aigc
大模型真好玩21 分钟前
LangChain1.0实战之多模态RAG系统(一)——多模态RAG系统核心架构及智能问答功能开发
人工智能·langchain·agent
聚梦小课堂22 分钟前
2025.11.16 AI快讯
人工智能·安全·语言模型
Mintopia32 分钟前
🚀 Trae 国际版 Max 模型升级:算力与智能的共舞
前端·人工智能·trae
Mintopia34 分钟前
🌍 WebAIGC的高算力消耗:技术优化与绿色计算路径
前端·人工智能·trae
kupeThinkPoem38 分钟前
代码生成工具GitHub Copilot介绍
人工智能
aneasystone本尊38 分钟前
重温 Java 21 之结构化并发
人工智能
咚咚王者1 小时前
人工智能之数据分析 numpy:第四章 数组属性和数据类型
人工智能·数据分析·numpy