github编辑

4.llm_note

参考https://github.com/changyeyu/LLM-RL-Visualizedarrow-up-right,对应的书《大模型算法:强化学习、微调与对齐》)

概述

llm训练时的teacher forcing机制:生成第i个token的输入:

  • 推理时:是模型生成的第0到第i-1的序列

  • 训练时:训练数据中实际的token序列

例如输入的是12345,输入1的时候生成了8,那要预测3的时候,输入的就是18;而训练时输入的还是12

SFT

lora

  • lora的核心思想:微调前后模型的参数差异具有低秩性,所以可以用A和B两个矩阵来表示,这两个矩阵的秩是loraranklora_{rank}

  • A一般是随机初始化,B用0初始化或者用很小的随机数初始化,为了保证在训练初期,lora不会对原始输出造成太大扰动

  • 参数loraalphalora_{alpha}用于缩放Lora输出,即Wmerge=W+ABloraalpha/lorarankW_{merge}=W+A*B*lora_{alpha}/lora_{rank}

  • 学习率一般开始的时候比较小,后面可以再调整,不过如果lora_alpha较大,可以适当减小学习率

  • 在推理的时候,可以先进行融合,其实就是算好WmergeW_{merge},推理的时候直接用

prefix-tuning

大概是在prompt的最前面加若干个虚拟token,然后这部分有自己的参数(最开始的emb,还有后面的k和v,这里的k和v都是2个mlp,先映射到小一点的d',再映射到d),总的可训练参数量参考:

sft loss与logsoftmax

  • LM head:从hidden dim映射到vocab size

  • 计算时label是shift得到的(左移一位,因为要预测next item)

  • 正常是先过LM head,算出logit矩阵,然后每个位置对所有词表里的词算softmax得到p,再去算交叉熵(只有label那个字有log(p)),所以就是log(softmax(x))

  • prompt没有loss,只有response有loss,假设response长度为k,假设第i个位置对应的label是j,那交叉熵是1/ki=1klog(pij)-1/k\sum_{i=1}^{k} log(p_ij)

对于response里的第i个词来说,词表大小为nnxmax=max(x0,x1,...,xn)x_{max}=max(x_0,x_1,...,x_n),下式第三行就是第二行分子分母同时乘exmaxe^{-x_{max}}

LogSoftmax(xi)=log(Softmax(xi))=log(exi/j=0nexj)=log(e(xixmax )/j=0ne(xjxmax ))=(xixmax )log(j=0ne(xjxmax ))\begin{aligned} \operatorname{LogSoftmax}\left(x_i\right) & =\log \left(\operatorname{Softmax}\left(x_i\right)\right) \\ & =\log \left(\mathrm{e}^{x_i} / \sum_{j=0}^n \mathrm{e}^{x_j}\right) \\ & =\log \left(\mathrm{e}^{\left(x_i-x_{\text {max }}\right)} / \sum_{j=0}^n \mathrm{e}^{\left(x_j-x_{\text {max }}\right)}\right) \\ & =\left(x_i-x_{\text {max }}\right)-\log \left(\sum_{j=0}^n \mathrm{e}^{\left(x_j-x_{\text {max }}\right)}\right) \end{aligned}

这个简化有2个好处:

  • 减少计算量:例如除法、少量对数

  • 数值稳定:上式是log-sum-exp技巧,减掉max可以避免溢出

另外还有一个常用名词logprobs(log probabilities),即logsoftmax的结果,因为softmax是0到1,所以logprobs取值范围是负无穷到0

如何减小SFT引入的幻觉

sft阶段引入的新知识越多,幻觉发生率也越高

模型主要通过预训练来获取知识,sft主要是用来教会模型如何更有效地利用这些知识。

所以,新知识应该在预训练阶段或者基于预训练模型继续预训练(CPT),再用sft进行优化

另外,sft选哪个版本的开源模型作为基础模型也有讲究:

  • 需要加一堆新知识进行深度微调时,选base版本,因为base版本未指令微调,更有通用性

  • 任务与现有指令任务类似(通用对话、开放域问答等),且指令数据不多,选指令微调版本(-instruct或者-chat)

DPO

DPO(direct preference optimization)是监督学习,不是强化学习,loss如下

LDPO(πθ;πref)=E(x,yw,y1)D[logσ(r(x,yw)r(x,y1))]=E(x,yw,y1)D[logσ(βlogπθ(ywx)πref (ywx)优质回答的隐式奖励βlogπθ(y1x)πref (y1x)劣质回答的隐式奖励 )]\begin{aligned} & \mathcal{L}_{\mathrm{DPO}}\left(\pi_\theta ; \pi_{\mathrm{ref}}\right) \\ & =-\mathbb{E}_{\left(x, y_{\mathrm{w}}, y_1\right) \sim \mathcal{D}}\left[\log \sigma\left(r\left(x, y_{\mathrm{w}}\right)-r\left(x, y_1\right)\right)\right] \\ & =-\mathbb{E}_{\left(x, y_{\mathrm{w}}, y_1\right) \sim \mathcal{D}}[\log \sigma(\underbrace{\beta \log \frac{\pi_\theta\left(y_{\mathrm{w}} \mid x\right)}{\pi_{\text {ref }}\left(y_{\mathrm{w}} \mid x\right)}}_{\text {优质回答的隐式奖励}\uparrow }-\underbrace{\beta \log \frac{\pi_\theta\left(y_1 \mid x\right)}{\pi_{\text {ref }}\left(y_1 \mid x\right)}}_{\text {劣质回答的隐式奖励 } \downarrow})] \end{aligned}

其中,

  • rr是策略模型和参考模型的比值,即一个隐式的奖励模型,rθ(x,y)=βlogπθ(yx)πref(yx)r_{\theta}(x,y)=\beta log \frac{\pi_{\theta}(y|x)}{\pi_{ref}(y|x)}

  • 策略模型是复制的sft模型,参考模型一般也是复制sft模型,有些时候可以选一个更复杂的模型,但要注意两者的kl散度和训练数据分布不要差太多

DPO流程

  • concat:将xxywy_wyly_l分别concat,作为策略模型和参考模型的输入(实际会将三者concat一起)

  • gather:算完logit和softmax后,再把y部分的拿出来,算出隐式奖励,再算Loss

beta作用

在RLHF中,β\beta和最终奖励=r(x,y)=r(x,y)、最终奖励=rϕ(x,y)=r_{\phi}(x,y)的关系如下,

r(x,y)=rϕ(x,y)β(logπθ(yx)logπref(yx))r(x,y)=r_{\phi}(x,y)-\beta (log \pi _{\theta}(y|x)-log \pi _{ref}(y|x))
  • β\beta很小时,策略模型和偏好数据分布更接近,

  • β\beta很大时,策略模型和参考模型更接近

在DPO中,

  • β\beta很小时,KL惩罚力度很小,策略模型有更多自由度去探索,策略模型和偏好数据分布更接近

  • β\beta很大时,KL惩罚力度很大,策略模型始终要兼顾和参考模型的距离,策略模型和参考模型更接近

DPO的效果

对无害性有很大提升,对基础能力基本无影响(MMLU等)

DPO的梯度

θLDPO(πθ;πref)=βE(x,yw,yl)D[σ(rθ(x,yl)rθ(x,yw))动态系数 [θlogπθ(ywx)优质回答的概率 θlogπθ(ylx)劣质回答的概率 ]]\nabla_\theta \mathcal{L}_{\mathrm{DPO}}\left(\pi_\theta ; \pi_{\mathrm{ref}}\right)=-\beta \mathbb{E}_{\left(x, y_{\mathrm{w}}, y_l\right) \sim \mathcal{D}}[\underbrace{\sigma\left(r_\theta\left(x, y_l\right)-r_\theta\left(x, y_{\mathrm{w}}\right)\right)}_{\text {动态系数 }}[\underbrace{\nabla_\theta \log \pi_\theta\left(y_{\mathrm{w}} \mid x\right)}_{\text {优质回答的概率 } \uparrow}-\underbrace{\nabla_\theta \log \pi_\theta\left(y_l \mid x\right)}_{\text {劣质回答的概率 } \downarrow}]]
  • 增加优势回答出现的概率,降低劣势回答出现的概率

  • 动态系数:优势答案和劣势答案的隐式奖励差异(注意rθ(x,y)=βlogπθ(yx)πref(yx)r_{\theta}(x,y)=\beta log \frac{\pi_{\theta}(y|x)}{\pi_{ref}(y|x)}),如下图:

    • rθ(x,yl)<rθ(x,yw))r_{\theta}(x,y_l)<r_{\theta}(x,y_w))时:隐式奖励模型能正确地给优质回答较高评分,图中左侧,说明已经学得比较好了,梯度比较小

    • rθ(x,yl)>rθ(x,yw))r_{\theta}(x,y_l)>r_{\theta}(x,y_w))时:隐式奖励模型不太行,图中右侧,要加强梯度

解释:

Training-free的方法

提示词工程

prompt设计原则:

  • 递进式尝试:先试zero-shot,效果不行再试few-shot,还是不行再尝试sft

  • 灵活运用系统消息:引导模型的行为、风格、角色等

  • 明确指令并用分隔符:在开头用冒号、三重引号、xml标签、换行等进行分隔

  • 明确期望的输出格式并提供输出示例:详细描述具体输出格式要求

  • 避免模糊描述:避免“较长”“较短”,要用具体数字,如5个要点、3段话

  • 同时提供禁止和替代指令:告诉模型不要做什么,还有对应的替代方案

  • 提供必要的上下文和角色信息:明确模型需要扮演的角色

  • 分解复杂任务:复杂任务可以分进行意图分类或者逐步拆解任务

  • 引导模型先思考后回答:明确指示模型在回答前先进行详细推理

  • 使用参考文本并基于参考作答:提供可信的参考文本,要求模型基于此作答,可以进一步要求模型标明引用来源或参考文献

  • 动态总结上下文:对话长度超出模型上下文窗口限制时,可以定期总结或筛选最相关信息

CoT

如何自动选择few-shot示例?langchain等框架中实现了example selector

  • 基于相似性

  • 基于n-gram重叠分数

  • 基于MMR(最大边际相关性):在保证相关性的基础上引入多样性

多模态CoT:

解码策略

以transformers.generate参数为例

  • beam search:每次保留累积概率的topk,最终有k个路径,再选出最高的那个

  • diverse beam search:Diverse Beam Search: Decoding Diverse Solutions from Neural Sequence Modelsarrow-up-right,分成多个组(num_beam_groups),每个组内beam search,组间通过多样性惩罚降低生成结果的相似性

  • 受限beam search:Guided Open Vocabulary Image Captioning with Constrained Beam Searcharrow-up-right,constraints参数指定限制条件,force_words_ids强制结果包含特定词/词组

  • temperature:控制不同词的概率差距。当调小时,x/T变大,然后经过exp会指数放大,这样高logit的会变得更巨大,词的差距会被拉大,所以模型的输出会更稳定,输出结果更确定;反之不同词的差距更小,输出更多样

  • 多项式采样:multinomial sampling,不是直接选概率最大的,而是按概率大小随机采样

    • top-k:只在概率前k的词中进行采样

    • top-p:累加概率大于p后截断,只对这些token采样,控制长尾词的概率阈值。top cummulative probability,是一个门槛,即从第一名往下数,累加后的概率大于p时,把后面的词扔掉,剩下的词再softmax,并去采样。调低会去掉长尾,输出稳定;调高会放低门槛,输出多样

==> temperature和top-p虽然原理不同,但均是越大越多样,适用创作等场景;越小越稳定,适用于代码、数学

其他解码策略:

  • contrastive search:对比搜索,A Contrastive Framework for Neural Text Generationarrow-up-right,在每个解码步骤中,从模型预测的最可能候选集中选择输出,以增强生成文本与人类编写前缀之间的语义连贯性,保持生成文本的词元相似度矩阵稀疏性,避免输出退化问题。

  • speculative decoding:投机解码,引入一个较小模型,能一次性预生成多个候选token,主模型也并行验证这些候选token。deepseek v3就整合了投机采样和多token预测(MTP),实现了每次预测2个token

  • lookahead decoding:前瞻解码,Break the Sequential Dependency of LLM Inference Using LOOKAHEAD DECODINGarrow-up-right,并行生成和验证多个n-gram,基于Jacobi迭代方法,打破自回归解码的顺序依赖,无需辅助模型或额外的数据存储,加速推理。

  • decoding by contrasting layers(DoLa):对比解码的一种,DoLa: Decoding by Contrasting Layers Improves Factuality in Large Language Modelsarrow-up-right,对比模型中较早层与最终层的logits的差异,DoLa能放大transformer层中特定部分局部化的事实知识,从而增强生成文本的真实性,旨在提高输出的事实准确性并减少幻觉现象。

控制生成细节的参数

  • max_length:包括prompt的总长度

  • max_new_tokens:不包括prompt的总长度

  • repetition_penalty:大于1增加重复惩罚,减少重复token生成

  • length_penalty:beam类方法的长度惩罚,大于0时鼓励生成较长序列,反之鼓励较短序列

  • force_word_ids/bad_words_ids:必须生成的token id列表/不能生成的token id列表

  • output_logits/output_scores:输出logits/scores

RAG

主要的点在于如何对文档进行分片(chunk),然后就是正常的向量召回流程了。例如Anthoripic的Contextual RAGarrow-up-right会给每个chunk加一个上下文,把这段context放到chunk前面,然后再去做embedding。类似如下prompt:

工具调用

详见:https://www.daiwk.net/5.llm_agentic#gong-ju-diao-yongarrow-up-right

强化学习核心知识

一些概念

  • 回合(episode):一次完整智能体和环境交互,从初始状态直到终止状态

  • 马尔可夫链(MC):下一状态只和当前状态有关,和之前时刻的状态无关

  • 马尔可夫决策过程(MDP):马尔可夫链的基础上引入动作和奖励,4元组(S,A,P,R)(S,A,P,R)

  • 部分可观测马尔可夫决策过程(POMDP):智能体无法观测到环境的完整状态,只能看到一部分,7元组(S,A,T,R,Ω,O,γ)(S,A,T,R,\Omega,O,\gamma)Ω\Omega是观测集,智能体能观测到的所有可能结果,γ\gamma是折扣因子,TT是转移概率,当前状态和动作下,转移到下一状态的概率

常见探索利用方法

  • ϵ\epsilon -greedy:以ϵ\epsilon的概率随机选一个动作,1ϵ1-\epsilon的概率选择Q最大的动作;训练初期可以用大的ϵ\epsilon鼓励探索,后期减小来鼓励利用

  • 上置信界(Upper Confidence Bound, UCB):计算每个动作的置信度上界值,将预期回报和不确定性结合,选最高上界的动作

  • 汤普森采样:从每个动作的后验概率分布中采样来选择动作

  • 熵正则化:优化目标中加入熵正则项,下次加油策略多样性和探索性,PPO算法中提到的

  • 乐观初始化:将价值函数的初始估计设置为较高值来促进探索,由于初始值被高估,算法会优先尝试未被充分探索的动作

  • 玻尔兹曼探索(Boltzmann Exploration):引入温度系数,将动作的估计价值转化为概率分布,以概率的方式选择动作。温度较高时,各动作的概率差异较小,更倾向于探索

  • 噪声注入:OpenAI的Parameter Space Noise for Explorationarrow-up-right,在参数空间注入噪声,在奖励信号稀疏的任务中效果很好

同/异策略、在/离线强化学习:

  • 行为策略(behavior policy):智能体与环境交互时,实际执行交互行为的策略,负责收集用于训练的数据。

  • 目标策略(target policy):最终希望得到的策略,用来最大化长期回报。

  • 同策略:行为和目标策略是同一个策略,例如policy gradient和SARSA,因为通常依赖最新生成的经验来训练并更新策略,所以一般不能用replay buffer

  • 异策略:两个策略是不同版本或者不同类型,Q-learning/DQN都是,行为策略是ϵ\epsilon -greedy,目标策略是最终要学习的,需要借助replay buffer

  • replay buffer:一般存(st,at,rt,st+1)(s_t,a_t,r_t,s_{t+1})四元组(非Sutton教材写法)

  • 在线强化学习:训练时策略持续和环境交互并收集经验,动态生成训练数据,目标策略也不断进化

  • 离线强化学习:又叫batch RL,或者fully off-policy RL,训练时智能体完全不和环境交互,仅依赖预先收集的数据。训练结束之后再将策略整体部署到线上环境中

model-based/model-free:

  • model-based:利用环境模型进行规划和决策,例如Dyna-Q、MCTS(用于AlphaGo等)

  • model-free:直接与环境交互,学习策略或者价值函数,例如基于价值(Q-learning、DQN、SARSA)、基于策略(REINFORCE、PG、GRPO)、Actor-Critic(DDPG、PPO、A3C)

奖励、回报、价值函数

  • 奖励r(reward):t时刻执行动作后,环境给的的实时奖励,在Sutton的教材里记为Rt+1R_{t+1}或者rt+1r_{t+1}(以下以这个为准),一般大写是随机变量,小写是观测到的具体值,另外,在别的地方也会记成rtr_t

  • 奖励塑形(reward shaping):设计复杂的奖励函数以表示具体任务目标,例如短视频推荐就可以设计一个多目标融合公式

  • 回报G(gain):到未来的累计奖励,可以加折扣,Gt=Rt+1+γGt+1G_t=R_{t+1}+\gamma G_{t+1}

  • 价值函数:

    • Qπ(s,a)Q_{\pi}(s,a):动作价值函数,在状态s下,采取动作a,获得的期望回报

    • Vπ(s)V_{\pi}(s):状态价值函数,在状态s下,采取所有可能动作获得的期望回报

贝尔曼方程

用动态规划解决优化和决策问题。对于给定策略π\pi

  • 状态价值函数的贝尔曼方程为Vπ(s)=aπ(as)s,rp(s,rs,a)[r+γVπ(s)]V_\pi(s)=\sum_a \pi(a \mid s) \sum_{s^{\prime}, r} p\left(s^{\prime}, r \mid s, a\right)\left[r+\gamma V_\pi\left(s^{\prime}\right)\right]

  • 动作价值函数的贝尔曼方程为Qπ(s,a)=s,rp(s,rs,a)[r+γaπ(as)Qπ(s,a)]Q_\pi(s, a)=\sum_{s^{\prime}, r} p\left(s^{\prime}, r \mid s, a\right)\left[r+\gamma \sum_{a^{\prime}} \pi\left(a^{\prime} \mid s^{\prime}\right) Q_\pi\left(s^{\prime}, a^{\prime}\right)\right]

  • 最优状态价值函数的贝尔曼方程为V(s)=maxas,rp(s,rs,a)[r+γV(s)]V_*(s)=\max _a \sum_{s^{\prime}, r} p\left(s^{\prime}, r \mid s, a\right)\left[r+\gamma V_*\left(s^{\prime}\right)\right]

  • 最优动作价值函数的贝尔曼方程为Q(s,a)=s,rp(s,rs,a)[r+γmaxaQ(s,a)]Q_*(s, a)=\sum_{s^{\prime}, r} p\left(s^{\prime}, r \mid s, a\right)\left[r+\gamma \max _{a^{\prime}} Q_*\left(s^{\prime}, a^{\prime}\right)\right]

蒙特卡洛方法(MC)

多次试验,获得多个实际运行轨迹(需要运行到回合结束),根据它们来估计价值函数或者优化策略。实际应用时,可以在每运行完一个回合后立即更新状态价值,如下,α\alpha是学习率,GtG_t是某个回合实验的回报

V(st)V(st)+α(GtV(st))V\left(s_t\right) \leftarrow V\left(s_t\right)+\alpha\left(G_t-V\left(s_t\right)\right)

时序差分方法(TD)

TD(Temporal Difference,TD),基于当前的价值估计进行自举(bootstrapping)学习,通过自身的估计值(如V(st+1)V(s_{t+1}))来更新当前的估计值(如V(st)V(s_{t}))。与MC的差别在于,TD不需要等整个回合结束,而是每前进一小就更新一次

TD目标和TD误差

V(st)V(st)+α[rt+1+γV(st+1)TD 目标 V(st)TD误差 ]V\left(s_t\right) \leftarrow V\left(s_t\right)+\alpha[\underbrace{\underbrace{r_{t+1}+\gamma V\left(s_{t+1}\right)}_{\text {TD 目标 }}-V\left(s_t\right)}_{\text {TD误差 }}]

TD误差:δt=VTD目标 V(st)=rt+1+γV(st+1)V(st)\delta_t=V_{\text {TD目标 }}-V\left(s_t\right)=r_{t+1}+\gamma V\left(s_{t+1}\right)-V\left(s_t\right)

  • 单步TD:也叫TD(0),智能体和环境每个时间步交互一次,仅依赖未来一步的奖励和下一个状态的价值估计V(st+1)V(s_{t+1})

  • 多步TD:智能体与环境交互n次,也可以在每个时间步更新,但依赖的是未来n步奖励和状态的价值估计V(st+n)V(s_{t+n}),如下:

V(st)V(st)+α[Gt(n)V(st)]=V(st)+α[(rt+1+γrt+2+γ2rt+3++γn1rt+n+γnV(st+n))n 步的折扣回报+第 (t+n) 步的价值 V(st+n)V(st)\begin{aligned} V\left(s_t\right) & \leftarrow V\left(s_t\right)+\alpha\left[G_t^{(n)}-V\left(s_t\right)\right] \\ & =V\left(s_t\right)+\alpha[\underbrace{\left(r_{t+1}+\gamma r_{t+2}+\gamma^2 r_{t+3}+\cdots+\gamma^{n-1} r_{t+n}+\gamma^n V\left(s_{t+n}\right)\right)}_{n \text { 步的折扣回报+第 }(t+n) \text { 步的价值 } V\left(s_{t+n}\right)}-V\left(s_t\right) \end{aligned}

TD(λ)TD(\lambda)如下:

V(st)V(st)+α[GtλV(st)]V\left(s_t\right) \leftarrow V\left(s_t\right)+\alpha\left[G_t^\lambda-V\left(s_t\right)\right]

其中,GtλG_t^\lambda是在时间步ttλ\lambda回报,即综合考虑多个步数的回报,以λ\lambda为权重的加权和,计算公式如下:

Gtλ=(1λ)n=1Tt1λn1Gt:t+n侧重于 TD+λTt1Gt侧重于 MCG_t^\lambda=\underbrace{(1-\lambda)_{n=1}^{T-t-1} \lambda^{n-1} G_{t: t+n}}_{\text {侧重于 } \mathrm{TD}}+\underbrace{\lambda^{T-t-1} G_t}_{\text {侧重于 } \mathrm{MC}}

REINFORCE recall

p.s.回头看一下REINFORCE recall:Off-policy Learning in Two-stage Recommender Systemsarrow-up-right

  1. 当reward是one-step的时候,等价于监督学习下的policy gradient;

  2. 当reward是multi-step的时候(例如从列表页点击视频,进入落地页后的时长叠加),等价于TD(1)的强化学习

最后更新于