Deepseek的RL算法GRPO解读
在本文中,我们将深入探讨Deepseek采用的策略优化方法GRPO,并顺带介绍一些强化学习(Reinforcement Learning, RL)的基础知识,包括PPO等关键概念。
策略函数(policy)
在强化学习中, a t ∣ s t a_t \mid s_t at∣st 表示在状态 s t s_t st 下采取动作 a t a_t at 的条件概率。具体来说,它是由策略函数 π \pi π 决定的。
详细说明
s t s_t st
- s t s_t st 表示在时间步 t t t 时的状态(state)。
- 状态是环境对智能体的当前描述,例如在游戏中可能是角色的位置、速度等信息。
a t a_t at
- a t a_t at 表示在时间步 t t t 时智能体采取的动作(action)。
- 动作是智能体在给定状态下可以执行的操作,例如在游戏中可能是“向左移动”或“跳跃”。
π ( a t ∣ s t ) \pi(a_t \mid s_t) π(at∣st)
- π ( a t ∣ s t ) \pi(a_t \mid s_t) π(at∣st) 是策略函数(policy),表示在状态 s t s_t st 下选择动作 a t a_t at 的概率。
- 如果是确定性策略, π ( a t ∣ s t ) \pi(a_t \mid s_t) π(at∣st) 会直接输出一个确定的动作;如果是随机策略,它会输出一个动作的概率分布。
r t ( θ ) = π θ ( a t ∣ s t ) π θ old ( a t ∣ s t ) r_t(\theta) = \frac{\pi_\theta(a_t \mid s_t)}{\pi_{\theta_{\text{old}}}(a_t \mid s_t)} rt(θ)=πθold(at∣st)πθ(at∣st)
- 在 PPO 中, r t ( θ ) r_t(\theta) rt(θ) 是新策略 π θ \pi_\theta πθ 和旧策略 π θ old \pi_{\theta_{\text{old}}} πθold 在状态 s t s_t st 下选择动作 a t a_t at 的概率比。
- 这个比值用于衡量策略更新的幅度,并通过裁剪机制限制其变化范围,确保训练的稳定性。
举例说明
假设我们有一个简单的游戏环境:
-
状态 s t s_t st:角色的位置。
-
动作 a t a_t at:可以执行的动作是“向左”或“向右”。
-
策略 π ( a t ∣ s t ) \pi(a_t \mid s_t) π(at∣st):在某个位置 s t s_t st 下,策略可能以 70% 的概率选择“向左”,以 30% 的概率选择“向右”。
在 PPO 中,我们会比较新旧策略在相同状态 s t s_t st 下选择相同动作 a t a_t at 的概率,从而计算概率比 r t ( θ ) r_t(\theta) rt(θ),并用于优化目标函数。
总结
a t ∣ s t a_t \mid s_t at∣st 表示在状态 s t s_t st 下选择动作 a t a_t at 的条件概率,由策略函数 π \pi π 决定。在 PPO 中,这一概率用于计算新旧策略的比值,从而控制策略更新的幅度。
近端策略优化(PPO)
PPO(Proximal Policy Optimization) 是一种用于强化学习的策略优化算法,由 OpenAI 提出。它通过限制策略更新的幅度,确保训练过程的稳定性。
核心思想
PPO 的核心在于限制策略更新的幅度,避免因更新过大导致性能下降。它通过引入“裁剪”机制,控制新旧策略之间的差异。
公式
PPO 的替代目标函数 J P P O ( θ ) \mathcal{J}_{PPO}(\theta) JPPO(θ) 用于优化策略 π θ \pi_\theta πθ,公式如下:
J P P O ( θ ) = E [ q ∼ P ( Q ) , o ∼ π θ o l d ( O ∣ q ) ] 1 ∣ o ∣ ∑ t = 1 ∣ o ∣ min [ π θ ( o t ∣ q , o < t ) π θ o l d ( o t ∣ q , o < t ) A t , clip ( π θ ( o t ∣ q , o < t ) π θ o l d ( o t ∣ q , o < t ) , 1 − ε , 1 + ε ) A t ] \mathcal{J}_{PPO}(\theta) = \mathbb{E}_{[q \sim P(Q), o \sim \pi_{\theta_{old}}(O|q)]} \frac{1}{|o|} \sum_{t=1}^{|o|} \min \left[ \frac{\pi_\theta(o_{t} | q, o_{<t})}{\pi_{\theta_{old}}(o_{t} | q, o_{<t})} A_{t}, \text{clip} \left( \frac{\pi_\theta(o_{t} | q, o_{<t})}{\pi_{\theta_{old}}(o_{t} | q, o_{<t})}, 1 - \varepsilon, 1 + \varepsilon\right) A_{t} \right] JPPO(θ)=E[q∼P(Q),o∼πθold(O∣q)]∣o∣1t=1∑∣o∣min[πθold(ot∣q,o<t)πθ(ot∣q,o<t)At,clip(πθold(ot∣q,o<t)πθ(ot∣q,o<t),1−ε,1+ε)At]
其中:
期望符号 E \mathbb{E} E 表示对查询 q q q 和输出 o o o 的期望:
-
q ∼ P ( Q ) q \sim P(Q) q∼P(Q): 查询 q q q 从分布 P ( Q ) P(Q) P(Q) 中采样。
-
o ∼ π θ o l d ( O ∣ q ) o \sim \pi_{\theta_{old}}(O|q) o∼πθold(O∣q): 输出 o o o 由旧策略 π θ o l d \pi_{\theta_{old}} πθold 生成。
1 ∣ o ∣ ∑ t = 1 ∣ o ∣ \frac{1}{|o|} \sum_{t=1}^{|o|} ∣o∣1∑t=1∣o∣ 对输出 o o o 的每个时间步 t t t 求平均:
- ∣ o ∣ |o| ∣o∣ 是输出序列的长度。
其核心目标函数为:
L C L I P ( θ ) = E t [ min ( r t ( θ ) A ^ t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) A ^ t ) ] L^{CLIP}(\theta) = \mathbb{E}_t \left[ \min \left( r_t(\theta) \hat{A}_t, \text{clip}(r_t(\theta), 1 - \epsilon, 1 + \epsilon) \hat{A}_t \right) \right] LCLIP(θ)=Et[min(rt(θ)A^t,clip(rt(θ),1−ϵ,1+ϵ)A^t)]
其中:
-
r t ( θ ) = π θ ( a t ∣ s t ) π θ old ( a t ∣ s t ) r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{\text{old}}}(a_t|s_t)} rt(θ)=πθold(at∣st)πθ(at∣st) 是新旧策略的概率比。
-
A ^ t \hat{A}_t A^t 是优势函数,衡量动作的相对好坏。
-
ϵ \epsilon ϵ 是裁剪参数,通常为 0.1 或 0.2。
步骤
- 采样:使用当前策略与环境交互,收集数据,在语言模型中,可以类比为生成补全(generating completions)。
- 计算优势值:基于收集的数据计算优势值函数 A ^ t \hat{A}_t A^t。
- 优化目标函数:通过梯度上升优化目标函数 L C L I P ( θ ) L^{CLIP}(\theta) LCLIP(θ)。
- 更新策略:重复上述步骤,直到策略收敛。
优点
- 稳定性:通过裁剪机制,避免策略更新过大。
- 高效性:相比 TRPO,PPO 实现更简单,计算效率更高。
补充
在强化学习中,策略的目标是最大化期望回报,而不是最小化损失。所以,在PPO中使用的是梯度上升,原因在于它的优化目标是最大化目标函数(如强化学习中的期望回报),而不是最小化损失函数(如分类或回归问题)。
Advantage(优势函数)
定义
Advantage函数用于衡量在某个状态(State)下,采取某个动作(Action)相对于平均表现的优劣程度。它的数学定义为:
A ( s , a ) = Q ( s , a ) − V ( s ) A(s, a) = Q(s, a) - V(s) A(s,a)=Q(s,a)−V(s), 其中:
-
Q ( s , a ) Q(s, a) Q(s,a) 是动作值函数,表示在状态 s s s 下采取动作 a a a 后,未来累积回报的期望。
-
V ( s ) V(s) V(s) 是状态值函数,表示在状态 s s s 下,按照当前策略采取动作后,未来累积回报的期望。
-
A ( s , a ) A(s, a) A(s,a) 是优势函数,表示在状态 s s s 下采取动作 a a a 比平均表现好多少(或差多少)。
作用
-
Advantage函数用于指导策略更新:
- 如果 A ( s , a ) > 0 A(s, a) > 0 A(s,a)>0,说明动作 a a a 比平均表现更好,策略应该更倾向于选择这个动作;
- 如果 A ( s , a ) < 0 A(s, a) < 0 A(s,a)<0,说明动作 a a a 比平均表现更差,策略应该减少选择这个动作的概率。
-
在PPO等算法中,Advantage函数通常通过**GAE(Generalized Advantage Estimation)**来估计。
直观理解
Advantage函数就像一个“评分”,告诉模型某个动作在当前状态下是好还是坏,以及好(或坏)的程度。
KL Penalty(KL散度惩罚)
定义
KL Penalty是基于**KL散度(Kullback-Leibler Divergence)**的一种正则化手段。KL散度用于衡量两个概率分布之间的差异。在强化学习中,KL Penalty通常用于限制当前策略 π θ \pi_{\theta} πθ 和参考策略 π ref \pi_{\text{ref}} πref 之间的差异。其数学定义为:
KL Penalty = D KL ( π ref ∥ π θ ) \text{KL Penalty} = D_{\text{KL}}(\pi_{\text{ref}} \| \pi_{\theta}) KL Penalty=DKL(πref∥πθ)
其中:
-
π θ \pi_{\theta} πθ 是当前策略(由模型参数 θ \theta θ 决定)。
-
π ref \pi_{\text{ref}} πref 是参考策略(通常是更新前的策略或某个基线策略)。
-
D KL D_{\text{KL}} DKL 是KL散度,用于衡量两个策略之间的差异。
作用
- KL Penalty用于防止策略更新过大,确保当前策略不会偏离参考策略太远。这样可以避免训练过程中的不稳定现象(如策略崩溃)。
- 在PPO等算法中,KL Penalty通常被添加到目标函数中,作为正则化项。
直观理解
KL Penalty就像一个“约束”,告诉模型在更新策略时不要“步子迈得太大”,以免失去稳定性。
Advantage和KL Penalty的关系
-
Advantage 用于指导策略更新,告诉模型哪些动作更好。
-
KL Penalty 用于约束策略更新,防止策略变化过大。
-
在PPO等算法中,Advantage和KL Penalty共同作用,既鼓励模型选择更好的动作,又确保更新过程稳定可靠。
举例说明
假设我们训练一个机器人走迷宫:
-
Advantage:机器人发现“向右转”比“向左转”更容易找到出口,于是Advantage函数会给“向右转”一个正的值,鼓励策略更倾向于选择“向右转”。
-
KL Penalty:为了防止策略突然变得只选择“向右转”而忽略其他可能性,KL Penalty会限制策略的变化幅度,确保策略更新是平滑的。
总结
-
Advantage(优势函数):衡量某个动作比平均表现好多少,用于指导策略更新。
-
KL Penalty(KL散度惩罚):限制策略更新的幅度,确保训练过程的稳定性。
群体相对策略优化(GRPO)
GRPO 是一种在线学习算法(online learning algorithm),这意味着它通过使用训练过程中由训练模型自身生成的数据来迭代改进。GRPO 的目标直觉是最大化生成补全(completions)的优势函数(advantage),同时确保模型保持在参考策略(reference policy)附近。
其目标函数为:
J GRPO ( θ ) = E q ∼ P ( Q ) , { o i } i = 1 G ∼ π old ( O ∣ q ) [ 1 G ∑ i = 1 G 1 ∣ o i ∣ ∑ t = 1 ∣ o i ∣ ( r i , t ( θ ) A ^ i , t − β D KL ( π θ ∣ ∣ π ref ) ) ] J_{\text{GRPO}}(\theta) = \mathbb{E}_{q \sim P(Q), \{o_i\}_{i=1}^G \sim \pi_{\text{old}}(O|q)} \left[ \frac{1}{G} \sum_{i=1}^G \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \left( r_{i,t}(\theta) \hat{A}_{i,t} - \beta D_{\text{KL}}(\pi_\theta || \pi_{\text{ref}}) \right) \right] JGRPO(θ)=Eq∼P(Q),{oi}i=1G∼πold(O∣q) G1i=1∑G∣oi∣1t=1∑∣oi∣(ri,t(θ)A^i,t−βDKL(πθ∣∣πref))
为了理解 GRPO 的工作原理,可以将其分解为四个主要步骤:
-
生成补全(Generating completions)
-
计算优势值(Computing the advantage)
-
估计KL散度(Estimating the KL divergence)
-
计算损失(Computing the loss)
1. 生成补全(Generating completions)
在每一个训练步骤中,我们从提示(prompts)中采样一个批次(batch),并为每个提示生成一组 G G G 个补全(completions)(记为 o i o_i oi)。
2. 计算优势值(Computing the advantage)
对于每一个 G G G 序列,使用奖励模型(reward model)计算其奖励(reward)。为了与奖励模型的比较性质保持一致——通常奖励模型是基于同一问题的输出之间的比较数据集进行训练的——优势的计算反映了这些相对比较。其归一化公式如下:
A ^ i , t = r i − mean ( r ) std ( r ) \hat{A}_{i,t} = \frac{r_i - \text{mean}(\mathbf{r})}{\text{std}(\mathbf{r})} A^i,t=std(r)ri−mean(r)
这种方法赋予了该方法其名称:群体相对策略优化(Group Relative Policy Optimization, GRPO)
GRPO通过优化PPO算法,解决了计算优势值时需要同时依赖奖励模型(reward model)和价值模型(value model)的问题,成功移除了value model(价值模型),显著降低了推理时的内存占用和时间开销。**Advantage(优势值)**的核心价值在于为模型输出提供更精准的评估,不仅衡量答案的绝对质量,还通过相对比较(与其他回答的对比)来更全面地定位其优劣。
3. 估计KL散度(Estimating the KL divergence)
在实际算法实现中,直接计算KL散度可能会面临一些挑战:
- 计算复杂度高:KL散度的定义涉及对两个概率分布的对数比值的期望计算。对于复杂的策略分布,直接计算KL散度可能需要大量的计算资源;
- 数值稳定性:在实际计算中,直接计算KL散度可能会遇到数值不稳定的问题,尤其是当两个策略的概率分布非常接近时,对数比值可能会趋近于零或无穷大。近似器可以通过引入一些数值稳定性的技巧(如截断或平滑)来避免这些问题;
- 在线学习:在强化学习中,策略通常需要在每一步或每几步更新一次。如果每次更新都需要精确计算KL散度,可能会导致训练过程变得非常缓慢。近似器可以快速估计KL散度,从而支持在线学习和实时更新。
Schulman et al. (2020) 提出的近似器可以根据当前策略和参考策略的差异动态调整估计的精度,从而在保证计算效率的同时,尽可能减少估计误差,其定义如下:
D KL [ π θ ∥ π ref ] = π ref ( o i , t ∣ q , o i , < t ) π θ ( o i , t ∣ q , o i , < t ) − log π ref ( o i , t ∣ q , o i , < t ) π θ ( o i , t ∣ q , o i , < t ) − 1 \mathbb{D}_{\text{KL}}\left[\pi_\theta \|\pi_{\text{ref}}\right] = \frac{\pi_{\text{ref}}(o_{i,t} \mid q, o_{i,<t})}{\pi_\theta(o_{i,t} \mid q, o_{i,<t})} - \log \frac{\pi_{\text{ref}}(o_{i,t} \mid q, o_{i,<t})}{\pi_\theta(o_{i,t} \mid q, o_{i,<t})} - 1 DKL[πθ∥πref]=πθ(oi,t∣q,oi,<t)πref(oi,t∣q,oi,<t)−logπθ(oi,t∣q,oi,<t)πref(oi,t∣q,oi,<t)−1
这个近似器的核心思想是通过对当前策略和参考策略的概率比值的简单变换来估计KL散度。具体来说:
- 第一项: π ref ( o i , t ∣ q , o i , < t ) π θ ( o i , t ∣ q , o i , < t ) \frac{\pi_{\text{ref}}(o_{i,t} \mid q, o_{i,<t})}{\pi_\theta(o_{i,t} \mid q, o_{i,<t})} πθ(oi,t∣q,oi,<t)πref(oi,t∣q,oi,<t) 是参考策略与当前策略的概率比值。
- 第二项: log π ref ( o i , t ∣ q , o i , < t ) π θ ( o i , t ∣ q , o i , < t ) \log \frac{\pi_{\text{ref}}(o_{i,t} \mid q, o_{i,<t})}{\pi_\theta(o_{i,t} \mid q, o_{i,<t})} logπθ(oi,t∣q,oi,<t)πref(oi,t∣q,oi,<t) 是对数概率比值。
- 第三项: − 1 -1 −1 是一个常数项,用于调整近似器的偏差。
这个近似器的优势在于它只需要计算当前策略和参考策略的概率比值,而不需要直接计算KL散度的积分或期望。因此,它可以在保证一定精度的同时,显著降低计算复杂度。
近似器的直观理解
这个近似器的设计灵感来自于泰勒展开。KL散度可以看作是两个分布之间的某种“距离”,而这个近似器通过一阶或二阶近似来估计这个距离。具体来说:
- 当 π θ \pi_\theta πθ 和 π ref \pi_{\text{ref}} πref 非常接近时, π ref π θ ≈ 1 \frac{\pi_{\text{ref}}}{\pi_\theta} \approx 1 πθπref≈1,此时 log π ref π θ ≈ 0 \log \frac{\pi_{\text{ref}}}{\pi_\theta} \approx 0 logπθπref≈0,近似器的值趋近于零,符合KL散度的性质。
- 当 π θ \pi_\theta πθ 和 π ref \pi_{\text{ref}} πref 差异较大时,近似器会给出一个较大的正值,反映出两个分布之间的差异。
4. 计算损失(Computing the loss)
这一步的目标是最大化优势,同时确保模型保持在参考策略附近。因此,损失定义如下:
L GRPO ( θ ) = − 1 G ∑ i = 1 G 1 ∣ o i ∣ ∑ t = 1 ∣ o i ∣ [ π θ ( o i , t ∣ q , o i , < t ) [ π θ ( o i , t ∣ q , o i , < t ) ] no grad A ^ i , t − β D KL [ π θ ∥ π ref ] ] \mathcal{L}_{\text{GRPO}}(\theta) = -\frac{1}{G} \sum_{i=1}^G \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \left[ \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\left[\pi_\theta(o_{i,t} \mid q, o_{i,< t})\right]_{\text{no grad}}} \hat{A}_{i,t} - \beta \mathbb{D}_{\text{KL}}\left[\pi_\theta \| \pi_{\text{ref}}\right] \right] LGRPO(θ)=−G1i=1∑G∣oi∣1t=1∑∣oi∣[[πθ(oi,t∣q,oi,<t)]no gradπθ(oi,t∣q,oi,<t)A^i,t−βDKL[πθ∥πref]]
其中第一项表示缩放后的优势,第二项通过KL散度惩罚与参考策略的偏离。
在原始论文中,该公式被推广为在每次生成后通过利用**裁剪替代目标(clipped surrogate objective)**进行多次更新:
L GRPO ( θ ) = − 1 G ∑ i = 1 G 1 ∣ o i ∣ ∑ t = 1 ∣ o i ∣ [ min ( π θ ( o i , t ∣ q , o i , < t ) π θ old ( o i , t ∣ q , o i , < t ) A ^ i , t , clip ( π θ ( o i , t ∣ q , o i , < t ) π θ old ( o i , t ∣ q , o i , < t ) , 1 − ϵ , 1 + ϵ ) A ^ i , t ) − β D KL [ π θ ∥ π ref ] ] \mathcal{L}_{\text{GRPO}}(\theta) = - \frac{1}{G} \sum_{i=1}^G \frac{1}{|o_i|} \sum_{t=1}^{|o_i|} \left[ \min \left( \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,< t})} \hat{A}_{i,t}, \, \text{clip}\left( \frac{\pi_\theta(o_{i,t} \mid q, o_{i,< t})}{\pi_{\theta_{\text{old}}}(o_{i,t} \mid q, o_{i,< t})}, 1 - \epsilon, 1 + \epsilon \right) \hat{A}_{i,t} \right) - \beta \mathbb{D}_{\text{KL}}\left[\pi_\theta \| \pi_{\text{ref}}\right] \right] LGRPO(θ)=−G1i=1∑G∣oi∣1t=1∑∣oi∣[min(πθold(oi,t∣q,oi,<t)πθ(oi,t∣q,oi,<t)A^i,t,clip(πθold(oi,t∣q,oi,<t)πθ(oi,t∣q,oi,<t),1−ϵ,1+ϵ)A^i,t)−βDKL[πθ∥πref]]
其中 clip ( ⋅ , 1 − ϵ , 1 + ϵ ) \text{clip}(\cdot, 1 - \epsilon, 1 + \epsilon) clip(⋅,1−ϵ,1+ϵ) 通过将策略比率限制在 1 − ϵ 1 - \epsilon 1−ϵ 和 1 + ϵ 1 + \epsilon 1+ϵ 之间,确保更新不会过度偏离参考策略。
在很多代码实现,比如Huggingface的TRL中,与原始论文一样每次生成只进行一次更新,因此可以将损失简化为第一种形式。
总结
GRPO通过优化PPO算法,移除了价值模型,降低了计算开销,同时利用群体相对优势函数和KL散度惩罚,确保策略更新既高效又稳定。
想象一下,你是个销售员,这个月业绩10万块,PPO算法就像个精明的老会计,拿着算盘噼里啪啦一顿算,考虑市场行情、产品类型,最后得出结论:“嗯,这10万还算靠谱,但GAE一算,发现你的优势值还不够高,还得再加把劲啊”
而GRPO呢,就像老板直接搞了个“内卷大赛”,把所有销售员拉到一个群里,每天晒业绩:“你10万,他15万,她20万……”老板还时不时发个红包,刺激大家继续卷。你的10万块在群里瞬间被淹没,老板摇摇头:“你这水平,还得加把劲啊!”
GRPO这招绝了,它把PPO的“算盘”扔了,省了不少计算功夫,直接搞“内卷PK”,用KL散度惩罚来确保大家别躺平。这样一来,策略更新既快又稳,老板再也不用担心有人摸鱼了,毕竟大家都在拼命卷,谁敢松懈?
总结一下:PPO是“单打独斗看实力”,GRPO是“内卷大赛拼到死”,最后GRPO还省了算盘钱,老板笑得合不拢嘴,而我们只能默默加班,继续卷。
相关文章:
Deepseek的RL算法GRPO解读
在本文中,我们将深入探讨Deepseek采用的策略优化方法GRPO,并顺带介绍一些强化学习(Reinforcement Learning, RL)的基础知识,包括PPO等关键概念。 策略函数(policy) 在强化学习中, a…...
设计模式的艺术-策略模式
行为型模式的名称、定义、学习难度和使用频率如下表所示: 1.如何理解策略模式 在策略模式中,可以定义一些独立的类来封装不同的算法,每个类封装一种具体的算法。在这里,每个封装算法的类都可以称之为一种策略(Strategy…...
MyBatis 写法
MyBatis 高效使用技巧 常见 MyBatis 使用技巧,这些技巧有助于简化数据库操作,提高开发效率,并增强系统的性能。 1. 动态 SQL 动态 SQL 让开发者能够依据参数灵活地构建 SQL 语句,避免了手动拼接字符串带来的复杂性和错误风险。…...
Git图形化工具【lazygit】
简要介绍一下偶然发现的Git图形化工具——「lazygit」 概述 Lazygit 是一个用 Go 语言编写的 Git 命令行界面(TUI)工具,它让 Git 操作变得更加直观和高效。 Github地址:https://github.com/jesseduffield/lazygit 主要特点 主要…...
K8s运维管理平台 - xkube体验:功能较多
目录 简介Lic安装1、需要手动安装MySQL,**建库**2、启动命令3、[ERROR] GetNodeMetric Fail:the server is currently unable to handle the request (get nodes.metrics.k8s.io qfusion-1) 使用总结优点优化 补充1:layui、layuimini和beego的详细介绍1.…...
5.3.1 软件设计的基本任务
文章目录 软件设计解决的问题概要设计基本任务详细设计基本任务 软件设计解决的问题 需求分析解决“做什么”的问题,软件设计解决“如何做”的问题。软件设计分为概要设计、详细设计两块。概要设计是设计软件和数据的总体框架,比详细设计的颗粒度更大。详…...
Go学习:字符、字符串需注意的点
Go语言与C/C语言编程有很多相似之处,但是Go语言中在声明一个字符时,数据类型与其他语言声明一个字符数据时有一点不同之处。通常,字符的数据类型为 char,例如 :声明一个字符 (字符名称为 ch) 的语句格式为 char ch&am…...
LabVIEW无线齿轮监测系统
本案例介绍了基于LabVIEW的无线齿轮监测系统设计。该系统利用LabVIEW编程语言和改进的天牛须算法优化支持向量机,实现了无线齿轮故障监测。通过LabVIEW软件和相关硬件,可以实现对齿轮箱振动信号的采集、传输和故障识别,集远程采集、数据库存储…...
基于SpringBoot的租房管理系统(含论文)
基于SpringBoot的租房管理系统是一个集订单管理、房源信息管理、屋主申诉处理、用户反馈等多项功能于一体的系统。该系统通过SpringBoot框架开发,拥有完善的管理员后台、屋主管理模块、用户功能模块等,适用于房地产租赁平台或中介公司进行日常管理与运营…...
剑指 Offer II 008. 和大于等于 target 的最短子数组
comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20008.%20%E5%92%8C%E5%A4%A7%E4%BA%8E%E7%AD%89%E4%BA%8E%20target%20%E7%9A%84%E6%9C%80%E7%9F%AD%E5%AD%90%E6%95%B0%E7%BB%84/README.md 剑指 Offer II 008.…...
【微服务与分布式实践】探索 Eureka
服务注册中心 心跳检测机制:剔除失效服务自我保护机制 统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况,Eureka Server会将当前的实例注册信息保护起来,让这些实例不会过期。当节点在短时间内丢失过多的心跳时&am…...
关于opencv环境搭建问题:由于找不到opencv_worldXXX.dll,无法执行代码,重新安装程序可能会解决此问题
方法一:利用复制黏贴方法 打开opencv文件夹目录找到\opencv\build\x64\vc15\bin 复制该目录下所有文件,找到C:\Windows\System32文件夹(注意一定是C盘)黏贴至该文件夹重新打开VS。 方法二:直接配置环境 打开opencv文…...
重构字符串(767)
767. 重构字符串 - 力扣(LeetCode) 解法: class Solution { public:string reorganizeString(string s){string res;//因为1 < s.length < 500 , uint64_t 类型足够uint16_t n s.size();if (n 0) {return res;}unordere…...
【MQ】如何保证消息队列的高性能?
零拷贝 Kafka 使用到了 mmap 和 sendfile 的方式来实现零拷贝。分别对应 Java 的 MappedByteBuffer 和 FileChannel.transferTo 顺序写磁盘 Kafka 采用顺序写文件的方式来提高磁盘写入性能。顺序写文件,基本减少了磁盘寻道和旋转的次数完成一次磁盘 IO࿰…...
通义灵码插件保姆级教学-IDEA(安装及使用)
一、JetBrains IDEA 中安装指南 官方下载指南:通义灵码安装教程-阿里云 步骤 1:准备工作 操作系统:Windows 7 及以上、macOS、Linux; 下载并安装兼容的 JetBrains IDEs 2020.3 及以上版本,通义灵码与以下 IDE 兼容&…...
babylon.js-3:了解STL网格模型
网格模型上色 本篇文章主要介绍如何在 BabylonJS 中实现STL网格模型上色。 文章目录 网格模型上色运用场景概要延申正文加载器库的支持认识 OBJ 和 STL 文件GUI 色板选择器网格模型异步加载加载动画网格模型上色官方即将弃用 ImportMesh 而推荐使用 ImportMeshAsync 说明OBJ …...
面向对象设计(大三上)--往年试卷题+答案
目录 1. UML以及相关概念 1.1 动态图&静态图 1.2 交互图 1.3 序列图 1.4 类图以及关联关系 1.4.1类图 1.4.2 关系类型 (1) 用例图中的包含、扩展关系(include & extend) (2) 类图中的聚合、组合关系(aggragation & composition) 1.5 图对象以及职责划…...
Java基础知识总结(二十四)--Collections
它的出现给集合操作提供了更多的功能。这个类不需要创建对象,内部提供的都是静态方法。 静态方法: Collections.sort(list);//list集合进行元素的自然顺序排序。 Collections.sort(list,new ComparatorByLen());//按指定的比较器方法排序。 class Co…...
大语言模型的API接口如何操作
选择大语言模型 根据自身需求和应用场景选择合适的大语言模型,如 OpenAI 的 GPT 系列、百度的文心一言、智谱的 GLM 等。需要考虑模型的性能、功能特点、适用领域、成本等因素。 获取 API 密钥和凭证 注册账号:访问所选大语言模型的官方平台或相关开发…...
【漫话机器学习系列】067.希腊字母(greek letters)-写法、名称、读法和常见用途
希腊字母(Greek Letters) 希腊字母在数学、科学、工程学和编程中广泛使用,常用于表示变量、常量、参数、角度等。以下是希腊字母的完整列表及其常见用途。 大写与小写希腊字母表 大写小写名称(英文)名称(…...
Kotlin判空辅助工具
1)?.操作符 //执行逻辑 if (person ! null) {person.doSomething() } //表达式 person?.doSomething() 2)?:操作符 //执行逻辑 val c if (a ! null) {a } else {b } //表达式 val c a ?: b 3)!!表达式 var message: String? &qu…...
【Python-办公自动化】实现自动化输出json数据类型的分析报告和正逆转换
分析报告 import json from pprint import pprint, PrettyPrinterdef analyze_energy_data(file_path):"""能源数据分析与结构查看函数参数:file_path (str): JSON文件路径功能:1. 加载并解析JSON数据2. 显示数据结构概览3. 交互式结构探索"""…...
深入理解指针(2)
数组名的理解 什么是数组名?在计算机编程中,数组名是用于标识一个数组的名称。那应当如何来理解数组名呢?事实上,在数组中数组名就是数组首元素的地址。 示例1: #include<stdio.h> int main() {int arr[10] …...
SOME/IP--协议英文原文讲解3
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 Note: Thi…...
计算机网络之计算机网络主要性能
一、速率与带宽 速率: 定义:数据的传送速率,也称数据率或比特率,表示单位时间内传输的比特数。 单位:比特/秒(bit/s),常用单位有千比特/秒(kb/s)、兆比特/秒…...
家居 EDI:Haverty‘s EDI 需求分析
Havertys 成立于 1885 年,是一家历史悠久的美国家具零售商。公司致力于为客户提供高品质的家具和家居饰品,其产品线涵盖客厅、卧室、餐厅及办公家具等多个领域。 电子数据交换(EDI)是一种通过标准化电子格式在商业伙伴之间进行数据…...
JavaScript - Web APIs(上)
Web API 介绍 严格意义上讲,我们在 JavaScript 阶段学习的知识绝大部分属于 ECMAScript 的知识体系,ECMAScript 简称 ES 它提供了一套语言标准规范,如变量、数据类型、表达式、语句、函数等语法规则都是由 ECMAScript 规定的。浏览器将 ECM…...
【漫话机器学习系列】068.网格搜索(GridSearch)
网格搜索(Grid Search) 网格搜索(Grid Search)是一种用于优化机器学习模型超参数的技术。它通过系统地遍历给定的参数组合,找出使模型性能达到最优的参数配置。 网格搜索的核心思想 定义参数网格 创建一个包含超参数值…...
MySQL 的索引类型【图文并茂】
基本分类 文本生成MindMap:https://app.pollyoyo.com/planttext <style> mindmapDiagram {node {BackgroundColor yellow}:depth(0) {BackGroundColor SkyBlue}:depth(1) {BackGroundColor lightGreen} } </style> * MySQL 索引** 数据结构角度 *** B树索引*** 哈…...
OSCP:发送钓鱼电子邮件执行客户端攻击
概述 在渗透测试领域,钓鱼攻击是一种有效的客户端攻击手段,尤其在目标用户缺乏安全意识或系统存在未修复漏洞时,成功率较高。针对Windows平台,滥用Windows库文件(.Library-ms)是一种技术性较强但易于实施的…...
Oracle 普通用户连接hang住处理方法
一、现象说明 $ sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Wed Dec 18 16:49:19 2024 Version 19.11.0.0.0Copyright (c) 1982, 2020, Oracle. All rights reserved.Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Pro…...
C++ ——— 学习并使用 priority_queue 类
目录 何为 priority_queue 类 学习并使用 priority_queue 类 实例化一个 priority_queue 类对象 插入数据 遍历堆(默认是大堆) 通过改变实例化的模板参数修改为小堆 何为 priority_queue 类 priority_queue 类为 优先级队列,其本质就是…...
JVM--类加载器
概念 类加载器:只参与加载过程中的字节码获取并加载到内存中的部分;java虚拟机提供给应用程序去实现获取类和接口字节码数据的一种技术,也就是说java虚拟机是允许程序员写代码去获取字节码信息 类加载是加载的第一步,主要有以下三…...
【C++】类与对象初级应用篇:打造自定义日期类与日期计算器(2w5k字长文附源码)
文章目录 一、日期类的实现1. 日期类的默认成员函数的分析与实现构造函数其它默认成员函数 2. 各种逻辑比较运算符重载3. 日期加与减天数日期加天数系列日期减天数系列日期加减天数的最后修定和- -系列 4. 日期减日期方法一方法二 5. 流插入与流提取重载流插入重载流提取重载(含…...
ROS应用之SwarmSim在ROS 中的协同路径规划
SwarmSim 在 ROS 中的协同路径规划 前言 在多机器人系统(Multi-Robot Systems, MRS)中,SwarmSim 是一个常用的模拟工具,可以对多机器人进行仿真以实现复杂任务的协同。除了任务分配逻辑以外,SwarmSim 在协同路径规划方…...
Shell特殊位置变量以及常用内置变量总结
目录 1. 特殊的状态变量 1.1 $?(上一个命令的退出状态) 1.2 $$(当前进程的 PID) 1.3 $!(后台进程的 PID) 1.4 $_(上一条命令的最后一个参数) 2.常用shell内置变量 2.1 echo&…...
【ollama通过命令行启动后如何在网页端查看运行】
ollama通过命令行启动后如何在网页端查看运行 http://localhost:11434/...
【MySQL】初始MySQL、库与表的操作
目录 基本使用 使用案例 SQL分类 存储引擎 库的操作 字符集和校验规则 查看系统默认字符集和校验规则 查看数据库支持的字符集 查看数据库支持的字符集校验规则 指定编码常见数据库 校验规则对数据库的影响 操纵数据库 库的备份与恢复 表的操作 创建表 查看表 …...
信息学奥赛一本通 1342:【例4-1】最短路径问题
【题目描述】 平面上有n个点(n<100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。 若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是…...
芯片AI深度实战:基础篇之langchain
基于ollama, langchain,可以构建一个自己的知识库,比如这个 Build Your Own RAG App: A Step-by-Step Guide to Setup LLM locally using Ollama, Python, and ChromaDB | HackerNoon 这是因为: 以上范例就实现了这样一个流程: 系列文章&…...
Autogen_core 测试代码:test_cache_store.py
目录 原始代码测试代码代码中用到的typing注解 原始代码 from typing import Dict, Generic, Optional, Protocol, TypeVarT TypeVar("T")class CacheStore(Protocol, Generic[T]):"""This protocol defines the basic interface for store/cache o…...
AI大模型开发原理篇-1:语言模型雏形之N-Gram模型
N-Gram模型概念 N-Gram模型是一种基于统计的语言模型,用于预测文本中某个词语的出现概率。它通过分析一个词语序列中前面N-1个词的出现频率来预测下一个词的出现。具体来说,N-Gram模型通过将文本切分为长度为N的词序列来进行建模。 注意:这…...
Haproxy入门学习二
一、Haproxy的算法 1.haproxy通过固定参数balance指明对后端服务器的调度算法,其中balance参数可以配置在listen或backend选项中 2.haproxy的调度算法分为静态和动态调度算法,其中有些算法可以根据参数在静态和动态算法中相互转换 3.静态算法:…...
【C++题解】1014. 编程求1+1/2+1/3+...+1/n
问题:1014. 编程求11/21/3…1/n 类型:简单循环 题目描述: 编程求 11/21/3⋯1/n 。 输入: 输入一行,只有一个整数 n(1≤n≤200) 。 输出: 输出只有一行(这意味着末尾有一个回车符号&#x…...
Java基础知识-第14章-Java注解
1、注解(Annotation)概述 从JDK5.0开始,Java增加了对元数据(MetaData) 的支持,也就是Annotation(注解)Annotation其实就是代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通…...
python算法和数据结构刷题[1]:数组、矩阵、字符串
一画图二伪代码三写代码 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中)-CSDN博客 算法通关手册(LeetCode) | 算法通关手册(LeetCode) (itcharge.cn) 面试经典 150 题 - 学习计…...
【javaweb项目idea版】蛋糕商城(可复用成其他商城项目)
该项目虽然是蛋糕商城项目,但是可以复用成其他商城项目或者购物车项目 想要源码的uu可点赞后私聊 技术栈 主要为:javawebservletmvcc3p0idea运行 功能模块 主要分为用户模块和后台管理员模块 具有商城购物的完整功能 基础模块 登录注册个人信息编辑…...
人格分裂(交互问答)-小白想懂Elasticsearch
通过交互式追问了解一个中间件 ? 啥是Elasticsearch ! 分布式搜索和分析引擎 ? 为啥是分布式搜索,单体难道用不了吗 ? 实际上是说这个东西可以分布式部署 ! 单机可用但扩展性差,分布式通过分片、副本和负载均衡实现海量数据存储与高并发处理 ? 提…...
独立开发者日刊 | Deepseek 统一多模态 AI Janus 开源 |语音秒变文章 | 免费 AI 视频答案引擎
独立开发者产品日刊,每日汇集 ProductHunt 热榜产品介绍,⚡️ 1句Slogan榨干产品灵魂,⚡️ 3秒 get 全球独立开发者的爆款灵感。关注小前,每日捕获全球产品灵感。 Jotform for Canva 标语:为 Canva 创建强大表单类别&a…...
1999-2020年 全国各地区-财政状况分析-一般预算收入-各项税收-个人所得税
1999-2020年 全国各地区-财政状况分析-一般预算收入-各项税收-个人所得税https://download.csdn.net/download/2401_84585615/89575946 https://download.csdn.net/download/2401_84585615/89575946 一般预算收入是指各级政府按照预算法规定,将预计取得的各项收入纳…...