大语言模型中一个调皮的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的知识的,最近没有时间好好研究,之后有时间再来补充一下。

相关推荐
罗西的思考22 分钟前
[2W字长文] 探秘Transformer系列之(23)--- 长度外推
人工智能·算法
小杨4042 小时前
python入门系列十四(多进程)
人工智能·python·pycharm
阿坡RPA16 小时前
手搓MCP客户端&服务端:从零到实战极速了解MCP是什么?
人工智能·aigc
用户277844910499317 小时前
借助DeepSeek智能生成测试用例:从提示词到Excel表格的全流程实践
人工智能·python
机器之心17 小时前
刚刚,DeepSeek公布推理时Scaling新论文,R2要来了?
人工智能
算AI19 小时前
人工智能+牙科:临床应用中的几个问题
人工智能·算法
凯子坚持 c20 小时前
基于飞桨框架3.0本地DeepSeek-R1蒸馏版部署实战
人工智能·paddlepaddle
你觉得20520 小时前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义下载方法
大数据·人工智能·python·gpt·学习·机器学习·aigc
8K超高清20 小时前
中国8K摄像机:科技赋能文化传承新图景
大数据·人工智能·科技·物联网·智能硬件
hyshhhh21 小时前
【算法岗面试题】深度学习中如何防止过拟合?
网络·人工智能·深度学习·神经网络·算法·计算机视觉