最近在做一个文本生成项目,想用PyTorch对预训练模型做Prompt tuning。看了几篇论文,有的说只训练prompt embedding,有的说要把MLP层也解冻,还有人说LoRA更稳。我试了只调prompt embedding,loss下降很慢,生成结果跟瞎猜差不多。是不是我初始化方式不对?还是说BERT类模型和GPT类模型的prompt tuning策略本来就不一样?有没有大佬分享一下实际调参经验,比如学习率、epoch数,或者什么情况下该解冻更多层?求指点,卡这儿好几天了。
用PyTorch写Prompt调优,到底该冻结哪些层?
全部回复
共 89 条我之前也踩过这个坑,只训prompt embedding的话学习率得拉到1e-2甚至更高,不然loss几乎不动,跟瞎猜差不多很正常。BERT那种双向的和GPT单向的确实不太一样,GPT系一般prompt tuning效果更依赖初始化,你可以试试用任务相关的词向量去初始化,别用随机。如果数据量不大的话LoRA确实更稳,我一般lr设1e-3到5e-4,epoch 3到5就够了,实在不行就解冻最后两层MLP一起调。
只训prompt embedding确实容易这样,尤其GPT类模型,软prompt初始化没弄好基本等于随机噪声,loss降得慢太正常了。我自己的经验是学习率得比全量微调大一个量级,1e-2到5e-2都试过,epoch一般10到20就够,再多容易过拟合。BERT和GPT差别挺大的,BERT双向注意力对prompt更敏感,GPT单向的话prefix tuning效果通常比prompt embedding稳。实在不行加个LoRA试试,rank设8或16,跟prompt一起训,收敛快很多。
只调prompt embedding确实容易这样,尤其GPT类模型,soft prompt初始化不好基本等于随机噪声,建议试试用真实文本的embedding做初始化,或者直接上prefix tuning那种带MLP重参数化的。学习率别按全量微调的来,1e-3到5e-4都算常见,epoch一般10-30就够,但要看任务。BERT类做prompt tuning通常比GPT稳,因为双向注意力对prompt位置没那么敏感。如果还卡着,LoRA确实省心,r=8、alpha=16先跑起来对比一下,别死磕纯prompt。
只调prompt embedding确实很容易卡住,尤其GPT类模型,prompt token少、梯度信号弱,loss降得慢太正常了。BERT那套prefix tuning思路搬到GPT上不一定灵,建议先检查初始化,用真实token的embedding去初始化prompt效果会好很多。学习率可以试试比全量微调大一个量级,比如1e-3到5e-3,epoch别太多,3到5轮先看趋势。要是还不行,直接上LoRA,稳得多,实在想解冻MLP也只解最后几层试试。
只调prompt embedding的话loss掉得慢太正常了,尤其是你如果只初始化成随机向量或者拿词表里随便几个token的embedding,模型基本等于在噪声里找路。我一般至少会用任务相关的几个关键词做soft prompt初始化,或者直接拿prompt tuning那篇的LM head反推初始化,效果差挺多的。BERT和GPT确实不太一样,BERT是双向的,prompt位置和attention mask的处理更微妙,GPT自回归的话prefix位置对生成影响更直接,但核心还是看预训练任务和你的下游任务差多远。LoRA稳是因为它动了attention里的投影矩阵,等于给了模型更多可调容量,而纯prompt tuning相当于只动输入空间,容量小,任务一复杂就容易欠拟合。我自己的经验是学习率别设太高,prompt embedding用1e-3到5e-4,如果解冻MLP或者加LoRA就降到1e-4到5e-5,epoch一般5到15看数据量。你要是loss降不下去,可以先试试把prompt长度加到20以上,或者干脆同时上LoRA加prompt,别死磕只调embedding。
只调prompt embedding确实容易这样,尤其BERT类模型本身没做过生成式预训练,你拿它做文本生成效果差很正常。GPT类的话prompt tuning会好一些,但学习率得给大点,我一般用1e-3到5e-4,epoch反而不用太多,10以内基本能看出趋势。如果loss降得太慢,可以试试把最后两层的LayerNorm和MLP解冻,比全冻着稳很多。LoRA确实更省心,但要看你的显存和任务复杂度,小任务prompt tuning够用。
prompt embedding初始化很关键,试试用类别词向量初始化,别随机。学习率我一般设1e-3,比全量微调大不少。
只训prompt embedding确实容易卡,尤其GPT类模型,它没有BERT那种双向attention来帮你快速适配,prompt初始化影响特别大。我之前也踩过坑,后来改成随机初始化+稍微大一点的学习率(1e-3左右)才慢慢有起色。如果效果还是不行,可以试试把最后几层的LayerNorm或者MLP解冻,或者直接上LoRA,稳很多。
GPT类光调prompt确实容易崩,我一般会解冻最后两层加个低学习率,稳很多。