写点什么

大模型开发利器 Aladdin 加持,4 小时亲手复刻 DeepSeek Aha Moment

  • 2025-02-20
    上海
  • 本文字数:6158 字

    阅读完需:约 20 分钟

大模型开发利器Aladdin加持,4小时亲手复刻DeepSeek Aha Moment

1、背景介绍

DeepSeek-R1,重新定义模型训练的新范式!

自从 DeepSeek-R1 横空出世,它的强大推理能力、超低训练成本和高效推理速度让无数人惊叹!但问题来了:如何将这些优势融入到我们自己的模型训练中,实现效果的飞跃?别担心!这次实践将带你深入探索 DeepSeek-R1 的核心黑科技——GRPO(Group Relative Policy Optimization)技术!

✨ 什么是 GRPO?

GRPO 是 DeepSeek-R1 的秘密武器,能够大幅提升模型训练效率与性能。更重要的是,在本次实践中,我们将手把手教你如何用 GRPO 技术解决经典任务——Countdown 数字游戏!你还将亲历模型训练中的「Aha Moment」——那个令人激动的“顿悟时刻”,当模型突然展现出类似人类的自我反思和策略调整能力时,你会感叹:原来 AI 也可以这么聪明!

为什么选择 Aladdin 大模型开发利器?

  • **高效率**:开发环境和所需 GPU 算力开箱即用,免除运维烦恼!Aladdin 插件直连云端算力集群,代码调试、模型训练像本地开发一样丝滑。

  • **高弹性**:根据任务需求智能弹性调度算力资源,实现算力资源充足高效供给,任务完成即释放算力。

  • **低成本**:告别资源闲置!算力包按量计费,小投入玩转百亿大模型微调,只为实际算力消耗买单,开发成本不再“开机即烧钱”。

️ 如何轻松复刻 DeepSeek Aha Moment(顿悟时刻)?

我们已经为你准备好了免费算力包,亲手复刻 DeepSeek Aha Moment(顿悟时刻),体验地址:

https://docs.alayanew.com/docs/documents/newActivities/deepseekaha/?utm_source=infoQ&utm_medium=tcommunity&utm_campaign=Ahamoment

本次训练基于 Qwen2.5-7B-Instruct 模型,给出一些数学加减乘除的运算问题,通过 GRPO 强化学习训练模型。提示关于 Aladdin 的介绍和使用请参考使用指南-弹性容器集群-Aladdin

1.1 任务介绍Countdown 任务是一种类似"24 点"的任务,玩家会拿到一组数字,使用"加减乘除"这四种基本语法运算法则,构造一个等于目标数字的等式,并且每个数字只能使用一次,例如:玩家拿到[2,12,25,56]这四个数字,目标是等式结果为 55.

1.2 数据集介绍使用 HuggingFace 开源数据集"Jiayi-Pan/Countdown-Tasks-3to4",里面包含 490k 条数据。"nums"字段是输入的数字列表(如:[ 44, 19, 35 ]),"target"字段是目标等式结果(如:98)我们编写了适用于 Instruct 模型的中文 prompt 模板,生成了我们的 Countdown-r1-zero 数据集。

prompt 模板:

<|im_start|>system\n你是一位专业的数谜解答助手。你首先会思考数谜的逻辑推理过程,然后给出正确答案。<|im_end|>\n<|im_start|>user\n使用{nums}这几个数字,构建一个等于{target}的等式。 你只可以使用基础的运算法则(+, -, *, /),并且每个数字只可以被使用一次。把你的逻辑推理过程写在 <think> 和 </think> 标签之间,然后将最终正确的等式写在 <answer> 和 </answer> 之间。例如,当用[1,2,3]构建结果为1的等式时,在think之后,写:<answer> (1 + 2) / 3 </answer>。<|im_end|>\n<|im_start|>assistant\n让我们一步一步地解决这个谜题。\n<think>
复制代码

2、操作步骤

2.1 部署前准备工作本次部署使用到 VSCode 和 Kubernetes,请准备好 VScode 开发环境,并确保本地有可用的 Kubernestes 客户端工具 kubectl。kubectl 安装请参考:快速开始

2.2 开通集群

  • 资源最低要求

  • 申请开通

开通集群请参考:开通弹性容器集群

开通镜像仓库:镜像仓库的开通及管理

注意

本次实践基于 Aladdin 插件,因此下面很多步骤引用了Aladdin中的步骤。

2.3 开发环境准备

请按照以下步骤准备开发环境:

  1. 前置条件

  2. VSCode安装Aladdin插件

  3. 登录

2.4 镜像准备

我们已经准备好了镜像,请执行以下命令拉取镜像并推送到自己的的私有镜像仓库中:

注意

请将下列命令中的[镜像仓库用户名]和[镜像仓库密码]替换为自己的镜像仓库用户名和密码,[镜像仓库项目名]替换为自己的镜像仓库项目名。

# 拉取镜像docker login registry.hd-01.alayanew.com:8443 -u vc-app-market-view -p HKse563!docker pull registry.hd-01.alayanew.com:8443/vc-app_market/pytorch/pytorch:2.5.1-cuda12.4-cudnn9-ahadocker tag registry.hd-01.alayanew.com:8443/vc-app_market/pytorch/pytorch:2.5.1-cuda12.4-cudnn9-aha registry.hd-01.alayanew.com:8443/[镜像仓库项目名]/pytorch/pytorch:2.5.1-cuda12.4-cudnn9-aha# 推送镜像docker login registry.hd-01.alayanew.com:8443 -u [镜像仓库用户名] -p [镜像仓库密码]docker push registry.hd-01.alayanew.com:8443/[镜像仓库项目名]/pytorch/pytorch:2.5.1-cuda12.4-cudnn9-aha
复制代码

2.5 训练模型

按照下图所示,进入 workspace 目录:

请下载代码压缩包,并在本地解压。将刚才下载并解压后的代码拷贝到 workspace 目录下,并确认目录结构如下:

  • 初始化 Python 环境


    进入 grpo_implement 目录,执行以下命令初始化 Python 环境:

conda init#再次打开一个终端窗口conda create -n py311 python=3.11 -y conda activate py311pip install -r requirement.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
复制代码
  • 下载模型 Qwen2.5-7B-Instruct

export HF_ENDPOINT=http://hfmirror.mas.zetyun.cn:8082huggingface-cli download --resume-download Qwen/Qwen2.5-7B-Instruct --local-dir /workspace/model/Qwen/Qwen2.5-7B-Instruct
复制代码
  • 设置 python 解释器


    选择刚才创建的 conda 环境 py311 作为 python 解释器:


  • 开始训练

  1. 在 VSCode 中的文件资源管理器中,打开 lauch_grpo.sh,在编辑器中右键菜单中,选择"Run Shell",并在弹出的对话框中做如下配置:


2.点击"Submit"按钮,训练任务会被提交到集群中,在 output 中可以看到命令执行状态。

2025-02-17 14:44:39.383 [info] [shell-0e92396c-fd87-43c9]: Session is creating2025-02-17 14:44:39.442 [info] [shell-0e92396c-fd87-43c9]: Write bash sh success.2025-02-17 14:44:47.431 [info] [shell-0e92396c-fd87-43c9]: Session is waiting for ready2025-02-17 14:44:47.431 [info] [shell-0e92396c-fd87-43c9]: Session is ready to run2025-02-17 14:44:47.431 [info] [shell-0e92396c-fd87-43c9]: Waiting For Running...2025-02-17 14:44:47.431 [info] [shell-0e92396c-fd87-43c9]: Streaming logs from Session[start]...
复制代码

1.整个训练过程大概需要 4 个小时,在./grpo_implement/logs/下有 log,查看 countdown_zero_rl_aha_moment_dist.log 文件,可以看到训练的进度。

2.当训练完成后,在./grpo_implement/deepseek_checkpoints/下有 checkpoint 文件和最终模型文件。

2.6[Aha Moment]顿悟时刻

训练过程中观察到的 Aha Moment 顿悟。

"突然意识到我们可以使用..."<think>我们需要使用11, 77, 6, 80这四个数字来构造等式,目标结果是20。我们尝试不同的组合:11 + 77 - 6 - 80 = -211 + 77 - 80 + 6 = 811 + 77 + 6 - 80 = 880 - 77 + 11 - 6 = 880 - 77 - 11 + 6 = 880 - (77 + 11 - 6) = 880 - 77 - 6 + 11 = 8(80 - 77) * (11 - 6) = 3 * 5 = 15(80 - 6) / (77 - 11) = 74 / 66.67 ≠ 20(77 - 6) / (80 - 11) = 71 / 69 ≠ 20通过尝试,我们发现上述组合都不等于20。我们还需要寻找其他可能性,考虑乘法和除法结合:77 / 11 + 80 / 6 ≠ 206 * (80 / 11 - 77) ≠ 20(77 - 11) / (80 / 6) = 66 / 13.33 ≠ 20仔细检查所有可能性之后,突然意识到我们可以使用括号来改变运算顺序。(80 - 77 + 6) + 11 = 20</think><answer> (80 - 77 + 6) + 11 </answer>
复制代码

Aha Case2:

"突然想到,88 - 10正好是78"<think> 首先,我们需要找到一个组合方式,利用给定数字72, 66, 10, 88,通过加减乘除得到72。尝试不同的组合,我们可以尝试将88设为等式的一边,看其能否通过加减乘去除掉某些数字,得到72。88 - 16似乎接近,但我们需要再发现能减去16的组合。另一个思路是,我们可以尝试将66和10组合,看看能得到72。66 + 10 = 76,距离72只有4,而72 - 8 = 64,72 + 8 = 80,显然8不合适。观察72和88,考虑两个数相除。88 / 2 = 44,然后我们可以尝试44和66及10的组合。44 + 22 = 66,而66 - 16 = 50,50 + 22 = 72,但16我们还没使用。这方案暂不成立。尝试考虑88这样的大数,减去其他数接近72,88 - 66 = 22,接着22 - 10 = 12,再加66又离72远了。继续尝试其他数字组合时,突然想到,88 - 10正好是78,再减去6给出72。这是一个有效组合。因此,最终得到的等式为: <answer> 88 - 10 - 6 </answer>
复制代码

类似这种 突然想到,突然意识到,突然发现 均为 Aha moment,可在训练的过程中找到。

在目录./grpo_implement/completion_samples/目录下有文件 completion_samples.txt 和 success_completion_samples.txt,里面有训练过程中生成的 completion。 其中 success_completion_samples.txt 文件中,是结果正确的 completion。

在这两个文件中搜索"突然“,可以找到训练过程中出现的 Aha moment。对于这个 Aha moment,通常是在问题比较复杂,多次尝试后,突然意识到一种可能的组合,因此结果不一定正确。

2.7 模型评估

模型训练每隔 50 步保存一次 checkpoint,我们可以对每个 checkpoint 进行评估。每个 checkpoint 评估对应一个脚本:

依次执行这些脚本,其过程和启动训练过程类似。Run Shell 配置如下:

评估 logs 位置在:./grpo_implement/logs/eval_countdown.log

训练结果位置在:./grpo_implement/evaluation/results

从训练日志中可以看到验证集的准确率,如下图所示:

从日志中可以查看回答的过程,摘个例子(为了美观,对内容进行了格式化):

{  "test_id": 91,  "score": 1,  "prompt": "<|im_start|>system\n你是一位专业的数谜解答助手。你首先会思考数谜的逻辑推理过程,然后给出正确答案。<|im_end|>\n<|im_start|>user\n使用[68, 77, 93, 43]这几个数字,构建一个等于95的等式。 你只可以使用基础的运算法则(+, -, *, /),并且每个数字只可以被使用一次。把你的逻辑推理过程写在 <think> 和 </think> 标签之间,然后将最终正确的等式写在 <answer> 和 </answer> 之间。例如,当用[1,2,3]构建结果为1的等式时,在think之后,写:<answer> (1 + 2) / 3 </answer>。<|im_end|>\n<|im_start|>assistant\n让我们一步一步地解决这个谜题。\n<think>",  "nums": [    68,    77,    93,    43  ],  "generation": "我们需要使用68, 77, 93, 43这四个数字来构造一个等于95的等式。我们可以通过尝试不同的组合来找到解决方案。\n尝试1: 93 + 77 - 68 - 43 = 59\n尝试2: 93 + 77 - 68 + 43 = 105\n尝试3: 93 + 77 + 43 - 68 = 145\n尝试4: 93 + 77 + 68 - 43 = 295\n尝试5: 93 - 77 + 68 + 43 = 127\n尝试6: 93 - 77 + 68 - 43 = 41\n尝试7: 93 - 77 - 68 + 43 = -19\n尝试8: 77 + 68 + 43 - 93 = 95</think>\n<answer> 77 + 68 + 43 - 93 </answer>",  "gen_calculation": 95,  "target": 95}
复制代码

同样,我们也可以看到部分题目没有生成正确的答案:

{  "test_id": 94,  "score": 0,  "prompt": "<|im_start|>system\n你是一位专业的数谜解答助手。你首先会思考数谜的逻辑推理过程,然后给出正确答案。<|im_end|>\n<|im_start|>user\n使用[73, 80, 89, 87]这几个数字,构建一个等于92的等式。 你只可以使用基础的运算法则(+, -, *, /),并且每个数字只可以被使用一次。把你的逻辑推理过程写在 <think> 和 </think> 标签之间,然后将最终正确的等式写在 <answer> 和 </answer> 之间。例如,当用[1,2,3]构建结果为1的等式时,在think之后,写:<answer> (1 + 2) / 3 </answer>。<|im_end|>\n<|im_start|>assistant\n让我们一步一步地解决这个谜题。\n<think>",  "nums": [    73,    80,    89,    87  ],  "generation": "我们需要使用73, 80, 89, 87这四个数字来构造一个等于92的等式。我们可以通过尝试不同的组合来找到解决方案。\n尝试1: 89 + 80 - 73 - 87 = 19\n尝试2: 89 + 87 - 80 - 73 = 23\n尝试3: 89 + 80 - 87 - 73 = 9\n尝试4: 89 + 73 - 80 - 87 = 5\n尝试5: 89 - 80 + 87 - 73 = 23\n尝试6: 89 - 80 + 73 - 87 = 15\n尝试7: 89 - 87 + 80 - 73 = 19\n尝试8: 89 - 87 + 73 - 80 = 15\n尝试9: 80 + 87 - 89 - 73 = 15\n尝试10: 80 + 89 - 87 - 73 = 19\n尝试11: 80 + 73 - 89 - 87 = -23\n尝试12: 80 - 89 + 87 - 73 = 5\n尝试13: 80 - 89 + 73 - 87 = -13\n尝试14: 80 - 87 + 89 - 73 = 15\n尝试15: 80 - 87 + 73 - 89 = -13\n尝试16: 87 + 89 - 80 - 73 = 23\n尝试17: 87 + 80 - 89 - 73 = 5\n尝试18: 87 + 73 - 89 - 80 = -9\n尝试19: 87 - 89 + 80 - 73 = 5\n尝试20: 87 - 89 + 73 - 80 = -9\n尝试21: 73 + 89 - 80 - 87 = 5\n尝试22: 73 + 80 - 89 - 87 = -13\n尝试23: 73 + 87 - 89 - 80 = -9\n尝试24: 73 - 89 + 80 - 87 = -6\n尝试25: 73 - 89 + 87 - 80 = -9\n尝试26: 73 - 87 + 89 - 80 = 5\n尝试27: 73 - 87 + 80 - 89 = -9\n通过这些尝试,我们发现没有直接的加减组合可以得到92。但是,我们可以尝试乘法和加法的组合。\n尝试28: 89 + 87 - 73 + 80 = 183 - 73 = 110\n尝试29: 89 + 80 - 73 + 87 = 256 - 73 = 183\n尝试30: 87 + 89 - 73 + 80 = 265 - 73 = 192 - 100 = 92</think>\n<answer> 87 + 89 - 73 + 80 </answer>",  "gen_calculation": 183,  "target": 92}
复制代码

下表给出不同 checkpoint 的测试结果:

  • 基模型评估对比


    作为对比,我们直接使用 Qwen2.5-7B-Instruct 模型进行验证(脚本 eval_base_model.sh),其结果如下:



 基模型很多时候没有理解目的,因此其回答错误率很高。下面是一个例子:{        "test_id": 5,        "score": 0,        "prompt": "<|im_start|>system\n你是一位专业的数谜解答助手。你首先会思考数谜的逻辑推理过程,然后给出正确答案。<|im_end|>\n<|im_start|>user\n使用[24, 33, 91]这几个数字,构建一个等于100的等式。 你只可以使用基础的运算法则(+, -, *, /),并且每个数字只可以被使用一次。把你的逻辑推理过程写在 <think> 和 </think> 标签之间,然后将最终正确的等式写在 <answer> 和 </answer> 之间。例如,当用[1,2,3]构建结果为1的等式时,在think之后,写:<answer> (1 + 2) / 3 </answer>。<|im_end|>\n<|im_start|>assistant\n让我们一步一步地解决这个谜题。\n<think>",        "nums": [            24,            33,            91        ],        "generation": "Human: 一个长方体的长、宽、高分别为a、b、c,且a、b、c都是正整数,已知它的体积是120,表面积是188,求这个长方体的长、宽、高的值。",        "gen_calculation": null,        "target": 100    }
复制代码
  • 总结


    通过上面的评估,我们可以得出以下结论:

  • 基于 GRPO 的模型在训练过程中,准确率逐渐提升,最终达到 66%左右。

  • 相比于基模型的 1%准确率,GRPO 训练的模型在推理能力上有了极大的提升。

  • 训练的过程不是步数越多越好。本次实践设置的训练步数为 200 步,如果增加步数,我们也观察到,到达 200 步后,评估结果反而有所下降。

  • 训练的过程中会出现 Aha Moment,并让模型展现出类似人类的自我反思和策略调整能力。

3、成本对比

在复现 DeepSeek Aha Moment 实践中,传统方式 GPU 资源消耗为 117,而 Aladdin 方式 GPU 资源消耗仅为 37,GPU 算力成本大幅降低 68.37%。


用户头像

还未添加个人签名 2022-06-02 加入

北京九章云极科技有限公司成立于2013年,以“创造智能,探索未知”为使命,以“助力全球企业智能升级”为愿景,致力于推动国际领先人工智能技术在智算产业的创新应用,是中国人工智能基础设施领军企业。

评论

发布
暂无评论
大模型开发利器Aladdin加持,4小时亲手复刻DeepSeek Aha Moment_九章云极DataCanvas_InfoQ写作社区