当前位置: 首页 > news >正文

deepseek GRPO算法保姆级讲解(数学原理+源码解析+案例实战)

文章目录

  • 什么是GRPO
    • 群组形成(Group Formation):让大模型创建多种解决方案
    • 偏好学习(Preference Learning):让大模型理解何为好的解答
      • 组内相对优势
    • 优化(optimization): 让大模型从经验中学习(learning from experience)
      • 目标函数
    • GRPO算法的伪码表示
    • GRPO算法的局限与挑战
  • 代码实现
    • GRPO训练参数配置
    • GRPO训练器
      • token对数概率计算
      • 奖励矩阵计算
      • 组内优势计算
      • 计算损失函数
  • 案例实战:使用TRL库实现GRPO训练文本生成模型
  • 推荐阅读
  • REF

什么是GRPO

GRPO(Groupwise relative policy optimization)群组相对策略优化是deepseek提出的一种RLHF(基于人类反馈的强化学习)技术。首次提出是在DeepSeekMath中,RL被证明在SFT阶段后能有效提升LLM的数学推理能力。
在GRPO提出之前,有两种流行的RLHF技术被广泛用于大模型的对齐过程中,分别是PPO和DPO。

群组形成(Group Formation):让大模型创建多种解决方案

GRPO算法的第一步非常直观,类似于学生尝试多种解法去解决同一个问题。对于给定的prompt,让大模型尝试生成多种解答(attempt)来解决同一个问题(通常4、8或16种的不同解答)。不同的解答示例如下图所示。
在这里插入图片描述

偏好学习(Preference Learning):让大模型理解何为好的解答

与其他的RLHF方法需要一个单独的奖励模型(reward model)不同,GRPO方法可以使用任何函数或模型来评估LLM解答(Solution)的质量。例如,可以使用一个长度函数作为评估器来奖励模型生成更简短的解答,或是使用一个数学求解器,来奖励模型生成更准确的数学解答方案。
评估过程会从多个角度来衡量大模型生成解答方案的质量,包括:
1)最终答案是否正确;2)答案是否按指定的格式输出(如XML标签格式正确性);3)推理过程与提供的答案是否一致。

组内相对优势

这种处理方式的巧妙之处还在于评分机制,GRPO不是简单的给出绝对分数,而是对每个组内的奖励进行归一化处理。它采用了一个简单但有效的方法来计算组内相对优势:

A d v a t a g e = ( r e w a r d − m e a n ( g r o u p r e w a r d s ) / s t d ( g r o u p r e w a r d s ) Advatage = (reward- mean(group_rewards)/ std(group_rewards) Advatage=(rewardmean(grouprewards)/std(grouprewards)

这种归一化方法帮助大模型理解,哪些解答方案比同组内其他解答方案更好或更差,而不是简单的反馈绝对得分给大模型。

优化(optimization): 让大模型从经验中学习(learning from experience)

GRPO的最后一步是根据解决方案组的评估结果,指导大模型进行改进。这一过程基于两个主要原则:

  1. 鼓励模型生成更多类似成功案例的解决方案,同时远离效果不佳的方法;
  2. 使用KL散度惩罚作为安全机制,防止模型在训练中一次发生过于剧烈的变化;

这种方法在实践中被证明比传统方法更稳定,原因在于:

  • 同时考虑多个解决方案,而不局限于两两比较;
  • 基于组的归一化有助于避免奖励缩放问题(reward scaling)
  • KL散度惩罚作为安全网,保证模型在学习新知识的同时,不会忘记已经掌握的内容;

总结GRPO的关键创新在于:

  1. 直接从任何函数或模型中学习,消除了对单独奖励模型的依赖。
  2. 基于组的学习方式,比传统的成对比较等方法更加稳定和高效。

目标函数

GRPO算法从旧的策略模型中采样一组输出 o 1 , o 2 , . . . , o G {o_1,o_2,...,o_G} o1,o2,...,oG,并通过下面的目标函数来优化策略模型:
在这里插入图片描述
GRPO的目标函数通过组内相对优势估计替代传统优势函数,并结合PPO的裁剪机制(限制策略更新幅度)和KL散度正则化(约束策略与参考模型的偏离),在最大化奖励的同时确保策略稳定性:

  1. 函数中通过最大化组内相对优势,增加生成优质结果的概率,减少生成劣质结果的概率;
  2. 通过KL散度惩罚项,确保模型策略不会过度偏离参考策略,从而保证优化过程的稳定性。

式中参数注释如下:
θ : 当前策略模型的可学习参数,通过优化目标函数更新 q ∼ P ( Q ) : 从问题分布中采样的输入(如用户指令) G : 每个输入生成的样本数(组内样本数) o i ∼ π θ old ( O ∣ q ) : 旧策略生成的第  i 个输出样本 π θ old : 旧策略模型(生成样本时固定) π θ : 当前策略模型(通过优化更新) O ∣ q : 输入  q 条件下策略生成的输出分布 ∣ o i ∣ : 输出序列  o i 的长度(token数量) t : 序列生成的时间步(第  t 个token位置) A ^ i , t : 组内相对优势(基于组内奖励差值计算) ϵ : 裁剪范围参数(限制策略更新幅度) β : KL散度正则化系数(控制策略与参考模型偏离) D KL ( π θ ∣ ∣ π ref ) : 当前策略与参考模型的KL散度 π ref : 参考模型(如初始SFT模型) \begin{aligned} &\theta &&: \text{当前策略模型的可学习参数,通过优化目标函数更新} \\ &q \sim P(Q) &&: \text{从问题分布中采样的输入(如用户指令)} \\ &G &&: \text{每个输入生成的样本数(组内样本数)} \\ &o_i \sim \pi_{\theta_{\text{old}}}(O|q) &&: \text{旧策略生成的第 }i\text{ 个输出样本} \\ &\pi_{\theta_{\text{old}}} &&: \text{旧策略模型(生成样本时固定)} \\ &\pi_{\theta} &&: \text{当前策略模型(通过优化更新)} \\ &O|q &&: \text{输入 }q\text{ 条件下策略生成的输出分布} \\ &|o_i| &&: \text{输出序列 }o_i\text{ 的长度(token数量)} \\ &t &&: \text{序列生成的时间步(第 }t\text{ 个token位置)} \\ &\hat{A}_{i,t} &&: \text{组内相对优势(基于组内奖励差值计算)} \\ &\epsilon &&: \text{裁剪范围参数(限制策略更新幅度)} \\ &\beta &&: \text{KL散度正则化系数(控制策略与参考模型偏离)} \\ &D_{\text{KL}}(\pi_{\theta}||\pi_{\text{ref}}) &&: \text{当前策略与参考模型的KL散度} \\ &\pi_{\text{ref}} &&: \text{参考模型(如初始SFT模型)} \end{aligned} θqP(Q)Goiπθold(Oq)πθoldπθOqoitA^i,tϵβDKL(πθ∣∣πref)πref:当前策略模型的可学习参数,通过优化目标函数更新:从问题分布中采样的输入(如用户指令):每个输入生成的样本数(组内样本数):旧策略生成的第 i 个输出样本:旧策略模型(生成样本时固定):当前策略模型(通过优化更新):输入 q 条件下策略生成的输出分布:输出序列 oi 的长度(token数量):序列生成的时间步(第 t token位置):组内相对优势(基于组内奖励差值计算):裁剪范围参数(限制策略更新幅度):KL散度正则化系数(控制策略与参考模型偏离):当前策略与参考模型的KL散度:参考模型(如初始SFT模型)
其中​两个超参数:𝜀是PPO机制中的裁剪范围参数,限制策略更新幅度;𝛽是KL散度正则化系数,控制当前策略与参考模型 π r e f π_{ref} πref的偏离程度。

这里的KL散度与传统的KL散度计算方式不同,使用Schulman提出的无偏估计,确保结果是正数:
在这里插入图片描述
式中 o < t o_{<t} o<t表示在时间步 t 之前的所有观测(或输出)序列 。

GRPO算法的伪码表示

DeepSeekMath论文里给出了GRPO迭代优化的步骤:
在这里插入图片描述

基于上述流程,GRPO算法的伪码可表示为:

Input: 
- initial_policy: Starting model to be trained
- reward_function: Function that evaluates outputs
- training_prompts: Set of training examples
- group_size: Number of outputs per prompt (typically 4-16)Algorithm GRPO:
1. For each training iteration:a. Set reference_policy = initial_policy (snapshot current policy)b. For each prompt in batch:i. Generate group_size different outputs using initial_policyii. Compute rewards for each output using reward_functioniii. Normalize rewards within group:normalized_advantage = (reward - mean(rewards)) / std(rewards)iv. Update policy by maximizing the clipped ratio:min(prob_ratio * normalized_advantage, clip(prob_ratio, 1-epsilon, 1+epsilon) * normalized_advantage)- kl_weight * KL(initial_policy || reference_policy)where prob_ratio is current_prob / reference_probOutput: Optimized policy model

GRPO算法的局限与挑战

GRPO算法在实践中也面临一些挑战:

  1. 生成成本。为每个提示词生成多个补全(4-16个)相比只生成一个或两个补全的方法,显著增加了计算需求。
  2. 批量大小限制。需要一起处理一组补全,这可能会限制有效的批量大小,增加训练过程的复杂性,并可能减缓训练速度。
  3. 奖励函数的设计。训练质量在很大程度上依赖于精心设计的奖励函数。设计不佳的奖励可能导致意外行为或优化错误的目标。
  4. 组大小的权衡。选择最优的组大小需要在解决方案的多样性与计算成本之间进行平衡。组内样本太少可能无法提供足够的多样性,而样本太多则会增加训练时间和资源需求。
  5. KL散度调参。找到合适的KL散度惩罚平衡需要谨慎调整——过高会导致模型无法有效学习,过低则可能使其偏离初始能力过远。

代码实现

GRPO训练参数配置

TRL库中将GRPO算法封装为GRPOConfig参数配置器和GRPOTrainer训练器。
这里参考TRL库的源码,给出简化版的代码解读。
将GRPO训练所需参数封装成 GRPOConfig数据类。用@dataclass装饰器将 GRPOConfig定义为一个数据类,并通过field函数为类中的字段指定默认值、默认工厂函数、元数据等。
原代码过长,这里只贴出控制GRPO训练的参数:

@dataclass
class GRPOConfig(TrainingArguments):
# Parameters that control the traininglearning_rate: float = field(default=1e-6,metadata={"help": "Initial learning rate for `AdamW` optimizer. The default value replaces that of ""`transformers.TrainingArguments`."},)beta: float = field(default=0.04,metadata={"help": "KL coefficient. If `0.0`, the reference model is not loaded, reducing memory usage and improving ""training speed, but may be numerically unstable for long training runs."},) # KL散度部分的超参数$\beta$,控制KL散度惩罚项的大小num_iterations: int = field(default=1,metadata={"help": "Number of iterations per batch (denoted as μ in the algorithm)."},)epsilon: float = field(default=0.2,metadata={"help": "Epsilon value for clipping."},) # clip部分超参数,控制裁剪的范围

控制每个奖励函数的权重占比的参数:

reward_weights: Optional[list[float]] = field(default=None,metadata={"help": "Weights for each reward function. Must match the number of reward functions. If `None`, all ""rewards are weighted equally with weight `1.0`."},) # 每个奖励函数的权重占比

TR-DPO论文中提出的控制参考模型动态更新的三个参数, 当前策略模型与旧参考模型的混合比例、是否启用参考模型与当前策略模型的同步机制、参考模型与当前策略模型同步的频率:

## >TR-DPO论文中提出的控制参考模型与当前策略模型同步机制以动态更新的三个参数# 是否启用参考模型与当前策略模型的同步机制sync_ref_model: bool = field(default=False,metadata={"help": "Whether to synchronize the reference model with the active model every `ref_model_sync_steps` ""steps, using the `ref_model_mixup_alpha` parameter."},) # 控制参考模型更新时,当前策略模型与旧参考模型的混合比例# 加权因子alpha控制软更新(soft update);aplha=1时更新方法变为硬更新(hard update),即将参考策略模型替换为当前策略模型ref_model_mixup_alpha: float = field(default=0.6,metadata={"help": "α parameter from the TR-DPO paper, which controls the mix between the current policy and the ""previous reference policy during updates. The reference policy is updated according to the equation: ""`π_ref = α * π_θ + (1 - α) * π_ref_prev`. To use this parameter, you must set `sync_ref_model=True`."},)# 控制参考模型与当前策略模型同步的频率# 每隔 ref_model_sync_steps 步,参考模型会根据 ref_model_mixup_alpha 的规则与当前策略模型进行同步更新。ref_model_sync_steps: int = field(default=512,metadata={"help": "τ parameter from the TR-DPO paper, which determines how frequently the current policy is ""synchronized with the reference policy. To use this parameter, you must set `sync_ref_model=True`."},)

GRPO训练器

将GRPO训练过程封装为一个Trainer的一个子类。

class GRPOtrainer(Trainer):def __init__(self,model,reward_funcs,args,train_dataset,eval_dataset,processing_class,reward_processing_classes,callbacks,optimizers,peft_config,):# Training argumentsself.max_prompt_length = args.max_prompt_lengthself.max_completion_length = args.max_completion_length  # = |o_i| in the GRPO paperself.num_generations = args.num_generations  # = G in the GRPO paper# Multi-stepself.num_iterations = args.num_iterations  # = 𝜇 in the GRPO paperself.epsilon = args.epsilon # $\epsilon$超参数用于梯度clip# Tracks the number of iterations (forward + backward passes), including those within a gradient accumulation cycle.self._step = 0self._buffered_inputs = [None] * args.gradient_accumulation_steps# Initialize the metricsself._metrics = {"train": defaultdict(list), "eval": defaultdict(list)}self.log_completions = args.log_completionssuper().__init__(model=model,args=args,data_collator=data_collator,train_dataset=train_dataset,eval_dataset=eval_dataset,processing_class=processing_class,callbacks=callbacks,optimizers=optimizers,)self.generation_config = GenerationConfig(max_new_tokens=self.max_completion_length,do_sample=True,pad_token_id=processing_class.pad_token_id,temperature=args.temperature,top_p=args.top_p,top_k=args.top_k,min_p=args.min_p,repetition_penalty=args.repetition_penalty,)

token对数概率计算

计算模型生成的每个token的对数概率,以控制模型在训练中的策略更新:

# Get the per-token log probabilities for the completions for the model and the reference model@profiling_decorator # 性能分析def _get_per_token_logps(self, model, input_ids, attention_mask, logits_to_keep):# We add 1 to `logits_to_keep` because the last logits of the sequence is later excludedlogits = model(input_ids=input_ids, attention_mask=attention_mask, logits_to_keep=logits_to_keep + 1).logitslogits = logits[:, :-1, :]  # (B, L-1, V), 排除最后一个 logit: 对应下一个token的预测input_ids = input_ids[:, -logits_to_keep:]logits = logits[:, -logits_to_keep:]return selective_log_softmax(logits, input_ids)  #  计算每个输入token的对数概率

奖励矩阵计算

初始化奖励矩阵后,遍历所有预定义的奖励函数(可灵活定义为pytorch模型或普通python函数),分别计算奖励值后更新奖励矩阵:

 rewards_per_func = torch.zeros(len(prompts), len(self.reward_funcs), device=device) # 初始化奖励矩阵for i, (reward_func, reward_processing_class) in enumerate(zip(self.reward_funcs, self.reward_processing_classes) # 遍历所有的奖励函数):if isinstance(reward_func, nn.Module):  # Module instead of PretrainedModel for compat with compiled modelsreward_func_name = f"reward {reward_func.config._name_or_path.split('/')[-1]}"else:reward_func_name = reward_func.__name__with profiling_context(self, reward_func_name):if isinstance( # 基于pytorch模型计算奖励值reward_func, nn.Module ):  # Module instead of PretrainedModel for compat with compiled modelsif is_conversational(inputs[0]):messages = [{"messages": p + c} for p, c in zip(prompts, completions)]texts = [apply_chat_template(x, reward_processing_class)["text"] for x in messages]else:texts = [p + c for p, c in zip(prompts, completions)]reward_inputs = reward_processing_class(texts, return_tensors="pt", padding=True, padding_side="right", add_special_tokens=False)reward_inputs = super()._prepare_inputs(reward_inputs)with torch.inference_mode():rewards_per_func[:, i] = reward_func(**reward_inputs).logits[:, 0]  # Shape (B*G,)else: # 基于python函数计算奖励值# Repeat all input columns (but "prompt" and "completion") to match the number of generationskeys = [key for key in inputs[0] if key not in ["prompt", "completion"]]reward_kwargs = {key: [example[key] for example in inputs] for key in keys}output_reward_func = reward_func(prompts=prompts, completions=completions, **reward_kwargs)rewards_per_func[:, i] = torch.tensor(output_reward_func, dtype=torch.float32, device=device)

在这里插入图片描述

组内优势计算

根据组内解答数(num_generations),计算组内优势:

		rewards_per_func = gather(rewards_per_func)# Apply weights to each reward function's output and sumrewards = (rewards_per_func * self.reward_weights.to(device).unsqueeze(0)).sum(dim=1)# Compute grouped-wise rewardsmean_grouped_rewards = rewards.view(-1, self.num_generations).mean(dim=1)std_grouped_rewards = rewards.view(-1, self.num_generations).std(dim=1)# Normalize the rewards to compute the advantagesmean_grouped_rewards = mean_grouped_rewards.repeat_interleave(self.num_generations, dim=0)std_grouped_rewards = std_grouped_rewards.repeat_interleave(self.num_generations, dim=0)advantages = (rewards - mean_grouped_rewards) / (std_grouped_rewards + 1e-4)

计算损失函数

在这里插入图片描述

根据deepseek math论文中公式(4), 计算 D K L D_{KL} DKL的无偏估计:

 # 计算参考模型与当前模型之间的KL散度if self.beta != 0.0: # 当KL散度正则项的参数$beta$不为0时ref_per_token_logps = inputs["ref_per_token_logps"]per_token_kl = (torch.exp(ref_per_token_logps - per_token_logps) - (ref_per_token_logps - per_token_logps) - 1) # KL散度的无偏估计,,deepseek math论文中公式(4)

在这里插入图片描述

根据deepseek math 论文中的公式(3),计算损失函数:

 # Compute the lossadvantages = inputs["advantages"]old_per_token_logps = inputs["old_per_token_logps"] if self.num_iterations > 1 else per_token_logps.detach()coef_1 = torch.exp(per_token_logps - old_per_token_logps) # 新旧模型token概率的比值(先取log再取指数便于计算)coef_2 = torch.clamp(coef_1, 1 - self.epsilon, 1 + self.epsilon) #clip截断部分per_token_loss1 = coef_1 * advantages.unsqueeze(1) # 未截断的概率比值计算的损失per_token_loss2 = coef_2 * advantages.unsqueeze(1) # 截断的概率比值计算的损失per_token_loss = -torch.min(per_token_loss1, per_token_loss2) # 损失部分计算,最小化损失(最大化奖励)if self.beta != 0.0:per_token_loss = per_token_loss + self.beta * per_token_kl # deepseek math 论文中的公式(3),GRPO目标函数loss = (per_token_loss * completion_mask).sum() / completion_mask.sum()

记录KL散度平均值:

 # 记录KL散度的平均值if self.beta != 0.0:mean_kl = (per_token_kl * completion_mask).sum() / completion_mask.sum()self._metrics[mode]["kl"].append(self.accelerator.gather_for_metrics(mean_kl).mean().item())

计算截断比例(clip ratio):

 # 计算截断比例is_clipped = (per_token_loss1 < per_token_loss2).float()clip_ratio = (is_clipped * completion_mask).sum() / completion_mask.sum() self._metrics[mode]["clip_ratio"].append(self.accelerator.gather_for_metrics(clip_ratio).mean().item())

案例实战:使用TRL库实现GRPO训练文本生成模型

这里给出一个用GRPO算法,在smoltldr数据集上训练SmolLM135M文本生成模型的demo例子。使用trl、peft库实现GRPO和LORA微调。
数据集介绍
mlabonne/smoltldr 是一个包含短篇小说列表的数据集,由用户 mlabonne 在 Hugging Face 上创建并维护。该数据集主要用于自然语言处理任务,例如文本生成、故事创作等。数据集中的每个样本通常是一个短篇故事,内容可能涵盖多种主题和风格。这些故事经过清洗和格式化,适合用于训练语言模型。SmolLM-135M则是用于文本生成的小模型。

数据和模型加载

import torch
import wandb
from datasets import load_dataset
from peft import LoraConfig,get_peft_model
from transformers import AutoModelForCausalLM,AutoTokenizer
from trl import GRPOConfig,GRPOTrainerwandb.login() # 登录wandb,输入api key,保存训练结果到wandb# 加载huggingface上的数据集
dataset = load_dataset("mlabonne/smoltldr")# 加载huggingface上的模型
model_id = "HuggingFaceTB/SmolLM-135M-Instruct"
model = AutoModelForCausalLM(model_id,torch_dtype = "auto",device_map = "auto",# attn_implementation = "flash_attention_2",attn_implementation = "eager",# GPU不支持flashattention时改用标准注意力
)
tokenizer = AutoTokenizer.from_pretrained(model_id)

LORA微调配置


# 加载PEFT库中的lora配置
lora_config = LoraConfig(task_type = "CAUSAL_LM", # 生成式任务r=16, # 秩为16lora_alpha=32, # 低秩矩阵权重贡献的缩放因子设为32target_modules = "all-linear",# 模型中的线性层应用lora
)
model = get_peft_model(model,lora_config) # 冻结预训练模型的所有参数,根据lora_config在模型中添加低秩矩阵
print(model.print_trainable_parameters()) # 打印模型中可训练参数的数量及占总参数的比例

定义奖励函数


# 定义奖励函数
def reward_len(completions,**kwargs):return [-abs(50-len(completion)) for completion in completions]

GRPO训练参数设置


# GRPO训练参数配置
training_args = GRPOConfig(output_dir="GRPO",run_name="GRPO_experi_0308_01",# wandb保存的实验名称learning_rate=2e-5,per_device_train_batch_size=4,# 批量大小设小一点减少显存占用gradient_accumulation_steps=2, # 梯度累积步数max_prompt_length=512,max_completion_length=96,num_generations=4,# GRPO每组生成的解答数optim="adamW_8bit",num_train_epochs=1,# 训练数据集训练的总轮数bf16=True,report_to=["wandb"],remove_unused_columns=False,# 不移除数据集中未使用的列logging_steps=1,# 每隔一步记录一次日志
)
# 设置训练器
trainer = GRPOTrainer(model=model,reward_funcs = [reward_len],# 自定义的奖励函数agrs=training_args,# GRPO的训练配置train_dataset = dataset["train"],
)

训练模型

# 训练模型
wandb.init(project="GRPO") # 初始化wandb日志环境
trainer.train() # 开始训练

上传训练完成的模型参数


# 保存模型参数,上传到huggingface hub
merged_model = trainer.model.merge_and_unload() # 合并lora权重和预训练权重
merged_model.push_to_hub("<your_username/your_modelname>",private=False) # 模型公开可见

下载训练好的模型参数进行文本生成


prompt = """
# A long document about the CatThe cat (Felis catus), also referred to as the domestic cat or house cat, is a small
domesticated carnivorous mammal. It is the only domesticated species of the family Felidae.
Advances in archaeology and genetics have shown that the domestication of the cat occurred
in the Near East around 7500 BC. It is commonly kept as a pet and farm cat, but also ranges
freely as a feral cat avoiding human contact. It is valued by humans for companionship and
its ability to kill vermin. Its retractable claws are adapted to killing small prey species
such as mice and rats. It has a strong, flexible body, quick reflexes, and sharp teeth,
and its night vision and sense of smell are well developed. It is a social species,
but a solitary hunter and a crepuscular predator. Cat communication includes
vocalizations—including meowing, purring, trilling, hissing, growling, and grunting—as
well as body language. It can hear sounds too faint or too high in frequency for human ears,
such as those made by small mammals. It secretes and perceives pheromones.
"""
messages = [{"role":"user","content":prompt},
]from transformers import pipeline
generator = pipeline("text-generation",model="<your_username/your_modelname>")
generate_kwargs = {"max_new_tokens": 256,"do_sample":True, # 启用采样生成模式"temperature":0.5, "min_p":0.1,
}
generated_text = generator(messages,generate_kwargs=generate_kwargs)
print(generated_text)

训练结果分析
随着模型的学习,奖励函数的奖励值逐渐接近0。这表明模型正在学习生成正确长度的文本。
在这里插入图片描述
在GRPO中,损失函数的初始值为零,然后在训练过程中增加。GRPO中的损失与KL散度(相对于原始策略的上限)成正比。随着训练的进行,模型学会了生成更好地符合奖励函数的文本,导致它与初始策略的偏差越来越大。这种增加的偏差反映在上升的损失值中,实际上表明模型正在成功地适应以优化奖励函数。
在这里插入图片描述


推荐阅读

  • 抱抱脸25年3月更新中的深度推理课程: https://huggingface.co/reasoning-course
  • DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models: https://arxiv.org/pdf/2402.03300

REF

  1. DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models: https://arxiv.org/pdf/2402.03300
  2. https://github.com/huggingface/trl/blob/main/trl/trainer/grpo_trainer.py#L98
  3. https://github.com/huggingface/open-r1/blob/main/src/open_r1/grpo.py
  4. https://open-r1.com/#:~:text=Open%20R1%20is%20an%20open-source%20reproduction%20of%20DeepSeek-R1%2C,MIT%20license%2C%20though%20original%20training%20data%20remains%20proprietary.
  5. DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning https://arxiv.org/abs/2501.12948
  6. https://huggingface.co/learn/nlp-course/en/chapter12/1?fw=pt

相关文章:

deepseek GRPO算法保姆级讲解(数学原理+源码解析+案例实战)

文章目录 什么是GRPO群组形成(Group Formation):让大模型创建多种解决方案偏好学习(Preference Learning)&#xff1a;让大模型理解何为好的解答组内相对优势 优化(optimization): 让大模型从经验中学习(learning from experience)目标函数 GRPO算法的伪码表示GRPO算法的局限与…...

【WEB APIs】DOM-节点操作

1. 日期对象 1.1 实例化 <script>// 实例化// 1.得到当前时间const date new Date()console.log(date);// 2.得到指定时间const date1 new Date(2025-3-14)console.log((date1));</script> 1.2 日期对象方法 千万不要忘记加小括号 // 获得日期对象const date2 …...

VSTO(C#)Excel开发7:自定义任务窗格

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

Qemu 详解与 ARM 虚拟机搭建指南

1. Qemu 是什么&#xff1f; Qemu&#xff08;Quick Emulator&#xff09;是一款开源的机器模拟器和虚拟化工具&#xff0c;支持多种硬件架构&#xff08;如 x86、ARM、PowerPC 等&#xff09;。它的核心功能包括&#xff1a; 动态指令翻译&#xff1a;将不同架构的指令实时翻…...

Windows编译Flash-attention模块

​ 博主的环境配置&#xff1a;windows11操作系统&#xff0c;cuda11.8.r11.8, cudnn8.9.7, git2.47.1&#xff0c;cmake4.0.0-rc4&#xff0c;ninja1.12.1, vs_buildTools17.4.21, cl19.34.31948, torch2.3.1 编译flash-attention的环境依赖如下图 #mermaid-svg-SZBhH41EsJGfu…...

《Python深度学习》第三讲:神经网络

在前面的课程里&#xff0c;我们已经了解了深度学习的数学基础&#xff0c;也用一个简单的例子展示了神经网络的强大能力。本讲我们要更深入地探讨神经网络的结构、训练过程&#xff0c;以及如何用它解决实际问题。 3.1 神经网络剖析 先来聊聊神经网络的核心组件&#xff1a;层…...

编程题《牛牛的链表删除》的python可以用非链表的方式

描述 牛牛从键盘输入了一个长度为 n 的数组&#xff0c;把这个数组转换成链表然后把链表中所有值是 x 的节点都删除。 输入描述&#xff1a; 第一行输入两个正整数 n 和 x 表示数组的长度和要删除的链表节点值 x 。 第二行输入 n 个正整数表示数组中每个元素的值。 输出描述&am…...

传统RAG vs 知识图谱:大模型时代的知识管理革命

引言&#xff1a;为什么需要突破传统RAG&#xff1f; 在大模型应用落地的浪潮中&#xff0c;检索增强生成&#xff08;RAG&#xff09;技术通过连接外部知识库&#xff0c;有效缓解了模型的幻觉问题。然而&#xff0c;当面对复杂关系推理、多文档关联分析等场景时&#xff0c;…...

【Go语言圣经2.6】

目标 概念 GOPATH模型 GOPATH&#xff1a;GOPATH 是一个环境变量&#xff0c;指明 Go 代码的工作区路径。工作区通常包含三个目录&#xff1a; src&#xff1a;存放源代码&#xff0c;按照导入路径组织。例如&#xff0c;包 gopl.io/ch2/tempconv 应存放在 $GOPATH/src/gopl.i…...

多时间尺度的配电网深度强化学习无功优化策略的Python示例代码框架

以下是一个简单的多时间尺度的配电网深度强化学习无功优化策略的Python示例代码框架&#xff0c;用于帮助你理解如何使用深度强化学习&#xff08;以深度Q网络 DQN 为例&#xff09;来处理配电网的无功优化问题。在实际应用中&#xff0c;你可能需要根据具体的配电网模型和需求…...

0CTF 2016 piapiapia 1

#源码泄露 #代码审计 #反序列化字符逃逸 #strlen长度过滤数组绕过 www.zip 得到源码 看到这里有flag &#xff0c;猜测服务端docker的主机里&#xff0c;$flag变量应该存的就是我们要的flag。 于是&#xff0c;我们的目的就是读取config.php 利用思路 这里存在 任意文件读取…...

ArcGIS Pro将有文字标注底图切换为无标注底图(在线地图图源)

今天介绍一下在ArcGIS Pro将有标注的地形底图换成无标注的底图。 大家在这项目底图时候会经常调用ArcGIS Pro自带的地形图&#xff0c;但是这个地形图自带是有注记的&#xff0c;如下图。 如何更改&#xff0c;才可以调用无文字注记的呢&#xff1f; 对于一个已经切好图的有注记…...

股指期货有卖不出去的时候吗?

在股指期货的交易世界里&#xff0c;很多人都有这样的疑问&#xff1a;股指期货会不会有卖不出去的时候呢&#xff1f;答案是会的&#xff0c;下面咱们就来详细唠唠为啥会出现这种情况。 市场极端行情下难以卖出 1.跌停限制&#xff1a;股指期货和股票一样&#xff0c;也有涨…...

NPM 常用操作指令大全

NPM&#xff08;Node Package Manager&#xff09;是 Node.js 默认的包管理工具&#xff0c;主要用于管理 JavaScript 项目的依赖包。以下是常用的 NPM 命令&#xff0c;涵盖安装、卸载、更新、查看等操作。 &#x1f4cc; 1. NPM 初始化 npm init 逐步询问项目信息&#xff…...

Mysql与ElasticSearch间的数据同步场景模拟

一、场景简介 现有酒店管理与酒店搜索预定两个分离的微服务模块&#xff0c;为了数据的安全性我们在就带你管理模块通过Mysql进行crud&#xff0c;为了搜索的高效和质量在搜索预定模块我们采用了ElasticSearch搜索引擎&#xff08;视作一种NoSQL 数据库&#xff09;&#xff0c…...

Qt-D指针与Q指针的设计哲学

文章目录 前言PIMLP与二进制兼容性D指针Q指针优化d指针继承Q_D和Q_Q 前言 在探索Qt源码的过程中会看到类的成员有一个d指针&#xff0c;d指针类型是一个private的类&#xff0c;这种设计模式称为PIMPL&#xff08;pointer to implementation&#xff09;&#xff0c;本文根据Q…...

安装配置Anaconda,配置VSCode

文章目录 Anaconda介绍下载Anaconda安装Anaconda换源创建一个新环境conda常用命令 VSCode环境配置 记录一下笔者收集的一些资料&#xff0c;不喜勿喷。 Anaconda介绍 Anaconda是一个用于科学计算的Python发行版&#xff0c;支持 Linux, Mac, Windows系统&#xff0c;提供了包管…...

迪威 3D 模型发布系统:制造业产品展示革新利器

在竞争激烈的制造业领域&#xff0c;如何将产品全方位、直观地呈现给客户&#xff0c;成为企业脱颖而出的关键。传统的产品展示方式往往受限于平面资料或有限的实物展示&#xff0c;难以让客户深入了解产品的复杂结构与精妙细节。迪威 3D 模型发布系统的问世&#xff0c;为制造…...

Matlab 汽车振动多自由度非线性悬挂系统和参数研究

1、内容简介 略 Matlab 169-汽车振动多自由度非线性悬挂系统和参数研究 可以交流、咨询、答疑 2、内容说明 略 第二章 汽车模型建立 2.1 汽车悬架系统概述 2.1.1 悬架系统的结构和功能 2.1.2 悬架分类 2.2 四分之一车辆模型 对于车辆动力学&#xff0c;一般都是研究其悬…...

编程题-第k个语法符号(中等)

题目&#xff1a; 我们构建了一个包含 n 行( 索引从 1 开始 )的表。首先在第一行我们写上一个 0。接下来的每一行&#xff0c;将前一行中的0替换为01&#xff0c;1替换为10。 例如&#xff0c;对于 n 3 &#xff0c;第 1 行是 0 &#xff0c;第 2 行是 01 &#xff0c;第3行…...

vscode打不开

Bug&#xff1a;窗口意外终止(原因:“launch-failed”&#xff0c;代码:“65" 对此造成的不便&#xff0c;我们深表歉意。可以打开新的空窗口以重新启动) 解决方法&#xff1a; 移情别恋&#xff1a;VS Code打开闪退并报‘launch-failed‘ code:‘65‘ 窗口意外终止(原因…...

使用生成对抗网络(GAN)进行人脸老化生成的Python示例

以下是一个使用生成对抗网络&#xff08;GAN&#xff09;进行人脸老化生成的Python示例&#xff0c;我们将使用PyTorch库来实现。GAN由生成器和判别器两部分组成&#xff0c;生成器尝试生成逼真的老化人脸图像&#xff0c;判别器则尝试区分生成的图像和真实的老化人脸图像。 步…...

202503执行jmeter压测数据库(ScyllaDB,redis,lindorm,Mysql)

一、Mysql 1 、 准备MySQL 连接内容 2 、 下载连接jar包 准备 mysql-connector-java-5.1.49.jar 放到 D:\apache-jmeter-5.6.3\lib\ext 目录下面; 3 、 启动jmeter ,配置脚本 添加线程组---》JDBC Connection Configuration---》JDBC Request---》查看结果树。 1)测…...

Uniapp当中的scroll-view滚动条不出现或者触底刷新事件不触发

一、未正确设置容器高度 问题描述 scroll-view 未设置明确高度或高度值无效&#xff0c;导致无法形成有效滚动区域。 解决方案 • 使用行内样式直接设置 height&#xff08;如 style"height: 500rpx;"&#xff09;&#xff0c;避免类名样式被覆盖。 • 动态计算高度…...

3.16学习总结

学习了Java的知识点 基本数据类型 byte占1字节&#xff0c;储存范围-128~127 short占2字节&#xff0c;储存范围-32768~32767 int占4字节&#xff0c;储存范围-2147483648~2147483647 long占8字节&#xff0c;储存范围是-9223372036854775808~9223372036854775807 float占…...

206. 反转链表

目录 一、题目二、思路2.1 解题思路2.2 代码尝试2.3 疑难问题2.4 AI复盘 三、解法四、收获4.1 心得4.2 举一反三 一、题目 二、思路 2.1 解题思路 需要有头尾指针&#xff0c;然后又觉得可以用递归 2.2 代码尝试 class Solution { public:ListNode* reverseList(ListNode* h…...

音视频缓存数学模型

2024年8月的笔记 音视频缓存数学模型 - Wesley’s Blog 播放器作为消费者&#xff0c;缓存作为生产者。 进入缓冲一次 设消费者速率为v1&#xff0c;生产者为v2&#xff0c;视频长度为l&#xff0c;x为生产者至少距离消费者多远才能保证在播完视频前两者重合。实际上就是一个…...

priority_queue模拟实现

目录 介绍 模拟实现 无参构造函数 迭代器构造 push插入 pop删除 top返回队首元素 返回队列元素个数 判空 仿函数 补充&#xff1a;反向迭代器 模拟实现反向迭代器 构造和析构 重载和-- 解引用*和地址访问-> ! 反向迭代器在容器中实现 补充练习 数组中第…...

ChatGPT、DeepSeek、Grok:AI 语言模型的差异与应用场景分析

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 人工智能&#xff08;AI&#xff09;语言模型正在快速发展&#xff0c;ChatGPT&#xff08;OpenAI&#xff09;、DeepSe…...

Nginx 刷新后 404 的原因与解决方案

文章目录 Nginx 刷新后 404 的原因与解决方案静态资源路径问题&#xff08;单页应用 SPA&#xff09;解决方案&#xff1a;使用 try_files Nginx 资源路径 (root 或 alias) 配置错误示例&#xff1a;正确的 root配置 浏览器缓存或 Nginx 缓存影响清除浏览器缓存给静态资源加版本…...

AI赋能实时安全背带监测解决方案

背景&#xff1a;安全背带检测的行业刚需与技术痛点 在建筑施工、石油化工、仓储物流等高危行业中&#xff0c;安全背带是保障作业人员生命安全的最后一道防线。据统计&#xff0c;超过30%的高空坠落事故与未正确佩戴安全背带直接相关。传统依赖人工巡检的监督方式存在效率低、…...

【ES6】03-Set + Map

本文介绍两种集合 set map 的操作和方法。 目录 1. Set 1.1 set基本使用 1.2 add 1.3 delete 1.4 has 1.5 size 1.6 set转换为数组 1.7 拓展运算符 1.8 for...of 1.9 forEach 1.10 set给数组去重 2. Map 2.1 创建map集合 2.2 set添加元素 2.3 delete删除元素 …...

GHCTF web方向题解

upload?SSTI! import os import refrom flask import Flask, request, jsonify,render_template_string,send_from_directory, abort,redirect from werkzeug.utils import secure_filename import os from werkzeug.utils import secure_filenameapp Flask(__name__)# 配置…...

网页制作15-Javascipt时间特效の记录网页停留时间

01效果图&#xff1a; 02运用&#xff1a; window.setTimeout&#xff08;&#xff09;刷新function&#xff08;&#xff09;函数document.forms&#xff08;&#xff09;&#xff1a;表单if条件语句window.alert&#xff08;&#xff09;窗口警示 03、操作代码&#xff1a;…...

LeetCode 解题思路 15(Hot 100)

解题思路&#xff1a; 引入哑节点&#xff1a; 简化头节点删除操作&#xff0c;统一处理所有边界条件。快慢指针法&#xff1a; 快指针先移动 n 步&#xff0c;确保快慢指针距离为 n&#xff0c;之后同步移动快慢指针。当快指针到达末尾时&#xff0c;慢指针指向倒数第 n 个节…...

STM32 - 在机器人领域,LL库相比HAL优势明显

在机器人控制器、电机控制器等领域的开发&#xff0c;需要高实时性、精细化控制或者对代码执行效率、占用空间有较高要求。所以&#xff0c;大家常用的HAL库明显不符合要求。再加上&#xff0c;我们学习一门技术&#xff0c;一定要学会掌握底层的原理。MCU开发的底层就是寄存器…...

如何查看mysql某个表占用的空间大小

在MySQL中&#xff0c;有几种方法可以查看某个表占用的空间大小。这通常涉及到查询数据库的元数据表&#xff0c;如 information_schema.TABLES&#xff0c;或者使用特定于存储引擎的命令&#xff08;例如对于InnoDB引擎&#xff09;。以下是几种常用的方法&#xff1a; 方法一…...

加固脱壳技术:DEX动态加载对抗

1. 加固技术原理剖析 1.1 DEX保护演进路线 加固方案发展历程&#xff1a; graph LR A[2015 代码混淆] --> B[2017 DEX动态加载] B --> C[2019 VMP指令虚拟化] C --> D[2022 全链路加密] 1.1.1 主流加固方案对比 厂商核心防护技术弱点分析梆梆加固DEX文件分片…...

树莓派 连接 PlutoSDR 教程

在树莓派5上安装PlutoSDR&#xff08;ADALM-Pluto&#xff09;的驱动程序&#xff0c;主要需要安装相关的库和工具&#xff0c;以便与PlutoSDR通信&#xff0c;比如libiio和libad9361&#xff0c;并确保系统能够识别设备。由于树莓派5运行的是基于Linux的系统&#xff08;通常是…...

山东省新一代信息技术创新应用大赛-计算机网络管理赛项(样题)

目录 竞赛试题 网络拓扑 配置需求 虚拟局域网 IPv4地址部署 OSPF及路由部署 配置合适的静态路由组网 MSTP及VRRP链路聚合部署 IPSEC部署 路由选路部署 设备与网络管理部署 1.R1 2.R2 3.S1 4.S2 5.S3 竞赛试题 本竞赛使用HCL(华三云实验室)来进行网络设备选择…...

文件上传漏洞

文件上传条件 有上传点 后缀没有过滤且可解析 能找到web路径 常见的绕过方式 前端绕过&#xff1a;上传一张图片&#xff0c;抓包修改后缀为php content-type绕过&#xff1a; applicaition/x-www-form-urlencoded multipart/form-data application/json image/jpeg image/png…...

Java 绘制图形验证码

在 Spring Boot 中生成图形验证码并校验其正确性&#xff0c;通常包括以下步骤&#xff1a; 生成验证码图片和对应的验证码值。将验证码值存储到 Session 或其他存储中&#xff08;如 Redis&#xff09;。将验证码图片返回给客户端。客户端提交表单时&#xff0c;校验用户输入的…...

APP自动化测试-备忘录:Appium 2.X的安装和启动服务方法

一、Appium 1.X 启动appium服务&#xff1a;appium --session-override 也可以这样启动appium服务&#xff1a;appium 二、Appium 2.X Appium 2.X 是一个自动化测试开源工具&#xff0c;用于测试原生、移动 Web 和混合应用程序。下面为你介绍其下载步骤&#xff1a; 1. 安装…...

卡尔曼滤波算法从理论到实践:在STM32中的嵌入式实现

摘要&#xff1a;卡尔曼滤波&#xff08;Kalman Filter&#xff09;是传感器数据融合领域的经典算法&#xff0c;在姿态解算、导航定位等嵌入式场景中广泛应用。本文将从公式推导、代码实现、参数调试三个维度深入解析卡尔曼滤波&#xff0c;并给出基于STM32硬件的完整工程案例…...

k8s serviceaccount在集群内指定apiserver时验证错误的问题

在主机上&#xff0c;找到TOKEN&#xff0c;可以直接指定apiserver使用 rootubuntu-server:/home# kubectl auth can-i --list --server https://192.168.85.198:6443 --token"eyJhbGciOiJSUzI1NiIsImtpZCI6IlFlMHQ3TzhpcGw1SnRqbkYtOC1NUWlWNUpWdGo5SGRXeTBvZU9ib25iZD…...

自动化测试脚本

一、自动化测试脚本是什么&#xff1f; 自动化测试脚本是由测试人员或开发人员编写的 代码或工具指令&#xff0c;用于 自动执行测试用例&#xff0c;模拟用户操作&#xff08;如点击按钮、输入数据&#xff09;&#xff0c;并对结果进行验证。 它与手动测试的核心区别在于&am…...

练习-串串变变变(字符串变换)

问题描述 小蓝现在有一个长度为 n 仅由小写字母组成的的字符串 s &#xff0c;小蓝可以对字符串进行任意次操作&#xff0c;每次操作小蓝可以选择一个整数 ii &#xff0c;其中 i∈[1,n−1]&#xff0c;然后选择如下两种操作之一&#xff1a; 将 si​ 变为其字典序加一的小写…...

99.HarmonyOS NEXT跑马灯组件教程:动画配置与参数详解

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT跑马灯组件教程&#xff1a;动画配置与参数详解 文章目录 HarmonyOS NEXT跑马灯组件教程&#xff1a;动画配置与参数详解1. 跑马灯动…...

【web逆向】优某愿 字体混淆

地址&#xff1a;aHR0cHM6Ly93d3cueW91enkuY24vY29sbGVnZXMvc2NvcmVsaW5lP2NvbGxlZ2VDb2RlPTEwMDAzJm5hbWU9JUU2JUI4JTg1JUU1JThEJThFJUU1JUE0JUE3JUU1JUFEJUE2​ 接口分析 接口&#xff1a;eW91enkuZG1zLmRhdGFsaWIuYXBpLmVucm9sbGRhdGEuZW50ZXIuY29sbGVnZS5lbmNyeXB0ZWQudj…...

MSP430 Proteus 仿真作品

https://www.dong-blog.fun/post/1998 1 、 电子万年历&#xff08;采用 DS1302 及 及 TC72 等芯片&#xff09; 基本要求&#xff1a; 可显示年、月、日、星期、时、分、秒&#xff1b; 有温度显示功能。 发挥部分&#xff1a; 可调节时间和日期&#xff1b; 有农历显示功能 &…...