迎接DeepSeek开源周[Kimi先开为敬]发布开源最新Muon优化器可替代 AdamW计算效率直接翻倍

news2025/2/24 14:36:54

Muon优化器在小规模语言模型训练中表现出色,但在大规模模型训练中的可扩展性尚未得到证实。月之暗面通过系统分析和改进,成功将 Muon 应用于 3B/16B 参数的 MoE 模型训练,累计训练 5.7 万亿 token。结果表明,Muon 可以替代 AdamW 成为大规模 LLM 训练的标准优化器,在训练效率和模型性能方面具有显著优势。通过开源实现、Moonlight 模型和训练中间检查点,本文旨在推动可扩展优化技术研究,加速 LLM 训练方法发展。

🔗 资源链接

  • 代码 & 实现
    https://github.com/MoonshotAI/Moonlight
  • 全系列模型(预训练/指令微调/中间检查点)
    https://huggingface.co/moonshotai
  • 技术报告
    https://github.com/MoonshotAI/Moonlight/blob/master/Moonlight.pdf

🛠 核心改进

1. 权重衰减机制

通过在 Muon 中引入标准 AdamW 式权重衰减,有效解决了模型参数和层输出 RMS 过大的问题。

参数更新公式

使用如下数学公式描述 Muon 优化器的权重更新规则:

W t = W t − 1 − η t ( O t + λ W t − 1 ) W_{t} = W_{t-1} - \eta_{t} \left( O_{t} + \lambda W_{t-1} \right) Wt=Wt1ηt(Ot+λWt1)

公式解析

  • W t W_t Wt:第 t 步的权重矩阵
  • η t \eta_t ηt:动态学习率
  • O t O_t Ot:当前梯度估计量
  • λ \lambda λ:权重衰减系数
  • ( ⋅ ) \left( \cdot \right) ():自适应缩放运算符

该公式实现了:

  1. 权重衰减项 λ W t − 1 \lambda W_{t-1} λWt1 的显式分离
  2. 梯度方向与正则化项的联合优化
  3. 通过动态学习率 η t \eta_t ηt 实现训练稳定性控制在这里插入图片描述

2. 参数更新尺度调整:一致的更新 RMS

在这里插入图片描述

改进参数更新规则,确保不同形状矩阵间的更新 RMS 一致性,显著提升训练稳定性。,提出基于矩阵维度特性的调整策略:

缩放规则

对每个矩阵按其最大维度进行归一化处理:
max ⁡ ( A , B ) \sqrt{\max(A,B)} max(A,B)

更新公式

调整后的参数更新规则实现为:
W t = W t − 1 − η t ( 0.2 ⋅ O t ⋅ max ⁡ ( A , B ) + λ W t − 1 ) W_{t} = W_{t-1} - \eta_{t} \left( 0.2 \cdot O_{t} \cdot \sqrt{\max(A,B)} + \lambda W_{t-1} \right) Wt=Wt1ηt(0.2Otmax(A,B) +λWt1)

关键改进

  1. 维度感知缩放:通过 max ⁡ ( A , B ) \sqrt{\max(A,B)} max(A,B) 补偿不同形状矩阵的梯度尺度差异
  2. 经验系数:Muon 的更新均方根误差控制在 0.2

3. 分布式实现优化

开发基于 ZeRO-1 风格的分布式版本,实现:

  • 内存占用优化
  • 通信效率提升(梯度同步频率降低 50%)

🧪 实验设计

模型架构

采用类 Deepseek-V3-Small 架构,并针对 Moonlight 模型需求进行微调。

数据集

使用 Kimi 团队提供的 5.7 万亿 token 数据集进行预训练。

训练流程

分阶段优化策略:

  1. 渐进式提升学习率
  2. 动态调整批量大小
  3. 多阶段数据质量优化

📊 实验结果

一致性更新 RMS

更新效果对比
调整学习率方法(Adjusted LR)表现最优,显著优于:

  • 基线方法(Baseline)
  • 仅保持与 AdamW 一致 RMS 的方法(Update Norm)

扩展性验证

Muon 在计算最优设置下仅需 52% 训练 FLOPs 即可达到 AdamW 同等性能。

预训练性能

Moonlight 模型在 1.2T token 时的表现显著优于 AdamW 训练的 Moonlight-A 模型。

微调表现

  • 优势场景:Muon 预训练+微调模型全面优于 AdamW 预训练+微调模型
  • 局限场景:当微调阶段切换优化器时,Muon 优势减弱

关键问题及回答

问题 1:Muon 优化器在大规模模型训练中引入权重衰减的具体作用是什么?

权重衰减在 Muon 优化器中的作用主要是防止模型权重过大,从而避免模型在训练过程中出现梯度爆炸或梯度消失的问题。具体来说,权重衰减通过在更新规则中加入一个正则化项来限制权重的增长。论文中的权重衰减公式如下:

[W_{t}=W_{t - 1}-\eta_{t}\left(O_{t}+\lambda W_{t - 1}\right)]

其中,(\lambda)是权重衰减比率。通过引入权重衰减,Muon 能够在训练过程中更好地控制权重的增长速度,确保模型在训练后期不会出现过大的权重值,从而提高模型的稳定性和泛化能力。实验结果表明,加入权重衰减后,Muon 在大规模模型训练中的性能显著提升。

问题 2:分布式 Muon 实现是如何提高内存效率和减少通信开销的?

分布式 Muon 实现通过以下方式提高内存效率和减少通信开销:

  1. Reduce-Scatter 操作:在数据并行组上进行梯度聚合,减少了全局通信的需求。
  2. 局部分区动量:使用局部分区动量进行动量应用,避免了全局动量的传输。
  3. Newton-Schulz 迭代:在本地计算 Newton-Schulz 迭代,只对需要的部分进行通信。
  4. DP Gather 操作:将局部分区更新矩阵聚合成全矩阵,这一步骤只在必要时进行一次。
  5. 减少冗余计算:在计算全更新矩阵后,丢弃不需要的部分,只保留局部更新矩阵进行下一步计算。

通过这些优化措施,分布式 Muon 在保持算法数学性质的同时,显著减少了内存使用和通信开销,提高了大规模模型训练的效率。

问题 3:Moonlight 模型在监督微调阶段的表现如何,与仅使用 AdamW 预训练和微调的模型相比有何优势?

Moonlight 模型在监督微调阶段表现出色,具体优势如下:

  1. 更高的性能:Muon 预训练和微调的模型在多个基准测试中均表现出比仅使用 AdamW 预训练和微调的模型更高的性能。例如,在 MMLU 和 GSM8k 基准上,Moonlight 模型分别取得了 70.0 和 77.4 的分数,而 AdamW 微调的模型分别为 66.7 和 70.7。
  2. 一致性优化:Muon 在整个训练过程中保持了更好的优化稳定性,避免了在微调阶段出现的梯度爆炸或梯度消失现象。
  3. 泛化能力:Muon 预训练和微调的模型在未见数据上的表现也更好,显示出更强的泛化能力。

注意

当微调阶段使用与预训练阶段不同的优化器时,Muon 并未表现出显著优势。这表明,为了充分发挥 Muon 的优势,建议在预训练和微调阶段都使用相同的优化器。

代码

class Muon(torch.optim.Optimizer):
    """
    Muon - MomentUm Orthogonalized by Newton-schulz

    Muon内部运行标准的SGD动量优化,然后执行一个正交化后处理步骤,
    在该步骤中,每个二维参数的更新将被替换为最近的正交矩阵。
    为了高效地对每个更新进行正交化,我们使用牛顿 - 舒尔茨迭代,
    其优点是可以在GPU上以bfloat16格式稳定运行。

    一些警告:
    - 我们认为这个优化器不太可能在小批量训练中表现良好。
    - 我们认为它可能不太适合微调预训练模型,但我们还没有进行测试。

    参数:
        muon_params: 要由Muon优化的参数。
        lr: 学习率。更新的谱范数将为`lr`。(0.02是一个不错的默认值)
        momentum: 内部SGD使用的动量。(0.95是一个不错的默认值)
        nesterov: 是否在内部SGD中使用Nesterov风格的动量。(推荐)
        ns_steps: 要运行的牛顿 - 舒尔茨迭代的步数。(6步可能总是足够的)
        adamw_params: 要由AdamW优化的参数。`muon_params`中任何为{0, 1}维的参数
                      或者被检测为嵌入层或lm_head的参数也将由AdamW进行优化。
        adamw_lr: 内部AdamW的学习率。
        adamw_betas: 内部AdamW的betas参数。
        adamw_eps: 内部AdamW的epsilon参数。
        adamw_wd: 内部AdamW的权重衰减参数。
    """

    def __init__(
        self,
        lr=1e-3,
        wd=0.1,
        muon_params=None,
        momentum=0.95,
        nesterov=True,
        ns_steps=5,
        adamw_params=None,
        adamw_betas=(0.95, 0.95),
        adamw_eps=1e-8,
    ):
        # 定义默认参数字典
        defaults = dict(
            lr=lr,
            wd=wd,
            momentum=momentum,
            nesterov=nesterov,
            ns_steps=ns_steps,
            adamw_betas=adamw_betas,
            adamw_eps=adamw_eps,
        )

        # 将muon_params转换为列表
        params = list(muon_params)
        # 如果adamw_params不为None,将其转换为列表,否则设为空列表
        adamw_params = list(adamw_params) if adamw_params is not None else []
        # 将adamw_params的参数添加到params列表中
        params.extend(adamw_params)
        # 调用父类的初始化方法
        super().__init__(params, defaults)
        # 将参数分为使用Muon优化的和不使用Muon优化的两类
        for p in muon_params:
            # 对于muon_params中的每个参数,确保其维度为2
            assert p.ndim == 2, p.ndim
            # 标记该参数使用Muon进行优化
            self.state[p]["use_muon"] = True
        for p in adamw_params:
            # 对于adamw_params中的每个参数,标记其不使用Muon进行优化
            self.state[p]["use_muon"] = False

    def adjust_lr_for_muon(self, lr, param_shape):
        # 获取参数矩阵的前两个维度
        A, B = param_shape[:2]
        # 我们根据参数矩阵的大小调整学习率和权重衰减,如论文中所述
        adjusted_ratio = 0.2 * math.sqrt(max(A, B))
        # 计算调整后的学习率
        adjusted_lr = lr * adjusted_ratio
        return adjusted_lr

    def step(self, closure=None):
        """执行单个优化步骤。

        参数:
            closure (Callable, optional): 一个闭包,用于重新评估模型并返回损失。
        """
        loss = None
        if closure is not None:
            with torch.enable_grad():
                loss = closure()

        for group in self.param_groups:

            ############################
            #           Muon           #
            ############################

            # 筛选出使用Muon优化的参数
            params = [p for p in group["params"] if self.state[p]["use_muon"]]
            # 获取当前组的学习率
            lr = group["lr"]
            # 获取当前组的权重衰减
            wd = group["wd"]
            # 获取当前组的动量
            momentum = group["momentum"]

            # 以分布式方式生成权重更新
            for p in params:
                # 进行合理性检查
                g = p.grad
                if g is None:
                    continue
                if g.ndim > 2:
                    g = g.view(g.size(0), -1)
                assert g is not None

                # 计算更新
                state = self.state[p]
                if "momentum_buffer" not in state:
                    # 如果动量缓冲区不存在,初始化为与梯度相同形状的零张量
                    state["momentum_buffer"] = torch.zeros_like(g)
                buf = state["momentum_buffer"]
                # 更新动量缓冲区
                buf.mul_(momentum).add_(g)
                if group["nesterov"]:
                    # 如果使用Nesterov动量,更新梯度
                    g = g.add(buf, alpha=momentum)
                else:
                    g = buf
                # 使用牛顿 - 舒尔茨迭代计算正交化更新
                u = zeropower_via_newtonschulz5(g, steps=group["ns_steps"])

                # 调整学习率
                adjusted_lr = self.adjust_lr_for_muon(lr, p.shape)

                # 应用权重衰减
                p.data.mul_(1 - lr * wd)

                # 应用更新
                p.data.add_(u, alpha=-adjusted_lr)

            ############################
            #       AdamW backup       #
            ############################

            # 筛选出不使用Muon优化的参数
            params = [p for p in group["params"] if not self.state[p]["use_muon"]]
            lr = group['lr']
            # 获取AdamW的betas参数
            beta1, beta2 = group["adamw_betas"]
            # 获取AdamW的epsilon参数
            eps = group["adamw_eps"]
            # 获取AdamW的权重衰减参数
            weight_decay = group["wd"]

            for p in params:
                g = p.grad
                if g is None:
                    continue
                state = self.state[p]
                if "step" not in state:
                    # 如果步数信息不存在,初始化步数和一阶、二阶动量
                    state["step"] = 0
                    state["moment1"] = torch.zeros_like(g)
                    state["moment2"] = torch.zeros_like(g)
                # 更新步数
                state["step"] += 1
                step = state["step"]
                buf1 = state["moment1"]
                buf2 = state["moment2"]
                # 更新一阶动量
                buf1.lerp_(g, 1 - beta1)
                # 更新二阶动量
                buf2.lerp_(g.square(), 1 - beta2)

                # 计算更新
                g = buf1 / (eps + buf2.sqrt())

                # 计算偏差修正
                bias_correction1 = 1 - beta1**step
                bias_correction2 = 1 - beta2**step
                scale = bias_correction1 / bias_correction2**0.5
                # 应用权重衰减
                p.data.mul_(1 - lr * weight_decay)
                # 应用更新
                p.data.add_(g, alpha=-lr / scale)

        return loss

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2304437.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【工作流】Spring Boot 项目与 Camunda 的整合

【工作流】Spring Boot 项目与 Camunda 的整合 【一】Camunda 和主流流程引擎的对比【二】概念介绍【1】Camunda 概念:【2】BPMN 概念 【三】环境准备【1】安装流程设计器CamundaModeler【画图工具】(1)下载安装 【2】CamundaModeler如何设计…

Grouped-Query Attention(GQA)详解: Pytorch实现

Grouped-Query Attention(GQA)详解 Grouped-Query Attention(GQA) 是 Multi-Query Attention(MQA) 的改进版,它通过在 多个查询头(Query Heads)之间共享 Key 和 Value&am…

docker基操

docker基操 首先就是安装docker使用docker:创建容器-制作一个镜像-加载镜像首先就是安装docker 随便找一个教程安装就可以,安装过程中主要是不能访问谷歌,下面这篇文章写了镜像的一些问题: 安装docker的网络问题 使用docker:创建容器-制作一个镜像-加载镜像 主要是参考:这篇…

SF-HCI-SAP问题收集1

最近在做HCI的集成,是S4的环境,发现很多东西都跑不通,今天开始收集一下错误点 如果下图冲从0001变成0010,sfiom_rprq_osi表就会存数据,系统检查到此表就会报错,这个选项的作用就是自定义信息类型也能更新&a…

当 OpenAI 不再 open,DeepSeek 如何掀起 AI 开源革命?

开源与闭源的路线之争成为了行业瞩目的焦点,DeepSeek掀起的 AI 开源风暴! 一、硅谷“斯普特尼克时刻” 1957年,苏联将人类首颗人造卫星“斯普特尼克”送上太空,美国举国震动。 这颗“篮球”般的卫星,刺痛了自诩科技霸…

论文笔记-WSDM2025-ColdLLM

论文笔记-WSDM2025-Large Language Model Simulator for Cold-Start Recommendation ColdLLM:用于冷启动推荐的大语言模型模拟器摘要1.引言2.前言3.方法3.1整体框架3.1.1行为模拟3.1.2嵌入优化 3.2耦合漏斗ColdLLM3.2.1过滤模拟3.2.2精炼模拟 3.3模拟器训练3.3.1LLM…

基于 Python Django 的校园互助平台(附源码,文档)

博主介绍:✌Java徐师兄、7年大厂程序员经历。全网粉丝13w、csdn博客专家、掘金/华为云等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不…

智慧废品回收小程序php+uniapp

废品回收小程序:数字化赋能环保,开启资源循环新时代 城市垃圾治理难题,废品回收小程序成破局关键 随着城市化进程加速与消费水平提升,我国生活垃圾总量逐年攀升,年均增速达5%-8%,其中超30%为可回收物。然…

网页版的俄罗斯方块

1、新建一个txt文件 2、打开后将代码复制进去保存 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>俄…

创建虚拟环境以及配置对应的项目依赖

文章目录 首先创建一个虚拟环境&#xff0c;创建一个名字为myenv,并且版本为xxx的虚拟环境 conda create --name myenv pythonxxx激活虚拟环境 conda activate myenv下载所需的依赖&#xff0c;如果有requirements.txt文件 pip install -r requirements.txt容易出现的错误&a…

网络安全第三次练习

一、实验拓扑 二、实验要求 配置真实DNS服务信息&#xff0c;创建虚拟服务&#xff0c;配置DNS透明代理功能 三、需求分析 1.创建用户并配置认证策略 2.安全策略划分接口 3.ip与策略配置 四、实验步骤 1.划分安全策略接口 2.创建用户并进行策略认证 3.配置安全策略 4.NAT配…

写大论文的word版本格式整理,实现自动生成目录、参考文献序号、公式序号、图表序号

前情提要&#xff1a;最近开始写大论文&#xff0c;发现由于内容很多导致用老方法一个一个改的话超级麻烦&#xff0c;需要批量自动化处理&#xff0c;尤其是序号&#xff0c;在不断有增添删减的情况时序号手动调整很慢也容易出错&#xff0c;所以搞一个格式总结&#xff0c;记…

STM32——HAL库开发笔记22(定时器3—呼吸灯实验)(参考来源:b站铁头山羊)

本文利用前几节所学知识来实现一个呼吸灯实验&#xff1a;两颗led灯交替呼吸。 一、STM32CubeMX配置 step1&#xff1a;配置调试接口 step2&#xff1a;配置定时器 定时器1位于APB2总线上&#xff0c;如上图所示。 step3&#xff1a;配置时基单元 按照下图配置 时钟来源配置…

玩转 Java 与 Python 交互,JEP 库来助力

文章目录 玩转 Java 与 Python 交互&#xff0c;JEP 库来助力一、背景介绍二、JEP 库是什么&#xff1f;三、如何安装 JEP 库&#xff1f;四、JEP 库的简单使用方法五、JEP 库的实际应用场景场景 1&#xff1a;数据处理场景 2&#xff1a;机器学习场景 3&#xff1a;科学计算场…

【单片机毕业设计14-基于stm32c8t6的智能宠物养护舱系统设计】

【单片机毕业设计14-基于stm32c8t6的智能宠物养护舱系统设计】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇14-基于stm32c8t6的智能宠物养护舱系统设计 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功…

DevEco Studio常用快捷键以及如何跟AndroidStudio的保持同步

DevEco Studio快捷键 DevEco Studio是华为推出的用于开发HarmonyOS应用的集成开发环境&#xff0c;它提供了丰富的快捷键以提高开发效率&#xff0c;以下为你详细介绍不同操作场景下的常用快捷键&#xff1a; 通用操作快捷键 操作描述Windows/Linux 快捷键Mac 快捷键打开设置窗…

[Windows] 全国油价实时查询,可具体到城市

[Windows] 全国油价实时查询&#xff0c;可具体到城市 链接&#xff1a;https://pan.xunlei.com/s/VOJnS3aOPeBwGaSvS0O0E1hwA1?pwdx83j# 出于代码练习的目的&#xff0c;调用公共免费api做的py程序&#xff0c;已经一键打包&#xff0c;双击启动即可 使用&#xff1a;选择…

【CSS】---- CSS 变量,实现样式和动画函数复用

1. 前言 本文介绍 CSS 的自定义属性(变量)来实现样式、动画等 CSS 的复用。都是知道在 CSS 和 JS 复用一个很重要的事情,比如 JS 的函数封装,各个设计模式的使用等等,CSS 中样式的复用,同样重要。MDN 使用 CSS 自定义属性(变量):自定义属性(有时候也被称作CSS 变量或…

装修流程图: 装修前准备 → 设计阶段 → 施工阶段 → 安装阶段 → 收尾阶段 → 入住

文章目录 引言I 毛坯房装修的全流程**1. 装修前准备****1.1 确定装修预算****1.2 选择装修方式****1.3 选择装修公司****1.4 办理装修手续****2. 设计阶段****2.1 量房****2.2 设计方案****2.3 确认方案****3. 施工阶段****3.1 主体拆改****3.2 水电改造****3.3 防水工程****3.…

【论文解读】《Training Large Language Models to Reason in a Continuous Latent Space》

论文链接 1. 背景与动机 语言空间与推理的矛盾 目前大多数大语言模型&#xff08;LLMs&#xff09;在解决复杂问题时采用链式思维&#xff08;Chain-of-Thought, CoT&#xff09;方法&#xff0c;即利用自然语言逐步推导出答案。然而&#xff0c;论文指出&#xff1a; 自然语言…