<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Allen AI on Jiang Yi(姜祎)'s Homepage</title><link>https://jiangyigithub.github.io/ai.github.io/tags/allen-ai/</link><description>Recent content in Allen AI on Jiang Yi(姜祎)'s Homepage</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 08 Apr 2026 21:44:44 +0800</lastBuildDate><atom:link href="https://jiangyigithub.github.io/ai.github.io/tags/allen-ai/index.xml" rel="self" type="application/rss+xml"/><item><title>Notes on olmoe</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/</link><pubDate>Sat, 01 Nov 2025 15:23:58 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/</guid><description>&lt;h2 id="introduction"&gt;&lt;a href="#introduction" class="header-anchor"&gt;&lt;/a&gt;Introduction
&lt;/h2&gt;&lt;p&gt;已有的模型如 &lt;a class="link" href="https://maosong.website/p/notes-on-deepseekmoe/" target="_blank" rel="noopener"
&gt;DeepSeek-MoE&lt;/a&gt;, &lt;a class="link" href="https://maosong.website/p/mixstral-8x7b/" target="_blank" rel="noopener"
&gt;Mixtral MoE&lt;/a&gt;, &lt;a class="link" href="https://maosong.website/search/?keyword=qwen1.5" target="_blank" rel="noopener"
&gt;Qwen1.5&lt;/a&gt; 等 MoE 模型基本只开源权重。也有一些开源的模型，比如 OpenMoE 等，但是开源信息不全。基于这个目的，作者提出了 olmoe 模型系列，包括 olmoe-7B-A1B 和 olmoe-7B-A1B-instruct 两个版本。&lt;/p&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;h3 id="pretraining"&gt;&lt;a href="#pretraining" class="header-anchor"&gt;&lt;/a&gt;Pretraining
&lt;/h3&gt;&lt;p&gt;模型的架构如下图所示，MoE 架构与 dense 架构不同的地方在于 decoder layer 中的 FFN 被替换为了 MoE layer.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-MoE_architecture.png"
width="1356"
height="912"
loading="lazy"
alt="Architecture of olmoe"
class="gallery-image"
data-flex-grow="148"
data-flex-basis="356px"
&gt;&lt;/p&gt;
&lt;p&gt;模型的配置如下表所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-config.png"
width="900"
height="1201"
loading="lazy"
alt="Model configuration"
class="gallery-image"
data-flex-grow="74"
data-flex-basis="179px"
&gt;&lt;/p&gt;
&lt;p&gt;训练的目标函数为&lt;/p&gt;
$$
\mathcal{L} = \mathcal{L}_{CE} +\alpha\mathcal{L}_{LB} +\beta\mathcal{L}_{RZ}
$$&lt;p&gt;其中 $\alpha,\beta$ 为系数， $\mathcal{L}_{CE}$, $\mathcal{L}_{LB}$ 以及 $\mathcal{L}_{RZ}$ 分别代表 cross-entropy loss, load balancing loss 以及 routing Z loss.&lt;/p&gt;
&lt;p&gt;预训练数据包括 DCLM 和 Dolma1.7 两个数据集的混合，作者将预训练数据集称为&lt;strong&gt;olmoe-mix&lt;/strong&gt;. 数据集的配比如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-composition-pretraining-data.png"
width="1147"
height="441"
loading="lazy"
alt="Composition of the pretraining data"
class="gallery-image"
data-flex-grow="260"
data-flex-basis="624px"
&gt;&lt;/p&gt;
&lt;h3 id="post-training"&gt;&lt;a href="#post-training" class="header-anchor"&gt;&lt;/a&gt;Post-training
&lt;/h3&gt;&lt;p&gt;在 post-training 时，作者将训练分为 instruction tuning 和 preference tuning 两个阶段，在 instruction dataset 中，作者加入了更多的代码和数学数据来提高对应的能力。数据集如下表所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-composition-post-training-data.png"
width="1208"
height="367"
loading="lazy"
alt="Post-training data"
class="gallery-image"
data-flex-grow="329"
data-flex-basis="789px"
&gt;&lt;/p&gt;
&lt;h2 id="ablation-study"&gt;&lt;a href="#ablation-study" class="header-anchor"&gt;&lt;/a&gt;Ablation Study
&lt;/h2&gt;&lt;h3 id="moe-settings"&gt;&lt;a href="#moe-settings" class="header-anchor"&gt;&lt;/a&gt;MoE Settings
&lt;/h3&gt;&lt;h4 id="moe-vs-dense"&gt;&lt;a href="#moe-vs-dense" class="header-anchor"&gt;&lt;/a&gt;MoE vs. Dense
&lt;/h4&gt;&lt;p&gt;作者对比了 MoE 模型和 dense 模型的训练效率，为了方便对比，作者使用 olmo-7B 和 olmo-1B 作为 baseline, 最终 olmoe 的总参数为 6.9B, 激活参数为 1.3B. 实验结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-MoE-vs-Dense-training-efficiency.png"
width="1155"
height="626"
loading="lazy"
alt="MoE vs. Dense"
class="gallery-image"
data-flex-grow="184"
data-flex-basis="442px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果发现，MoE 模型所需要的 token 或者 FLOPs 是 dense 模型的 $1/3$, 但是由于 MoE 模型需要额外的内存开销，因此从训练时间上来看，MoE 模型训练时间仅比 dense 模型快 $2$ 倍左右。&lt;/p&gt;
&lt;h4 id="expert-granularity"&gt;&lt;a href="#expert-granularity" class="header-anchor"&gt;&lt;/a&gt;Expert Granularity
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://maosong.website/p/notes-on-deepseekmoe/" target="_blank" rel="noopener"
&gt;DeepSeekMoE&lt;/a&gt; 提出使用细粒度的专家来提供更多的组合可能性。作者探究了不同的粒度对模型表现的影响，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-expert-granularity.png"
width="1446"
height="592"
loading="lazy"
alt="Expert granularity"
class="gallery-image"
data-flex-grow="244"
data-flex-basis="586px"
&gt;&lt;/p&gt;
&lt;p&gt;结果显示，当专家粒度从 8E-1A 扩展到 32E-4A 时，模型在 HellaSwag 上的表现提升了 $10\%$, 但是进一步扩展到 64E-8A 时，模型的表现提升不到 $2\%$, 这说明了无限制提升粒度对模型的提升越来越有限。在本文中，作者使用了 64 个专家。&lt;/p&gt;
&lt;h4 id="shared-experts"&gt;&lt;a href="#shared-experts" class="header-anchor"&gt;&lt;/a&gt;Shared Experts
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://maosong.website/p/notes-on-deepseekmoe/" target="_blank" rel="noopener"
&gt;DeepSeekMoE&lt;/a&gt; 提出使用共享专家来学习 common knowledge, 作者对这种方法进行了实验，结果如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-shared-experts.png"
width="1156"
height="477"
loading="lazy"
alt="Shared experts"
class="gallery-image"
data-flex-grow="242"
data-flex-basis="581px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，加入一个 shared expert 之后，模型的表现没有变化，作者认为减少 routed expert 之后，模型的组合可能性降低为原来的 $10\%$ 左右。因此作者认为没有必要使用共享专家，因此作者在 olmoe 中没有采用共享专家这个方法。&lt;/p&gt;
&lt;h4 id="expert-choice-vs-token-choice"&gt;&lt;a href="#expert-choice-vs-token-choice" class="header-anchor"&gt;&lt;/a&gt;Expert Choice vs. Token Choice
&lt;/h4&gt;&lt;p&gt;作者探究了 routing 的策略，一个是 expert choice (EC), 另一种是 token choice (TC), 分别代表了每个 expert 选取固定的 token 数和每个 token 选取固定的 expert 数这两种情况。实验结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-routing-strategy.png"
width="1157"
height="450"
loading="lazy"
alt="Expert choice (EC) vs. token choice (TC)"
class="gallery-image"
data-flex-grow="257"
data-flex-basis="617px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，token choice 的表现明显更好。EC 虽然可以实现负载均衡。但是因为自回归模型在生成时是无法提前确定生成的 token 数的，因此 EC 很可能导致算力资源浪费或者是 token dropping. 在本文中，作者采用了 TC 这种策略。&lt;/p&gt;
&lt;h4 id="sparse-upcycling"&gt;&lt;a href="#sparse-upcycling" class="header-anchor"&gt;&lt;/a&gt;Sparse Upcycling
&lt;/h4&gt;&lt;p&gt;作者还对比了从零开始训练 MoE 与基于 dense model upcycling 的方式训练 MoE，sparse upcycling 的相关工作有 MiniCPM, &lt;a class="link" href="https://maosong.website/p/notes-on-qwen2/" target="_blank" rel="noopener"
&gt;Qwen2&lt;/a&gt; 以及 &lt;a class="link" href="https://maosong.website/p/mixstral-8x7b/" target="_blank" rel="noopener"
&gt;Mixtral MoE&lt;/a&gt;.结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-sparse-upcycling.png"
width="1440"
height="680"
loading="lazy"
alt="Sparse upcycling"
class="gallery-image"
data-flex-grow="211"
data-flex-basis="508px"
&gt;&lt;/p&gt;
&lt;p&gt;结果发现，upcycling 确实可以提高训练效率，但是这种方法的缺陷在于：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;upcycling 受 dense model 的超参数限制&lt;/li&gt;
&lt;li&gt;upcycling 的训练不是很稳定&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此在本文中作者没有采取 upcycling 的做法。&lt;/p&gt;
&lt;h4 id="load-balancing-loss"&gt;&lt;a href="#load-balancing-loss" class="header-anchor"&gt;&lt;/a&gt;Load Balancing Loss
&lt;/h4&gt;&lt;p&gt;作者还探究 Load Balancing loss 对模型表现的影响，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-load-balancing-loss.png"
width="1450"
height="532"
loading="lazy"
alt="Impact of applying a load balancing loss"
class="gallery-image"
data-flex-grow="272"
data-flex-basis="654px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，加入 load balancing loss 之后，模型的表现均超过了不加时的表现。&lt;/p&gt;
&lt;p&gt;作者进一步分析了不同专家在加/不加 load balancing loss 时的激活情况，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/ollmoe-load-balancing-expert-assignment.png"
width="1443"
height="566"
loading="lazy"
alt="Expert assignment during training"
class="gallery-image"
data-flex-grow="254"
data-flex-basis="611px"
&gt;&lt;/p&gt;
&lt;p&gt;结果显示，load balancing loss 确实可以让不同专家的激活概率大致相当。&lt;/p&gt;
&lt;h4 id="router-z-loss"&gt;&lt;a href="#router-z-loss" class="header-anchor"&gt;&lt;/a&gt;Router Z-loss
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://maosong.website/p/st-moe/" target="_blank" rel="noopener"
&gt;ST-MoE&lt;/a&gt; 提出了 Router z-loss 来提高 MOE 训练的稳定性和表现。其表达式如下所示&lt;/p&gt;
$$
\mathcal{L}_{RZ}(x) = \frac{1}{B}\sum_{i=1}^B\left(\log\sum_{j=1}^{N_E}\exp(x_i^{(i)})\right)^2
$$&lt;p&gt;实验结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-routing-z-loss.png"
width="1162"
height="419"
loading="lazy"
alt="Router z-loss"
class="gallery-image"
data-flex-grow="277"
data-flex-basis="665px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，加入 router Z-loss 之后，模型训练的稳定性有所提升。因此在本文中作者使用了这个 loss.&lt;/p&gt;
&lt;h3 id="general-pre-training-settings"&gt;&lt;a href="#general-pre-training-settings" class="header-anchor"&gt;&lt;/a&gt;General Pre-training Settings
&lt;/h3&gt;&lt;h4 id="initialization"&gt;&lt;a href="#initialization" class="header-anchor"&gt;&lt;/a&gt;Initialization
&lt;/h4&gt;&lt;p&gt;作者探究了不同初始化策略对模型训练的影响，结果发现使用 truncate normal initialization 的训练稳定性更高&lt;/p&gt;
&lt;h4 id="qk-norm"&gt;&lt;a href="#qk-norm" class="header-anchor"&gt;&lt;/a&gt;QK-Norm
&lt;/h4&gt;&lt;p&gt;作者探究了 &lt;a class="link" href="https://maosong.website/p/notes-on-qk-norm/" target="_blank" rel="noopener"
&gt;QK-norm&lt;/a&gt; 对模型训练的影响，结果发现 QK-norm 可以提高模型训练的稳定性，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-QK-norm-ablation.png"
width="1157"
height="306"
loading="lazy"
alt="ablation study on QK-Norm"
class="gallery-image"
data-flex-grow="378"
data-flex-basis="907px"
&gt;&lt;/p&gt;
&lt;h4 id="adamw-epsilon"&gt;&lt;a href="#adamw-epsilon" class="header-anchor"&gt;&lt;/a&gt;AdamW Epsilon
&lt;/h4&gt;&lt;p&gt;作者发现，在 &lt;a class="link" href="https://maosong.website/p/notes-on-adamw/" target="_blank" rel="noopener"
&gt;AdamW&lt;/a&gt; 优化器中，使用更小的 &lt;code&gt;eps&lt;/code&gt; 可以提高模型的表现，因此作者将 &lt;code&gt;eps&lt;/code&gt; 设置为 $1e-8$.&lt;/p&gt;
&lt;h4 id="adaptation-settings"&gt;&lt;a href="#adaptation-settings" class="header-anchor"&gt;&lt;/a&gt;Adaptation Settings
&lt;/h4&gt;&lt;p&gt;在 post-training 阶段，作者在三个方面进行了实验：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;是否加入 load balancing loss: 结论是不加，因为负载均衡在 pre-training 阶段已经实现了&lt;/li&gt;
&lt;li&gt;是否使用 annealing: 结论是使用，因为效果更好&lt;/li&gt;
&lt;li&gt;使用 DPO 还是 KTO, 结论是两种方法结果差不多&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;实验结果如下表所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-adaptation-experiments.png"
width="1105"
height="588"
loading="lazy"
alt="Adaptation experiments"
class="gallery-image"
data-flex-grow="187"
data-flex-basis="451px"
&gt;&lt;/p&gt;
&lt;h4 id="load-balancing-precision"&gt;&lt;a href="#load-balancing-precision" class="header-anchor"&gt;&lt;/a&gt;Load Balancing Precision
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://maosong.website/p/switch-transformer/" target="_blank" rel="noopener"
&gt;Switch Transformer&lt;/a&gt; 中提出使用 &lt;code&gt;float32&lt;/code&gt; 精度来进行 routing 的计算，作者通过实验发现，这一方法并不能提高模型训练的稳定性，因此作者没有采用这一策略。&lt;/p&gt;
&lt;h2 id="moe-analysis"&gt;&lt;a href="#moe-analysis" class="header-anchor"&gt;&lt;/a&gt;MoE Analysis
&lt;/h2&gt;&lt;h3 id="router-saturation"&gt;&lt;a href="#router-saturation" class="header-anchor"&gt;&lt;/a&gt;Router Saturation
&lt;/h3&gt;&lt;p&gt;作者探究了训练过程中激活的专家和训练结束后激活的专家的匹配程度，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-olmoe/olmoe-router-saturation.png"
width="1149"
height="393"
loading="lazy"
alt="Router saturation"
class="gallery-image"
data-flex-grow="292"
data-flex-basis="701px"
&gt;&lt;/p&gt;
&lt;p&gt;结果发现，训练 $1\%$ 的数据之后，就有 $40\%$ 的 routing 和训练完毕的 routing 一致，当训练 $40\%$ 的数据之后，这个比例提升到了 $80\%$.&lt;/p&gt;
&lt;p&gt;作者还发现，later layers 比 early layers 饱和更快，early layer, 特别是 layer 0, 饱和的非常慢。作者认为，这是 &lt;a class="link" href="https://maosong.website/p/notes-on-deepseekmoe/" target="_blank" rel="noopener"
&gt;DeepSeekMoE&lt;/a&gt; 放弃在第一层使用 MoE layer 的原因，因为 load balancing loss 收敛更慢。&lt;/p&gt;
&lt;h3 id="expert-co-activation"&gt;&lt;a href="#expert-co-activation" class="header-anchor"&gt;&lt;/a&gt;Expert Co-activation
&lt;/h3&gt;&lt;p&gt;作者分析了 expert 之间的互相依赖程度，作者通过可视化发现，不同的 expert 之间 co-activation 的比例比较小，说明 expert redundancy 比较低&lt;/p&gt;
&lt;h3 id="domain-specialization"&gt;&lt;a href="#domain-specialization" class="header-anchor"&gt;&lt;/a&gt;Domain Specialization
&lt;/h3&gt;&lt;p&gt;作者还探究了不同 expert 对于不同 domain 的 specialization 程度，作者发现对于 specialized domain 的数据，expert 会出现一定程度的 specialization, 但是对于通用 domain 的数据，expert 的 specialization 程度比较低。这个结论与 &lt;a class="link" href="https://maosong.website/p/mixstral-8x7b/" target="_blank" rel="noopener"
&gt;Mixtral MoE&lt;/a&gt; 的结论不同，作者认为这个原因是 &lt;a class="link" href="https://maosong.website/p/mixstral-8x7b/" target="_blank" rel="noopener"
&gt;Mixtral MoE&lt;/a&gt; 使用了 upcycling 的方式，这会限制模型的表现。因此，作者进一步强调 MoE 从零开始训练是一个更好的训练方式。&lt;/p&gt;
&lt;h3 id="vocabulary-specialization"&gt;&lt;a href="#vocabulary-specialization" class="header-anchor"&gt;&lt;/a&gt;Vocabulary Specialization
&lt;/h3&gt;&lt;p&gt;作者还探究了 vocabulary 中不同 token index 与激活专家之间的关系，结果发现 later layers 的 specialization 程度更高，这与 saturation 的趋势一致&lt;/p&gt;
&lt;h2 id="conclusion"&gt;&lt;a href="#conclusion" class="header-anchor"&gt;&lt;/a&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;作者在本文中提出了 olmoe, 一个全开源的 moe 大模型系列，作者详细介绍了针对 MoE 架构和通用架构的设计，为后来的模型架构设计提供了基础。&lt;/p&gt;
&lt;h2 id="references"&gt;&lt;a href="#references" class="header-anchor"&gt;&lt;/a&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://arxiv.org/abs/2409.02060" target="_blank" rel="noopener"
&gt;arxiv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>