韩国网站建设,彩票网站搭建 做网站,室内设计公司平面图,wordpress多用户主题背景 最近需要做一个微调的培训#xff0c;所以不可避免地需要上手一下相关的微调#xff0c;而受限于机器资源#xff0c;暂时没法做全参数微调#xff0c;所以就尝试了目前比较火的两种高效微调方式#xff0c;分别是PTuning和LoRA。模型选择得自然是现在中文做的比较好…背景 最近需要做一个微调的培训所以不可避免地需要上手一下相关的微调而受限于机器资源暂时没法做全参数微调所以就尝试了目前比较火的两种高效微调方式分别是PTuning和LoRA。模型选择得自然是现在中文做的比较好的ChatGLM2-6B。
微调的代码分别用的是
PTuning LoRA 在分别尝试了两个结果后发现LoRA微调出来的结果有点抽风喜欢疯狂输出而它就是咱们今天的主角ChatGLM2-6B的Tokenizer所使用的EOSend-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的知识的最近没有时间好好研究之后有时间再来补充一下。