RLHF的替代算法之DPO原理解析:从Zephyr的DPO到Claude的RAILF

前言

本文的成就是一个点顺着一个点而来的,成文过程颇有意思

  1. 首先,如上文所说,我司正在做三大LLM项目,其中一个是论文审稿GPT第二版,在模型选型的时候,关注到了Mistral 7B(其背后的公司Mistral AI号称欧洲的OpenAI,当然 你权且一听,切勿过于当真)
  2. 而由Mistral 7B顺带关注到了基于其微调的Zephyr 7B,而一了解Zephyr 7B的论文,发现它还挺有意思的,即它和ChatGPT三阶段训练方式的不同在于:
    在第二阶段训练奖励模型的时候,不是由人工去排序模型给出的多个答案,而是由AI比如GPT4去根据不同答案的好坏去排序
    且在第三阶段的时候,用到了一个DPO的算法去迭代策略,而非ChatGPT本身用的PPO算法去迭代策略
  3. 考虑到ChatGPT三阶段训练方式我已经写得足够完整了(instructGPT论文有的细节我做了重点分析、解读,论文中没有的细节我更做了大量的扩展、深入、举例,具体可以参见《ChatGPT技术原理解析:从RL之PPO算法、RLHF到GPT4、instructGPT》)
    而有些朋友反馈到DPO比PPO好用(当然了,我也理解,毕竟PPO那套算法涉及到4个模型,一方面是策略的迭代,一方面是价值的迭代,理解透彻确实不容易)
  4. 加之ChatGPT的最强竞品Claude也用到了一个RAILF的机制(和Zephyr 7B的AI奖励/DPO颇有异曲同工之妙),之前也曾想过写来着,但此前一直深究于ChatGPT背后的原理细节,现在也算有时间好好写一写了

综上,便拟定了本文的标题

第一部分 什么是DPO

今年5月份,斯坦福的一些研究者提出了RLHF的替代算法:直接偏好优化(Direct Preference Optimization,简称DPO),其对应论文为《Direct Preference Optimization: Your Language Model is Secretly a Reward Model》

1.1 DPO与RLHF的本质区别

那其与ChatGPT所用的RLHF有何本质区别呢,简言之

  1. 在做了SFT之后,RLHF将奖励模型拟合到人类偏好数据集上,然后使用RL方法比如PPO算法优化语言模型的策略
    即经典的ChatGPT三阶段训练方式:1) supervised fine-tuning (SFT); 2) preferencesampling and reward learning and 3) reinforcement-learning optimization

    虽然RLHF产生的模型具有令人印象深刻的会话和编码能力,但RLHF比监督学习复杂得多,其涉及训练多个LM和在训练循环中从LM策略中采样(4个模型,涉及到经验数据的采集,以及策略的迭代和价值的迭代,如果不太熟或忘了,请参见《ChatGPT技术原理解析》),从而产生大量的计算成本
    While RLHF produces models with impressive conversational and coding abilities, the RLHFpipeline is considerably more complex than supervised learning, involving training multiple LMs andsampling from the LM policy in the loop of training, incurring significant computational costs.
  2. 相比之下,DPO通过简单的分类目标直接优化最满足偏好的策略,而没有明确的奖励函数或RL
    DPO directly optimizes for the policy best satisfying the preferences with a simple classification objective, without an explicit reward function or RL

更具体而言,DPO的本质在于增加了被首选的response相对不被首选的response的对数概率(increases the relative log probability of preferred to dispreferred responses),但它包含了一个动态的、每个示例的重要性权重,以防止设计的概率比让模型的能力退化(it incorporates a dynamic, per-example importance weight that prevents the model degeneration that we find occurs with a naive probability ratio objective)

与RLHF一样,DPO依赖于理论偏好模型,衡量给定的奖励函数与经验偏好数据的一致性

  • 在SFT阶段,针对同一个prompt x生成答案对\left(y_{1}, y_{2}\right) \sim \pi^{\mathrm{SFT}}(y \mid x),然后人工标注出y_w是相对y_l是更好的答案,接着通过这些偏好数据训练一个奖励模型r^{*}(y, x)

    那怎么建模偏好损失函数呢,Bradley-Terry(BT)模型是一个常见选择(当然,在可以获得多个排序答案的情况下,Plackett-Luce 是更一般的排序模型)。BT 模型规定人类偏好分布p *可以表示成
    p^{*}\left(y_{1} \succ y_{2} \mid x\right)=\frac{\exp \left(r^{*}\left(x, y_{1}\right)\right)}{\exp \left(r^{*}\left(x, y_{1}\right)\right)+\exp \left(r^{*}\left(x, y_{2}\right)\right)}
    假定我们从上面的分布中采样出来一个数据集 
    \mathcal{D}=\left\{x^{(i)}, y_{w}^{(i)}, y_{l}^{(i)}\right\}_{i=1}^{N}
    同时,建立我们的奖励模型r_{\phi}(x, y),然后对其参数做最大似然估计,从而将问题建模为二分类问题,并使用负对数似然损失:
    \mathcal{L}_{R}\left(r_{\phi}, \mathcal{D}\right)=-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\log \sigma\left(r_{\phi}\left(x, y_{w}\right)-r_{\phi}\left(x, y_{l}\right)\right)\right]

    与RLHF类似,其中\sigma是logistic函数,r_{\phi}(x, y)通常从SFT模型\pi^{\mathrm{SFT}}(y \mid x)初始化,并在transformer结构的顶部添加一个线性层,该层对奖励值产生单个标量预测
  • 接下来,虽然ChatGPT所用的RLHF是在训练好的奖励模型的指引下迭代策略,其迭代策略的方法是PPO算法
    \max _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[r_{\phi}(x, y)\right]-\beta \mathbb{D}_{\mathrm{KL}}\left[\pi_{\theta}(y \mid x) \| \pi_{\mathrm{ref}}(y \mid x)\right]
    其中,\beta修正项是对奖励函数的修正,避免迭代中的策略\pi_{\theta}(y \mid x)与基线策略\pi_{\mathrm{ref}}(y \mid x)偏离太远
    r(x, y)=r_{\phi}(x, y)-\beta\left(\log \pi_{\theta}(y \mid x)-\log \pi_{\text {ref }}(y \mid x)\right)

    DPO利用从奖励函数到最优策略的解析映射,这使我们能够将奖励函数上的偏好损失函数转换为策略上的损失函数(our key insight is to leverage an analyticalmapping from reward functions to optimal policies, which enables us to transform a loss functionover reward functions into a loss function over policies)
    具体做法是给定人类对模型响应的偏好数据集,DPO使用简单的二元交叉熵目标优化策略,而无需在训练期间明确学习奖励函数或从策略中采样(Given a dataset of human preferences overmodel responses, DPO can therefore optimize a policy using a simple binary cross entropy objective,without explicitly learning a reward function or sampling from the policy during training)
    \pi_{r}(y \mid x)=\frac{1}{Z(x)} \pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)

    其中
    Z(x)=\sum_{y} \pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)
    实际上,我们使用使用 ground-truth 奖励函数 r^{*} 的最大似然估计值 r_{\phi},估计配分函数Z(x)依然十分困难,这使得这种表示方法在实践中难以利用,那咋办呢?

1.2 DPO的逐步推导:力求清晰易懂

1.2.1 公式3到4的推导:带KL 约束的奖励最大化目标

我们从头到尾梳理一下,且以下第几点则代表公式几

  1. p^{*}\left(y_{1} \succ y_{2} \mid x\right)=\frac{\exp \left(r^{*}\left(x, y_{1}\right)\right)}{\exp \left(r^{*}\left(x, y_{1}\right)\right)+\exp \left(r^{*}\left(x, y_{2}\right)\right)}
  2. \mathcal{L}_{R}\left(r_{\phi}, \mathcal{D}\right)=-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\log \sigma\left(r_{\phi}\left(x, y_{w}\right)-r_{\phi}\left(x, y_{l}\right)\right)\right]
  3. 公式3:\max _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[r_{\phi}(x, y)\right]-\beta \mathbb{D}_{\mathrm{KL}}\left[\pi_{\theta}(y \mid x) \| \pi_{\mathrm{ref}}(y \mid x)\right]
  4. 通过上面公式3,可以得到公式4:
    \pi_{r}(y \mid x)=\frac{1}{Z(x)} \pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)
    ____________________
    这一步很关键,是怎么推导出来的呢?
    对于公式3,一方面有
    \begin{aligned} \max _{\pi_{\theta}} & \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}[r(x, y)]-\beta \mathbb{D}_{\mathrm{KL}}\left[\pi_{\theta}(y \mid x) \| \pi_{\mathrm{ref}}(y \mid x)\right] \\ & =\max _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}[r(x, y)]-\beta \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[\log \frac{\pi_{\theta}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}\right] \\ & =\max _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[r(x, y)-\beta \log \frac{\pi_{\theta}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}\right] \\ & =\min _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[\beta \log \frac{\pi_{\theta}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}-r(x, y)\right] \\ & =\min _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[\log \frac{\pi_{\theta}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}-\frac{1}{\beta} r(x, y)\right] \\ & =\min _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[\log \frac{\pi_{\theta}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)}\right] \end{aligned}

    还是针对公式3,另一方面,假定在奖励函数r下的最优策略为\pi _r,公式3的目标自然便是要得到最优策略,因此公式3等价于最小化\pi _\theta\pi _r的KL散度,即有
    \begin{aligned} \max _{\pi_{\theta}} & \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}[r(x, y)]-\beta \mathbb{D}_{\mathrm{KL}}\left[\pi_{\theta}(y \mid x) \| \pi_{\mathrm{ref}}(y \mid x)\right] \\ & =\min _{\pi_{\theta}} \mathbb{D}_{\mathrm{KL}}\left[\pi_{\theta}(y \mid x)|| \pi_{r}(y \mid x)\right] \\ & =\min _{\pi_{\theta}} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_{\theta}(y \mid x)}\left[\log \frac{\pi_{\theta}(y \mid x)}{\pi_{r}(y \mid x)}\right] \end{aligned}

    因此,结合上面第4点区块的推导,可得
    \min _{\pi_{\theta}} \mathbb{E}_{x, y}\left[\log \frac{\pi_{\theta}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)}\right]=\min _{\pi_{\theta}} \mathbb{E}_{x, y}\left[\log \frac{\pi_{\theta}(y \mid x)}{\pi_{r}(y \mid x)}\right]
    从而有\pi_{r}(y \mid x)\pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)正相关,因此不妨设\pi_{r}(y \mid x)=\frac{1}{Z(x)} \pi_{\text {ref }}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)
    其中,Z(x)=\sum_{y} \pi_{\text {ref }}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right),其目的是使得右边满足取值在[0,1],相当于起到一个归一化的效果
  5. 为了根据其对应的最优策略\pi_{r}、基线策略\pi_{r e f}和未知的配分函数Z(\cdot),来表示奖励函数
    首先对上面式子4\pi_{r}(y \mid x)=\frac{1}{Z(x)} \pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)的两边取对数,然后通过一些代数运算得到公式5
    r(x, y)=\beta \log \frac{\pi_{r}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}+\beta \log Z(x)
    假定最优奖励函数 r^{*}下对应的最优模型策略是\pi^{*} ,则有
    r^{*}(x, y)=\beta \log \frac{\pi^{*}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}+\beta \log Z(x)
  6. 考虑到最优策略不确定,因此先用参数化的策略\pi _\theta来表示,相应的奖励函数即可表示为
    r_{\theta}(x, y)=\beta \log \frac{\pi_{\theta}(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}+\beta \log Z(x)
  7. 接下来,便可以为策略 \pi_{\theta}构建最大似然目标。类似于奖励建模方法(即公式2),即最大化偏好答案与非偏好答案奖励的差值,我们的策略目标变为:
    \begin{aligned} \mathcal{L}_{\mathrm{DPO}}(\theta) & =-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\log \sigma\left(r_{\theta}\left(x, y_{w}\right)-r_{\theta}\left(x, y_{l}\right)\right)\right] \\ & =-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\log \sigma\left(\beta \log \frac{\pi_{\theta}\left(y_{w} \mid x\right)}{\pi_{\mathrm{ref}}\left(y_{w} \mid x\right)}-\beta \log \frac{\pi_{\theta}\left(y_{l} \mid x\right)}{\pi_{\mathrm{ref}}\left(y_{l} \mid x\right)}\right)\right] \end{aligned}
    完美!

以下是论文中关于公式3到4的推导,不算特别清晰易懂,仅做参考

对于奖励函数 r(x, y)、基线模型 \pi_{r e f}和一般的无参策略类型,我们优化以下目标:\max _{\pi} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi}[r(x, y)]-\beta \mathbb{D}_{\mathrm{KL}}\left[\pi(y \mid x) \| \pi_{\text {ref }}(y \mid x)\right]

  1. 一步步推导下,可得
    \begin{array}{l} \max _{\pi} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi}[r(x, y)]-\beta \mathbb{D}_{\mathrm{KL}}\left[\pi(y \mid x) \| \pi_{\mathrm{ref}}(y \mid x)\right] \\ =\max _{\pi} \mathbb{E}_{x \sim \mathcal{D}} \mathbb{E}_{y \sim \pi(y \mid x)}\left[r(x, y)-\beta \log \frac{\pi(y \mid x)}{\pi_{\text {ref }}(y \mid x)}\right] \\ =\min _{\pi} \mathbb{E}_{x \sim \mathcal{D}} \mathbb{E}_{y \sim \pi(y \mid x)}\left[\log \frac{\pi(y \mid x)}{\pi_{\mathrm{ref}}(y \mid x)}-\frac{1}{\beta} r(x, y)\right] \\ =\min _{\pi} \mathbb{E}_{x \sim \mathcal{D}} \mathbb{E}_{y \sim \pi(y \mid x)}\left[\log \frac{\pi(y \mid x)}{\frac{1}{Z(x)} \pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y) \right)}-\log Z(x)\right] \\ \end{array}
    其中,Z(x)是一个配分函数
    Z(x)=\sum_{y} \pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)
    这个函数只与 x 和基线策略\pi_{r e f}有关,而不依赖于策略 \pi
  2. 现在我们可以定义:
    \pi^{*}(y \mid x)=\frac{1}{Z(x)} \pi_{\mathrm{ref}}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)
    这是一个有效的概率分布,因为对于所有的 y 都有\pi^{*}(y \mid x) \geq 0 且 \sum_{y} \pi^{*}(y \mid x)=1
  3. 由于 Z(x) 不是一个关于y 的函数,因此我们把目标函数重新变换下,可得:
    \begin{array}{l} \min _{\pi} \mathbb{E}_{x \sim \mathcal{D}} {\left[\mathbb{E}_{y \sim \pi(y \mid x)}\left[\log \frac{\pi(y \mid x)}{\pi^{*}(y \mid x)}\right]-\log Z(x)\right]=} \\ \min _{\pi} \mathbb{E}_{x \sim \mathcal{D}}\left[\mathbb{D}_{\mathrm{KL}}\left(\pi(y \mid x) \| \pi^{*}(y \mid x)\right)+Z(x)\right] \end{array}
    现在,由于 Z(x)与 x 无关,上式等价于最小化第一个 KL 项
    根据吉布斯(Gibbs)不等式,当且只当两个分布相等时,KL 散度有最小值 0。 因此对于任意 x 我们可以得到最优解:
    \pi(y \mid x)=\pi^{*}(y \mid x)=\frac{1}{Z(x)} \pi_{\text {ref }}(y \mid x) \exp \left(\frac{1}{\beta} r(x, y)\right)

1.2.2 求解DPO目标函数梯度的推导

为了进一步理解DPO,求解下上述公式7\mathcal{L}_{\mathrm{DPO}}\left(\pi_{\theta} ; \pi_{\mathrm{ref}}\right)=-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\log \sigma\left(\beta \log \frac{\pi_{\theta}\left(y_{w} \mid x\right)}{\pi_{\text {ref }}\left(y_{w} \mid x\right)}-\beta \log \frac{\pi_{\theta}\left(y_{l} \mid x\right)}{\pi_{\text {ref }}\left(y_{l} \mid x\right)}\right)\right]的梯度

  • u=\beta \log \frac{\pi_{\theta}\left(y_{w} \mid x\right)}{\pi_{\text {ref }}\left(y_{w} \mid x\right)}-\beta \log \frac{\pi_{\theta}\left(y_{l} \mid x\right)}{\pi_{\text {ref }}\left(y_{l} \mid x\right)},则
    \begin{aligned} \nabla_{\theta} \mathcal{L}_{\mathrm{DPO}} & =-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\nabla_{\theta} \log \sigma(u)\right] \\ & =-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\frac{1}{\sigma(u)} \nabla_{\theta} \sigma(u)\right] \\ & =-\mathbb{E}_{\left(x, y_{w}, y_{l}\right) \sim \mathcal{D}}\left[\frac{\sigma^{\prime}(u)}{\sigma(u)} \nabla_{\theta} u\right] \end{aligned}

    根据sigmoid函数的性质\sigma^{\prime}(x)=\sigma(x)(1-\sigma(x))以及\sigma(-x)=1-\sigma(x)可得

    其中,\hat{r}_{\theta}(x, y)=\beta \log \frac{\pi_{\theta}(y \mid x)}{\pi_{r e f}(y \mid x)}是由优化策略 \pi_{\theta}和基线策略 \pi_{r e f}定义的对奖励函数的修正项(在 DPO的论文中,该修正项称为隐式奖励模型)
    红色部分表示当非偏好答案y_l的奖励大于偏好答案y_w的奖励时,梯度越大,而损失函数的梯度会增加生成偏好回答 y_w的概率(对应绿色部分),降低非偏好回答 y_l 的概率(对应蓝色部分)

// 待更

第二部分 Zephyr 7B三阶段训练方式:SFT AIF DPO

// 待更

第三部分 Claude的RAILF

// 待更


参考文献与推荐阅读

  1. ChatGPT技术原理解析:从RL之PPO算法、RLHF到GPT4、instructGPT
  2. DPO——RLHF 的替代之《Direct Preference Optimization: Your Language Model is Secretly a Reward Model》论文阅读
  3. DPO: Direct Preference Optimization训练目标推导,推导简练易懂,推荐

创作、修改、完善记录

  1. 11.6日,写第一部分 什么是DPO
    且反复对比介绍DPO的各篇文章,研究如何阐述才是最清晰易懂的
  2. //..

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/118591.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【技术干货】开源库 Com.Gitusme.Net.Extensiones.Core 的使用

目录 1、项目介绍 2、为项目添加依赖 3、代码中导入命名空间 4、代码中使用 示例 1:string转换 示例 2:object转换 1、项目介绍 Com.Gitusme.Net.Extensiones.Core是一个.Net扩展库。当前最新版本1.0.4,提供了常见类型转换&#xff0c…

【Java 进阶篇】Java Session 原理及快速入门

大家好,欢迎来到本篇博客。今天,我们将探讨Java Web开发中一个重要而令人兴奋的概念,即Session(会话)。Session是一种在Web应用程序中跟踪用户状态和数据的机制。我们将深入了解Session的原理,并通过示例来…

1688店铺所有商品数据接口(1688.item_search_shop)

1688店铺所有商品数据接口是一种允许开发者在其应用程序中调用1688店铺所有商品数据的API接口。利用这一接口,开发者可以获取1688店铺的所有商品信息,包括产品ID、SKU信息、价格、库存、图片等。这些数据可以用于构建各种业务场景,例如供应链…

腾讯云CVM服务器标准型S5、SA3、S6详细介绍

腾讯云CVM服务器标准型实例的各项性能参数平衡,标准型云服务器适用于大多数常规业务,例如:web网站及中间件等,常见的标准型云服务器有CVM标准型S5、S6、SA3、SR1、S5se等规格,腾讯云服务器网txyfwq.com来详细说下云服务…

[第二章—Spring MVC的高级技术] 2.1Spring MVC配置的替代方案

7.1.1 自定义DispatcherServlet配置 例如,在本章稍后的内容中(7.2节),我们将会看到如何在Spring MVC中处理multipart请求和文件上传。 如果计划使用Servlet 3.0对multipart配置的支持,那么需要使用DispatcherServlet的…

【移远QuecPython】EC800M物联网开发板调用网络API(使用SIM卡联网并调用高德地图API的定位坐标转换)

【移远QuecPython】EC800M物联网开发板调用网络API(使用SIM卡联网并调用高德地图API的定位坐标转换) 高德API使用方法: 文章目录 API相关配置SIM卡联网网络操作API调用 高德地图API产品介绍适用场景使用限制使用说明坐标转换 附录&#xff…

【源码解析】聊聊SpringBean是如何初始化和创建

我们知道通过类进行修复不同的属性,比如单例、原型等,而具体的流程是怎么样的呢,这一篇我们开始从源码的视角分析以下。 刷新方法 在刷新容器中有一个方法,其实就是 Bean创建的过程。 finishBeanFactoryInitialization(beanFact…

图像切分:将一张长图片切分为指定长宽的多张图片

1.需求 比如有一张很长的图片其大小为宽度779,高度为122552,那我想把图片切分为779乘以1280的格式。 步骤如下: 使用图像处理库(如PIL或OpenCV)加载原始图片。确定子图片的宽度和高度。计算原始图片的宽度和高度&am…

Java —— 类和对象(一)

目录 1. 面向对象的初步认知 1.1 什么是面向对象 1.2 面向对象与面向过程 2. 类定义和使用 2.1 认识类 2.2 类的定义格式 3. 类的实例化(如何产生对象) 3.1 什么是实例化 3.2 访问对象的成员 3.3 类和对象的说明 4. this引用 4.1 为什么要有this引用 4.2 什么是this引用 4.3 th…

硕鼠——视频下载利器

相信很多做自媒体、剪辑的同志们,经常会遇到一个棘手的问题:剪辑的素材从何而来。诸如很多高燃混剪的视频,往往需要多个影视作品中的原画来进行二次创作,可是这些视频素材从何而来呢? 有小伙伴们提出,通过录…

功率放大器主要特点是什么

功率放大器是一种常见的电子设备,用于放大输入信号的电压。它在各种领域中都有广泛的应用,包括音频放大、通信系统、仪器仪表等。功率放大器具有以下主要特点: 功率放大器具有高放大增益。其主要功能是将输入信号的电压放大到所需的输出电压水…

什么是商业?什么是企业?什么又是竞争呢?

博主从商了,读了一些关于商业企业跟竞争的关系的书跟文章,突然就有点感受想分享一下,请诸位佬讨论一下,听取一下各位佬的意见,学习一下各位的宝贵经验。 百度百科是这样解释商业企业跟竞争的 商业是以买卖方式使商品流…

优雅设计之美:实现Vue应用程序的时尚布局

前言 页面布局是减少代码重复和创建可维护且具有专业外观的应用程序的基本模式。如果使用的是Nuxt,则可以提供开箱即用的优雅解决方案。然而,令人遗憾的是,在Vue中,这些问题并未得到官方文档的解决。 经过多次尝试,小…

stable-diffusion-webui安装Wav2Lip

常见错误 1.错误:Torch is not able to use GPU; add --skip-torch-cuda-test to COMMANDLINE_ARGS variable to disable this check 修改代码: launch_utils.py 删除三个地方:

简单工厂VS工厂方法

工厂方法模式–制造细节无需知 前面介绍过简单工厂模式,简单工厂模式只是最基本的创建实例相关的设计模式。在真实情况下,有更多复杂的情况需要处理。简单工厂生成实例的类,知道了太多的细节,这就导致这个类很容易出现难维护、灵…

windows环境下安装Java过程(免登录Oracle官网下载java)

下载路径 oracle官网: java下载路径 Oracle共享账号可下载JDK: 指路 安装流程 执行下载后的jdk的可执行文件一路next下去, 可以自定义安装路径添加环境变量, 两个地方需要添加 在cmd中输入java -version 进行验证,…

IOC容器创建bean实例的4种方式

🎈个人公众号:🎈 :✨✨✨ 可为编程✨ 🍟🍟 🔑个人信条:🔑 知足知不足 有为有不为 为与不为皆为可为🌵 🍉本篇简介:🍉 本篇记录IOC容器创建bean实例的4种方式,…

关于 HTML 的一切:初学者指南

HTML 代表超文本标记语言,是用于创建网页和 Web 应用程序的标准语言。 本指南将全面介绍 HTML,涵盖从基本语法和语义到更高级功能的所有内容。 我的目标是用简单的术语解释 HTML,以便即使没有编码经验的人也能学习如何使用 HTML 构建网页。…

PostCSS通过px2rem插件和lib-flexible将px单位转换为rem(root em)单位实现大屏适配

目录 文档postcss中使用postcss-plugin-px2rem安装postcss-plugin-px2rem示例默认配置 webpack中使用postcss-plugin-px2rem项目结构安装依赖文件内容 大屏适配参考文章 文档 类似的插件 postcss-plugin-px2rem https://www.npmjs.com/package/postcss-plugin-px2remhttps://g…

Go invalid memory address or nil pointer dereference错误 空指针问题

Go 指针声明后赋值,出现 panic: runtime error: invalid memory address or nil pointer dereference,这种是内存地址错误。 首先我们要了解指针,指针地址在 Go 中 * 代表取指针地址中存的值,& 代表取一个值的地址对于指针&am…