Zhuang's Diary

言之有物,持之以恒

使用 DORA 指标,向管理层展示交付流程的整体效率和稳定性。

一、战略层(DORA Metrics)

指标 描述 目标值
部署频率(Deployment Frequency) 每月部署到生产环境的次数 ≥ 每周一次
变更前置时间(Lead Time for Changes) 从代码提交到生产环境部署的平均时间 ≤ 1周
变更失败率(Change Failure Rate) 生产环境变更导致事故的比例 ≤ 5%
平均恢复时间(Mean Time to Restore,MTTR) 故障发生到修复完成的平均时长 ≤ 2小时

二、执行层(精细化指标体系)

(一)研发阶段(Development)

指标 描述 目标值
单元测试覆盖率 单元测试代码覆盖率 ≥80%
代码审查一次通过率 首次通过代码审查比例 ≥85%
技术债务 SonarQube技术债务评分 ≤ 技术债务比例15%
敏捷迭代按时交付率 Sprint内任务完成率 ≥90%

(二)部署阶段(Deployment)

指标 描述 目标值
首次上线成功率 一次性成功部署比例 ≥95%
部署自动化覆盖率 CI/CD管道自动化程度 ≥90%
平均部署周期 提交到上线部署的周期 ≤2天

(三)运维阶段(Operation)

指标 描述 目标值
系统可用率 系统正常运行的比例 ≥99.95%
平均故障间隔(MTBF) 系统两次事故之间的平均时间 ≥30天
自动化监控覆盖率 关键系统自动监控覆盖程度 ≥95%
服务响应延迟 应用的99%响应延迟 ≤500ms

(四)事故管理(Incident Management)

指标 描述 目标值
事故响应时间 事故发生到首次响应的平均时间 ≤15分钟
事故关闭时间(MTTR) 从事故发生到关闭的平均时间 ≤2小时
一级事故数量 严重事故(P1级)发生次数 每月≤2次
RCA完成率 重大事故根因分析完成比例 100%

(五)变更管理(Change Management)

指标 描述 目标值
变更回退率 需要回滚的变更比例 ≤5%
紧急变更比例 紧急变更占全部变更的比例 ≤10%
变更审批效率 变更申请到审批完成时间 ≤1个工作日

(六)系统淘汰管理(Demise & Decommission)

指标 描述 目标值
系统及时退役率 按计划淘汰系统的及时率 100%
淘汰成本控制 实际退役成本与计划的差异比例 ≤10%

三、实施与治理模式

0. CIO 应该参加critical级别的incident现场解决会议

1. 报告与回顾机制

  • 每季度向战略层汇报DORA指标,审视整体战略目标达成情况。
  • 每月运营回顾精细化指标,针对执行偏差提出整改。
  • 每周团队自查具体指标,持续改进。

    2. 技术支撑平台

  • DevOps平台自动收集开发、测试、部署数据。
  • ITSM(如ServiceNow)跟踪事故、变更数据。
  • APM(如Prometheus/Grafana)实时监控运维指标。
  • 数据可视化平台(如Power BI)集中展现指标。

    3. 组织与激励

  • 指标与团队绩效激励直接关联,优秀团队给予奖励。
  • 存在明显问题的团队,组织针对性改进辅导。

    四、预期效果

  • 保持开发与运维的效率、稳定性双平衡。
  • 确保监管合规性,同时保证技术与业务的快速响应能力。
  • 促进组织持续改善,实现稳定高效的整体技术管理水平。

https://dora.dev/capabilities/

结论总结:

模型名称 SFTTrainer - Supervised Fine-Tuning Trainer - 监督式微调训练器 DPOTrainer - Direct Preference Optimization Trainer - 直接偏好优化训练器 GRPOTrainer - Generative Reward Policy Optimization Trainer - 生成式奖励策略优化训练器
训练目标 模仿训练数据 对齐人类偏好 最大化奖励函数
数据需求 输入-输出数据对。数据形式是 “指令 -> 期望输出” 的对应关系 偏好数据。”指令 -> (偏好输出, 非偏好输出)” 的成对比较 奖励信号。数据形式是一个数值奖励,用于评价模型在环境中的行为
核心算法 监督学习 (交叉熵损失) 直接偏好优化 (DPO 损失) 强化学习 (PPO 算法)
优势 简单易用, 高效, 适用多种任务 更符合人类偏好, 避免奖励函数设计难题, 训练稳定, 对奖励函数偏差更鲁棒 直接优化目标指标, 可学习复杂策略, 适用于与环境交互任务, 精细行为控制
劣势 可能放大数据偏差, 难处理复杂偏好, 可能过拟合 需要偏好数据, 对偏好数据质量敏感, 可能牺牲部分生成能力 训练复杂不稳定, 奖励函数设计困难, 计算成本高, 可能奖励函数偏移
复杂度
应用场景示例 - 内容生成: 自动生成产品描述、新闻稿、社交媒体文案等。
- 指令跟随: 简单的问答系统、文档摘要、代码生成等。
- 数据增强: 生成特定格式或风格的合成数据,例如特定风格的文本或代码。
- 对话系统: 训练客服机器人、聊天机器人,使其回复更礼貌、更人性化、更符合用户期望。
- 内容审核: 训练模型判断文本是否安全、无害、符合道德标准。
- 偏好排序: 训练模型根据用户偏好对多个选项进行排序或选择 (例如,排序新闻摘要、推荐商品)。
- 游戏 AI: 训练游戏 Bot,在游戏中获得高分或战胜对手。
- 交易策略: 训练交易机器人,使其在股票市场或加密货币市场中最大化收益。
- 机器人控制: 训练机器人完成复杂任务,例如导航、物体抓取等,最大化任务完成效率或成功率。
- 复杂对话策略: 训练对话系统进行多轮对话,最终达成用户目标 (例如,预定餐厅、解决复杂问题)。

1. 输入-输出数据对 (Input-Output Data Pairs) - SFTTrainer 使用

这种数据形式是最直接的,用于监督式微调 (SFTTrainer)。 每个数据样本都包含一个 输入 (Input) 和一个期望的 输出 (Output)。

应用场景例子:指令跟随 (Instruction Following) - 简单的问答任务
示例:

  • 问答系统: “问题 -> 答案”
  • 翻译任务: “原文 -> 译文”
  • 摘要生成: “文章 -> 摘要”
  • 样例数据格式 (JSON 格式示例):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [
    {
    "instruction": "法国的首都是哪里?",
    "output": "法国的首都是巴黎。"
    },
    {
    "instruction": "请写一个关于夏天的简短故事。",
    "output": "阳光洒在金色的沙滩上,海风轻轻吹拂,孩子们在海边嬉戏,冰淇淋融化在甜甜的笑容里,夏天真美好。"
    },
    {
    "instruction": "将这句话翻译成英文:你好世界。",
    "output": "Hello world."
    }
    // ... 更多数据样本
    ]
    解释:
  • “instruction” (输入): 代表用户给模型的指令或问题。
  • “output” (输出): 代表模型应该生成的期望回复或答案。
  • 数据目标: SFTTrainer 的目标是让模型学习将 “instruction” 映射到 “output”,模仿训练数据中的这种对应关系。

应用场景例子:内容生成 (Content Generation) - 生成产品描述

  • 样例数据格式 (JSON 格式示例):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [
    {
    "input": {
    "product_name": "智能咖啡机",
    "features": ["一键操作", "多种咖啡模式", "可预约", "自动清洗"],
    "materials": ["不锈钢", "耐热玻璃"]
    },
    "output": "这款智能咖啡机让您在家也能轻松享受咖啡馆级的美味。一键操作,多种咖啡模式随心选择,更有预约功能,让您早晨醒来就能品尝到香浓咖啡。采用不锈钢和耐热玻璃材质,坚固耐用,并具备自动清洗功能,省心省力。"
    },
    // ... 更多数据样本
    ]
    解释:
  • “input” (输入): 可以是更结构化的信息,例如产品的特征、材质等。
  • “output” (输出): 是基于输入信息生成的期望产品描述文本。

2. 偏好数据 (Pairwise Ranking) - DPOTrainer 使用

这种数据形式用于直接偏好优化 (DPOTrainer)。 对于同一个输入,我们提供两个模型生成的输出,并标注哪个输出更符合偏好。

应用场景例子:对话系统 (Chatbot) - 提升回复质量和偏好

  • 样例数据格式 (JSON 格式示例):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    [
    {
    "instruction": "今天天气怎么样?",
    "chosen": "今天天气晴朗,阳光明媚,非常适合户外活动。",
    "rejected": "天气还行。"
    },
    {
    "instruction": "请问你能推荐一家附近的意大利餐厅吗?",
    "chosen": "当然,附近有一家评价很高的意大利餐厅,名叫“托斯卡纳阳光”,他们家的披萨和意面非常受欢迎,地址是… [地址信息] …,您要我帮您查询一下电话或者预定吗?",
    "rejected": "我推荐一家意大利餐厅。"
    },
    // ... 更多数据样本
    ]
  • 解释:
    • “instruction” (输入): 用户的问题或指令。
    • “chosen” (偏好输出): 被认为更好或更符合偏好的回复。例如,更详细、更礼貌、更乐于助人的回复。
    • “rejected” (非偏好输出): 被认为相对较差或不太符合偏好的回复。例如,更简短、更生硬、信息量较少的回复。
    • 数据目标: DPOTrainer 学习到,对于相同的 “instruction”,模型应该倾向于生成类似 “chosen” 这样的回复,而不是 “rejected” 这样的回复。偏好可以是基于礼貌程度、信息量、是否乐于助人、是否符合特定价值观等等。

3. 奖励信号 (Reward Signal) - GRPOTrainer 使用

奖励信号是一个数值,用于评价模型在特定环境或任务中生成的输出质量。 GRPOTrainer 使用强化学习方法,目标是最大化模型获得的累积奖励。

应用场景例子:游戏 AI (Game AI) - 训练游戏 Bot 下围棋

  • 奖励函数示例 (Python 伪代码):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    def reward_function(game_state, action):
    """
    定义围棋游戏中的奖励函数.

    Args:
    game_state: 当前的棋局状态.
    action: 模型采取的落子动作.

    Returns:
    reward: 一个数值奖励信号.
    """

    if is_illegal_move(game_state, action): # 落子是否为非法
    reward = -10 # 非法落子,负奖励,惩罚模型
    elif is_capture_opponent_piece(game_state, action): # 是否吃掉对方棋子
    reward = +5 # 吃掉对方棋子,正奖励
    elif is_win(game_state): # 是否赢得游戏
    reward = +100 # 赢得游戏,巨大正奖励
    elif is_lose(game_state): # 是否输掉游戏
    reward = -50 # 输掉游戏,负奖励
    else:
    reward = -0.1 # 常规落子,轻微负奖励 (鼓励尽快结束游戏,避免无意义的步骤 - 可根据实际情况调整)

    return reward
  • 解释:
    • 奖励函数: reward_function 就是一个奖励函数,它根据当前的游戏状态和模型采取的动作,计算出一个数值奖励。
    • 奖励信号: 每次模型在游戏中执行一个动作后,环境 (围棋游戏) 会根据 reward_function 计算出一个奖励值,并将这个奖励值反馈给模型。
    • 数据目标: GRPOTrainer 通过不断尝试不同的动作,并根据获得的奖励信号学习,目标是找到一个策略 (即模型的参数),使得在围棋游戏中能够获得尽可能高的累积奖励 (例如,最终赢得游戏)。

部署要占用多少显存

以运行精度为 INT8 的大模型为例,这种精度的参数,一个参数需要占用一个字节。
$1B参数模型 = 10亿参数 * 每个参数占用1Byte$
$1G显存 = 102410241024Byte$
也就是说
INT8 精度类型:1B 参数需要约 1G 显存。

dtype 1B模型需要占用的显存
float32 4G
fp16/bf16 2G
int8 1G
int4 0.5G
然后就可以快速计算各个类型精度的大模型需要多少显存,例如 f16 的 70B 参数大模型,就需要“精度膨胀系数” 2*70=140G显存。

训练要占用多少显存

这里还有另外一个在线的网页工具:https://huggingface.co/spaces/hf-accelerate/model-memory-usage

模型包括: DeepSeek R1 (671B),DeepSeek R1 Distill Qwen 7B, 14B, 32B, 以及 DeepSeek R1 Distill Llama 8B, 70B 这些模型,

  1. 假设在并发 3 个用户的情况下运行这些模型所需的资源?
  2. 关于 DeepSeek R1 系列模型在不同数据量下进行微调(并非全量训练),并在一天内完成微调所需的硬件资源。分别在 1K,1M,1GB,1T 数据量下训练这些模型所需的资源和训练时长。

根据您提供的信息,以及之前的分析,以下是关于 DeepSeek R1 系列模型微调硬件资源需求的全面分析,并以表格形式呈现:

DeepSeek R1 模型微调硬件资源需求总表 (单日内完成)

采用BF16(2字节/参数)的情况下,考虑到 Unsloth 主要优化 LoRA 微调,并且更适用于单 GPU 或少量 GPU 场景,基于 Unsloth 优化 LoRA 微调的假设,重新评估 DeepSeek R1 系列模型在中小数据量 (1K, 1M, 1G, 10G) 下的硬件资源需求。 对于超大数据量 (100G) 和超大模型 (DeepSeek-R1-671B),我仍然保留 ZeRO-3 优化。

模型 数据size GPU 配置 (显存需求) CPU 核心数 内存 存储 (SSD/NVMe) 网络带宽 关键配置说明
DeepSeek-R1-671B BF16 1M 16×A100 80G 64核 512GB 2TB 25Gbps RDMA 模型并行 (TP=16) + 数据并行 (DP=2)
1G 64×A100 80G 256核 1TB 5TB 50Gbps RDMA TP=8 + DP=8 + ZeRO-3
10G 128×A100 80G 512核 2TB 10TB 100Gbps RDMA TP=8 + DP=16 + ZeRO-3
100G 192×A100 80G 768核 4TB 15TB 150Gbps RDMA TP=8 + DP=24 + ZeRO-3
Distill-Qwen-7B 4-bit 1M 1×A10G 24G (Unsloth) 8核 64GB 500GB 1Gbps 单卡 4-bit LoRA 微调 (Unsloth)
1G 2×A10G 24G (Unsloth) 16核 128GB 1TB 5Gbps DP=2 + LoRA 微调 (Unsloth)
10G 4×A10G 24G (Unsloth) 32核 256GB 2TB 5Gbps DP=4 + LoRA 微调 (Unsloth)
100G 8×A10G 24G (Unsloth) 64核 512GB 3TB 10Gbps DP=8 + LoRA 微调 (Unsloth)
Distill-Qwen-14B 4-bit 1M 1×A100 40G (Unsloth) 16核 128GB 1TB 5Gbps 单卡 LoRA 微调 (Unsloth)
1G 4×A100 40G (Unsloth) 32核 256GB 2TB 10Gbps DP=4 + LoRA 微调 (Unsloth)
10G 8×A100 40G (Unsloth) 64核 512GB 3TB 10Gbps DP=8 + LoRA 微调 (Unsloth)
100G 16×A100 40G (Unsloth) 128核 1TB 5TB 25Gbps DP=16 + LoRA 微调 (Unsloth)
Distill-Qwen-32B BF16 1G 4×A100 80G (Unsloth) 64核 512GB 2TB 10Gbps TP=4 + DP=2
10G 8×A100 80G (Unsloth) 128核 1TB 3TB 25Gbps DP=8 + LoRA 微调 (Unsloth)
100G 32×A100 80G 256核 2TB 10TB 50Gbps RDMA TP=4 + DP=8 + ZeRO-3
Distill-Llama-8B 4-bit 1M 1×A10G 24G (Unsloth) 8核 64GB 500GB 1Gbps 单卡 LoRA 微调 (Unsloth)
1G 2×A10G 24G (Unsloth) 16核 128GB 1TB 5Gbps DP=2 + LoRA 微调 (Unsloth)
10G 4×A10G 24G (Unsloth) 32核 256GB 2TB 5Gbps DP=4 + LoRA 微调 (Unsloth)
100G 8×A10G 24G (Unsloth) 48核 384GB 3TB 10Gbps DP=8 + LoRA 微调 (Unsloth)
Distill-Llama-70B BF16 1M 8×A100 80G 64核 512GB 2TB 25Gbps RDMA TP=4 + DP=2 (ZeRO-3 for 70B still recommended)
1G 32×A100 80G 128核 1TB 5TB 25Gbps RDMA TP=4 + DP=8 (ZeRO-3 for 70B still recommended)
10G 64×A100 80G 256核 2TB 10TB 50Gbps RDMA TP=8 + DP=8 + ZeRO-3
100G 128×A100 80G 512核 4TB 15TB 100Gbps RDMA TP=8 + DP=16 + ZeRO-3

GPU 配置 (显存需求): 指完成微调任务所需的 GPU 型号和数量,以及总显存需求。例如 “16×A100 80G” 表示需要 16 张 80GB 显存的 A100 GPU。
CPU 核心数: 训练任务所需的 CPU 核心数量,主要用于数据预处理和模型管理。
内存: 系统内存需求,用于数据缓存、模型加载和训练过程中的临时数据存储。
存储 (SSD/NVMe): 高速固态硬盘容量需求,用于存储训练数据、模型参数和中间结果。NVMe SSD 提供更快的读写速度,适用于大数据量训练。
网络带宽: 多 GPU 训练时所需的网络带宽,用于 GPU 之间的数据通信。RDMA (Remote Direct Memory Access) 网络提供更低的延迟和更高的带宽,适用于大规模分布式训练。
关键配置说明: 简要描述了针对不同模型和数据量所采用的关键并行策略和优化技术,例如模型并行 (TP)、数据并行 (DP)、ZeRO-3 优化和梯度累积等。
预估并发 3 用户显存需求: 粗略估计为模型参数显存占用的 3 倍或更高。因为并发用户需要模型的多份副本或共享模型但需要额外的上下文缓存等。实际情况可能更复杂。

  1. Unsloth 对资源需求的影响:
    • 中小模型 (Distill-Qwen-7B/14B/32B, Distill-Llama-8B) 和中小数据量 (1K - 100G): 使用 Unsloth 库进行 LoRA 微调,可以显著降低 GPU 资源需求。例如,Distill-Qwen-7B 在 1K 数据量下,单张 A10G 24G 即可完成微调;即使在 100G 数据量下,也仅需 8 张 A10G 24G GPU。
    • 超大模型 (DeepSeek-R1-671B) 和大数据量 (100G): 对于这些极端情况,Unsloth 的优化可能不足以完全解决显存瓶颈。因此,表格中仍然保留了 ZeRO-3 优化,并结合 Unsloth 的 FlashAttention-2 优化,以期达到最佳的性能和资源效率。
  2. LoRA 微调的优势:
    • 表格中所有基于 Unsloth 的配置方案都假设使用 LoRA 微调。LoRA 本身就是一种参数高效微调方法,可以显著减少需要训练的参数量,从而降低显存需求和加速训练。
    • Unsloth 进一步优化了 LoRA 的实现,使其在速度和显存效率方面更具优势。
  3. FlashAttention-2 的加速作用:
    • Unsloth 集成的 FlashAttention-2 可以显著加速训练过程,这有助于在 “日内完成微调” 的目标下,使用更少的 GPU 资源。

关键分析逻辑

  1. 模型参数量 vs. GPU 显存:
    • 参数高效微调 (如 LoRA) 显著降低了显存需求,公式估算如下: $$ \text{显存} \approx \text{模型参数} \times (2\ \text{bytes} \times \text{激活系数}) + \text{优化器状态} $$ 其中,激活系数在 LoRA 场景下约为 0.1-0.3,优化器状态通过 ZeRO-3 等技术可以大幅减少。
  2. 数据量 vs. 训练并行度:
    • 小数据量 (1K, 1M): 资源需求主要由模型大小决定。较小的 Distill 模型甚至可以在单张消费级 GPU 上完成微调。
    • 大数据量 (1G, 1T): 数据并行成为关键。需要增加 GPU 数量以提高数据吞吐量,并配合高速网络 (如 RDMA) 保证并行效率。
  3. 训练时长与硬件资源:
    • 表格中的配置旨在将微调时间压缩到 一天以内。更快的训练速度通常需要更多的 GPU 资源并行计算。
    • 实际训练时间还会受到 模型结构超参数设置优化算法 等多种因素影响。上述表格提供的是一个 硬件配置参考,实际部署时可能需要根据具体情况进行调整。
  4. 优化技术:
    • 混合精度训练 (BF16/FP16): 降低显存占用和计算复杂度,加速训练过程。
    • 梯度检查点: 通过计算换取显存,进一步降低显存峰值。
    • ZeRO-3: 将优化器状态、梯度和模型参数分片到多张 GPU 上,极大地减少单卡显存需求,尤其适用于超大模型 (如 671B)。
    • 模型并行 (Tensor Parallelism, TP): 将模型按层或张量切分到多张 GPU 上,降低单卡显存压力,适用于超大模型。
    • 数据并行 (Data Parallelism, DP): 将数据分片到多张 GPU 上,每张 GPU 训练模型完整副本的一部分数据,提高数据吞吐量,适用于大数据量训练。
    • 梯度累积: 在显存受限时,通过多次小批量梯度计算累积梯度,模拟大批量训练的效果。
  5. 网络与存储:
    • RDMA 网络: 对于大规模分布式训练 (尤其是模型并行和数据并行结合),RDMA 网络可以显著降低 GPU 间通信延迟,提高并行效率。
    • 高速 SSD/NVMe 存储: 大数据量训练时,高速存储可以加速数据加载,避免 I/O 瓶颈。

请注意:

  • 上述表格提供的是 估算和建议,实际资源需求可能因具体任务和实现细节有所不同。
  • 在实际部署时,建议 从小规模配置开始测试,并根据训练速度和资源利用率逐步调整硬件配置。
  • 云服务平台通常提供多种 GPU 实例和高速网络配置,可以根据表格中的建议选择合适的云资源进行模型微调。

DeepSeek-R1的实施步骤

DeepSeek-R1本身就是开源的,HuggingFace Open R1 项目李飞飞团队s1项目simpleRL-reason 在部分复现DeepSeek R1,还有 TinyZero 项目在复现DeepSeek R1-Zero,又是为何?
根据 DeepSeek-R1 的技术报告,分3个步骤完成这个项目:

  • 第1步:用 DeepSeek-R1 蒸馏高质量语料库,来复制R1-Distill模型。
  • 第2步:复制 DeepSeek (V3) 用来构建R1-Zero的纯强化学习(RL)pipeline。这可能涉及为数学、推理和代码整理新的大规模数据集。
  • 第3步:通过多阶段训练,从基础模型过渡到RL版本。

结合DeepSeek的官方技术报告来看,也就是说,Open R1项目首先要实现的,是用R1数据蒸馏小模型,看看效果是不是像DeepSeek说的那么好:

DeepSeek-R1的实施效果

DeepSeek开源了6个用R1蒸馏的小模型,其中蒸馏版Qwen-1.5甚至能在部分任务上超过GPT-4o。

接下来,就是按照DeepSeek所说,不用SFT,单纯依靠RL调教出R1-Zero,在R1-Zero的基础上复刻出性能逼近o1的R1模型。

其中R1技术报告讲到,DeepSeek-R1训练过程中引入了一个多阶段训练流程,具体包括以下4个阶段:

  1. 冷启动
    用数千个长思维链(CoT)样本对基础模型进行监督微调(SFT),为模型提供初始的推理能力。
  2. 面向推理的强化学习
    在第一个SFT阶段的基础之上,用和训练R1-Zero相同的大规模强化学习方法,进一步提升模型的推理能力,特别是应对编程、数学、科学和逻辑推理任务的能力。
  3. 拒绝采样的监督微调
    再次使用监督微调(SFT),提升模型的非推理能力,如事实知识、对话能力等。
  4. 针对所有场景的强化学习
    这次强化学习的重点是让模型行为与人类偏好保持一致,提升模型的可用性和安全性。

    Open R1做了什么?

    目前,在open-r1 GitHub仓库中,已经可以看到这几个文件:
  • GRPO(Grouped Relative Policy Optimization)实现,grpo.py: trains a model with GRPO on a given dataset.
    在 Open R1 发布后,GRPO已整合至TRL最新版本(v0.14,Jan 30, 2025)。该整合方案支持使用单个或多个奖励函数模型进行模型训练。GRPO 实现方案深度集成了 DeepSpeed ZeRO 1/2/3 分布式训练框架以实现多 GPU 扩展,并采用 vLLM 加速生成过程——这正是在线训练方法的主要性能瓶颈。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    from datasets import load_dataset
    from trl import GRPOConfig, GRPOTrainer

    dataset = load_dataset("trl-lib/tldr", split="train")

    # Dummy reward: rewards completions that are close to 20 characters
    def reward_len(completions, **kwargs):
    return [-abs(20 - len(completion)) for completion in completions]

    training_args = GRPOConfig(output_dir="Qwen2-0.5B-GRPO", logging_steps=10)
    trainer = GRPOTrainer(
    model="Qwen/Qwen2-0.5B-Instruct",
    reward_funcs=reward_len,
    args=training_args,
    train_dataset=dataset,
    )
    trainer.train()
    # (Feb 2nd)仍存在显存占用过高的问题,我们正在通过性能剖析进行优化改进。
  • 合成数据生成器,generate.py: generates synthetic data from a model using Distilabel.
    R1 技术报告中最引人注目的发现之一是:主模型可用于生成合成推理轨迹,而基于该数据集微调的较小模型可获得与主模型相近的性能提升。因此Open R1自然希望复现该合成推理数据集,使社区能够在其他模型上进行微调实验。
    面对 R1 这类超大模型,核心挑战在于高效扩展生成规模。Open R1花费一周时间尝试了多种配置方案:该模型可部署在 2 个 8xH100 节点(16 块 H100 GPU)上,我们最初基于此配置使用 vLLM 作为推理服务器。但很快发现该方案存在性能瓶颈:由于 GPU 的 KV 缓存快速耗尽,吞吐量未达最优且仅支持 8 路并行请求。当缓存耗尽时,占用大量缓存资源的请求会被抢占;若配置为PreemptionMode.RECOMPUTE模式,这些请求将在显存释放后重新调度。为此我们切换至 4x8xH100 节点配置(共 32 块 H100 GPU)。该方案为 32 路并行请求提供了充足的显存余量,基本避免了因 100% 缓存占用导致的请求重新调度问题。初始阶段我们采用批量请求查询 vLLM 服务器,但很快发现批次中的长尾样本会导致GPU利用率波动——新批次需等待前一批次最后一个样本完成后才能开始处理。将批量推理切换为流式处理后,GPU利用率显著稳定。

    该优化仅需修改vLLM服务器的请求发送代码。批量推理代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    # send requests in batches of 500
    for batch in batch_generator(dataset, bs=500):
    active_tasks = []
    for row in batch:
    task = asyncio.create_task(send_requests(row))
    active_tasks.add(task)
    if active_tasks:
    await asyncio.gather(*active_tasks)

    流式请求的新版代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    active_tasks = []
    for row in dataset:
    # keep the total active requests under 500
    while len(active_tasks) >= 500:
    done, active_tasks = await asyncio.wait(
    active_tasks,
    return_when=asyncio.FIRST_COMPLETED
    )

    task = asyncio.create_task(send_requests(row))
    active_tasks.add(task)

    # wait for all remaining tasks to complete
    if active_tasks:
    await asyncio.gather(*active_tasks)
    # Open R1当前的生成速率已趋于稳定,但对于长查询被抢占时是否采用CPU 缓存策略仍需进一步探索。
  • 实施监督微调训练代码,sft.py: performs a simple SFT of a model on a dataset.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # Train via command line
    accelerate launch --config_file=recipes/accelerate_configs/zero3.yaml src/open_r1/sft.py \
    --model_name_or_path Qwen/Qwen2.5-1.5B-Instruct \
    --dataset_name HuggingFaceH4/Bespoke-Stratos-17k \
    --learning_rate 2.0e-5 \
    --num_train_epochs 1 \
    --packing \
    --max_seq_length 4096 \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 8 \
    --gradient_checkpointing \
    --bf16 \
    --output_dir data/Qwen2.5-1.5B-Open-R1-Distill

    # Train via YAML config
    accelerate launch --config_file recipes/accelerate_configs/zero3.yaml src/openr1/sft.py \
    recipes/Qwen/Qwen2.5-1.5B-Instruct/sft/config_demo.yaml
  • 训练和评估代码,evaluate.py: evaluates a model on the R1 benchmarks.

数据集

社区在多个与R1相关的数据集项目上非常活跃,以下是一些亮点:

  • bespokelabs/Bespoke-Stratos-17k:这是对 Berkeley Sky-T1 数据管线的复制,使用 DeepSeek-R1 创建一个包含问题、推理轨迹和答案的数据集。随后,这些数据被用于通过类似于 R1 论文中的蒸馏方法,微调 7B 和 32B 的 Qwen 模型。
  • open-thoughts/OpenThoughts-114k:一个“开放的合成推理数据集,包含 114k 个高质量样本,涵盖数学、科学、代码和谜题”。这是 Open Thoughts 项目的一部分。
  • cognitivecomputations/dolphin-r1:一个包含 80 万样本的数据集,样本来自 DeepSeek-R1、Gemini flash 以及来自 DolphinChat 的 20 万样本,目的是帮助训练 R1 风格的模型。
  • ServiceNow-AI/R1-Distill-SFT:目前有 17,000 个样本,这是 ServiceNow 语言模型实验室为支持 Open-R1 工作而创建的数据集。
  • NovaSky-AI/Sky-T1_data_17k:用于训练 Sky-T1-32B-Preview 的 17k 训练数据。最终数据包含来自 APPs 和 TACO 的 5k 编码数据,以及来自 NuminaMATH 数据集的 AIME、MATH 和 Olympiads 子集的 10k 数学数据。此外,我们还维护了来自 STILL-2 的 1k 科学和拼图数据。使用该数据集训练的模型成本不到 450 美元。
  • Magpie-Align/Magpie-Reasoning-V2-250K-CoT-Deepseek-R1-Llama-70B:这个数据集扩展了 Magpie 和方法,通过生成没有起始提示的指令数据来包括推理过程。指令由 Llama 3.1 70B Instruct 和 Llama 3.3 70B Instruct 生成,响应则由 DeepSeek-R1-Distill-Llama-70B 生成。

总结

  1. SFT后,进步显著,怎么做到的?
    一是微调用的训练数据起到了一定作用;二是强制让模型延长思考时间(test time scaling),具体做法叫做(Budget Forcing)预算强制,也就是强制限制模型使用最大或最小 tokens 进行推理,以此控制模型的思考长度。
    为了尽可能延长模型的思考,他们将模型的思考放在标签内,当结束后,以 final answer 给出答案,同时,当 LLM 即将停止思考时,会强制输出 Wait 来迫使模型继续思考,通过这样的方式,模型会进入反思,并可能会发现自己的错误。
    推理时插入的“Wait”,也许会像当初的 Step by Step 一样,成为一个魔法 token。“这或许就是古人‘三思而后行’的哲学吧!”
  2. R1 训练的步骤总结:
    1)精心选择若干条(如 8000 条)高质量的数据,
    2)通过让 Gemini/DeepSeek V3 补充完善思维链COT之后作为数据集,
    3)以开源的大模型(如 Qwen2.5-32B,Llama 3.1)为基座微调出结果(如 R1)。
    4)最后,在模型输出时,用(Budget Forcing)预算强制方法强行拉长模型的思考时长和输出 token,结果发现其在特定测试集上进步显著。

一、关于DeepSeek公司及其大模型

1.1 公司概况

DeepSeek 2023年7月成立于杭州,是幻方量化旗下的子公司,全称是杭州深度求索人工智能基础技术研究有限公司。”成立时间才一年多”、”最近推出的V3已经能和OpenAI的4o媲美”、”训练成本不到600W美元”、”API定价仅是国内其他头部厂商几十分之一”、”APP已经在中美APP store登上免费应用榜首”;

以上是最近关于DeepSeek的一些新闻热点信息,下面我们从官网看下:
DeepSeek近半年相继推出了3个主要的大模型版本,分别是DeepSeek V2.5、DeepSeek V3、DeepSeek-R1(无一例外的都是用了MOE架构)。在这之前还推出了DeepSeek-VL、DeepSeek Coder、DeepSeek Math。

1.2 模型能力

DeepSeek模型已经对标国内Qwen、海外Llama、GPT 4o,从公布的榜单评测上看:DeepSeek-V3 在开源模型中位列榜首,与世界上最先进的闭源模型不分伯仲。

1.3训推成本

推理成本(API报价):百万Token输入价格能达到1元。


训练成本:从技术报告中看DeepSeek用的是H800的GPU做的训练,而且只有2千张左右的H800,整个V3的正式训练成本不超过600W美元。

1、预训练阶段,每万亿的Token 训练V3使用 2048 个H800GPU集群,只需要 180K 个H800 GPU小时,大概 3.7 天(180000/2048/24)
2、整个预训练总耗时 2664K GPU小时(不到2个月),加上 上下文扩展和后训练,总耗时大概2788KGPU耗时。
3、按照 H800 每小时2美元租赁,总的训练成本不超过600W美元

这么低的推理和训练成本不由引出以下的问题:

  • 模型采用了什么样的网络架构?
  • 训练的精度、框架和并行策略是怎样的?
  • 模型的部署和优化方案是怎样的?
  • 在硬件层的计算和通信上做了什么优化?

二、DeepSeek训推核心技术

2.1 DeepSeek-V3模型网络架构

1) DeepSeekV3 整体预训练用了14.8万亿的高质量Token,2) 并且在后期做了SFT和RL,模型参数量达到 671B,但是每个Token仅激活37B参数。为了做到高效的推理和训练,3) DeepSeekV3自研了MLA注意力机制和无辅助损失负载均衡策略的MoE架构。

从技术报告中看出,是经典的Transformer架构,比较亮眼的就是前馈网络使用的DeepSeekMoE架构、Attention机制使用MLA架构,其实这两个在DeepSeekV2模型已经被验证使用过。
与DeepSeek-V2相比,V3额外引入了一种无辅助损失的负载均衡策略,用于DeepSeekMoE,以减轻因需要保证Expert负载均衡而导致的性能下降。

2.1.1 DeepSeekMoE

第一个将MoE架构引入Transformer网络的就是GShard架构了,与传统大模型架构相比,MoE架构在数据流转过程中集成了一个专家网络层。
可以看出传统的MoE基本两部分组成:Gating门控网络、稀疏MoE层;

  • 稀疏 MoE 层: 这些层代替了传统 Transformer 模型中的前馈网络 (FFN) 层。MoE 层包含若干“专家”(例如 8 个),每个专家本身是一个独立的神经网络。在实际应用中,这些专家通常是前馈网络 (FFN),但它们也可以是更复杂的网络结构,甚至可以是 MoE 层本身,从而形成层级式的 MoE 结构。
  • 门控网络或路由: 这个部分用于决定哪些Token被发送到哪个专家。Token的路由方式是 MoE 使用中的一个关键点,因为路由器由学习的参数组成,并且与网络的其他部分一同进行预训练。


和传统的MoE架构相比,DeepSeekMoE使用更细粒度的专家,并将一些专家隔离为共享专家,减少专家间的知识冗余


门控网络路由策略:TopK表示第t个Token和所有路由专家计算出的亲和力分数中K个最高分数的集合,在DeepSeekV3中,使用sigmoid函数计算亲和力分数,然后在所有选择的亲和力分数中应用归一化来生成门控值。
通常在MoE模型的训练过程中,不同专家因为路由策略的因素会导致接收的训练数据分布不均,比如所有的Token都被发送到只有少数几个受欢迎的专家,那么有些专家就可能没有被训练到。
业界通用的解决方案就是引入辅助损失,但是,有时候过大的辅助损失会损害模型性能。
为了在负载均衡和模型性能之间取得更好的平衡,DeepSeek开创了一种无辅助损失的负载均衡策略:为每个专家引入一个偏差项 bi,并将其添加到相应的亲和力分数 Si,t 中以确定top-K路由,具体来说:如果其对应的专家过载,我们将偏差项减少γ;如果其对应的专家负载不足,我们将偏差项增加γ,其中γ是一个称为偏差更新速度的超参数。

门控网络本质上就是一个softmax叠加一个分类网络,那么辅助loss往往就是添加一个惩罚项,对输出过大的 logits 进行惩罚,鼓励模型生成更加适度的 logits 值,防止模型生成过于极端的输出。

2.1.2 MLA 多头潜在注意力

大模型推理过程KV Cache机制一般是限制推理效率的一大瓶颈,而标准的Transformer 架构里面的MHA架构会产出非常多的KV Cache,为了减少对应的KV Cache业界实践过很多方案,例如PagedAttention、多查询注意力(MQA)和分组查询注意力(GQA),但是性能相比原生的MHA有一定差距。

DeepSeek-V2,提出一种创新的注意力机制:多头潜在注意力(MLA)。
相比MQA的KV共用和GQA的KV分组,MLA的核心是注意力键和值的低秩联合压缩,以减少推理过程中的键值(KV)缓存。相比MHA具有更好的性能,但需要的 KV 缓存量要少得多。

低秩矩阵是指其秩(rank)远小于其行数和列数的矩阵。
假设我们有一个矩阵,其实际结构允许它被分解为两个较小的矩阵的乘积。这种情况通常意味着原矩阵是低秩的。
假设我们有一个4×5的矩阵A,这个矩阵可以通过两个更小的矩阵的乘积来表示,比如一个4×2的矩阵B和一个2×5的矩阵C。这意味着原始矩阵A的信息可以通过这两个较小的矩阵来捕捉,表明A是一个低秩矩阵。

低秩压缩计算核心过程:



这里的 ht 表示第 t 个Token的输入,WDKV 表示KV的向下投影矩阵,将 ht 做降维压缩表示,实际得到 cKVt 就是要缓存的KV压缩隐向量;WUK和WUV是向上做升维的投影矩阵,将Token的压缩隐向量cKVt复原为原始KV矩阵;
MLA 模块架构图如下:

2.2 训练推理核心技术

2.2.1 训练框架HAI-LLM

DeepSeek-V3在一个配备了2048个NVIDIA H800 GPU的集群上进行训练,使用的是自研的HAI-LLM框架,框架实现了四种并行训练方式:ZeRO 支持的数据并行、流水线并行、张量切片模型并行和序列并行。  
这种并行能力支持不同工作负载的需求,可以支持数万亿规模的超大模型并扩展到数千个 GPU,同时还自研了一些配套的高性能算子haiscale,可以帮助 HAI-LLM 极大优化大模型训练的显存效率和计算效率。

2.2.2 核心算法DualPipe-创新流水线并行算法

i.通信计算重叠优化
DeepSeek-V3应用了16路流水线并行(PP),跨越8个节点的64路专家并行(EP),以及ZeRO-1数据并行(DP)。
与现有的流水线并行方法相比,DualPipe的流水线气泡更少。同时重叠了前向和后向过程中的计算和通信阶段,解决了跨节点专家并行引入的沉重通信开销的挑战
DualPipe的关键思想是重叠一对单独的前向和后向块中的计算和通信:将每个块划分为四个组件:注意力、all-all调度、MLP和all-all组合

例如,假设我们有两个计算块,A和B:
1.在块A进行前向传播计算时,可以同时进行块B的后向传播通信过程。
2.当块A完成前向传播计算后,开始它的通信过程;而块B则开始它的前向传播计算。


通过优化排列这些功能模块,并精确调控用于通信和计算的 GPU SM资源分配比例,系统能够在运行过程中有效隐藏全节点通信和 PP 通信开销。
可以看出DeepSeek在PP这块,做了大量的通信计算重叠优化,从技术报告中看出,即使是细粒度的all-all专家通信,all-all的通信开销几乎为0。


  • 计算通信重叠
    在深度学习大规模分布式训练过程中,通信的速度往往落后于计算的速度,如何在通信的gap期间内并行做一些计算就是高性能计算和通信重叠,是实现高效训练的关键因素。
  • 流水线并行气泡问题
    一些大的模型会采用流水线并行策略,将模型的不同层放在不同的GPU上,但是不同层之间有依赖关系,后面层需要等前面的计算完才能开始计算,会导致GPU在一段时间是闲置的,如下图所示:

ii.跨节点全对全通信
DeepSeek还专门定制了高效的跨节点all-all通信内核(包括调度和组合)。
具体来说:跨节点 GPU 通过 IB 完全互连,节点内通信通过 NVLink 处理,每个Token最多调度到 4个节点,从而减少 IB 通信量。同时使用warp专业化技术做调度和组合的优化

在调度过程中,(1) IB 发送,(2) IB 到 NVLink 转发,以及 (3) NVLink 接收分别由各自的 warp 处理。分配给每个通信任务的 warp 数会根据所有 SM 上的实际工作负载动态调整。
在合并过程中,(1) NVLink 发送,(2) NVLink 到 IB 的转发和累积,以及 (3) IB 接收和累积也由动态调整的 warp 处理。

通过这种方式,IB 和 NVLink 的通信实现完全重叠,每个 token 能够在不产生 NVLink 额外开销的情况下,在每个节点上平均高效选择 3.2 个专家。这意味着,虽然 DeepSeek-V3 实际只选择 8 个路由专家,但它可以将这个数字扩展到最多 13 个专家(4 个节点 × 3.2 个专家/节点),同时保持相同的通信成本。

DSV3采用了1个共享专家和256个路由专家的MoE架构,每个token会激活8个路由专家。

2.2.3 用于FP8训练的混合精度框架

这里并没有将全量参数FP8量化训练,大多数计算密集型操作都在FP8中进行,而一些关键操作则战略性地保留其原始数据格式,以平衡训练效率和数值稳定性。

哪些算子启用FP8量化去计算?取舍逻辑是什么?

  • 大多数核心计算过程,即 GEMM 运算,都以 FP8 精度实现
  • 涉及对低精度计算的敏感性的算子,仍然需要更高的精度
  • 一些低成本算子也可以使用更高的精度
    以下组件保留了原始精度(例如,BF16 或 FP32):Embedding模块、输出头、MoE 门控模块、Normalization 算子以及 Attention 算子。

如何提高低精度训练精度?

  • 细粒度量化

    对激活,在token维度采用group-wise的量化(1128);对权重,采用128 128的block-wise量化

  • 提高累加精度

    在 TensorCore 上执行矩阵 MMA(矩阵乘法累加)操作时,每当累加达到一个间隔时,这些部分结果会被传输到 CUDA Cores 上的 FP32 寄存器中,并在那里进行FP32 精度的累加计算。

2.2.4 MTP的训练目标

DeepSeekV3训练过程设置了多Token预测的目标,从技术报告的消融实验看出,确实提高了模型在大多数评估基准上的性能,而且MTP模块还可以用于推理加速。

2.2.5 推理部署方案

DeepSeek-V3 整体参数量达到了671B,如此多的参数量,我们看下他的一个部署方案:
推理部署采用了预填充(Prefilling)和解码(Decoding)分离的策略,确保了在线服务的高吞吐量和低延迟。通过冗余专家部署和动态路由策略,模型在推理时保持了高效的负载均衡。
整套部署方案下来基本是跨机分布式推理。

2.2.5.1 Prefill 阶段
这个阶段简单说就是并行处理用户的Prompt,将其转为KV Cache。

预填充阶段的最小部署单元由4个节点组成,每个节点配备32个GPU。注意力部分采用4路张量并行(TP4)和序列并行(SP),并结合8路数据并行(DP8)。其较小的TP规模(4路)限制了TP通信的开销。对于MoE部分,我们使用32路专家并行(EP32)

2.2.5.2 Decoder 阶段
这个阶段就是做自回归的每个Token的输出。

解码阶段的最小部署单元由40个节点和320个GPU组成。注意力部分采用TP4和SP,结合DP80,而MoE部分使用EP320。对于MoE部分,每个GPU只承载一个专家,64个GPU负责承载冗余专家和共享专家

总结:为什么DeepSeekV3训练成本这么低?

训练成本主要由模型架构以及训练架构所决定,而且两者一定是相辅相成。从报告中可以看出以下几个原因:
I.MLA 机制:通过对KV做联合低秩压缩大幅减少KV Cache,相比业界从KV数量角度做KV Cache的减少,MLA 的压缩实现很考验研究团队的基本功。
II.FP8 训练:通过低精度计算减少了 GPU 内存使用和计算开销,技术报告中也提到FP8混合精度训练框架是首次在一个极大规模的模型上验证了其有效性,这一点也看出DeepSeek的Infra工程团队的底蕴。
III.MoE 架构:通过MoE稀疏激活机制大幅减少了计算量,相比Qwen和Llama的Dense架构有很大的训推先天优势,不过难题(专家的负载、通信、路由)也给到了Infra工程团队。

三、为什么是DeepSeek?

在硅谷,类似DeepSeek这样的AI创新并不少有,只是这次是一家中国公司做出了这个动作,相比传统的‘美国创新、中国应用’的模式显得格外的让人兴奋。

从最近的一些访谈以及DeepSeek的技术报告中也能看出以下几点:
1、大模型是一个知识密集型产业,如何组织高密度人才?显然DeepSeek做到了。
2、大模型技术没有魔法,更多时候就是考验基本功和驱动力。
3、不以商业化为第一要义,很多时候能轻装上阵。

四、个人思考

1、长远来看,后续可能会有专门的适配Transformer架构的芯片,就像为卷积设计了ASIC芯片。
2、多Token预测、MoE架构可能很长一段时间都是大模型训推架构热门研究方向。
3、在国内做AI,应用始终会比基础研究有市场,更有话语权,但是基础创新和海外的代际差距会越来越小。
4、大模型训练和推理,软硬件是一个协同的生态,DeepSeek的出现将会促进AI全行业的更加快速且低成本的迭代。

参考资料

1、Better & Faster Large Language Models via Multi-token Prediction
4、DeepSeek-V3 Technical Report
5、DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model
6、deepseek v3的成本这么低的根本原因是什么?
7、GPipe: Easy Scaling with Micro-Batch Pipeline Parallelism