GRPO 代码实战!让大模型具备思维能力,打造你的专属DeepSeek

前言

DeepSeek-R1-0528 的发布再次让DeepSeek重夺开源大模型王者的宝座(DeepSeek-R1-0528详细测评可见我的文章详细DeepSeek-R1-0528模型测评报告)。作为国产模型之光,DeepSeek-R1使用的强化学习GRPO后训练方法已经成为当今大模型训练的必备流程,无论是闭源的王Gemini Pro,Claude4,还是开源的神Qwen3训练过程中,都有GRPO算法的影子。

可以说GRPO算法已经成为大语言模型获得思维能力不可或缺的关键环节,大家也不只一次在后台私信:"除了微调教程,能不能出一期GRPO算法的实战分享呢?"。

应大家要求本期分享笔者将使用通俗易懂的语言向大家介绍GRPO 算法的核心原理,并通过在Qwen2.5-0.5B-Instruct 模型上进行GRPO强化学习训练,让Qwen2.5-0.5B-Instruct这个小模型具备思考求解数学题的能力,大家赶快来学习吧~

一、GRPO算法核心原理

GRPO算法 是DeepSeek-R1诞生思考过程用到的一种强化学习方法。DeepSeek-R1原版论文中GRPO算法的描述夹杂着大量的公式,不利于大家理解。笔者这里将不涉及任何公式,通过通俗易懂的类比讲解,确保大家看完本篇分享后将理解GRPO算法的核心原理(更推荐理解后去看看原DeepSeek-R1的论文,配合公式加深印象)。

1.1 强化学习

GRPO算法是强化学习的一种,要想了解GRPO算法必须先了解强化学习。强化学习的核心思想很简单:想象一下我们是小孩子的时候,每当我们做正确的事比如助人为乐,努力学习等,大人就会给我们奖励,当我们做错误的事比如欺骗、霸凌等,大人就会赏我们巴掌。久而久之,我们就建立了"做正确事"的人生观,在正确的认识道路上成长。

强化学习训练大模型的本质和我们成长过程是一样的。在大模型训练过程中,如果大模型回答问题是正确的,我们给大模型设置较高的奖励分数,如果大模型回答问题是错误的,那么不得分或者得负分,优化的目标就是让大模型得到更高的分数,在这种机制下大模型会不断试错直到达到我们的既定效果。

以上就是强化学习的核心机制,是不是非常好理解~

1.2 GRPO算法流程

传统的强化学习方法(例如PPO)除了被训练的大模型外,还要引入其它大模型用来评估被训练大模型的生成结果,指明被训大模型的发展方向。GRPO算法的精髓在于撤掉用于评估的大模型,通过设置合理的奖励函数进行"小组内部PK制"的方法让模型具备思考能力,相比之下节约了大量资源。

GRPO算法的主要流程分为三步:

  1. 让大模型输出多种解法: 以一个"下蛋鸡"问题为例,大模型返回了三种回答,我们将这三种回答作为一组。
ini 复制代码
 比如提问一个问题"农场有10只鸡,5只是公鸡,3只是下蛋的母鸡,问有几只鸡不下蛋?"
    大模型要针对该问题输出多个答案:
    (1) 10-5-3+5=7只 是正确推理
    (2) 10-5-3=2只 是接近正确答案的推理
    (3) 5只公鸡 是错误的推理
  1. 小组内比优势: GRPO算法把同一个问题的多个回答当成"一组作业", 通过奖励函数计算每个回答的相对优势值。每个回答的相对优势值等于得分-全组平均分。大模型会选择相对优势值高的回答作为进化方向,继续看示例
ini 复制代码
"下蛋鸡"问题的三个回答:
(1) 10-5-3+5 = 7 回答正确得 5分 优势值:5-(5+2+0)/3=2.7分
(2) 10-5-3=2 回答近似正确得 2分 优势值:2-(5+2+0)/3=-0.3分
 (3)  5只公鸡  回答错误得     0分 优势值:0-(5+2+0)/3=-2.3分
 
 选择优势值最高的第(1)个回答作为进化方向
  1. 触发顿悟时刻: 使用GRPO算法不断训练你提供的数据集你会发现练着练着模型突然开窍了,自己能通过不断思考写对正确答案了。这种自主延长思考、涌现推理能力的神奇现象在DeepSeek-R1论文中被称为"Aha Moment"!(也叫做 啊哈 时刻,像不像你做对数学题之后的狂喜时刻!)

二、GRPO代码实战------前期准备

想必看到这里大家已经对GRPO算法的核心原理有了大致了解,接下来我们就快速编写代码,上手实践GRPO算法!

伴随着DeepSeek R1火爆全球,GRPO算法的使用需求也是不断增加。截至目前,主流的强化学习框架均支持GRPO算法,可以快速完成GRPO算法的推理流程。

那这时大家可能会问:"既然主流框架已经支持GRPO算法,那我们要编写的代码主要作用于哪一过程呢?"

诚然目前主流框架已经实现了GRPO的算法流程,但是模型回答质量的好坏是需要我们自己编写"奖励函数 "评估的。奖励函数编写的好坏是GRPO算法取得成效的关键,只有好的奖励函数才能决定大模型向正确的道路进化。

本期分享我将自行编写奖励函数搭配TRL强化学习库 (Unsloth、MS-Swift训练框架均采用的强化学习库),让Qwen2.5-0.5B-Instruct小模型诞生数学推理的能力。完整的代码在github.com/TangBaron/G... 本次实验用到的数据和模型训练前后参数大家可关注我的同名微信公众号:大模型真好玩 ,私信GRPO代码实战免费获取。

2.1 环境准备

  1. 本篇分享我们采用Qwen2.5-0.5B-Instruct 模型为例进行GRPO强化学习训练,访问网址modelscope.cn/models/Qwen... 从ModelScope下载模型权重。大家可以直接通过浏览器将模型权重下载到本地,也可以执行如下命令下载到指定文件夹:
python 复制代码
pip install modelscope # 安装魔搭社区依赖
mkdir ./Qwen2.5-0.5B-Instruct # 新建Qwen2.5-0.5B-Instruct 目录保存模型权重
modelscope download --model Qwen/Qwen2.5-0.5B-Instruct --local_dir ./Qwen2.5-0.5B-Instruct # 下载模型权重到指定目录
  1. 本篇分享我们同样使用Anaconda管理python环境避免冲突,执行如下命令新建环境并安装GRPO的依赖库:
python 复制代码
conda create -n grpo python=3.11 # 创建名为grpo的conda虚拟环境
conda activate grpo # 激活虚拟环境
pip install torch # 安装pytorch依赖
pip install transformers # 安装transformers依赖用于辅助模型推理和训练
pip install trl # 安装trl依赖用于执行GRPO强化学习
pip install wandb # 安装wanb依赖用于监控我们的训练流程

2.2 模型GRPO之前测试

进行GRPO训练前,我们需要测试一下目前Qwen2.5-0.5B-Instruct的能力,让大家更直观对比GRPO前后的模型性能,执行如下代码:

  1. modelscope导入模型加载依赖库,并加载保存在本地的模型:
python 复制代码
from modelscope import AutoModelForCausalLM, AutoTokenizer
from datasets import load_dataset

model_name = "./models/Qwen2.5-0.5B-Instruct" # 本地模型保存位置

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto"
) # 加载模型

tokenizer = AutoTokenizer.from_pretrained(model_name) # 加载模型分词器
  1. 提出一个小学数学问题测试:"Joy 每20分钟读8页书,那么它读完120页书需要几小时?"。将提示词加入messages列表并转化为大模型提问模板。我们输入的提示词语句会被分词器tokenizer转化为词语的id列表,id列表在输入模型后不同的id转化为不同词向量。
python 复制代码
prompt = "Joy can read 8 pages of a book in 20 minutes. How many hours will it take her to read 120 pages?"
messages = [
    {"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
) # 将提示词代入Qwen提问模板
model_inputs = tokenizer([text], return_tensors="pt").to(model.device) # 模板文字经过分词器转换成向量形式后转移到GPU上
print(model_inputs)
  1. 将提问输入大模型并生成回答,回答的生成形式也是id列表
python 复制代码
generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=512
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
print(generated_ids)
  1. 使用分词器将回复得到的词id列表转化为文本, 回答结果如下图所示,可见Qwen2.5-0.5B-Instruct模型初始状态下并不会主动思考。
python 复制代码
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)

2.3 准备数据集

为了提升Qwen模型数学问题思考能力,本期分享使用来自OpenAI/GSM8K数据集 : hf-mirror.com/datasets/op... , 该数据集包含从小学到高中大约8000个数学问题。该数据集详细介绍可参考我上篇文章:最强大模型评测工具EvalScope------模型好不好我自己说了算!

以下是该数据集的详细情况,可以看到答案中使用####对推理过程和标准答案进行区分。

使用如下代码下载数据集,该数据集默认会从huggingface下载,如果遇到网络问题无法下载,也可以关注我的微信同名公众号:大模型真好玩 , 私信 GRPO代码实战 获得完整数据集。

python 复制代码
data = load_dataset('openai/gsm8k', 'main')
print(data)

GSM8K 数据集包含7473条训练问答对和1319条测试问答对,问答对由questionanswer字段构成。

2.4 WandB环境配置(建议使用)

在大规模模型训练中,我们往往需要监控和分析大量的训练数据,而WandB 可以帮助我们实现这一目标。WandB 的使用教程可见笔者文章可视化神器WandB,大模型训练的必备工具!, 我们只需要添加如下代码即可:

python 复制代码
import wandb
wandb.login(key="根据笔者教程注册的WandB API KEY")
wandb.init(project="GRPO-test")

当然WandB 的使用不是必须的,WandB只是可以方便的记录大家训练过程中的奖励得分、loss曲线等,更有助于大家分析整个训练流程。

三、 GRPO代码实战------训练流程

3.1 提示词测试

完成上述全部环境搭建、模型下载测试工作后,接下来将正式开启GRPO强化学习的流程~

  1. 基础准备工作,导入GRPO用到的相关库:
python 复制代码
import re # 正则表达式匹配库
import torch # 导入pytorch库
from datasets import load_dataset, Dataset # 导入数据集处理依赖库
from transformers import AutoTokenizer, AutoModelForCausalLM # 导入模型加载库
from trl import GRPOConfig, GRPOTrainer # 导入GRPO算法配置和训练类
  1. 定义提示词模板与模型文本输出格式
  • SYSTEM_PROMPT是提示词模板,它是一个多行字符串,用于指定模型需要生成的结果格式,该提示词表示模型的回答中需要包含<reasoning></reasoning>推理过程标签(也就是<think></think>过程,这里只是更换了标签表示)。<answer></answer>是大模型最终的回答结果。在生成式模型中,模型需要先给出推理过程,然后再给出答案。
  • XML_COT_FORMAT则定义了一个结构化的输出形式,这种输出形式会作为格式奖励函数的优化目标,从而让Qwen2.5-0.5B-Instruct模型生成符合XML_COT_FORMAT格式的文本。
python 复制代码
SYSTEM_PROMPT = """
Respond in the following format:
<reasoning>
...
</reasoning>
<answer>
...
</answer>
"""

XML_COT_FORMAT = """\
<reasoning>
{reasoning}
</reasoning>
<answer>
{answer}
</answer>
"""
  1. 定义工具函数, extract_xml_answer用于从大模型回答中提取答案, extract_hash_answer则用于从gsm8k数据集中提取答案。
python 复制代码
# 提取answer标签之间内容
def extract_xml_answer(text):
    answer = text.split("<answer>")[-1]
    answer = answer.split("</answer>")[0]
    return answer.strip()

# 提取gsm8k数据集中的答案部分
def extract_hash_answer(text: str) -> str | None:
    if "####" not in text:
        return None
    return text.split("####")[1].strip()
  1. 加载 GSM8K 数据集并处理,修改原先数据集中的answer字段让它只包含答案,同时增加prompt字段指定系统输出格式SYSTEM_PROMPT和用户的输入问题。
python 复制代码
def get_gsm8k_questions(split = "train"):
    data = load_dataset('openai/gsm8k', 'main')[split] 
    data = data.map(lambda x: { 
        'prompt': [
            {'role': 'system', 'content': SYSTEM_PROMPT},
            {'role': 'user', 'content': x['question']}
        ],
        'answer': extract_hash_answer(x['answer'])
    }) 
    return data 
dataset = get_gsm8k_questions()
print(dataset)
print(dataset[0])

可见处理后的数据集增加了prompt字段,同时answer字段也被修改

  1. 在正式开启GRPO训练前,我们还是先测试一下模型输出。
python 复制代码
messages = dataset[0]['prompt']
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)

generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=512
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]

response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

print(response)

可见在明显向Qwen2.5-0.5B-Instruct模型提供系统返回格式提示词SYSTEM_PROMPT的情况下,模型的回答也并未诞生思考过程且没有满足格式要求。

3.2 奖励函数编写

要想模型能够按照固定思考格式回复,我们必须对它进行GRPO训练GRPO训练 最重要的部分是奖励函数的编写,毕竟GRPO的基本原理是是依照获得更高奖励函数得分的方向不断强化模型的性能,让其具备思考的格式和能力。

本次GRPO训练中用到的奖励函数模型组如下:

  • correctness_reward_func:根据正确性对答案进行奖励。
  • int_reward_func:根据是否为数字对输出进行奖励。
  • strict_format_reward_func:根据严格的格式要求检查并奖励。
  • soft_format_reward_func:根据稍微宽松的格式要求检查并奖励。
  • count_xml:计算文本中的 XML 标签结构并给予奖励。
  • xmlcount_reward_func:为每个输出计算 XML 标签结构的符合度并返回奖励。

具体的函数编写如下:

python 复制代码
# 检查模型输出是否与正确答案匹配,并根据匹配情况返回奖励分数
def correctness_reward_func(prompts, completions, answer, **kwargs):
    responses = [completion[0]['content'] for completion in completions]
    q = prompts[0][-1]['content']
    extracted_responses = [extract_xml_answer(r) for r in responses]
    print('-' * 20, f"Question:\n{q}", f"\nAnswer:\n{answer[0]}", f"\nResponse:\n{responses[0]}",
          f"\nExtracted:\n{extracted_responses[0]}")
    return [2.0 if r == a else 0.0 for r, a in zip(extracted_responses, answer)]


# 检查模型输出是否为有效的整数,并根据结果给予奖励。
def int_reward_func(completions, **kwargs):
    responses = [completion[0]['content'] for completion in completions]
    extracted_responses = [extract_xml_answer(r) for r in responses]
    return [0.5 if r.isdigit() else 0.0 for r in extracted_responses]


# 检查模型的输出是否符合严格的格式要求,包括<reasoning></reasoning>和<answer></answer>标签
def strict_format_reward_func(completions, **kwargs):
    """Reward function that checks if the completion has a specific format."""
    pattern = r"^<reasoning>\n.*?\n</reasoning>\n<answer>\n.*?\n</answer>\n$"
    responses = [completion[0]["content"] for completion in completions]
    matches = [re.match(pattern, r) for r in responses]
    return [0.5 if match else 0.0 for match in matches]


# 检查模型的输出是否符合稍微宽松的格式要求, <reasoning>和<answer>标签之间可以有空白字符。
def soft_format_reward_func(completions, **kwargs):
    """Reward function that checks if the completion has a specific format."""
    pattern = r"<reasoning>.*?</reasoning>\s*<answer>.*?</answer>"
    responses = [completion[0]["content"] for completion in completions]
    matches = [re.match(pattern, r) for r in responses]
    return [0.5 if match else 0.0 for match in matches]


# 计算文本中<reasoning></reasoning>和<answer></answer>标签的出现次数,并根据它们的位置和频率分配奖励。
def count_xml(text):
    count = 0.0
    if text.count("<reasoning>\n") == 1:
        count += 0.125
    if text.count("\n</reasoning>\n") == 1:
        count += 0.125
    if text.count("\n<answer>\n") == 1:
        count += 0.125
        count -= len(text.split("\n</answer>\n")[-1]) * 0.001
    if text.count("\n</answer>") == 1:
        count += 0.125
        count -= (len(text.split("\n</answer>")[-1]) - 1) * 0.001
    return count


# 该函数用于计算每个模型输出的XML结构符合度,并返回奖励分数
def xmlcount_reward_func(completions, **kwargs):
    contents = [completion[0]["content"] for completion in completions]
    return [count_xml(c) for c in contents]

奖励函数是强化学习中的反馈机制,帮助模型优化输出结果,并满足格式、正确性等多方面要求。可以说奖励函数是大模型实现GRPO的关键,大模型只有在合理的奖励函数中不断"撞墙"并向着高分值的方向逼近,才能具备思考能力!

3.3 执行GRPO过程

完成了奖励函数的编写后,终于来到GRPO算法的执行过程了。

  1. 首先读取模型并设置模型保存地址:
python 复制代码
model_name = "models/Qwen2.5-0.5B-Instruct"

output_dir="outputs/Qwen-0.5B-GRPO"
run_name="Qwen-0.5B-GRPO-gsm8k"
  1. 然后利用GRPOConfig类创建训练参数, TRL已经将GRPO很好的封装.
python 复制代码
training_args = GRPOConfig(
    output_dir=output_dir,
    run_name=run_name,
    learning_rate=5e-6,
    adam_beta1 = 0.9,
    adam_beta2 = 0.99,
    weight_decay = 0.1,
    warmup_ratio = 0.1,
    lr_scheduler_type='cosine',
    logging_steps=1,
    bf16=True,
    per_device_train_batch_size=1,
    gradient_accumulation_steps=4,
    num_generations=16,
    max_prompt_length=256,
    max_completion_length=200,
    num_train_epochs=1,
    save_steps=100,
    max_grad_norm=0.1,
    log_on_each_node=False,
    use_vllm=False,
    vllm_gpu_memory_utilization=.3,
    vllm_device="cuda:0",
    report_to="wandb" 
)

GRPOConfig 是TRL设计的用于GRPO强化学习和优化训练GRPO训练过程的配置类,它包含了GRPO训练的各种设置参数,这些参数的具体含义如下所示:

  • output_dir: 指定训练结果保存的目录(例如模型检查点、日志文件)。output_dir 变量应事先定义。
  • run_name: 运行的名称,用于标识该训练任务的名称。
  • learning_rate=5e-6: 学习率,决定了每次参数更新时模型更新的步长。较小的学习率意味着训练更加稳定,但可能需要更长的时间。
  • adam_beta1=0.9 和 adam_beta2=0.99: Adam 优化器的超参数,分别对应一阶矩和二阶矩的衰减率。它们通常用于控制优化过程中的动量。
  • weight_decay=0.1: 权重衰减,通常用于防止过拟合,是一种正则化方法。
  • warmup_ratio=0.1: 学习率的预热比例,表示在训练的初期阶段逐步增加学习率,避免直接开始时学习率过高。
  • lr_scheduler_type='cosine': 学习率调度类型,cosine 表示使用余弦退火(Cosine Annealing)来调整学习率,通常在训练的后期将学习率逐渐减小。
  • logging_steps=1: 每训练 1 步就记录一次日志。这个参数控制了日志记录的频率。
  • bf16=True: 启用 bfloat16 精度训练。bfloat16 是一种数值精度格式,通常在支持该格式的硬件(如 Google TPU)上能有效加速训练,同时减少显存占用。
  • per_device_train_batch_size=1: 每个设备上进行的训练批次大小,即每次计算时使用的样本数。此处设置为 1,表示每个 GPU 或设备上处理 1 个样本。
  • gradient_accumulation_steps=4: 梯度累积步数,在训练时通过累计多个小批次的梯度来模拟更大的批次大小,以节省显存。
  • num_generations=16: 每个训练样本生成的输出数量,通常用于生成式任务(如文本生成)。
  • max_prompt_length=256: 最大输入长度(包括问题和上下文),超过此长度的输入会被截断。
  • max_completion_length=200: 模型生成的最大输出长度。
  • num_train_epochs=1: 训练的总轮数。每一轮都将对整个数据集进行一次完整的训练。
  • save_steps=100: 每 100 步保存一次模型的检查点。
  • max_grad_norm=0.1: 梯度裁剪的最大范数,这有助于避免梯度爆炸的问题,尤其是在深度神经网络中。
  • log_on_each_node=False: 在每个节点上是否记录日志,通常在分布式训练时使用。
  • use_vllm=False: 是否使用 vllm 进行训练。使用vllm使模型快速生成补全结果
  • vllm_gpu_memory_utilization=.3: 如果启用了 vllm,这是每个 GPU 的内存使用比例(通常是一个浮动值,0 到 1)。
  • vllm_device="cuda:0": 指定要在第一个 GPU 上运行 vllm。
  • report_to="none": 禁用训练过程中的报告工具(如 WandB)。如果设置为 "wandb",则训练过程中会记录数据并上传到 WandB。
  1. 加载模型和分词器,创建GRPOTrainer训练类并传入奖励函数,执行trainer.train()开启GRPO训练过程,然后就是漫长的等待过程啦~
python 复制代码
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.bfloat16,
    device_map=None
).to("cuda")

tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

trainer = GRPOTrainer(
    model=model,
    processing_class=tokenizer,
    reward_funcs=[
        xmlcount_reward_func,
        soft_format_reward_func,
        strict_format_reward_func,
        int_reward_func,
        correctness_reward_func],
    args=training_args,
    train_dataset=dataset,
)

trainer.train()

trainer.save_model(output_dir)

本次训练使用了WandB记录模型的训练流程, 我们可以在WandB中查看模型的训练状态,从中可以看到我们的奖励函数从0开始逐步升高,这表示模型已经按照我们的设定格式回答问题啦!

四、GRPO训练结果检测

GRPO训练完成后我们可以通过两种方法检测结果:

第一种方法是人工向模型提问, 检验模型输出答案和输出格式是否正确,以下是我们同样向模型提问"Joy 每20分钟读8页书,那么它读完120页书需要几小时?"的问题:

python 复制代码
grpo_model_name = "./outputs/Qwen-0.5B-GRPO"

model = AutoModelForCausalLM.from_pretrained(
    grpo_model_name,
    torch_dtype="auto",
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

prompt = "Joy can read 8 pages of a book in 20 minutes. How many hours will it take her to read 120 pages?"
messages = [
    {"role": "system", "content": SYSTEM_PROMPT},
    {"role": "user", "content": prompt}
]

text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)

generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=512
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]

response = tokenizer.batch_decode(generated_ids, skip_special_tokens=False)[0]

print(response)

下面是该问题的执行结果,对比此前原始模型的输入,GRPO训练好的模型已经能够顺利执行思考过程并按照要求格式返回输出结果,多试几个例子同样会有这样的结果!GRPO果然让Qwen2.5-0.5B-Instruct模型插上了思考的翅膀!

第二种方法我们可以使用笔者文章最强大模型评测工具EvalScope中介绍的EvalScope 对GSM8K的test数据集进行测试,具体的代码实现就当作小练习交给大家自行复习实现啦!笔者这边在GSM8K的test数据集上的评测结果由22.4% 提升到 48.6%, 可见GRPO不但实现了格式上的对齐,更让模型具备思考能力,在数学数据集上取得了惊人性能!

五、 总结

以上就是今天GRPO代码实战的全部分享啦!本篇分享笔者通俗易懂的讲述了GRPO核心原理,并通过TRL库和自定义奖励函数实现GRPO的完整训练流程!相信大家认真看完了本篇分享一定会对GRPO算法有更全面的了解,也具备了让大模型能够思考推理的超能力!GRPO算法是DeepSeek更是中国在世界人工智能发展历史上留下的炫丽瑰宝,应该被每一个中国人工智能爱好者掌握。

今天的分享到此结束,大家感兴趣可以关注我的掘金账号,更可关注我的同名微信公众号:大模型真好玩, 查阅更多笔者学习工作中免费的大模型经验分享和相关资料~

相关推荐
4 分钟前
前端工程师必备:5个改变开发效率的 MCP Server
人工智能
Ai尚研修-贾莲9 分钟前
最新Transformer模型及深度学习前沿技术应用
人工智能·深度学习·transformer·生成式模型·图神经网络·注意力机制·目标检测算法
weixin_4532536518 分钟前
机器学习----模型评价与优化
人工智能·机器学习
DeepSeek忠实粉丝29 分钟前
Deepseek篇--阿里QwQ-325b性能比肩Deepseek满血版
人工智能·程序员·llm
jndingxin29 分钟前
OpenCV CUDA模块图像变形------对图像进行 尺寸缩放(Resize)操作函数resize()
人工智能·opencv·计算机视觉
luofeiju32 分钟前
数字图像处理与OpenCV初探
c++·图像处理·python·opencv·计算机视觉
清醒的兰33 分钟前
OpenCV 多边形绘制与填充
图像处理·人工智能·opencv·计算机视觉
luozhonghua200035 分钟前
opencv opencv_contrib vs2020 源码安装
人工智能·opencv·计算机视觉
JC_You_Know35 分钟前
边缘计算一:现代前端架构演进图谱 —— 从 SPA 到边缘渲染
前端·人工智能·边缘计算
吴声子夜歌35 分钟前
OpenCV——图像金字塔
人工智能·opencv·计算机视觉