<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Qwen on Jiang Yi(姜祎)'s Homepage</title><link>https://jiangyigithub.github.io/ai.github.io/tags/qwen/</link><description>Recent content in Qwen 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/qwen/index.xml" rel="self" type="application/rss+xml"/><item><title>Notes on Qwen3-Next</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-next/</link><pubDate>Fri, 23 Jan 2026 10:29:56 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-next/</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;当前大语言模型在性能与效率上面临双重挑战：纯 Softmax 注意力计算成本高，而纯线性注意力则性能不足。Qwen3-Next 尝试通过&lt;strong&gt;混合注意力机制&lt;/strong&gt;解决这一矛盾，同时结合 MoE 架构与多项训练优化策略，实现在保持高性能的同时大幅提升训练与推理效率。&lt;/p&gt;
&lt;p&gt;Qwen3-Next 包含三个模型：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Qwen3-Next-80B-A3B-Base&lt;/li&gt;
&lt;li&gt;Qwen3-Next-80B-A3B-Instruct&lt;/li&gt;
&lt;li&gt;Qwen3-Next-80B-A3B-Thinking&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;h3 id="architecture"&gt;&lt;a href="#architecture" class="header-anchor"&gt;&lt;/a&gt;Architecture
&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-qwen3-next/Qwen3-Next-architecture.png"
width="2204"
height="2348"
loading="lazy"
alt="architecture of Qwen3-Next"
class="gallery-image"
data-flex-grow="93"
data-flex-basis="225px"
&gt;&lt;/p&gt;
&lt;h3 id="hybrid-attention"&gt;&lt;a href="#hybrid-attention" class="header-anchor"&gt;&lt;/a&gt;Hybrid Attention
&lt;/h3&gt;&lt;p&gt;作者首先总结了 linear attention 和 softmax attention 各自的优缺点。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;pros&lt;/th&gt;
&lt;th&gt;cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;linear attention&lt;/td&gt;
&lt;td&gt;fast&lt;/td&gt;
&lt;td&gt;low performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;softmax attention&lt;/td&gt;
&lt;td&gt;slow&lt;/td&gt;
&lt;td&gt;high performance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;因此，作者的动机就是是结合 linear attention 与 softmax attention, 在局部利用 linear attention 的高效性来提高训练和推理效率，在关键部分使用 softmax attention 来提高模型的能力。 这种混合注意力机制之前也有很多模型采用，比如 &lt;a class="link" href="https://maosong.website/p/notes-on-minimax-01/" target="_blank" rel="noopener"
&gt;MiniMax-01&lt;/a&gt; 等。最终 Qwen3-Next 使用了 Gated DeltaNet+Gated Attention 的混合注意力机制，模型的 transformer layers 按照 4 个为一组，前三层使用 Gated DeltaNet, 第四层使用 Gated Attention.&lt;/p&gt;
&lt;p&gt;下面是一些细节：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Gated DeltaNet 相比于 &lt;a class="link" href="https://maosong.website/p/notes-on-rnope-swa/" target="_blank" rel="noopener"
&gt;SWA&lt;/a&gt; 和 Mamba2, 其 in-context learning 能力更强&lt;/li&gt;
&lt;li&gt;对于 softmax attention:
&lt;ol&gt;
&lt;li&gt;使用了 &lt;a class="link" href="https://maosong.website/p/notes-on-gated-attention/" target="_blank" rel="noopener"
&gt;Gated Attention&lt;/a&gt; 提出的 gating 机制来解决 massive activation 和 attention sink 问题&lt;/li&gt;
&lt;li&gt;将 attention head 的 dimension 从 128 提高到 256&lt;/li&gt;
&lt;li&gt;使用了和 &lt;a class="link" href="https://maosong.website/p/notes-on-deepseek-v3/" target="_blank" rel="noopener"
&gt;DeepSeek-V3&lt;/a&gt; 类似的 partial RoPE 机制，仅对前 $25\%$ 的元素进行旋转&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="moe"&gt;&lt;a href="#moe" class="header-anchor"&gt;&lt;/a&gt;MoE
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;1 个共享专家，512 个路由专家，其中激活专家个数为 10 个。&lt;/li&gt;
&lt;li&gt;对于 MoE router 的参数，作者还进行了 normalization 来保证每个专家被选择的概率相同。&lt;/li&gt;
&lt;li&gt;与 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen3/" target="_blank" rel="noopener"
&gt;Qwen3&lt;/a&gt; 一致，Qwen3-Next 也是用了 &lt;a class="link" href="https://maosong.website/p/notes-on-global-batch-load-balancing/" target="_blank" rel="noopener"
&gt;Global-batch load balancing&lt;/a&gt; 策略，在保持激活专家数不变的情况下，通过提高总专家个数来降低训练损失。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="normalization-and-training"&gt;&lt;a href="#normalization-and-training" class="header-anchor"&gt;&lt;/a&gt;Normalization and Training
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;使用 Gemma 提出的 Zero-Centered RMSNorm 以及 weight decay 来避免过大的权重出现&lt;/li&gt;
&lt;li&gt;为了提高数据使用效率，作者还使用了 MTP 策略来提高训练效率，模型表现以及 Speculative decoding 的接受率。&lt;/li&gt;
&lt;li&gt;预训练时，Qwen3-Next 使用了&lt;strong&gt;15T&lt;/strong&gt; token 进行训练，训练时间相比于 Qwen3-30B-A3B 有了大幅度的提升&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="experiments"&gt;&lt;a href="#experiments" class="header-anchor"&gt;&lt;/a&gt;Experiments
&lt;/h2&gt;&lt;h3 id="efficiency"&gt;&lt;a href="#efficiency" class="header-anchor"&gt;&lt;/a&gt;Efficiency
&lt;/h3&gt;&lt;p&gt;下图是 Qwen3-Next 与 Qwen3-32B 模型的训练效率对比&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-next/Qwen3-Next-pre-training-efficiency.png"
width="2860"
height="1114"
loading="lazy"
alt="Pre-training efficiency of Qwen3-Next"
class="gallery-image"
data-flex-grow="256"
data-flex-basis="616px"
&gt;&lt;/p&gt;
&lt;p&gt;从结果可以看出，相比于 Qwen3-32B, Qwen3-Next 只用了 $9.3\%$ 的算力就达到了更强的表现。&lt;/p&gt;
&lt;p&gt;并且，在 inference 阶段，由于使用了 linear attention, Qwen3-Next 的效率也更高，下面是 Qwen3-Next 相比于 Qwen3-32B 的效率提升&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;4K&lt;/th&gt;
&lt;th&gt;32K&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prefilling&lt;/td&gt;
&lt;td&gt;$7\times$&lt;/td&gt;
&lt;td&gt;$10\times$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decoding&lt;/td&gt;
&lt;td&gt;$4\times$&lt;/td&gt;
&lt;td&gt;$10\times$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="performance"&gt;&lt;a href="#performance" class="header-anchor"&gt;&lt;/a&gt;Performance
&lt;/h3&gt;&lt;p&gt;下面是 Qwen3-Next-Base 的表现&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-next/Qwen3-Next-base-performance.png"
width="1288"
height="844"
loading="lazy"
alt="Performance of Qwen3-Next-Base"
class="gallery-image"
data-flex-grow="152"
data-flex-basis="366px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，Qwen3-Next-Base 在多个 Benchmark 上的表现仅次于 Qwen3-235B-A22B&lt;/p&gt;
&lt;p&gt;Qwen3-Next-Instruct 的表现如下表所示&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benchmark&lt;/th&gt;
&lt;th&gt;Qwen3-Next-80B-A3B-Instruct&lt;/th&gt;
&lt;th&gt;Qwen3-235B-A22B-Instruct-2507&lt;/th&gt;
&lt;th&gt;Qwen3-32B Non-thinking&lt;/th&gt;
&lt;th&gt;Qwen3-30B-A3B-Instruct-2507&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SuperGPQA&lt;/td&gt;
&lt;td&gt;58.8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;62.6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;43.2&lt;/td&gt;
&lt;td&gt;53.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AIME25&lt;/td&gt;
&lt;td&gt;69.5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;70.3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20.2&lt;/td&gt;
&lt;td&gt;61.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiveCodeBench v6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;56.6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;51.8&lt;/td&gt;
&lt;td&gt;29.1&lt;/td&gt;
&lt;td&gt;43.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arena-Hard v2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;82.7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;79.2&lt;/td&gt;
&lt;td&gt;34.1&lt;/td&gt;
&lt;td&gt;69.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiveBench&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;75.8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;75.4&lt;/td&gt;
&lt;td&gt;59.8&lt;/td&gt;
&lt;td&gt;69.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Qwen3-Next-Instruct 的长文本表现（RULER Benchmark）如下&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Avg.&lt;/th&gt;
&lt;th&gt;4K&lt;/th&gt;
&lt;th&gt;8K&lt;/th&gt;
&lt;th&gt;16K&lt;/th&gt;
&lt;th&gt;32K&lt;/th&gt;
&lt;th&gt;64K&lt;/th&gt;
&lt;th&gt;96k&lt;/th&gt;
&lt;th&gt;128K&lt;/th&gt;
&lt;th&gt;192k&lt;/th&gt;
&lt;th&gt;256k&lt;/th&gt;
&lt;th&gt;384k&lt;/th&gt;
&lt;th&gt;512k&lt;/th&gt;
&lt;th&gt;640k&lt;/th&gt;
&lt;th&gt;768k&lt;/th&gt;
&lt;th&gt;896k&lt;/th&gt;
&lt;th&gt;1M&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-30B-A3B-Instruct-2507&lt;/td&gt;
&lt;td&gt;86.8&lt;/td&gt;
&lt;td&gt;98.0&lt;/td&gt;
&lt;td&gt;96.7&lt;/td&gt;
&lt;td&gt;96.9&lt;/td&gt;
&lt;td&gt;97.2&lt;/td&gt;
&lt;td&gt;93.4&lt;/td&gt;
&lt;td&gt;91.0&lt;/td&gt;
&lt;td&gt;89.1&lt;/td&gt;
&lt;td&gt;89.8&lt;/td&gt;
&lt;td&gt;82.5&lt;/td&gt;
&lt;td&gt;83.6&lt;/td&gt;
&lt;td&gt;78.4&lt;/td&gt;
&lt;td&gt;79.7&lt;/td&gt;
&lt;td&gt;77.6&lt;/td&gt;
&lt;td&gt;75.7&lt;/td&gt;
&lt;td&gt;72.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-235B-A22B-Instruct-2507&lt;/td&gt;
&lt;td&gt;92.5&lt;/td&gt;
&lt;td&gt;98.5&lt;/td&gt;
&lt;td&gt;97.6&lt;/td&gt;
&lt;td&gt;96.9&lt;/td&gt;
&lt;td&gt;97.3&lt;/td&gt;
&lt;td&gt;95.8&lt;/td&gt;
&lt;td&gt;94.9&lt;/td&gt;
&lt;td&gt;93.9&lt;/td&gt;
&lt;td&gt;94.5&lt;/td&gt;
&lt;td&gt;91.0&lt;/td&gt;
&lt;td&gt;92.2&lt;/td&gt;
&lt;td&gt;90.9&lt;/td&gt;
&lt;td&gt;87.8&lt;/td&gt;
&lt;td&gt;84.8&lt;/td&gt;
&lt;td&gt;86.5&lt;/td&gt;
&lt;td&gt;84.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-Next-80B-A3B-Instruct&lt;/td&gt;
&lt;td&gt;91.8&lt;/td&gt;
&lt;td&gt;98.5&lt;/td&gt;
&lt;td&gt;99.0&lt;/td&gt;
&lt;td&gt;98.0&lt;/td&gt;
&lt;td&gt;98.7&lt;/td&gt;
&lt;td&gt;97.6&lt;/td&gt;
&lt;td&gt;95.0&lt;/td&gt;
&lt;td&gt;96.0&lt;/td&gt;
&lt;td&gt;94.0&lt;/td&gt;
&lt;td&gt;93.5&lt;/td&gt;
&lt;td&gt;91.7&lt;/td&gt;
&lt;td&gt;86.9&lt;/td&gt;
&lt;td&gt;85.5&lt;/td&gt;
&lt;td&gt;81.7&lt;/td&gt;
&lt;td&gt;80.3&lt;/td&gt;
&lt;td&gt;80.3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可以看到， Qwen3-Next-Instruct 在 1M 长度范围内保持稳定性能，整体平均得分 91.8，接近 Qwen3-235B（92.5）。&lt;/p&gt;
&lt;p&gt;Qwen3-Next-Thinking 的表现如下表所示&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Benchmark&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Qwen3-Next-80B-A3B-Thinking&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Gemini-2.5-Flash Thinking&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Qwen3-32B Thinking&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Qwen3-30B-A3B-Thinking2507&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SuperGPQA&lt;/td&gt;
&lt;td&gt;60.8&lt;/td&gt;
&lt;td&gt;57.8&lt;/td&gt;
&lt;td&gt;54.1&lt;/td&gt;
&lt;td&gt;56.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AIME25&lt;/td&gt;
&lt;td&gt;87.8&lt;/td&gt;
&lt;td&gt;72.0&lt;/td&gt;
&lt;td&gt;72.9&lt;/td&gt;
&lt;td&gt;85.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiveCodeBench v6&lt;/td&gt;
&lt;td&gt;68.7&lt;/td&gt;
&lt;td&gt;61.2&lt;/td&gt;
&lt;td&gt;60.6&lt;/td&gt;
&lt;td&gt;66.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arena-Hard v2&lt;/td&gt;
&lt;td&gt;62.3&lt;/td&gt;
&lt;td&gt;56.7&lt;/td&gt;
&lt;td&gt;48.4&lt;/td&gt;
&lt;td&gt;56.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiveBench&lt;/td&gt;
&lt;td&gt;76.6&lt;/td&gt;
&lt;td&gt;74.3&lt;/td&gt;
&lt;td&gt;74.9&lt;/td&gt;
&lt;td&gt;76.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可以看到，Qwen3-Next-Thinking 的表现在除了 Livebench 之外的三个 Benchmark 均达到了 SOTA&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;Qwen3-Next 通过&lt;strong&gt;混合注意力架构&lt;/strong&gt;与&lt;strong&gt;精细化 MoE 设计&lt;/strong&gt;，在训练与推理效率上实现突破性提升。其仅以较小计算代价达到接近超大模型性能的表现，为下一代高效大语言模型的设计提供了重要参考。&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="https://qwen.ai/blog?id=4074cca80393150c248e508aa62983f9cb7d27cd&amp;amp;from=research.latest-advancements-list" target="_blank" rel="noopener"
&gt;Qwen3-Next: Towards Ultimate Training &amp;amp; Inference Efficiency&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Gated Attention</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/</link><pubDate>Tue, 20 Jan 2026 15:41:52 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/</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;现有的大部分模型都基于 Transformer 提出的 softmax attention (SDPA), 虽然也有相关的改进工作，但是主要集中于降低 attention 计算复杂度，提高 attention 在推理时的内存使用效率等。之前的工作提出了关于 attention 的两个问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;attention sink, 即模型的注意力会放在初始几个 token 上, 这限制了模型的上下文扩展能力&lt;/li&gt;
&lt;li&gt;massive activation, 少部分 token 的 hidden states 会非常大，这限制了模型的训练稳定性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在本文中，作者通过在 attention 中加入 gating 机制来探索 gating 对模型表现和训练稳定性的影响。尽管 gating 并没有降低 attention 计算复杂度，但是 gating 提出了一个新的视角，即 sparity 与 attention sink 和 massive activation 息息相关，这为后面 sparse attention 的研究提供了 Insight.&lt;/p&gt;
&lt;p&gt;作者发现，对 Multi head attention 的输出进行 head-specific gating 的效果最好，并且这种方式还可以提高训练稳定性，模型的表达能力和长上下文能力。作者还进一步分析了这种 gating 方式更好的原因，发现有两点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;non-linearity: 通过 gating 可以有效提高 output projection layer 输入的秩，进而提高表达能力&lt;/li&gt;
&lt;li&gt;sparsity: gating 可以降低 massive activation 和 attention sink 的影响&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;作者最终推荐使用 element-wise SDPA gating 方式来进行训练&lt;/p&gt;
&lt;h2 id="related-work"&gt;&lt;a href="#related-work" class="header-anchor"&gt;&lt;/a&gt;Related Work
&lt;/h2&gt;&lt;p&gt;作者主要介绍了 gating 和 attention sink 这两部分的工作。&lt;/p&gt;
&lt;p&gt;gating 早在 LSTM 和 GRU 使其就得到了广泛的运用，在 transformer 之后，相关的现行注意力也有应用，比如 &lt;a class="link" href="https://maosong.website/p/notes-on-minimax-01/" target="_blank" rel="noopener"
&gt;MiniMax-01&lt;/a&gt; 所使用的 Lightning Attention 等，但是这些工作没有系统性探究 gating 背后的机制。&lt;/p&gt;
&lt;p&gt;第二部分是 attention sink, attention sink 现象由 &lt;a class="link" href="https://maosong.website/p/notes-on-streamingllm/" target="_blank" rel="noopener"
&gt;StreamingLLM&lt;/a&gt; 提出， 即模型会将相当一部分注意力权重方开始开始的几个 token 上。而本文提出的 gating 机制可以缓解 attention sink 现象。&lt;/p&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;p&gt;首先是标准 MHA 定义：&lt;/p&gt;
$$
\begin{aligned}
Q &amp;= XW_Q, K=XW_K, V=XW_V\\
\mathrm{Attn}_i(Q,K,V) &amp;= \mathrm{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V, i=1,\dots,h\\
\mathrm{MHA}(Q, K, V) &amp;= \mathrm{Concat}([\mathrm{Attn}_1,\dots,\mathrm{Attn}_h])\\
O &amp;= \mathrm{MHA}(Q, K, V) W_O
\end{aligned}
$$&lt;p&gt;这里 $X\in\mathbb{R}^{n\times d}$ 是 transformer layer pre-normalization 的输出（或者 attention block 的输入）, $n$ 是 sequence length, $d$ 是 hidden size, $h$ 是 number of heads, $d_k$ 是 head dimension.&lt;/p&gt;
&lt;p&gt;接下来，作者介绍了不同的 gating 策略。这里作者用同一的公式来进行表示&lt;/p&gt;
$$
Y' = g(Y,X,W_\theta, \sigma) = Y\odot \sigma(XW_\theta)
$$&lt;p&gt;这里 $Y$ 是输入， $X$ 是 attention 的输入，$W_\theta$ 是可学习权重&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Position&lt;/strong&gt;
首先是位置，作者考虑了如下几种变体：&lt;/p&gt;
$$
\begin{align}
\mathrm{MHA}(Q, K, V)' &amp;= \mathrm{MHA}(Q, K, V)\odot \sigma\left(X W_\theta)\right) \tag{G1}\\
Q' &amp;= Q\odot \sigma\left(XW_\theta\right) \tag{G2}\\
K' &amp;= K\odot \sigma\left(XW_\theta\right) \tag{G3}\\
V' &amp;= V\odot \sigma\left(XW_\theta\right) \tag{G4}\\
O' &amp;= O\odot \sigma\left(XW_\theta\right) \tag{G5}\\
\end{align}
$$&lt;p&gt;这里 $\sigma$ 是激活函数，$W_\theta$ 是激活函数的可学习参数，我们可以将其理解为一个 linear layer, 即当前模块的输出取决于输入 hidden sates 经过一个线性层和激活层之后的结果，相似的做法还有 &lt;a class="link" href="https://maosong.website/p/moe-tutorial/" target="_blank" rel="noopener"
&gt;MoE&lt;/a&gt; 中的 gating layer, &lt;a class="link" href="https://maosong.website/p/notes-on-nsa/" target="_blank" rel="noopener"
&gt;NSA&lt;/a&gt; 中的 gating layer 等。对应的示意图如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/Gated-attention-position.png"
width="517"
height="565"
loading="lazy"
alt="Positions of different gating methods"
class="gallery-image"
data-flex-grow="91"
data-flex-basis="219px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;granularity&lt;/strong&gt;
作者设计了不同粒度的 gating（假设输入为 $X\in\mathbb{R}^{n\times h\times d_k}$）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;head-shared: 不同 head 共享 gating score, &lt;code&gt;Y'[i,h,k]=gate[i,k]*Y[i,h,k]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;head-wise: 同一个 head 共享 gating score, &lt;code&gt;Y'[i,h,:]=gate[i,h]*Y[i,h,:]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;element-wise: 不同元素不共享 gating score, &lt;code&gt;Y'[i,h,k]=gate[i,h,k]*Y[i,h,k]&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;从 attention 的角度看，不同 head 本身就承担不同的语义子空间，如果强行共享 gating，会破坏这种分工。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;format&lt;/strong&gt;
作者还构建了 multiplication 和 addition 两种形式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;multiplication: $Y'=Y\odot \sigma(XW_\theta)$&lt;/li&gt;
&lt;li&gt;addition: $Y'=Y+\sigma(XW_\theta)$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;activation function&lt;/strong&gt;
本文中作者使用了 SiLU 和 sigmoid 两种形式，即&lt;/p&gt;
$$
\sigma_{\mathrm{sigmoid}}(x) = \frac{1}{1+e^{-x}},\quad \sigma_{\mathrm{SiLU}} = x*\sigma_{\mathrm{sigmoid}}(x)=\frac{x}{1+e^{-x}}
$$&lt;h2 id="experiments"&gt;&lt;a href="#experiments" class="header-anchor"&gt;&lt;/a&gt;Experiments
&lt;/h2&gt;&lt;p&gt;作者构建了三个模型进行实验，模型配置如下表所示&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;1.7B-28 layers&lt;/th&gt;
&lt;th&gt;1.7B-48 layers&lt;/th&gt;
&lt;th&gt;15B-A2.4B MoE&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Layers&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;query heads&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;key/value heads&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;head dim&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tie embedding&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QK normalization&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hidden size&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;1536&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ffn hidden size&lt;/td&gt;
&lt;td&gt;6144&lt;/td&gt;
&lt;td&gt;4608&lt;/td&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;experts&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;top-K&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;首先是不同 gating 方法对 MoE model 影响，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/Gated-attention-gating-variant-performance.png"
width="1292"
height="847"
loading="lazy"
alt="Performance of different gating variants"
class="gallery-image"
data-flex-grow="152"
data-flex-basis="366px"
&gt;&lt;/p&gt;
&lt;p&gt;结论如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对 SDPA 的输出 (G1) 或者 value (G2) 进行 gating 效果最好&lt;/li&gt;
&lt;li&gt;head-specific gating 效果更好&lt;/li&gt;
&lt;li&gt;multiplication 效果比 addition 效果更好&lt;/li&gt;
&lt;li&gt;sigmoid 效果比 SiLU 效果更好&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;总的来说，position 对最终结果提升最明显，其次是 granularity 和 activation function.&lt;/p&gt;
&lt;p&gt;接下来是不同 gating 方法对 dense model 的影响，作者构建了两个 dense 模型，参数都是 1.7B, 这两个模型的 layers 和 FFN hidden size 不同（通过调整保持总参数一致）。作者对比了 G1 和 baseline 的表现， 结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/Gated-attention-dense-model-performance.png"
width="1290"
height="750"
loading="lazy"
alt="Performance of dense models with Gated attention"
class="gallery-image"
data-flex-grow="172"
data-flex-basis="412px"
&gt;&lt;/p&gt;
&lt;p&gt;结论验证了 gating 机制可以有效提高模型的表现。作者还发现使用 gating 之后，模型的训练也更加稳定，训练的损失变化曲线如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/Gated-attention-training-loss-curve.png"
width="387"
height="515"
loading="lazy"
alt="training loss curve of gated attention"
class="gallery-image"
data-flex-grow="75"
data-flex-basis="180px"
&gt;&lt;/p&gt;
&lt;h2 id="analysis"&gt;&lt;a href="#analysis" class="header-anchor"&gt;&lt;/a&gt;Analysis
&lt;/h2&gt;&lt;p&gt;首先，作者对 multi head attention 进行了重写，得到如下形式&lt;/p&gt;
$$
o_i^k = \sum_{j=1}^i\left(S_{ij}^k X_jW_V^k\right)W_O^k = \sum_{j=1}^i S_{ij}^k X_j(W_V^kW_O^k)
$$&lt;p&gt;也就是说，$W_K$ 和 $W_O$ 可以吸收到一起，由于 $W_V^j\in\mathbb{R}^{d\times d_k}$, $W_O^k\in\mathbb{R}^{d_k\times d}$, 从而 $\mathrm{rank}(W_V^jW_O^k)\leq \max(\mathrm{rank}(W_V^j), \mathrm{rank}(W_O^k))\leq d_k$. 对于 &lt;a class="link" href="https://maosong.website/p/notes-on-gqa/" target="_blank" rel="noopener"
&gt;GQA&lt;/a&gt; 和 &lt;a class="link" href="https://maosong.website/p/notes-on-mqa/" target="_blank" rel="noopener"
&gt;MQA&lt;/a&gt;, 最终的有效秩会进一步降低。&lt;/p&gt;
&lt;p&gt;而使用本文提到的 G1 和 G2 gating 策略之后，我们相当于是通过非线性机制提高了上面的秩，进而解决了 softmax attention 表达能力不足的问题, 实际上，StepFun 的 &lt;a class="link" href="https://maosong.website/p/notes-on-mfa/" target="_blank" rel="noopener"
&gt;MFA&lt;/a&gt; 也是类似的思想。下面是 G1 和 G2 做的改进：&lt;/p&gt;
$$
\begin{align}
o_i^k &amp;= \sum_{j=1}^i\left(S_{ij}^k \mathrm{gating}(X_jW_V^k)\right)W_O^k\tag{G1}\\
o_i^k &amp;= \mathrm{gating}\left(\sum_{j=1}^iS_{ij}^k X_jW_V^k\right)W_O^k \tag{G2}
\end{align}
$$&lt;p&gt;通过 gating 的非线性机制，我们提高的矩阵的秩，进而提高了模型的表达能力，而 G5 提升有限的原因也在于此。实验结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/Gated-attention-non-linearity-performance.png"
width="957"
height="261"
loading="lazy"
alt="Performance of different non-linearity variants"
class="gallery-image"
data-flex-grow="366"
data-flex-basis="880px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，不同的 non-linearity 方法对模型表现都有提升，这验证了矩阵秩会影响模型表达能力的分析。&lt;/p&gt;
&lt;p&gt;接下来，作者探究了 gating 机制对 attention score distribution 的影响，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/Gated-attention-score-distribution.png"
width="1283"
height="408"
loading="lazy"
alt="attention score distribution of different methods"
class="gallery-image"
data-flex-grow="314"
data-flex-basis="754px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果说明：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;有效的 gating 机制对应的 attention score 是非常稀疏的&lt;/li&gt;
&lt;li&gt;head-specific sparsity 非常重要，当在不同的 head 共享 gating 时，模型表现会有所下降&lt;/li&gt;
&lt;li&gt;gating 必须与 query 相关，与 G2 先比，G1 的表现更好，这说明 gating score 更依赖于 query. 作者认为基于当前 query token 构建 gating, 可以有效过滤历史 token 的噪音信息&lt;/li&gt;
&lt;li&gt;non-sparse gating 效果比较差，作者构建了一个 non-sparse 版本的 sigmoid, 结果发现模型表现非常差，这说明了 attention score 应该是一个稀疏形式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;通过前面的分析和实验结果，作者认为 gating 机制还可以缓解 attention sink 现象，作者对 baseline 以及 G1 两种方法的 attention 分布进行了可视化，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gated-attention/Gated-attention-sink-visualization.png"
width="1263"
height="721"
loading="lazy"
alt="Visualization of attention sink"
class="gallery-image"
data-flex-grow="175"
data-flex-basis="420px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果整理如下表所示&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;massive activation&lt;/th&gt;
&lt;th&gt;attention sink&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;input-independence&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;head-shared gating&lt;/td&gt;
&lt;td&gt;low&lt;/td&gt;
&lt;td&gt;high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;head-specific gating&lt;/td&gt;
&lt;td&gt;low&lt;/td&gt;
&lt;td&gt;low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;因此，作者的结论为，input-dependent, head-specific gating 可以提高 attention score distribution 的 sparsity, 进而减缓 attention sink. 并且引入 spaisity 之后，我们还可以避免 massive activation, 进而使用更低的精度进行训练。&lt;/p&gt;
&lt;p&gt;最后，作者探究了以下 gating 机制的上下文扩展能力，作者在已有的模型上基于 32k 上下文长度使用了 80B token 进行 continue pre-training, 然后使用 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 将模型上下文长度扩展到了 128K。 测试的结果如下图所示&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;4k&lt;/th&gt;
&lt;th&gt;8k&lt;/th&gt;
&lt;th&gt;16k&lt;/th&gt;
&lt;th&gt;32k&lt;/th&gt;
&lt;th&gt;64k&lt;/th&gt;
&lt;th&gt;128k&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;88.89&lt;/td&gt;
&lt;td&gt;85.88&lt;/td&gt;
&lt;td&gt;83.15&lt;/td&gt;
&lt;td&gt;79.50&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDPA-Gate&lt;/td&gt;
&lt;td&gt;90.56&lt;/td&gt;
&lt;td&gt;87.11&lt;/td&gt;
&lt;td&gt;84.61&lt;/td&gt;
&lt;td&gt;79.77&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;YaRN Extended&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;82.90 (-6.0)&lt;/td&gt;
&lt;td&gt;71.52 (-14.4)&lt;/td&gt;
&lt;td&gt;61.23 (-21.9)&lt;/td&gt;
&lt;td&gt;37.94 (-41.56)&lt;/td&gt;
&lt;td&gt;37.51&lt;/td&gt;
&lt;td&gt;31.65&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDPA-Gate&lt;/td&gt;
&lt;td&gt;88.13 (-2.4)&lt;/td&gt;
&lt;td&gt;80.01 (-7.1)&lt;/td&gt;
&lt;td&gt;76.74 (-7.87)&lt;/td&gt;
&lt;td&gt;72.88 (-6.89)&lt;/td&gt;
&lt;td&gt;66.60&lt;/td&gt;
&lt;td&gt;58.82&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可以看到，对于短上下文，虽然两者表现都有所下降，但是本文提出的 gating 表现下降程度较小。而对于长上下文，本文提出的 gating 机制效果明显更好。作者分析原因认为这是由于 softmax attention 倾向于退化为对少数 token 的依赖， 而 gating 通过引入 token-level sparsity，避免了这种路径依赖。&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;在本文中，作者系统性探究了 attention 中的 gating 机制，包括 gating 对模型表现，训练稳定性以及训练动态的影响。作者发现，通过提高 non-linearity 和 sparsity 我们可以有效提高模型的上下文能力以及减缓 attention sink 现象。&lt;/p&gt;
&lt;p&gt;从更高层次看，本文的结果可以总结为一点：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;attention 的问题不在于 softmax 本身，而在于线性 aggregation 的表达上限与缺乏选择性。而 gating 提供了一种几乎零成本、却极其有效的方式来引入非线性与稀疏性。&lt;/p&gt;
&lt;/blockquote&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="https://openreview.net/forum?id=1b7whO4SfY" target="_blank" rel="noopener"
&gt;Gated Attention for Large Language Models: Non-linearity, Sparsity, and Attention-Sink-Free&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="appendix"&gt;&lt;a href="#appendix" class="header-anchor"&gt;&lt;/a&gt;Appendix
&lt;/h2&gt;&lt;p&gt;作者在附录中还进一步分析了 massive activation 以及 attention sink.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;massive activation 并不是 attention sink 产生的必要原因，并且 sparsity 可以减缓这一现象&lt;/li&gt;
&lt;li&gt;head-specific gating 会提升 gating score 的值，因此不同的 head 需要安排不同的 sparsity&lt;/li&gt;
&lt;li&gt;并不能通过 clipping 的方式来提高训练稳定性&lt;/li&gt;
&lt;li&gt;在 continue pre-training 阶段加入 gating 机制并不能提高模型的表现&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Notes on Global-batch load balancing</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-global-batch-load-balancing/</link><pubDate>Thu, 11 Dec 2025 16:09:34 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-global-batch-load-balancing/</guid><description>&lt;p&gt;Qwen 在 25 年 2 月提出了 global batching load balancing loss strategy, 其在 global level 上考虑每个专家的负载均衡，从而提高模型的表现&lt;/p&gt;
&lt;h2 id="introduction"&gt;&lt;a href="#introduction" class="header-anchor"&gt;&lt;/a&gt;Introduction
&lt;/h2&gt;&lt;p&gt;实现 MoE 模型负载均衡的原因有两点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Effectiveness: 通过负载均衡才能更高效地利用各个专家&lt;/li&gt;
&lt;li&gt;Efficiency: 一般需要使用 expert parallel 来部署 MoE 模型，不均衡的负载会大幅度降低前向过程&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;已有的框架如 DeepSpeed, Megablocks 和 Megatron-Core 都是在 micro-batch level 上计算负载均衡损失的，但是，一个 micro-batch 通常只包含少数序列，因此 load balancing loss 就要求各个专家在每个序列上均匀分布。&lt;/p&gt;
&lt;p&gt;针对这个问题，作者在本文中提出的解决方法是在 global-batch 层面考虑负载均衡，&lt;/p&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;p&gt;MoE 模型定义如下&lt;/p&gt;
$$
y = \sum_{i\in N_E,g_i\in\mathrm{TopK}(g)}g_i(x)E_i(x)
$$&lt;p&gt;其中 $E_i$ 是对应的专家, $g_i$ 是对应的权重&lt;/p&gt;
&lt;p&gt;Load balancing loss 定义如下&lt;/p&gt;
$$
\mathrm{LBL} = N_E\sum_{i=1}^{N_E}f_iP_i
$$&lt;p&gt;一般来说，MoE 模型训练时会使用 expert parallel 策略，此时 load balancing loss 修改为&lt;/p&gt;
$$
\mathrm{LBL}_{\mathrm{micro}}= \frac{1}{N_P}\sum_{j=1}^{N_P}\left(N_E\sum_{i=1}^{N_E}f_i^hP_i^j\right)
$$&lt;p&gt;其中 $N_P$ 是 parallel groups 的个数。在这种情况下，模型需要再每个 parallel group 中实现负载均衡。但是某一个 mircro-batch 里可能只包含某一个 domain 的序列，因此各个专家被强制要求在每一个 domain 中也均衡分布。作者认为，这种方式会限制专家的能力，进而影响模型的表现。&lt;/p&gt;
&lt;p&gt;作者的解决方法在于，获取每个 parallel group 的 $f_i$ 然后求 global-batch 的 $\bar{f}_i$.&lt;/p&gt;
$$
\mathrm{LBL}_{\mathrm{global}}=N_E\sum_{i=1}^{N_E}\bar{f}_i\bar{P}_i=N_E\sum_{i=1}^{N_E}\bar{f}_i\left(\frac{1}{N_P}\sum_{j=1}^{N_P}P_j\right) = \frac{1}{N_P}\sum_{j=1}^{N_P}\left(N_E\sum_{i=1}^{N_E}\bar{f}_iP_i^j\right)
$$&lt;p&gt;实际中，由于计算节点数量有限，micro-batch size 之和可能会小于 global-batch size, 因此我们会使用 gradient accumulation. 在这种情况下， 作者使用了一个 buffer 来保存多个 micro-batch 的专家选择次数，最终算法实现过程如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-global-batch-load-balancing/Global-batch-LBL-approximation.png"
width="891"
height="339"
loading="lazy"
alt="Approximate Global-Batch LBL"
class="gallery-image"
data-flex-grow="262"
data-flex-basis="630px"
&gt;&lt;/p&gt;
&lt;h2 id="experiments"&gt;&lt;a href="#experiments" class="header-anchor"&gt;&lt;/a&gt;Experiments
&lt;/h2&gt;&lt;p&gt;作者使用了不同大小的模型来进行实验，作者用 &lt;strong&gt;Balance BSZ&lt;/strong&gt; 来表现计算 expert selection frequency 时的 token 数，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-global-batch-load-balancing/Global-batch-LBL-performance.png"
width="954"
height="598"
loading="lazy"
alt="Performance of different balance methods and Balance BSZ"
class="gallery-image"
data-flex-grow="159"
data-flex-basis="382px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，global LBL 可以提高模型的表现，并且，当 Balance BSZ 增加时，模型的表现也会提升。作者发现对于 &lt;a class="link" href="https://maosong.website/p/notes-on-loss-free-balancing/" target="_blank" rel="noopener"
&gt;Loss-Free Balancing&lt;/a&gt; 来说，使用 global batch 的效果也更好。&lt;/p&gt;
&lt;p&gt;作者还发现，global LBL 会提高专家的特化程度，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-global-batch-load-balancing/Global-batch-LBL-specialization.png"
width="1221"
height="571"
loading="lazy"
alt="The impact of the Balance BSZ"
class="gallery-image"
data-flex-grow="213"
data-flex-basis="513px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，使用默认的 LBL loss, 各个专家的特化程度很低，而使用本文的 global LBL 之后，专家的特化程度有了大幅度的提高。&lt;/p&gt;
&lt;p&gt;作者还进一步发现，随着 Balance BSZ 的提高，模型表现也持续提升，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-global-batch-load-balancing/Global-batch-LBL-balance-BSZ.png"
width="613"
height="455"
loading="lazy"
alt="Performance against Balance BSZ"
class="gallery-image"
data-flex-grow="134"
data-flex-basis="323px"
&gt;&lt;/p&gt;
&lt;p&gt;作者认为，synchronization 和 buffer 机制相比于 micro-batch 来说可以带来大幅度提升。&lt;/p&gt;
&lt;h2 id="analysis"&gt;&lt;a href="#analysis" class="header-anchor"&gt;&lt;/a&gt;Analysis
&lt;/h2&gt;&lt;p&gt;首先，为了分析 global batch LBL 优于 Micro batch 的关键原因，作者先同步所有 group 的矩阵 $G$, 然后再从全局 token 中随机选一批，用这批 token 计算专家选择频率。通过这个方法，我们可以保证 token 数量与 micro-batch 一致，但是分布于 Global-batch 一致。实验结果发现，这种方法的表现优于 micro-batch LBL, 说明 global batch LBL 的优势在于 Token 分布更全局，而不是 token 数量更多。&lt;/p&gt;
&lt;p&gt;作者还分析了 global batch LBL 和 micro batch LBL 两种模式，作者认为前者是后者的一个宽松版约束，作者发现从后者切换为前者之后，模型的表现可以得到进一步提升，但是其表现仍然不如一开始就使用 global batch LBL 更好。作者分析原因认为，这是因为 expert 收敛速度比较快。&lt;/p&gt;
&lt;p&gt;作者进一步通过降低 micro batch LBL 权重来探究是否可以达到同样的表现，结果发现适度江都权重确实可以提高模型的表现，但是降低太多会损害模型的表现，即此时出现了负载不均衡的现象&lt;/p&gt;
&lt;p&gt;作者对比了 global batch LBL 和 micro batch LBL 效率发现，前者比后者慢 $2\%$ 左右，这个差距几乎可以忽略不计&lt;/p&gt;
&lt;p&gt;作者进一步分析了不同 balancing 方式的专家特化程度，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-global-batch-load-balancing/Global-batch-LBL-balance-topK-score.png"
width="1269"
height="656"
loading="lazy"
alt="The topK score sums across layers"
class="gallery-image"
data-flex-grow="193"
data-flex-basis="464px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果发现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 global batch LBL 之后，topK sum 明显变大，这说明 routing 和 language modeling 任务对齐地更好&lt;/li&gt;
&lt;li&gt;global batch LBL 的专家在不同任务上的特化程度更明显&lt;/li&gt;
&lt;li&gt;micro batch LBL 的 topK sum 比较小&lt;/li&gt;
&lt;li&gt;Loss-free balancing 的 topK sum 介于 micro batch LBL 和 global batch LBL 之间&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusion"&gt;&lt;a href="#conclusion" class="header-anchor"&gt;&lt;/a&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;作者在本文中提出了 global LBL 来在全局为负载均衡提供指导，结果发现通过在更大的范围进行负载均衡的计算，我们可以有效提高专家的特化程度以及提高模型在下游任务上的表现&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/2501.11873" target="_blank" rel="noopener"
&gt;Arxiv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen3 VL</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/</link><pubDate>Fri, 05 Dec 2025 10:12:01 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/</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;作者在本文中提出了 Qwen3-VL 系列多模态大模型，包括 4 个 dense 模型和两个 MoE 模型，模型的上下文长度为 256K, 通过数据和训练上的优化，作者保持了模型的纯文本能力。最终 Qwen3-VL 包括 non-thinking 和 thinking variants.&lt;/p&gt;
&lt;p&gt;在架构上，Qwen3-VL 进行了三点改进：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Interleaved MRoPE: 作者解决了 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen2.5-vl/" target="_blank" rel="noopener"
&gt;Qwen2.5-VL&lt;/a&gt; 提出的 MRoPE 在长视频理解场景下的频谱不平衡问题&lt;/li&gt;
&lt;li&gt;DeepStack: 作者使用了 DeepStack 来提取 &lt;a class="link" href="https://maosong.website/p/notes-on-vit/" target="_blank" rel="noopener"
&gt;ViT&lt;/a&gt; 不同 layer 的视觉特征&lt;/li&gt;
&lt;li&gt;Explicit Video timestamps: 作者使用了绝对时间来标记 frame 来提供更直接的时间信息&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在数据上，作者使用了 image caption, OCR, grounding, spatial reasoning, code, long documents 以及 temporally grounded video 等数据，作者 还是用了 GUI-agent interaction 数据来提高模型的 action 能力&lt;/p&gt;
&lt;p&gt;在训练上，Qwen3-VL 包含两个大的阶段：pre-training 和 post-traing, pre-training 包含 4 个小阶段，post-training 包含 3 个阶段。&lt;/p&gt;
&lt;h2 id="architecture"&gt;&lt;a href="#architecture" class="header-anchor"&gt;&lt;/a&gt;Architecture
&lt;/h2&gt;&lt;p&gt;Qwen3-VL 的架构如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/Qwen3-VL-Architecture.png"
width="5908"
height="3413"
loading="lazy"
alt="Architecture of Qwen3-VL"
class="gallery-image"
data-flex-grow="173"
data-flex-basis="415px"
&gt;&lt;/p&gt;
&lt;p&gt;其中，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLM: LLM 使用了 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen3/" target="_blank" rel="noopener"
&gt;Qwen3&lt;/a&gt; 系列大语言模型，包括 2B, 4B, 8B, 32B 四个 dense model 以及 30B-A3B, 235B-A22B 两个 moe 模型&lt;/li&gt;
&lt;li&gt;Vision Encoder: encoder 基于 [[SigLip-2]] 初始化，然后使用了 dynamic input resolutions 进行 continue training, 作者使用了 &lt;a class="link" href="https://maosong.website/p/notes-on-comp/" target="_blank" rel="noopener"
&gt;CoMP&lt;/a&gt; 提出的 2D-RoPE 以及 interpolate absolute position embedding, 最终包括 SigLip2-SO-400M 和 SigLip-Large (300M) 两个 size, 后者用于 2B 和 4B 两个 size&lt;/li&gt;
&lt;li&gt;Patch Merger: 一个 2 层的 MLP, 将四个 visual token 压缩为 1 个&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="interleaved-mrope"&gt;&lt;a href="#interleaved-mrope" class="header-anchor"&gt;&lt;/a&gt;Interleaved MRoPE
&lt;/h3&gt;&lt;p&gt;这部分介绍见 [[MRoPE-Interleave]]&lt;/p&gt;
&lt;h3 id="deepstack"&gt;&lt;a href="#deepstack" class="header-anchor"&gt;&lt;/a&gt;DeepStack
&lt;/h3&gt;&lt;p&gt;受 Deepstack 启发，作者从 vision encoder 的中间层（具体来说是第 8， 16， 24 层）提取对应的视觉特征，然后经过 MLP 与 LLM 对应 layer 的视觉 token 直接进行相加。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/Qwen3-VL-DeepStack.png"
width="1723"
height="1024"
loading="lazy"
alt="architecture of DeepStack"
class="gallery-image"
data-flex-grow="168"
data-flex-basis="403px"
&gt;&lt;/p&gt;
&lt;h3 id="video-timestamp"&gt;&lt;a href="#video-timestamp" class="header-anchor"&gt;&lt;/a&gt;Video Timestamp
&lt;/h3&gt;&lt;p&gt;作者发现，&lt;a class="link" href="https://maosong.website/p/notes-on-qwen2.5-vl/" target="_blank" rel="noopener"
&gt;Qwen2.5-VL&lt;/a&gt; 中使用的 MRoPE 存在如下问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将 temporal position 与绝对时间绑定之后，对于长视频会产生非常大且稀疏的 temporal position ids&lt;/li&gt;
&lt;li&gt;需要使用不同的 FPS 进行采样来提高模型的泛化性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为了解决这个问题，作者使用了一个 textual token-based time encoding strategy, 其中每个 video temporal patch 对应的 timestamp 表示为 &lt;code&gt;&amp;lt;3.0 seconds&amp;gt;&lt;/code&gt;, 这样视频会被处理为以下格式&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;lt;0.0 seconds&amp;gt; &amp;lt;video token&amp;gt; &amp;lt;video token&amp;gt; ... &amp;lt;4.0 seconds&amp;gt; &amp;lt;video token&amp;gt; &amp;lt;video token&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在训练时，作者还使用了 seconds 以及 HMS 两种格式来提高模型对于不同格式的泛化能力。作者认为，虽然这种表示会提高上下文长度，但是也能够提高模型 video grounding 或者 dense captioning 等时序信息敏感任务的表现&lt;/p&gt;
&lt;h2 id="pre-training"&gt;&lt;a href="#pre-training" class="header-anchor"&gt;&lt;/a&gt;Pre-training
&lt;/h2&gt;&lt;h3 id="training-recipe"&gt;&lt;a href="#training-recipe" class="header-anchor"&gt;&lt;/a&gt;Training Recipe
&lt;/h3&gt;&lt;p&gt;预训练阶段包含 4 个阶段，如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/Qwen3-VL-pre-training-recipe.png"
width="1209"
height="216"
loading="lazy"
alt="Qwen3-VL pretraining recipe"
class="gallery-image"
data-flex-grow="559"
data-flex-basis="1343px"
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stage 0: 这一阶段的目的是对齐视觉特征和文本特征，只训练 Patch merger, 训练使用了 67B token, 覆盖 image-caption, knowledge, OCR 数据，上下文长度为 8192&lt;/li&gt;
&lt;li&gt;Stage 1: 这一阶段所有参数都参加训练，训练使用了 1Ttoken, 作者在训练是加入了纯文本数据，最终数据包含 interleaved image-text, visual grounding, VQA, STEM, video 数据，上下文长度为 8192&lt;/li&gt;
&lt;li&gt;Stage 2: 这一阶段的目的是扩展模型的上下文长度到 32K, 训练使用了 1T token, 数据包括长视频以及 agent-oriented instruction-following 数据&lt;/li&gt;
&lt;li&gt;Stage 3: 这一阶段的目的是将模型的上下文长度进一步扩展到 262K, 训练使用了 100B token. 数据包括长视频以及长文本&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="data"&gt;&lt;a href="#data" class="header-anchor"&gt;&lt;/a&gt;Data
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;Image Caption Data: 作者使用了 Qwen2.5-VL 32B 来进行 re-captioning, 然后进行了 de-duplication 以及 clustering 来提高数据的质量和多样性&lt;/li&gt;
&lt;li&gt;Interleaved Text-Image Data: 作者对文档进行分裂，然后使用微调的 Qwen2.5-VL 7B 来进行解析，对于长文本，作者将连续页面拼接在一起。作者使用了对齐以及页数来保证数据的质量&lt;/li&gt;
&lt;li&gt;Knowledge Data: 作者构建了多个类别的数据，然后对这些数据进行 refine&lt;/li&gt;
&lt;li&gt;OCR: 作者构造了 30M 的数据以及 1M 的多语种数据&lt;/li&gt;
&lt;li&gt;Document Parsing Data: 作者从 CC 上收集了 3M PDF 以及处理了自有的 4M 数据，最终数据集里包含合成数据和真实数据；对于长文档理解数据，作者通过将 single-page 数据 merge 在一起得到，然后作者构造了 long document VQA 数据&lt;/li&gt;
&lt;li&gt;Grounding and counting Data: grounding 数据包括 box-based 和 Point-based 两种形式，均从开源数据集收集得到，前者包括 RefCOCO, Object365, 后者包括 PixMo; 对于 Counting, 作者基于 grounding 数据构造了 direct counting, box-based counting 以及 point-based counting 三种形式&lt;/li&gt;
&lt;li&gt;Spatial Understanding: 数据包括 spatial understanding 和 3D grounding 两类数据，前者的数据使用了相对位置关系来提高 spatial reasoning 的 robustness; 后者使用了 Omni3D 来统一数据格式&lt;/li&gt;
&lt;li&gt;Code: 包括 Qwen3, Qwen3-Coder 的纯文本 coding 数据，以及多模态 coding 数据，覆盖了将 UI 截图转换为 HTML/CSS 以及从图片生成 SVG 等任务&lt;/li&gt;
&lt;li&gt;Video: 包括 Dense Caption Synthesis 以及 Spatial-Temporal Video Grounding 两个任务。作者还对不同来源不同长度的数据进行了平衡&lt;/li&gt;
&lt;li&gt;STEM: 作者构造了一个合成数据 pipeline, 合成了 1M point-grounding samples, 2M perception-oriented VQA 数据，最终数据集包含 6M 标注图表数据，覆盖了 STEM 相关学科；对于多模态推理数据，作者收集了 60M 的 K12 以及本科生级别的练习题，作者还合成了 12M 的多模态推理数据。除了多模态推理数据，作者还加入了纯文本推理数据&lt;/li&gt;
&lt;li&gt;Agent: 这部分数据包括 GUI, function calling 以及 Search 三部分， GUI 数据通过数据合成得到，Function calling 数据通过强模型生成轨迹得到，search 数据通过收集执行搜索轨迹得到&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="post-training"&gt;&lt;a href="#post-training" class="header-anchor"&gt;&lt;/a&gt;Post-training
&lt;/h2&gt;&lt;p&gt;Post-training 包含三个阶段：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;SFT: 提高模型的指令跟随能力，SFT 又分为了两个小阶段，上下文长度分别为 32K 和 256K, 对于 instruct 和 reasoning 版本，作者设计了不同的数据格式，后者包含 CoT reasoning trace&lt;/li&gt;
&lt;li&gt;Strong-to-Weak Distillation: 提高小模型的能力，这里应该是和 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen3/" target="_blank" rel="noopener"
&gt;Qwen3&lt;/a&gt; 一样，将大模型的能力蒸馏到小模型里&lt;/li&gt;
&lt;li&gt;RL: 提高模型的 reasoning 能力以及人类偏好对齐。这里包含了 Reasoning RL 以及 General RL 两个阶段，覆盖了 math, OCR, grounding, instruction following 等 domain&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;整体的训练 pipeline 我猜测应该是这样：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/Qwen3-VL-post-training-pipeline.png"
width="1282"
height="279"
loading="lazy"
alt="Post-training pipeline of Qwen3-VL (guessed)"
class="gallery-image"
data-flex-grow="459"
data-flex-basis="1102px"
&gt;&lt;/p&gt;
&lt;h3 id="code-start-data"&gt;&lt;a href="#code-start-data" class="header-anchor"&gt;&lt;/a&gt;Code-start Data
&lt;/h3&gt;&lt;p&gt;Code-start Data 分为 SFT 数据和 Long CoT SFT 数据，前者用于训练 instruct 版模型，后者用于训练 reasoning 版模型&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;th&gt;tasks&lt;/th&gt;
&lt;th&gt;samples&lt;/th&gt;
&lt;th&gt;training&lt;/th&gt;
&lt;th&gt;filtering&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SFT&lt;/td&gt;
&lt;td&gt;spatial reasoning&lt;br&gt;image-grounded reasoning&lt;br&gt;spatio-temporal grounding&lt;br&gt;long document understanding&lt;/td&gt;
&lt;td&gt;1.2M (1/3 are text-only)&lt;/td&gt;
&lt;td&gt;- stage 1: 32K&lt;br&gt;- stage 2: 256K&lt;/td&gt;
&lt;td&gt;- query &lt;br&gt;- rule-based&lt;br&gt;- model-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long CoT SFT&lt;/td&gt;
&lt;td&gt;VQA, OCR, 2D/3D grounding, &lt;br&gt;video analysis, STEM, agent&lt;/td&gt;
&lt;td&gt;text:multimodal = 1:1&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;- difficulty&lt;br&gt;- multi-modal&lt;br&gt;- response quality&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="strong-to-weak-distillation"&gt;&lt;a href="#strong-to-weak-distillation" class="header-anchor"&gt;&lt;/a&gt;Strong-to-Weak Distillation
&lt;/h3&gt;&lt;p&gt;蒸馏过程包括两个阶段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;off-policy Distillation: 使用教师模型的输出进行训练提高模型基本的 reasoning 能力&lt;/li&gt;
&lt;li&gt;On-policy Distillation: 使用教师模型输出的 logit 作为蒸馏信号提高模型的 reasoning 能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rl"&gt;&lt;a href="#rl" class="header-anchor"&gt;&lt;/a&gt;RL
&lt;/h3&gt;&lt;h4 id="reasoning-rl"&gt;&lt;a href="#reasoning-rl" class="header-anchor"&gt;&lt;/a&gt;Reasoning RL
&lt;/h4&gt;&lt;p&gt;作者收集了 30K 的 RL 数据，然后对通过率超过 90% 的数据进行过滤 (16 responses per query), 对于 reward, 作者构建了一个 unified reward framework 来提供奖励&lt;/p&gt;
&lt;p&gt;训练时，作者使用了 &lt;a class="link" href="https://maosong.website/p/notes-on-sapo/" target="_blank" rel="noopener"
&gt;SAPO&lt;/a&gt; 算法进行训练&lt;/p&gt;
&lt;h4 id="general-rl"&gt;&lt;a href="#general-rl" class="header-anchor"&gt;&lt;/a&gt;General RL
&lt;/h4&gt;&lt;p&gt;作者采用了一个 multi-task RL 的范式来提高模型在不同任务上的表现，reward 主要包含两个方面：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;instruction following: 评估模型遵循用户指令的能力，包括内容，格式，长度等&lt;/li&gt;
&lt;li&gt;preference alignment: 对于开放式问题，评估模型帮助性，事实准确性等方面的表现&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基于这两个方面 reward 有两个部分组成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;rule-based reward: 基于规则的 reward, 比如格式要求等&lt;/li&gt;
&lt;li&gt;model-based reward: 使用 Qwen2.5-VL 72B 和 Qwen3 作为 judge model 来提供奖励&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为了解决模型的重复性实处，中英文混杂等问题，作者构造了一个数据集来故意触发模型这些问题然后加以改正。&lt;/p&gt;
&lt;h3 id="thinking-with-images"&gt;&lt;a href="#thinking-with-images" class="header-anchor"&gt;&lt;/a&gt;Thinking with Images
&lt;/h3&gt;&lt;p&gt;作者还够在了数据提高模型的 &amp;ldquo;thinking with images&amp;rdquo; 的能力，训练包含两个阶段：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stage 1: 作者构造了 10K Grounding 数据，然后对 Qwen2.5-VL 32B 进行 SFT 来模仿 agent 的行为: think -&amp;gt; act -&amp;gt; analyze feedback -&amp;gt; answer, 然后作者使用 multi-turn, tool-integrated RL 来进一步提高模型的 reasoning 能力&lt;/li&gt;
&lt;li&gt;Stage 2: 作者从 Qwen2.5-VL 32B 蒸馏得到 120K multi-turn agentic interactions 数据集， 然后作者使用了相似的 cold-start SFT 以及 tool-integrated RL pipeline 来训练 Qwen3-VL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这里 RL 训练的 reward 包含以下几部分：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;answer accuracy reward&lt;/li&gt;
&lt;li&gt;multi-turn reasoning reward&lt;/li&gt;
&lt;li&gt;tool-calling reward&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="experiments"&gt;&lt;a href="#experiments" class="header-anchor"&gt;&lt;/a&gt;Experiments
&lt;/h2&gt;&lt;h3 id="performance"&gt;&lt;a href="#performance" class="header-anchor"&gt;&lt;/a&gt;Performance
&lt;/h3&gt;&lt;p&gt;Qwen3-VL 235B-A22B 的表现如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/Qwen3-VL-performance.png"
width="721"
height="1060"
loading="lazy"
alt="Performance of Qwen3-VL 235B-A22B"
class="gallery-image"
data-flex-grow="68"
data-flex-basis="163px"
&gt;&lt;/p&gt;
&lt;h3 id="ablation-study"&gt;&lt;a href="#ablation-study" class="header-anchor"&gt;&lt;/a&gt;Ablation Study
&lt;/h3&gt;&lt;p&gt;作者对比了以下 Qwen3-ViT 和 SigLIP-2 的表现，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/Qwen3-VL-ablation-on-ViT.png"
width="1349"
height="136"
loading="lazy"
alt="Ablation on Qwen3-ViT"
class="gallery-image"
data-flex-grow="991"
data-flex-basis="2380px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果显示，使用 1.7B 的 Qwen3 和 1.5T tokens 进行训练之后，Qwen3-ViT 的表现超过了 SigLIP2 的表现，验证了 Qwen3-ViT 的有效性&lt;/p&gt;
&lt;p&gt;作者对比了 Deepseek 和 baseline 的表现，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-vl/Qwen3-VL-Ablation-on-Deepstack.png"
width="1355"
height="130"
loading="lazy"
alt="Ablation on DeepStack"
class="gallery-image"
data-flex-grow="1042"
data-flex-basis="2501px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，相比于 baseline, DeepStack 的表现更好，说明了 DeepStack 可以提供更丰富的视觉信息。&lt;/p&gt;
&lt;p&gt;作者还评估了以下 Qwen3-VL 在视频版大海捞针任务上的表现，实验结果发现，对于 30 分钟的视频，Qwen3-VL 的准确率为 $100\%$, 通过 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 上下文扩展策略，模型在 2 个小时视频上的准确率为 $99.5\%$.&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;作者在本文中提出了 Qwen3-VL 系列多模态大模型，在架构上，作者使用了 interleaved-MRoPE, DeepStack 等改进策略，在数据上，作者扩展了训练数据的多样性，在训练上，作者分别训练了 instruct 版本和 reasoning 版本。最终评估发现，Qwen3-VL 达到了 SOTA 表现。&lt;/p&gt;
&lt;p&gt;作者认为，未来的工作在于&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;基于 Qwen3-VL 构建具身智能 agent&lt;/li&gt;
&lt;li&gt;提高模型的可交互感知，tool-augmented reasoning 以及 real-time multimodal control 能力&lt;/li&gt;
&lt;li&gt;提高模型与人类学习，合作的能力&lt;/li&gt;
&lt;li&gt;统一理解与生成多模态大模型&lt;/li&gt;
&lt;/ol&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="https://qwen.ai/blog?id=99f0335c4ad9ff6153e517418d48535ab6d8afef&amp;amp;from=research.latest-advancements-list" target="_blank" rel="noopener"
&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="http://arxiv.org/abs/2511.21631" target="_blank" rel="noopener"
&gt;Arxiv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on SAPO</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-sapo/</link><pubDate>Fri, 05 Dec 2025 10:09:06 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-sapo/</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;相关工作包括 GRPO 以及 &lt;a class="link" href="https://maosong.website/p/notes-on-gspo/" target="_blank" rel="noopener"
&gt;GSPO&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;SAPO 的关键思想有两点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;tokne-level soft trust region 可以保证 sequence-level coherence&lt;/li&gt;
&lt;li&gt;非对称的 temperature 可以针对 postive token 和 negative token 进行不同的优化&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;p&gt;作者首先给出了 SAPO 的目标函数如下：&lt;/p&gt;
$$
\mathcal{J}_{\mathrm{SAPO}}(\theta) = \mathbb{E}_{(x, y)\sim\mathcal{D},\{y_i\}_{i=1}^G\sim \pi_{\theta_{old}}(\cdot\mid x)}\left[ \frac{1}{G}\sum_{i=1}^G\frac{1}{|y_i|}\sum_{t=1}^{|y_i|}f_{i,t}(r_{i,t}(\theta))\hat{A}_{i,t} \right],
$$&lt;p&gt;其中，&lt;/p&gt;
$$
f_{i,t}(x) = \sigma(\tau_{i,t}(x-1))\cdot \frac{4}{\tau_{i,t}}, \tau_{i,t} = \begin{cases}
\tau_{pos}, &amp; \text{if }\hat{A}_{i,t}&gt;0\\
\tau_{neg}, &amp;\text{otherwise}
\end{cases}
$$&lt;p&gt;这里&lt;/p&gt;
$$
\hat{A}_{i,t} = \hat{A}_{i} = \frac{r(x,y_i) - \mathrm{mean}(\{r(x,y_i)\}_{i=1}^G)}{\mathrm{std}(\{r(x,y_i)\}_{i=1}^G)},\quad r_{i,t}(\theta) = \frac{\pi_{\theta}(y_{i,t}\mid x, y_{i,&lt; t})}{\pi_{\theta_{old}}(y_{i,t}\mid x, y_{i,&lt; t})}
$$&lt;p&gt;$\tau_{pos}$ 和 $\tau_{neg}$ 分别是 positive token 以及 negative token 对应的温度, $\sigma(x)=1/(1+e^{-x})$ 是 sigmoid function.&lt;/p&gt;
&lt;p&gt;对 $\mathcal{J}_{\mathrm{SAPO}}(\theta)$ 求导得到&lt;/p&gt;
$$
\nabla_\theta \mathcal{J}_{\mathrm{SAPO}}(\theta) = \mathbb{E}_{(x, y)\sim\mathcal{D},\{y_i\}_{i=1}^G\sim \pi_{\theta_{old}}(\cdot\mid q)}\left[ \frac{1}{G}\sum_{i=1}^G\frac{1}{|y_i|}\sum_{t=1}^{|y_i|}w_{i,t}(\theta)r_{i,t}(\theta)\nabla_\theta \log \pi_\theta(y_{i,t}\mid q, y_{i, &lt;t}) \right]
$$&lt;p&gt;其中&lt;/p&gt;
$$
w_{i,t}(\theta) = 4p_{i,t}(\theta)(1-p_{i,t}(\theta)),\quad p_{i,t}(\theta) = \sigma(\tau_{i,t} (r_{i,t}(\theta)-1)),
$$&lt;p&gt;$\mathcal{J}_{\mathrm{SAPO}}(\theta)$ 和 $w_{i,t}(\theta)$ 与 $r_{i,t}(\theta)$ 的关系如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-sapo/SAPO-gating-illustration.png"
width="1352"
height="426"
loading="lazy"
alt="illustration of gating mechanism"
class="gallery-image"
data-flex-grow="317"
data-flex-basis="761px"
&gt;&lt;/p&gt;
&lt;p&gt;为了保证当 $r_{i,t}(\theta)=1$ 时，SAPO 等价于 $r_{i,t}(\theta)\hat{A}_{i,t}$ 而与 $\tau_{i,t}$ 无关，作者在 $f_{i,t}(x)$ 加入了系数 $4/\tau_{i,t}$.&lt;/p&gt;
&lt;h2 id="comparison"&gt;&lt;a href="#comparison" class="header-anchor"&gt;&lt;/a&gt;Comparison
&lt;/h2&gt;&lt;p&gt;作者接下来对比了 GSPO 以及 GRPO 两个算法&lt;/p&gt;
&lt;p&gt;首先作者使用了一下统一的目标函数公式来表示三个算法&lt;/p&gt;
$$
\mathcal{J}(\theta) = \mathbb{E}_{(x, y)\sim\mathcal{D},\{y_i\}_{i=1}^G\sim \pi_{\theta_{old}}(\cdot\mid x)}\left[ \frac{1}{G}\sum_{i=1}^G\frac{1}{|y_i|}\sum_{t=1}^{|y_i|}f_{i,t}(r_{i,t}(\theta))\hat{A}_{i,t} \right],
$$&lt;p&gt;其中不同算法的 $f_{i,t}(\cdot)$ 不一样，三种算法的定义如下&lt;/p&gt;
$$
\begin{aligned}
\mathrm{SAPO}&amp;:f_{i,t}^{\mathrm{SAPO}}(r_{i,t}(\theta))=\sigma(\tau_{i,t}(x-1))\cdot \frac{4}{\tau_{i,t}}, \tau_{i,t} = \begin{cases}
\tau_{pos}, &amp; \text{if }\hat{A}_{i,t}&gt;0\\
\tau_{neg}, &amp;\text{otherwise}
\end{cases}\\
\mathrm{GRPO}&amp;:f_{i,t}^{\mathrm{GRPO}}(r_{i,t}(\theta), \hat{A}_{i,t})=\begin{cases}
\min(r_{i,t}(\theta), 1+\epsilon) &amp; \hat{A}_{i,t}&gt;0\\
\max(r_{i,t}(\theta), 1-\epsilon) &amp; \hat{A}_{i,t}\leq0
\end{cases}\\
\mathrm{GSPO}&amp;:f_{i,t}^{\mathrm{GSPO}}(r_{i,t}(\theta), \hat{A}_{i,t})=f_{i,t}^{\mathrm{seq}}(r_{i,t}(\theta), \hat{A}_{i,t})=\begin{cases}
\min(s_{i,t}(\theta), 1+\epsilon) &amp; \hat{A}_{i,t}&gt;0\\
\max(s_{i,t}(\theta), 1-\epsilon) &amp; \hat{A}_{i,t}\leq0
\end{cases}
\end{aligned}
$$&lt;p&gt;其中&lt;/p&gt;
$$
s_i(\theta) = \left(\frac{\pi_{\theta}(y_{i}\mid x)}{\pi_{\theta_{old}}(y_{i}\mid x)}\right)^{\frac{1}{|y_i|}}, s_{i,t}(\theta) = \mathrm{sg}[s_i(\theta)]\frac{\pi_{\theta}(y_{i,t}\mid x, y_{i,&lt; t})}{\mathrm{sg}[\pi_{\theta}(y_{i,t}\mid x, y_{i,&lt; t})]}
$$&lt;p&gt;首先是与 GSPO 的对比，通过一些假设和简化，我们得到&lt;/p&gt;
$$
\begin{aligned}
\nabla_\theta \mathcal{J}_{\mathrm{SAPO}}(\theta) &amp;=\mathbb{E}\left[\frac1G\sum_{i=1}^G g_{\tau_i}(\log s_i(\theta))\nabla_\theta \log s_i(\theta)\hat{A}_i\right]\\
\nabla_\theta \mathcal{J}_{\mathrm{GSPO}}(\theta) &amp;=\mathbb{E}\left[\frac1G\sum_{i=1}^G s_i(\theta)\nabla_\theta \log s_i(\theta)\hat{A}_i\right]
\end{aligned}
$$&lt;p&gt;其中 $g_{\tau_i}(\log s_i(\theta)) = \mathrm{sech}^2\left(\tau_i/2\log s_i(\theta)\right)$. 相比于 GSPO, SAPO 有两个优势：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;smoothness and stability, soft gate 避免了 hard clipping 带来的不连续性&lt;/li&gt;
&lt;li&gt;token-level adaptivity with sequence-level coherence. 当假设不成立的时候，SAPO 退化为 token-level gating, 这样可以降低 outliers 的权重&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;GRPO 的函数可以进一步简化为&lt;/p&gt;
$$
f_{i,t}^{\mathrm{GRPO}}(r_{i,t}(\theta), \hat{A}_{i,t})= \begin{cases}
1, &amp; \text{if }\hat{A}_{i,t}&gt;0\text{ and }r_{i,t}(\theta)\leq 1+ \epsilon\\
0, &amp; \text{if }\hat{A}_{i,t}&gt;0\text{ and }r_{i,t}(\theta)&gt; 1+ \epsilon\\
1, &amp; \text{if }\hat{A}_{i,t}\leq0\text{ and }r_{i,t}(\theta)\geq 1- \epsilon\\
0, &amp; \text{if }\hat{A}_{i,t}\leq0\text{ and }r_{i,t}(\theta)&lt; 1- \epsilon
\end{cases}\\
$$&lt;p&gt;可以看到，GRPO 对应一个 binary trust region. 与 GRPO 相比，SAPO 将对应的 hard indicator 替换未来一个 smooth kernel $f_{i,t}^{\mathrm{SAPO}}(r_{i,t}(\theta))=\mathrm{sech}^2\left(\tau_i/2r_{i,t}(\theta)-1\right)$, 这样可以避免 gradient vanishing 以及提高训练的稳定性。&lt;/p&gt;
&lt;p&gt;最终结论为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;相比于 GSPO, SAPO 对于 off-policy 的数据利用率更高&lt;/li&gt;
&lt;li&gt;相比于 GRPO, SAPO 避免了 hard token level clipping 导致的 zero-gradient 问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="experiments"&gt;&lt;a href="#experiments" class="header-anchor"&gt;&lt;/a&gt;Experiments
&lt;/h2&gt;&lt;p&gt;作者对比了 SAPO, GSPO 以及 GRPO-R2(GRPO with routing replay) 三种方法，实验结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-sapo/SAPO-performance.png"
width="1211"
height="869"
loading="lazy"
alt="Performance of SAPO"
class="gallery-image"
data-flex-grow="139"
data-flex-basis="334px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果显示，SAPO 的表现超过了 GSPO 以及 GRPO&lt;/p&gt;
&lt;p&gt;作者还探究了超参数 $\tau_{pos}$ 和 $\tau_{neg}$ 的影响，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-sapo/SAPO-ablation-on-temperature.png"
width="1219"
height="853"
loading="lazy"
alt="Ablation study on temperature"
class="gallery-image"
data-flex-grow="142"
data-flex-basis="342px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果显示，当 $\tau_{neg}&gt;\tau_{pos}$ 时，模型训练最稳定，这说明了 negative token 是导致训练不稳定的主要原因。&lt;/p&gt;
&lt;p&gt;作者还在 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen3-vl/" target="_blank" rel="noopener"
&gt;Qwen3-VL&lt;/a&gt; 上进行了验证，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-sapo/SAPO-Qwen3-VL-perfornance.png"
width="1220"
height="447"
loading="lazy"
alt="Performance of SAPO on Qwen3-VL"
class="gallery-image"
data-flex-grow="272"
data-flex-basis="655px"
&gt;&lt;/p&gt;
&lt;p&gt;实验结果显示，SAPO 的表现超过了 GSPO 以及 GRPO-R2&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;在本文中，作者提出了 SAPO, 一个解决 hard-clipping 训练不稳定性以及低效率的策略优化算法，作者使用了基于温度的 soft gate 来代替 clipping, 以及对于 positive token 和 negative token 使用了不同的 temperature 这两点改进。结果验证了 SAPO 的有效性，作者认为使用 smooth 以及 adaptive gating 机制可以有效提高 RL 训练的稳健性以及有效性。&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/2511.20347" target="_blank" rel="noopener"
&gt;arxiv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on GSPO</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-gspo/</link><pubDate>Wed, 06 Aug 2025 11:26:26 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-gspo/</guid><description>&lt;p&gt;Qwen 提出了 Group Sequence Policy Optimization (GSPO), 一个针对 GRPO 进行改进的 RL 算法。GSPO 在 sequence 层面计算 importance ratio, 避免了 token-level 计算带来的训练不稳定性。&lt;/p&gt;
&lt;h2 id="introduction"&gt;&lt;a href="#introduction" class="header-anchor"&gt;&lt;/a&gt;Introduction
&lt;/h2&gt;&lt;p&gt;GRPO 的问题在于训练超大规模的 LLM 时，会出现 model collapse, &lt;a class="link" href="https://maosong.website/p/notes-on-qwen3/" target="_blank" rel="noopener"
&gt;Qwen3&lt;/a&gt; 和 &lt;a class="link" href="https://maosong.website/p/notes-on-minimax-01/" target="_blank" rel="noopener"
&gt;MiniMax-01&lt;/a&gt; 均对 GRPO 算法进行了改进。&lt;/p&gt;
&lt;p&gt;在本文中，作者认为 GRPO 算法的问题在于 Importance sampling weight 的计算是有问题的，这导致了误差随生成回答长度累积，最后被 clipping 机制放大，从而导致模型崩溃。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，作者提出了 GSPO, 一个在 sequence 层面进行 Importance sampling 的 RL 算法，GSPO 还对 reward 进行 normalization 来保持训练的稳定性&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="preliminary"&gt;&lt;a href="#preliminary" class="header-anchor"&gt;&lt;/a&gt;Preliminary
&lt;/h3&gt;&lt;p&gt;对于一个大语言模型 $\pi_{\theta}$, 我们将 $x$ 记为 query, 将 $y$ 记为 $\pi_{\theta}$ 针对 $x$ 的 response, 即&lt;/p&gt;
$$
\pi_{\theta}(y\mid x) = \prod_{t=1}^{|y|}\pi_{\theta}(y_t\mid x, y_{&lt;t})
$$&lt;p&gt;其中 $|y|$ 代表 response $y$ 的长度, 一般我们还有一个 reward model $r$, 用于生成奖励 $r(x,y)\in[0, 1]$.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!tip] Note
本文中没有提及 KL divergence, 作者认为这不是重点，所以没有在公式中标出。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PPO 算法包含四个模型：reference model, 也就是 $\pi_{old}$, policy model, 也就是 $\pi_{\theta}$, value model, 用于计算 advantage, 以及 reward model, 用于计算奖励。 PPO 算法如下面公式所示&lt;/p&gt;
$$
\mathcal{J}_{\mathrm{PPO}}(\theta) = \mathbb{E}_{(x,y)\sim\mathcal{D},y_{\leq t}\sim \pi_{\theta_{old}}(\cdot\mid q)}\left[ \min\left(r_t(\theta)\hat{A}_t,\mathrm{clip}\left(r_t(\theta), 1-\epsilon, 1+\epsilon\right)\hat{A}_t\right) \right]
$$&lt;p&gt;其中&lt;/p&gt;
$$
r_t(\theta) = \frac{\pi_{\theta}(y_t\mid x, y_{&lt; t})}{\pi_{\theta_{old}}(y_t\mid x, y_{&lt; t})}
$$&lt;p&gt;是 token $y_t$ 的 importance ratio, $\hat{A}_t$ 是 $y_t$ 的 advantage estimation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PPO&lt;/strong&gt; 算法的问题在于其严重依赖 value model, 一般 value model 与 policy model 的大小相当，以保持内存和算力的负载均衡。&lt;/p&gt;
&lt;p&gt;为了解决 PPO 的这个问题，GRPO 通过多次采样然后计算 relative advantage 来避免使用 value model. 其目标函数为&lt;/p&gt;
$$
\mathcal{J}_{\mathrm{GRPO}}(\theta) = \mathbb{E}_{(x, y)\sim\mathcal{D},\{y_i\}_{i=1}^G\sim \pi_{\theta_{old}}(\cdot\mid q)}\left[ \frac{1}{G}\sum_{i=1}^G\frac{1}{|y_i|}\sum_{t=1}^{|y_i|}\min\left(r_{i,t}(\theta)\hat{A}_{i,t},\mathrm{clip}\left(r_{i,t}(\theta), 1-\epsilon, 1+\epsilon\right)\hat{A}_{i,t}\right) \right]
$$&lt;p&gt;其中，$G$ 是针对 query $x$ 的多次采样 response,&lt;/p&gt;
$$
r_{i,t}(\theta) = \frac{\pi_{\theta}(y_{i,t}\mid x, y_{i,&lt; t})}{\pi_{\theta_{old}}(y_{i,t}\mid x, y_{i,&lt; t})}
$$&lt;p&gt;是 importance ratio,&lt;/p&gt;
$$
\hat{A}_{i,t} = \hat{A}_{i} = \frac{r(x,y_i) - \mathrm{mean}(\{r(x,y_i)\}_{i=1}^G)}{\mathrm{std}(\{r(x,y_i)\}_{i=1}^G)}
$$&lt;p&gt;是使用 group response 估计得到的 advantage.&lt;/p&gt;
&lt;h3 id="motivation"&gt;&lt;a href="#motivation" class="header-anchor"&gt;&lt;/a&gt;Motivation
&lt;/h3&gt;&lt;p&gt;在 Qwen3 中已经提到，对于稀疏的 MoE 模型，我们必须使用更大的 batch size 来最大化内存和算力使用效率。但是，更大的 batch 意味着有一些数据必须是 off-policy 的，因此 PPO 和 GRPO 就需要使用 clipping 来降低 off-policy sample 对模型表现产生过大影响。&lt;/p&gt;
&lt;p&gt;基于 clipping 机制，作者认为 GRPO 的目标函数是 &amp;ldquo;ill-pose&amp;rdquo; 的，其原因在于 GRPO 计算的 Importance ratio 是与 RL 训练目标不匹配的。&lt;/p&gt;
&lt;p&gt;通常，importance sampling 的公式如下：&lt;/p&gt;
$$
\mathbb{E}_{z\sim\pi_{\mathrm{tar}}}[f(z)] = \mathbb{E}_{z\sim\pi_{\mathrm{beh}}}\left[\frac{\pi_{\mathrm{tar}}(z)}{\pi_{\mathrm{beh}}(z)}f(z)\right]
$$&lt;p&gt;其中 $\pi_{\mathrm{tar}}$ 是目标分布， $\pi_{\mathrm{beh}}$ 是采样分布, importance ratio $\pi_{\mathrm{tar}}(z)/\pi_{\mathrm{beh}}(z)$ 负责对采样进行修正。&lt;/p&gt;
&lt;p&gt;对于 GRPO, 其 importance ratio 是在 token 层面定义的，而一次采样是在 sequence 层面定义的，因此这种区别就导致了 GRPO 存在 high-variance noise.&lt;/p&gt;
&lt;p&gt;因此，作者认为，&lt;strong&gt;Importance ratio 的关键在于优化目标应该与 reward 的粒度是一致的&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="gspo"&gt;&lt;a href="#gspo" class="header-anchor"&gt;&lt;/a&gt;GSPO
&lt;/h3&gt;&lt;p&gt;基于上面的想法，作者就提出了 GSPO, 作者首先针对 LLM 改写了上面的 importance sampling 的公式&lt;/p&gt;
$$
\mathbb{E}_{x\sim \mathcal{D}, y\sim\pi_{\theta}(\cdot\mid x)}[r(x,y)] = \mathbb{E}_{x\sim\mathcal{D}, y\sim\pi_{\theta_{old}}(\cdot\mid x)}\left[\frac{\pi_{\theta}(y\mid x)}{\pi_{\theta_{old}}(y\mid x)}r(x,y)\right]
$$&lt;p&gt;这里的 Importance ratio 表现了采样的回答 $\pi_{old}(y\mid x)$ 与目标回答 $\pi_{\theta}(y\mid x)$ 之间的差距，这是从 sequence 层面上体现的。&lt;/p&gt;
&lt;p&gt;因此，作者基于上面的式子，构建出了 GSPO 的目标函数&lt;/p&gt;
$$
\mathcal{J}_{\mathrm{GSPO}}(\theta) = \mathbb{E}_{(x, y)\sim\mathcal{D},\{y_i\}_{i=1}^G\sim \pi_{\theta_{old}}(\cdot\mid q)}\left[ \frac{1}{G}\sum_{i=1}^G\min\left(s_{i}(\theta)\hat{A}_{i},\mathrm{clip}\left(s_{i}(\theta), 1-\epsilon, 1+\epsilon\right)\hat{A}_{i}\right) \right]
$$&lt;p&gt;这里 $\hat{A}_{i}$ 与 GRPO 一致， $s_i(\theta)$ 是 normalize 之后的 importance ratio, 定义如下&lt;/p&gt;
$$
s_i(\theta) = \left(\frac{\pi_{\theta}(y_{i}\mid x)}{\pi_{\theta_{old}}(y_{i}\mid x)}\right)^{\frac{1}{|y_i|}} = \exp\left(\frac{1}{|y_i|}\sum_{i=1}^{|y_i|}\frac{\pi_{\theta}(y_{i,t}\mid x, y_{i,&lt; t})}{\pi_{\theta_{old}}(y_{i,t}\mid x, y_{i,&lt; t})}\right)
$$&lt;p&gt;这里作者使用了 length normalization 来控制 variance.&lt;/p&gt;
&lt;p&gt;作者对比了以下 GSPO 和 GRPO 两者的梯度，我们忽略期望的计算，直接写出内部的梯度，有&lt;/p&gt;
$$
\begin{aligned}
\nabla_\theta \mathcal{J}_{\mathrm{GSPO}}(\theta) &amp;= \frac{1}{G}\sum_{i=1}^G\left(\frac{\pi_{\theta}(y_{i}\mid x)}{\pi_{\theta_{old}}(y_{i}\mid x)}\right)^{\frac{1}{|y_i|}}\hat{A}_i\cdot \frac{1}{|y_i|}\sum_{t=1}^{|y_i|} \nabla_{\theta} \log\pi_{\theta}(y_{i,t}\mid x, y_{&lt;t})\\
\nabla_\theta \mathcal{J}_{\mathrm{GRPO}}(\theta) &amp;= \frac{1}{G}\sum_{i=1}^G\hat{A}_i\cdot \frac{1}{|y_i|}\sum_{t=1}^{|y_i|} \frac{\pi_{\theta}(y_{i,t}\mid x, y_{i,&lt; t})}{\pi_{\theta_{old}}(y_{i,t}\mid x, y_{i,&lt; t})}\nabla_{\theta} \log\pi_{\theta}(y_{i,t}\mid x, y_{&lt;t})\\
\end{aligned}
$$&lt;p&gt;可以看到，两者不同的地方在于 token 的 reweight 方式，GRPO 中先加权再求和；而 GSPO 中则是先求和，然后在 sequence 层面进行加权&lt;/p&gt;
&lt;h3 id="gspo-token"&gt;&lt;a href="#gspo-token" class="header-anchor"&gt;&lt;/a&gt;GSPO-token
&lt;/h3&gt;&lt;p&gt;为了支持 multi-turn RL 等需要细粒度 advantage 的场景，作者对 GSPO 的目标函数进行了改进，得到了 GSPO-token, 其目标函数为&lt;/p&gt;
$$
\mathcal{J}_{\mathrm{GSPO-token}}(\theta) = \mathbb{E}_{(x, y)\sim\mathcal{D},\{y_i\}_{i=1}^G\sim \pi_{\theta_{old}}(\cdot\mid q)}\left[ \frac{1}{G}\sum_{i=1}^G\frac{1}{|y_i|}\sum_{t=1}^{|y_i|}\min\left(s_{i,t}(\theta)\hat{A}_{i},\mathrm{clip}\left(s_{i,t}(\theta), 1-\epsilon, 1+\epsilon\right)\hat{A}_{i}\right) \right]
$$&lt;p&gt;其中，&lt;/p&gt;
$$
s_{i,t}(\theta) = \mathrm{sg}[s_i(\theta)]\frac{\pi_{\theta_{old}}(y_{i,t}\mid x, y_{i,&lt; t})}{\mathrm{sg}[\pi_{\theta_{old}}(y_{i,t}\mid x, y_{i,&lt; t})]}
$$&lt;p&gt;这里 $\mathrm{sg}$ 是 stop gradient operation. 通过这种改写方式，GSPO-token 与 GSPO 的优化目标一致，但是可以在更细粒度的 token 层面进行优化。&lt;/p&gt;
&lt;h2 id="evaluation"&gt;&lt;a href="#evaluation" class="header-anchor"&gt;&lt;/a&gt;Evaluation
&lt;/h2&gt;&lt;p&gt;作者使用 Qwen3-30B-A3B 进行测试。对于 GRPO，作者发现必须使用 Routing Replay training strategy 才能提升 MoE RL 的收敛性， Routing Replay 的具体做法就是保留 $\pi_{\theta_{old}}$ 的激活专家，在 $\pi_{\theta}$ 中使用相同的专家来保持稳定性。但是，GSPO 则不需要这个技巧。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-gspo/GSPO-GRPO-routing-replay.png"
width="1218"
height="388"
loading="lazy"
alt="Routing Replay strategy for GRPO"
class="gallery-image"
data-flex-grow="313"
data-flex-basis="753px"
&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-gspo/GSPO-performance.png"
width="1214"
height="701"
loading="lazy"
alt="Comparison of GSPO and GRPO"
class="gallery-image"
data-flex-grow="173"
data-flex-basis="415px"
&gt;&lt;/p&gt;
&lt;p&gt;从实验结果可以看到，GSPO 比 GRPO 更加高效，效果也更好。&lt;/p&gt;
&lt;p&gt;作者带对比了 GSPO 与 GRPO 的 clipping 比例，结果发现，GSPO clipping 的 token 比例比 GRPO 高几个数量级，作者认为，尽管 GSPO clip 了更多 token, 但是 GSPO 更加高效，这也说明 GRPOtoken 层面的梯度估计是存在噪声的。&lt;/p&gt;
&lt;p&gt;作者还介绍了以下 MoE 模型中 RL 训练的 expert-activation volatility 现象，也就是说，MoE 模型参数更新之后，对于同一个 response, 激活的专家可能飞铲个不同。作者举例说明，对于 Qwen3-30B-A3B, 更新一次梯度之后，有 $10\%$ 左右的激活专家变得不一样了。&lt;/p&gt;
&lt;p&gt;作者最后介绍了以下 GSPO 的两个优势，一个是解决了 GRPO 依赖于 Routing Replay 的问题；第二个是支持 SGLang 和 vLLM 等推理框架。&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;作者提出了 GSPO，一个在 sequence 层面计算 importance ratio 的 RL 算法，解决了 GRPO 在训练大规模 MoE LLM 时出现的训练不稳定性以及 mode collapse 现象。&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/2507.18071" target="_blank" rel="noopener"
&gt;Group Sequence Policy Optimization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen2.5-1M</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-1m/</link><pubDate>Sat, 12 Jul 2025 11:00:47 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-1m/</guid><description>&lt;p&gt;Qwen 在 2025 年 1 月提出了 Qwen2.5-1M，一个拥有 1M 上下文长度的大语言模型系列。包含 7B，14B 两个开源模型以及 API 模型 Qwen2.5-Turbo. 主要改进方法包括长上下文数据合成，渐进式预训练以及多阶段 post-training 等。作者还对 inference 进行了优化，提高了 inference 的效率。&lt;/p&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;p&gt;架构上，Qwen2.5-1M 与 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen2.5/" target="_blank" rel="noopener"
&gt;Qwen2.5&lt;/a&gt; 的架构一致，Qwen2.5-1M 包括 7B，14B 两个 size，还包括一个基于 MoE 的 API 模型 Qwen2.5-Turbo，不同的点在于，Qwen2.5-1M 的上下文长度为 1M，最大生成长度为 8K&lt;/p&gt;
&lt;h3 id="pretraining"&gt;&lt;a href="#pretraining" class="header-anchor"&gt;&lt;/a&gt;Pretraining
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Data&lt;/strong&gt;
作者首先从 CC, arxiv, book, code repositories 等 domain 收集了原始数据。但是，作者发现，原始数据的局部相关性强，但是全局相关性弱。因此，作者基于原始数据进行了增广，来提高数据的长上下文依赖关系。具体有三个任务：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fill in the middle&lt;/strong&gt;: FIM 是 openAI 提出来的一个做法，核心思想就是将填空类问题转化为 next-token-prediction 的问题。通过这种方式，作者希望提升模型理解长上下文依赖的能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keyword-based and Position-based retrieval&lt;/strong&gt;: 基于 keywords 或者 position 来找到对应的 paragraph，这个任务的目的是提高模型识别并连接相关信息的能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paragraph Reordering&lt;/strong&gt;: 对输入的 paragraphs 进行随机打乱，然后要求模型重新组织段落的关系&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Training&lt;/strong&gt;
作者将训练拆分为了 5 个 stage：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;stage 1 和 stage 2 与 Qwen2.5 的训练过程一致，stage 1 的上下文长度为 4096，stage 2 的上下文长度为 32768, 训练时，作者使用了 ABF 技巧来将 RoPE 的 base frequency 从 10,000 调整到了 1,000,000.&lt;/li&gt;
&lt;li&gt;stage 3, stage 4 和 stage 5 分别将模型的上下文长度扩展到了 65,536 tokens, 131,072 tokens 以及 262,144 tokens, 对应的 RoPE base frequency 分别为 1M, 5M 和 10M. 训练时，作者使用了 75% 的长文本和 25% 的短文本，这样可以保证模型在短文本任务上的表现&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最后，作者在评估了一下每个 stage 的表现，结果如下表所示&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Training Length&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;RULER&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Avg.&lt;/td&gt;
&lt;td&gt;4K&lt;/td&gt;
&lt;td&gt;8K&lt;/td&gt;
&lt;td&gt;16K&lt;/td&gt;
&lt;td&gt;32K&lt;/td&gt;
&lt;td&gt;64K&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32,768 Tokens&lt;/td&gt;
&lt;td&gt;82.3&lt;/td&gt;
&lt;td&gt;96.8&lt;/td&gt;
&lt;td&gt;94.7&lt;/td&gt;
&lt;td&gt;95.9&lt;/td&gt;
&lt;td&gt;92.2&lt;/td&gt;
&lt;td&gt;76.4&lt;/td&gt;
&lt;td&gt;37.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;65,536 Tokens&lt;/td&gt;
&lt;td&gt;86.8&lt;/td&gt;
&lt;td&gt;96.5&lt;/td&gt;
&lt;td&gt;95.5&lt;/td&gt;
&lt;td&gt;93.6&lt;/td&gt;
&lt;td&gt;92.5&lt;/td&gt;
&lt;td&gt;86.7&lt;/td&gt;
&lt;td&gt;56.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;131,072 Tokens&lt;/td&gt;
&lt;td&gt;92.5&lt;/td&gt;
&lt;td&gt;96.5&lt;/td&gt;
&lt;td&gt;95.9&lt;/td&gt;
&lt;td&gt;93.0&lt;/td&gt;
&lt;td&gt;92.6&lt;/td&gt;
&lt;td&gt;93.0&lt;/td&gt;
&lt;td&gt;83.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;262,144 Tokens&lt;/td&gt;
&lt;td&gt;92.7&lt;/td&gt;
&lt;td&gt;95.6&lt;/td&gt;
&lt;td&gt;93.8&lt;/td&gt;
&lt;td&gt;93.1&lt;/td&gt;
&lt;td&gt;94.1&lt;/td&gt;
&lt;td&gt;91.9&lt;/td&gt;
&lt;td&gt;87.6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&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 阶段与 Qwen2.5 一样，也分为了 SFT 和 RL 两个阶段。&lt;/p&gt;
&lt;p&gt;在 SFT 阶段，作者从预训练预料中选择了一部分长文档的片段，然后让 Qwen2.5 来生成对应的 query，query 类型包括 summarization, information retrieval, multi-hop QA 等任务。接下来，作者使用 Qwen-Agent 框架基于全文来回答这些问题。最后，作者基于生成的 query，全文，以及模型产生的回答作为训练数据。&lt;/p&gt;
&lt;p&gt;SFT 训练时，作者拆分为了两个 stage。 stage 1 作者在 32768 的上下文上进行训练，来提高模型短文本回答能力。第二个阶段，作者混合了 262,144 和 32768 上下文长度的训练数据。&lt;/p&gt;
&lt;p&gt;RL 训练时，与 Qwen2.5 不一样的是，作者进使用了 offline RL，也就是 DPO。作者仅在 8192 的上下文长度上面进行训练。作者认为，长上下文的 RL 训练是非常耗时的，并且作者发现，短文本上进行 RL 的训练之后，模型在长文本上的表现也能得到提升。结果如下表所示&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Before RL&lt;/th&gt;
&lt;th&gt;After RL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-7B-Instruct-1M&lt;/td&gt;
&lt;td&gt;7.32&lt;/td&gt;
&lt;td&gt;8.08 (+0.75)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-14B-Instruct-1M&lt;/td&gt;
&lt;td&gt;8.56&lt;/td&gt;
&lt;td&gt;8.76 (+0.20)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Turbo&lt;/td&gt;
&lt;td&gt;7.60&lt;/td&gt;
&lt;td&gt;8.34 (+0.74)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="inference"&gt;&lt;a href="#inference" class="header-anchor"&gt;&lt;/a&gt;Inference
&lt;/h2&gt;&lt;p&gt;前面是训练部分的优化，主要是提升模型的上下文能力。接下来，作者详细介绍了如何在 Inference 阶段提升整体的推理效率和减少内存占用。&lt;/p&gt;
&lt;h3 id="length-extrapolation"&gt;&lt;a href="#length-extrapolation" class="header-anchor"&gt;&lt;/a&gt;Length Extrapolation
&lt;/h3&gt;&lt;p&gt;与 Qwen2.5 一样，Qwen2.5-1M 也是用了 &lt;a class="link" href="https://maosong.website/p/dual-chunk-attention/" target="_blank" rel="noopener"
&gt;Dual Chunk Attention&lt;/a&gt; 和 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 来在推理阶段扩展模型的上下文长度，作者做了如下实验，来对比 Qwen2.5, Qwen2.5-1M 加上 DCA 之后的影响&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-1m/Qwen2_5_1M_DCA.png"
width="1351"
height="764"
loading="lazy"
alt="Qwen2.5 performance of DCA"
class="gallery-image"
data-flex-grow="176"
data-flex-basis="424px"
&gt;&lt;/p&gt;
&lt;p&gt;结果显示，Qwen2.5-1M 的表现比 Qwen2.5 更好，并且加上 DCA 之后，两者的表现都有进一步的提升。&lt;/p&gt;
&lt;h3 id="sparse-attention"&gt;&lt;a href="#sparse-attention" class="header-anchor"&gt;&lt;/a&gt;Sparse Attention
&lt;/h3&gt;&lt;p&gt;为了进一步提高计算效率，作者基于 MInference 来加速 perfilling phase. 并结合了 前面的技巧来防止模型性能下降。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MInference&lt;/strong&gt;
MInference 的主要思想就是在长上下文中，有一些 critical token 对最终结果的影响是更大的。因此我们可以识别出这些 critical token 并只计算这些 token 对应的 attention score. 这些 critical token 对应的 pattern 被称为 Vertical-Slash pattern.&lt;/p&gt;
&lt;p&gt;为了识别出这个 pattern，作者首先进行离线搜索，来决定最优的 configuration。这个 configuration 决定了 attention 应该如何计算。在 Inference 阶段，MInference 首先计算最后一个 query 和前面所有 key 的 attention，然后基于 configuration 来动态选择 pattern。通过 MInference，我们可以降低 10 倍以上的内存和算力消耗。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Integrating with Chunked prefill&lt;/strong&gt;
但是 MInference 的问题在于，整个 sequence 是并行处理的，这会导致内存占用持续上升。为了解决这个问题，作者提出了 chunked prefilling 的技巧，来降低 VRAM 的消耗。具体做法就是，将整个 sequence 分为若干个 chunk，然后每个 chunk 里，选取最后 64 个 token 作为 query，在每个 chunk 中分别识别出 critical token，这样就降低了 MInference 的内存占用&lt;/p&gt;
&lt;p&gt;接下来，作者在集成 DCA 的时候，发现性能有所下降。作者认为，这是由于 DCA 的 position id 信息不连续所导致的，为了解决这个问题，作者在选择 critical token 的时候，使用了连续版的 position id 信息。在最终推理的时候，还是使用 DCA 本身的位置信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sparsity refinement&lt;/strong&gt;
前面提到，MInference 需要先进行离线搜索决定最优的 configuration，但是对于 1M token 的上下文，这个过程还是非常耗时的。因此，作者构建了一个加速离线搜索的方法，具体做法就是定义两个 attention score，一个是 full attention, 另一个是 sparse attention， 然后计算两者的差值，如果说相差比较小，则说明 critical token 抓住了全局信息，这个配置是有效的。其公式定义如下：&lt;/p&gt;
$$
\mathrm{Attention\_Recall} = \exp\left(\log\sum_{0\leq j\leq i}\exp \left(\frac{q^Tk_j}{\sqrt {d}}\right) - \log\sum_{j\in\mathcal{critical}}\exp \left(\frac{q^Tk_j}{\sqrt {d}}\right)\right)
$$&lt;p&gt;Attention Recall 越高，说明选取的 critical token 越好，其 configuration 也就越好。&lt;/p&gt;
&lt;p&gt;作者进一步分析了 sparse attention 对 accuracy 的影响，结果如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-1m/Qwen2_5_1M_sparsity_config_performance.png"
width="1151"
height="836"
loading="lazy"
alt="Qwen2.5 performance on sparsity refinement"
class="gallery-image"
data-flex-grow="137"
data-flex-basis="330px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，仅使用 MInference 会导致模型性能 下降，但是加入 refinement 之后，模型的表现基本上和 full attention 差不太多。&lt;/p&gt;
&lt;h3 id="inference-engine"&gt;&lt;a href="#inference-engine" class="header-anchor"&gt;&lt;/a&gt;Inference Engine
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Kernel Optimization&lt;/strong&gt;
作者还对 inference engine 进行了优化，作者使用 BladeLLM 作为 Qwen2.5-1M 的推理引擎。&lt;/p&gt;
&lt;p&gt;作者主要做了两点优化，第一是对 sparse attention kernel 进行了优化，提高了 sparse attention 的计算效率，结果发现，在 1M 的上下文下，BladeLLM 比 &lt;a class="link" href="https://maosong.website/p/notes-on-flashattention/" target="_blank" rel="noopener"
&gt;flash attention&lt;/a&gt; 要快 27.8 倍。&lt;/p&gt;
&lt;p&gt;第二是针对 MoE kernel 的优化。作者发现，decoding 的表现是与 memory access speed 相关的。具体来讲，当 batch size 超过 32 之后，获取模型参数成了效率的瓶颈。因此，作者使用了一系列技巧来提高 memory access 的效率&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pipeline parallelism&lt;/strong&gt;
作者还对 Chunked pipeline parallelism 进行了优化，Chunked pipeline parallelism 的问题在于，在长上下文的场景下，不同长度的 chunk 会对 attention 的计算时间产生很大影响。不同的计算时间会产生 pipeline bubbles.&lt;/p&gt;
&lt;p&gt;BladeLLm 使用了 Dynamic Chunked pipeline parallelism 来解决这个问题，该方法通过计算复杂度来调整每个 chunk 的大小，进而使得最终的处理时间尽可能一致&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-1m/Qwen2_5_1M_PP.png"
width="1366"
height="224"
loading="lazy"
alt="Qwen2.5-1M DCPP"
class="gallery-image"
data-flex-grow="609"
data-flex-basis="1463px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scheduling&lt;/strong&gt;
作者还在 Scheduling 上进行了优化，已有的推理引擎主要分为四个模块：API server, scheduler, model runner 以及 decoder&lt;/p&gt;
&lt;p&gt;已有方法的问题在于，non-GPU 的操作会占用大量时间，导致 GPU 利用率非常低。因此，作者在 BladeLLM 中进行了改进，使用了 Totally Asynchronous Generator (TAG) 的架构，主要有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Scheduler：动态分配 KV cache，类似于 speculative sampling, 而不必等前面的结果完成&lt;/li&gt;
&lt;li&gt;Runner: 基于 Scheduler 分配的任务直接进行处理，处理完之后直接处理下一个任务&lt;/li&gt;
&lt;li&gt;Decoder：基于 token id，进行解码，然后发送给前端的 API server&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-1m/Qwen2_5_1M_PP.png"
width="1366"
height="224"
loading="lazy"
alt="Qwen2.5-1M scheduling"
class="gallery-image"
data-flex-grow="609"
data-flex-basis="1463px"
&gt;&lt;/p&gt;
&lt;h2 id="evaluation"&gt;&lt;a href="#evaluation" class="header-anchor"&gt;&lt;/a&gt;Evaluation
&lt;/h2&gt;&lt;p&gt;作者主要在三个 benchmark 上进行了评测：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;RULER: RULER 是 Needle-in-ahaystack 任务的一个扩展笨笨，其要求模型从不相关的上下文中找到多个 &amp;ldquo;needles&amp;rdquo; 或者回答多个问题，数据最长为 128K tokens.&lt;/li&gt;
&lt;li&gt;LV-Eval: LV-Eval 要求模型从上文本中同时理解多个 evidence fragments，数据最长为 256K tokens&lt;/li&gt;
&lt;li&gt;Longbench-Chat: 评估模型在长上下文下与人类偏好对齐的程度，数据最长为 100K tokens&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Qwen2.5-1M 与 Qwen2.5 的对比表现如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-1m/Qwen2_5_1M_RULER_performance.png"
width="1340"
height="652"
loading="lazy"
alt="Qwen2.5-1M perofermence on RULER"
class="gallery-image"
data-flex-grow="205"
data-flex-basis="493px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，相比于 Qwen2.5，Qwen2.5 模型的表现有了大幅度的提升。&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;在本文中，作者提出了 Qwen2.5-1M 系列大语言模型，包括 7B，14B 两个 size，以及一个 MoE 架构的 API 模型 Qwen2.5-Turbo。作者在训练和推理两方面进行了改进，最终将模型的上下文长度扩展到了 1M。从现在的角度来看，不管是 Reasoning model 还是 agent 的训练都依赖 long Context 作为基础能力。&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/2501.15383" target="_blank" rel="noopener"
&gt;Qwen2.5-1M Technical Report&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen2.5</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5/</link><pubDate>Sat, 12 Jul 2025 10:51:42 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5/</guid><description>&lt;p&gt;2024 年 12 月 Qwen 发布了 Qwen 2.5 系列大语言模型，包括 7 个 dense 模型以及两个 MoE 模型，Qwen2.5 在 pre-training 阶段使用了 18T token 进行。在 post-training 阶段使用了 1M 的样本，还使用了 &lt;a class="link" href="https://maosong.website/p/notes-on-dpo/" target="_blank" rel="noopener"
&gt;DPO&lt;/a&gt; 以及 GRPO 来进行 RL 的训练&lt;/p&gt;
&lt;p&gt;Qwen2.5 主要在以下方面进行了改进&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;模型方面，提供了更多的 size，&lt;a class="link" href="https://maosong.website/p/notes-on-qwen2/" target="_blank" rel="noopener"
&gt;Qwen2&lt;/a&gt; 中只有 0.5B, 1.5B, 7B, 72B 四个 size, 在 Qwen2.5 中，加入了 3B, 14B 和 32B 三个 size 的模型&lt;/li&gt;
&lt;li&gt;数据方面，pre-training 阶段使用了 18T 的 token， post-training 阶段使用了 1M 的样本&lt;/li&gt;
&lt;li&gt;功能方面，Qwen2.5 支持更长的上下文长度（8K），支持结构化输入和输出，拥有更强的工具调用能力。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;h3 id="architecture"&gt;&lt;a href="#architecture" class="header-anchor"&gt;&lt;/a&gt;Architecture
&lt;/h3&gt;&lt;p&gt;模型架构这方面，Qwen2.5 和 Qwen2 的模型架构是一致的，tokenizer 页没有太大变化。为了支持工具调用，作者额外增加了 18 个 control token&lt;/p&gt;
&lt;h3 id="pre-training"&gt;&lt;a href="#pre-training" class="header-anchor"&gt;&lt;/a&gt;Pre-training
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;data&lt;/strong&gt;
Qwen2.5 从以下方面提高了预训练数据的质量&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Better data filtering: 使用 Qwen2-Instruct 来过滤掉质量的数据，然后从多维度对训练数据进行打分，从而提高数据的质量&lt;/li&gt;
&lt;li&gt;Better math and code data: 加入了 Qwen2.5 Math 以及 Qwen2.5 Coder 的训练数据来提高模型的数学和代码能力&lt;/li&gt;
&lt;li&gt;Better synthetic data: 作者使用 Qwen2-72B-Instruct 以及 Qwen2-Math-72B-Instruct 来合成 math, code, knowledge domain 的数据，然后通过过滤以及 Qwen2-Math-RM-72B 来提高数据的质量&lt;/li&gt;
&lt;li&gt;Better data mixture: 作者使用 Qwen2-Instruct 来分类，然后平衡不同 domain 的数据分布。作者发现 e-commerce, social media 以及 entertainment 的数据重复性高，且大多都是机器生成的。而 technology, science 以及 academic research 等 domain 的数据质量更高。作者对不同 domain 的数据进行了上采样或者下采样。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基于这个过程，作者一共收集了&lt;strong&gt;18T&lt;/strong&gt; tokens&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hyper-parameters&lt;/strong&gt;
作者构建了针对超参数的 scaling law，即决定最优的训练超参数如 batch size, learning rate 等&lt;/p&gt;
&lt;p&gt;作者通过实验得到了 model size $N$ 以及 pre-training data size $D$ 与 learning rate $\mu_{opt}$ 和 batch size $B_{opt}$ 之间的关系。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Long context pre-training&lt;/strong&gt;
为了提升模型的上下文长度，作者将 pre-training 拆分为两个 stage，第一个 stage 的上下文长度为 4096， 第二个 stage，作者将上下文长度从 4096 扩展到 32768.&lt;/p&gt;
&lt;p&gt;在提升模型上下文过程中，作者使用 ABF 技巧将 &lt;a class="link" href="https://maosong.website/p/notes-on-position-encoding/" target="_blank" rel="noopener"
&gt;Position Encoding&lt;/a&gt; 的 base frequency 从 10,000 提升到了 1,000,000.&lt;/p&gt;
&lt;p&gt;对于 Qwen2-5-Turbo，作者实现了渐进式上下文长度扩展策略，模型上下文长度扩展经历四个阶段：32768, 65536, 131072 到最终的 262,144. 此时，RoPE 的 base frequency 为 10,000,000. 在训练的每个阶段，作者都使用了 40% 的长文本以及 60% 的短文本，以保证在扩展模型上下文长度的同时，还能保持模型在不同上下文长度下的表现。&lt;/p&gt;
&lt;p&gt;为了提高模型在 inference 时的长上下文表现，作者使用了 &lt;a class="link" href="https://maosong.website/p/dual-chunk-attention/" target="_blank" rel="noopener"
&gt;Dual Chunk Attention&lt;/a&gt; 和 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 两个技巧。通过这两个技巧，作者将 Qwen2.5-Turbo 的上锈阿文扩展到了 1M，将其他模型的上下文长度扩展到了 131072.&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;Qwen2.5 的 post-training 分为两个大的 stage: SFT 和 RL，其中 RL 又分为两个小的 stage，分别是 offline RL 和 online RL&lt;/p&gt;
&lt;p&gt;在 SFT 阶段，作者主要做了以下改进：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Long-sequence generation: 作者将 Qwen2.5 的输出长度提升到了 8192, 为了扩展模型输出的长度，作者构建了 Long-response 数据集，然后基于 back-translation 来生成对应的 query，最后使用 Qwen2 来过滤低质量的数据&lt;/li&gt;
&lt;li&gt;Math: 作者在 SFT 阶段加入了 Qwen2.5-Math 的 CoT 数据，包括公开数据集，K12 问题集一集合成数据等。作者通过 rejection sampling 以及 annotated answers 来生成 CoT 过程&lt;/li&gt;
&lt;li&gt;Code: 作者加入了 Qwen2.5-Coder 的 SFT 数据，作者基于多个 agent 来生成多样化高质量的 Instruction, 然后还从 code-related QA website 以及 Github 上获取数据来扩展数据集。对于最终的数据，作者使用了 sandbox 来保证代码的质量&lt;/li&gt;
&lt;li&gt;Instruction following: 作者构建了一个基于 code 的验证框架，让 LLM 同时生成 Instruction 和对应的验证代码，验证的单元测试。最后，通过 rejection sampling 来得到最终的数据集&lt;/li&gt;
&lt;li&gt;Structured Data Understanding: 作者还构建了针对 tabular QA, fact verification, error correction 以及 structured understanding 等数据集。作者在回答中加入 CoT，作者提高了模型对 structured data 的理解能力&lt;/li&gt;
&lt;li&gt;Logical Reasoning: 作者构建了 70,000 个不同 domain 的 query，有多种格式，覆盖了 analogical reasoning, causal reasoning 等 domain&lt;/li&gt;
&lt;li&gt;Cross-Lingual Transfer: 作者使用了一个翻译模型，来将 Instruction 转换到 low-resource language 上，进而提高模型在对应语种上的表现&lt;/li&gt;
&lt;li&gt;Robust System Instruction: 作者构建了不同的 system prompt 用于提升 system prompt 的多样性。作者发现，使用不同的 system prompt 可以减少模型的 variance, 提高模型的 robustness.&lt;/li&gt;
&lt;li&gt;Response Filtering: 作者使用了多种自动化标注方法来保证最终 response 的质量&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最终，作者一共收集到 &lt;strong&gt;1M&lt;/strong&gt; 的 SFT 样本，模型训练了两个 epoch&lt;/p&gt;
&lt;p&gt;在 RL 阶段，作者首先基于 SFT model 来进行采样，然后将高质量的回答作为正样本，低质量的回答作为负样本，通过这个过程，一共采集到了&lt;strong&gt;150K&lt;/strong&gt;的样本。最后，作者使用 DPO 来进行训练。&lt;/p&gt;
&lt;p&gt;然后，作者进行了 online stage 的 RL 训练，这一阶段主要是对齐模型与人类的价值观。这一阶段的数据包括公开数据集，私有数据集。作者使用不同的 checkpoint 来进行采样，然后作者使用 GRPO 来进行训练.&lt;/p&gt;
&lt;h3 id="long-cotnext-fine-tuning"&gt;&lt;a href="#long-cotnext-fine-tuning" class="header-anchor"&gt;&lt;/a&gt;Long Cotnext Fine-tuning
&lt;/h3&gt;&lt;p&gt;作者还针对 Qwen2.5-Turbo 做了额外的 post-training, 来进一步提高其在长上下文下的表现。&lt;/p&gt;
&lt;p&gt;在 SFT 阶段，作者使用了一个两阶段方法，第一阶段仅在短文本上进行训练（上下文长度为 32768），这一阶段的训练数据与其他 Qwen2.5 的模型训练数据相同。第二个阶段，作者混合了短文本和长文本（262144）来进行训练，来提高模型在长上下文情景下的指令跟随能力&lt;/p&gt;
&lt;p&gt;在 RL 阶段，作者使用了和其他 Qwen2.5 模型相同的训练策略。作者认为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;长上下文下训练 RL 代价很大&lt;/li&gt;
&lt;li&gt;reward model 更偏向于长文本&lt;/li&gt;
&lt;li&gt;RL 尽管只在短文本上进行训练，其还是可以提高模型在长上下文下的表现。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="evaluation"&gt;&lt;a href="#evaluation" class="header-anchor"&gt;&lt;/a&gt;Evaluation
&lt;/h2&gt;&lt;p&gt;我们仅关注 instruction 版本的 72B,32B 和 7B 模型&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5/Qwen2_5_72b_instruct_performance.png"
width="1112"
height="757"
loading="lazy"
alt="Performance of Qwen2.5 72B"
class="gallery-image"
data-flex-grow="146"
data-flex-basis="352px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5/Qwen2_5_32b_instruct_performance.png"
width="1339"
height="744"
loading="lazy"
alt="Performance of Qwen2.5 32B"
class="gallery-image"
data-flex-grow="179"
data-flex-basis="431px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5/Qwen2_5_7b_instruct_performance.png"
width="845"
height="746"
loading="lazy"
alt="Performance of Qwen2.5 7B"
class="gallery-image"
data-flex-grow="113"
data-flex-basis="271px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，Qwen2.5 72B 模型表现和 LLaMA3.1 405B 表现差不多，其他两个 size 的模型基本上达到了 SOTA&lt;/p&gt;
&lt;p&gt;最后，作者评估了一下 DCA+YaRN v.s. Full attention 的表现，结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5/Qwen2_5_long_context_TTFT.png"
width="1078"
height="958"
loading="lazy"
alt="TTFT of Qwen2.5 on long context"
class="gallery-image"
data-flex-grow="112"
data-flex-basis="270px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，使用 DCA+YaRN 之后，模型的推理效率比 full attention 要快 3-4 倍。&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;在本文中，作者提出了 Qwen2.5 系列大语言模型，包括 7 个 dense 模型以及两个 MoE 模型，作者详细介绍了模型的 pre-training 和 post-training. 评测结果发现 Qwen2.5 模型基本上达到了 SOTA.&lt;/p&gt;
&lt;p&gt;作者认为，未来工作有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用更多更多样化的 pre-training 和 post-training 数据&lt;/li&gt;
&lt;li&gt;多模态大模型的构建，特别是 omni-modal&lt;/li&gt;
&lt;li&gt;提高模型的 Reasoning 能力&lt;/li&gt;
&lt;/ol&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/2412.15115" target="_blank" rel="noopener"
&gt;Arxiv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Dual Chunk Attention</title><link>https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/</link><pubDate>Sat, 12 Jul 2025 10:41:12 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/</guid><description>&lt;p&gt;Dual Chunk Attention (DCA) 由阿里巴巴在 2024 年 9 月份提出，DCA 是一个无需训练的，扩展 LLM 上下文长度的方法，后续，DCA 被应用于 Qwen2, Qwen2.5, Qwen2.5-1M 以及 Qwen3 中，与 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 一起作为扩展模型上下文的有效手段&lt;/p&gt;
&lt;h2 id="introduction"&gt;&lt;a href="#introduction" class="header-anchor"&gt;&lt;/a&gt;Introduction
&lt;/h2&gt;&lt;p&gt;提升 LLM 上下文长度的方法可以分为两类：一类是 training-free 的，包括 LM-infinite 和 StreamingLLM 等，这些方法以损失 long range dependency 为代价来保持较低的 perplexity。另一类为了保留全局信息，则是通过外插来扩展模型的上下文，主要工作我们在 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 中已经回顾了。&lt;/p&gt;
&lt;p&gt;第二类方法的问题在于，其依赖训练，在 training-free 的 setting 下，这些方法也会导致 perplexity 的上升&lt;/p&gt;
&lt;p&gt;因此，在本文中，作者就提出了 Dual Chunk Attention (DCA) ，一个无需训练的，扩展 LLM 上下文长度的方法。DCA 的主要做法是将 attention 的计算进行分块，这样就可以提高计算效率。&lt;/p&gt;
&lt;p&gt;通过实验，作者给出了三点关键发现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Extrapolation&lt;/strong&gt;： DCA 可以在无需训练的情况下，将 LLM 的上下文提升到 32K，而不导致 Perplexity 大幅度增加&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Orthogonality&lt;/strong&gt;： DCA 可以和其他方法一起使用，如 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt;, 这一点已经在 Qwen2.5-1M 以及 Qwen3 中得到了应用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Long Context Understanding&lt;/strong&gt;: DCA 可以在无需训练的情况下，在长上下文设置下，达到已有 SOTA 模型的表现&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="preliminary"&gt;&lt;a href="#preliminary" class="header-anchor"&gt;&lt;/a&gt;Preliminary
&lt;/h2&gt;&lt;p&gt;对于一个长度为 $L$ 的 token 序列，我们首先定义对应的 position id 如下&lt;/p&gt;
$$
P_{\mathbf{q}} = [0,1,\dots,L-1],\quad P_{\mathbf{k}} = [0,1,\dots,L-1]
$$&lt;p&gt;然后，对于第 $i$ 个位置和第 $j$ 个位置的 token，其 attention score 定义为：&lt;/p&gt;
$$
\langle f(\mathbf{q}, i), f(\mathbf{k}, j)\rangle =\langle R_{\theta,i}\mathbf{q}, R_{\theta,j}\mathbf{k}\rangle =\mathbf{q}^TR_{\theta, i-j}\mathbf{k}
$$&lt;p&gt;具体细节参考 &lt;a class="link" href="https://maosong.website/p/notes-on-position-encoding/" target="_blank" rel="noopener"
&gt;Position Encoding&lt;/a&gt; 中的 RoPE 部分介绍。这里面的关键在于，最后的结果只与相对位置 $i-j$ 相关，而与绝对位置 $i$ 和 $j$ 无关。因此，我们可以用一个相对位置矩阵 $M\in\mathbb{R}^{L\times L}$ 来表示这个信息，其中 $M_{ij}=P_{\mathbf{q},i}- P_{\mathbf{k},j}$ 代表了第 $i$ 个位置的 query $\mathbf{q}$ 和第 $j$ 个位置的 key $\mathbf{k}$ 的相对位置信息，其示意图如下所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/DCA_relative_position_visualization.png"
width="379"
height="384"
loading="lazy"
alt="Relative Position Visualization"
class="gallery-image"
data-flex-grow="98"
data-flex-basis="236px"
&gt;&lt;/p&gt;
&lt;p&gt;原始版本的 RoPE 的问题在于，在训练时，模型没有见过更长的上下文，因此其泛化性也最差，这一点在 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 已经得到了验证&lt;/p&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;p&gt;DCA 的关键在于将 sequence 分割为若干个 Chunk，然后将 attention 的计算拆分为三个部分：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;intra-chunk：负责计算每个 chunk 内部的 attention&lt;/li&gt;
&lt;li&gt;inter-chunk ：负责计算 chunk 之间的 attention&lt;/li&gt;
&lt;li&gt;successive-chunk：负责计算相邻两个 chunk 之间的 attention&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为了更好理解 DCA，我们接下来假设 $L=12$, 这时我们有&lt;/p&gt;
$$
P_{\mathbf{q}} = [0,1,\dots,11],\quad P_{\mathbf{k}} = [0,1,\dots,11]
$$&lt;h3 id="intra-chunk-attention"&gt;&lt;a href="#intra-chunk-attention" class="header-anchor"&gt;&lt;/a&gt;Intra-Chunk Attention
&lt;/h3&gt;&lt;p&gt;我们首先定义个超参数 chunk size $s&gt;0$, 然后我们将我们的 sequence 分割成 $L/s$ 个 chunk，然后每个 chunk 重新进行编号，就得到了如下的 position id&lt;/p&gt;
$$
P_{\mathbf{q}}^{Intra} = [0,1,\dots,L-1]\mod s,\quad P_{\mathbf{k}}^{Intra} = [0,1,\dots,L-1]\mod s
$$&lt;p&gt;接下来，我们定义 intra-chunk 的相对位置矩阵 $M$， 此时，我们仅在每个 chunk 内部进行计算 attention，即&lt;/p&gt;
$$
M[i][j] = \begin{cases} P_{\mathbf{q},i}^{Intra} - P_{\mathbf{k},j}^{Intra},&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor = \lfloor P_{\mathbf{k},j} /s\rfloor ,\\
0,&amp;\text{otherwise}
\end{cases}
$$&lt;p&gt;在上面的例子中，假设 $s=6$, 那么我们新的 position id 就变成了&lt;/p&gt;
$$
\begin{aligned}
P_{\mathbf{q}}^{Intra} = [0,1,2,3,4,5,0,1,2,3,4,5]\\
P_{\mathbf{k}}^{Intra} = [\underbrace{0,1,2,3,4,5}_{\text{Chunk 0}},\underbrace{0,1,2,3,4,5}_{\text{Chunk 1}}]
\end{aligned}
$$&lt;p&gt;对其进行可视化，我们就得到&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/DCA_intra_chunk_attention_visualization.png"
width="362"
height="386"
loading="lazy"
alt="Intra Chunk Attention Visualization"
class="gallery-image"
data-flex-grow="93"
data-flex-basis="225px"
&gt;&lt;/p&gt;
&lt;h3 id="inter-chunk-attention"&gt;&lt;a href="#inter-chunk-attention" class="header-anchor"&gt;&lt;/a&gt;Inter-Chunk Attention
&lt;/h3&gt;&lt;p&gt;接下来，我们来看一下不同 chunk 之间如何计算彼此的 attention。在 Intra-chunk attention 计算中，我们忽略了跨 chunk 的信息，而且，由于现在的 position id 不再是单调递增的了，我们直接使用 $P_{\mathbf{q}}^{Intra}$ 和 $P_{\mathbf{k}}^{Intra}$ 给出的位置信息不对，这也是为什么我们在 Intra-chunk attention 中要求 query 和 key 在同一个 chunk 中才能计算的原因。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，作者构建了一个新的 position id。首先我们引入一个新的超参数 $c&gt;\max_i P_{\mathbf{q},i}$, $c$ 代表了模型预训练时的上下文长度，如 4096。&lt;/p&gt;
&lt;p&gt;接下来，基于 $c$, 我们定义新的 position id 如下：&lt;/p&gt;
$$
P_{\mathbf{q}}^{Inter} = [c-1,c-1,\dots,c-1]\in\mathbb{R}^s,\quad P_{\mathbf{k}}^{Inter} = P_{\mathbf{k}}^{Intra}
$$&lt;blockquote&gt;
&lt;p&gt;注：这里的 $P_{\mathbf{q}}^{Inter}$ 指的是某一个 chunk 中的 position id，每个 chunk 中的 position id 都相同，请参考例子理解，后面不再赘述。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也就是说，在计算跨 chunk 的 attention 的时候，我们直接把 query 的 position id 设置为最大值，然后 key 的 position id 依然使用 intra-chunk 的位置信息。由于 $\max_i P_{\mathbf{k},i}=s-1$, 因此我们有&lt;/p&gt;
$$
M[i][j] = P_{\mathbf{q},i}^{Inter} - P_{\mathbf{k},j}^{Inter} = c - 1 - P_{\mathbf{k},j}^{Inter}\geq c - 1 - (s- 1) \geq c-s.
$$&lt;p&gt;最后，我们对于 inter chunk 的位置矩阵 $M$ 定义如下：&lt;/p&gt;
$$
M[i][j] = \begin{cases} P_{\mathbf{q},i}^{Inter} - P_{\mathbf{k},j}^{Inter},&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor \neq \lfloor P_{\mathbf{k},j} /s\rfloor ,\\
0,&amp;\text{otherwise}
\end{cases}
$$&lt;p&gt;在上面的例子中，当 $c=10$ 时，$c-1=9$, 我们有&lt;/p&gt;
$$
P_{\mathbf{q}}^{Inter}=[\underbrace{9,9,9,9,9,9}_{\text{Chunk 0}},\underbrace{9,9,9,9,9,9}_{\text{Chunk 1}}]
$$&lt;p&gt;对其进行可视化，得到&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/DCA_inter_chunk_attention_visualization.png"
width="351"
height="388"
loading="lazy"
alt="Inter Chunk Attention Visualization"
class="gallery-image"
data-flex-grow="90"
data-flex-basis="217px"
&gt;&lt;/p&gt;
&lt;h3 id="successive-chunk-attention"&gt;&lt;a href="#successive-chunk-attention" class="header-anchor"&gt;&lt;/a&gt;Successive-Chunk Attention
&lt;/h3&gt;&lt;p&gt;现在我们既可以计算 intra-chunk，也可以计算 inter-block 的 attention，但是问题是对于相邻的 chunk，其位置信息不对了，从上面的可视化中，我们可以看到，当 $P_{\mathbf{q},i}=6$ , $P_{\mathbf{k},j}=5$ 时，我们有&lt;/p&gt;
$$
P_{\mathbf{q},i}^{Inter} - P_{\mathbf{k},j}^{Inter}=9-5=4\neq 1 = P_{\mathbf{q},i}-P_{\mathbf{k},j}
$$&lt;p&gt;也就是说，inter-block 的 attention 会破坏原有的相对位置信息，因此我们就通过 successive chunk attention 来解决这个问题，使得 $P_{\mathbf{q},i}^{Inter} - P_{\mathbf{k},j}^{Inter}\approx P_{\mathbf{q},i}-P_{\mathbf{k},j}$.&lt;/p&gt;
&lt;p&gt;作者发现，这个问题不是所有的 chunk 都有，而是只存在于相邻的 chunk 中，因此，作者又加入了一个超参数 $w&gt;0$ 代表了 local window size，我们可以直接将其设置为 $c-s$, 通过这个 local window，我们调整对应的 position id 如下：&lt;/p&gt;
$$
P_{\mathbf{q}}^{Succ} = [\overbrace{s,s+1,\dots,s+w-1}^{w \text{ elements}},c-1, \dots,c-1]\in\mathbb{R}^s,\quad P_{\mathbf{k}}^{Succ} = P_{\mathbf{k}}^{Inter}
$$&lt;p&gt;对于 successive chunk 的位置矩阵 $M$ 定义如下：&lt;/p&gt;
$$
M[i][j] = \begin{cases} P_{\mathbf{q},i}^{Inter} - P_{\mathbf{k},j}^{Inter},&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor - \lfloor P_{\mathbf{k},j} /s\rfloor=1 ,\\
0,&amp;\text{otherwise}
\end{cases}
$$&lt;p&gt;在上面的例子中，我们设置 $w=4$, 就得到&lt;/p&gt;
$$
P_{\mathbf{q}}^{Succ}=[\underbrace{6,7,8,9,9,9}_{\text{Chunk 0}},\underbrace{6,7,8,9,9,9}_{\text{Chunk 1}}]
$$&lt;p&gt;对其进行可视化，得到&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/DCA_successive_chunk_attention_visualization.png"
width="388"
height="388"
loading="lazy"
alt="Successive Chunk Attention Visualization"
class="gallery-image"
data-flex-grow="100"
data-flex-basis="240px"
&gt;&lt;/p&gt;
&lt;h3 id="computation"&gt;&lt;a href="#computation" class="header-anchor"&gt;&lt;/a&gt;Computation
&lt;/h3&gt;&lt;p&gt;接下来，我们把所有的改进放在一起，就得到&lt;/p&gt;
$$
M[i][j] = \begin{cases}
P_{\mathbf{q},i}^{Intra} - P_{\mathbf{k},j},&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor - \lfloor P_{\mathbf{k},j} /s\rfloor=0 ,\\
P_{\mathbf{q},i}^{Succ} - P_{\mathbf{k},j},&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor - \lfloor P_{\mathbf{k},j} /s\rfloor=1 ,\\
P_{\mathbf{q},i}^{Inter} - P_{\mathbf{k},j},&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor - \lfloor P_{\mathbf{k},j} /s\rfloor&gt;1.
\end{cases}
$$&lt;p&gt;基于上面的位置矩阵 $M$， 我们再依次计算对应的 attention score&lt;/p&gt;
$$
\langle f(\mathbf{q}, i), f(\mathbf{k}, j)\rangle = \begin{cases}
\langle f(\mathbf{q}, P_{\mathbf{q},i}^{Intra})
, f(\mathbf{k}, P_{\mathbf{k},j})\rangle,&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor - \lfloor P_{\mathbf{k},j} /s\rfloor=0 ,\\
\langle f(\mathbf{q}, P_{\mathbf{q},i}^{Succ})
, f(\mathbf{k}, P_{\mathbf{k},j})\rangle,&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor - \lfloor P_{\mathbf{k},j} /s\rfloor=1 ,\\
\langle f(\mathbf{q}, P_{\mathbf{q},i}^{Inter})
, f(\mathbf{k}, P_{\mathbf{k},j})\rangle,&amp;\text{if}\lfloor P_{\mathbf{q},i}/s \rfloor - \lfloor P_{\mathbf{k},j} /s\rfloor&gt;1.
\end{cases}
$$&lt;h2 id="code"&gt;&lt;a href="#code" class="header-anchor"&gt;&lt;/a&gt;Code
&lt;/h2&gt;&lt;p&gt;首先是 &lt;code&gt;RotaryEmbedding&lt;/code&gt; 部分的修改&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DCARotaryEmbedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;local_window&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;local_window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;local_window&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv_freq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qc_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q_t&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seq_len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q_freqs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q_t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv_freq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# seq_len x dim/2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qc_freqs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qc_t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv_freq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k_freqs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k_t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv_freq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# seq_len x dim/2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q_emb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;q_freqs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q_freqs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# seq_len x dim&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;qc_emb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;qc_freqs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qc_freqs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k_emb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;k_freqs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_freqs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# seq_len x dim&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# compute related sin, cos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;q_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q_cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qc_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qc_cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_cos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;attention 计算时的逻辑&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Attention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;key_states&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apply_rotary_pos_emb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_states&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q_states_intra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apply_rotary_pos_emb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;chunk_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:],&lt;/span&gt; &lt;span class="n"&gt;q_cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;position_ids&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;chunk_len&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k_states_prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;chunk_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;v_states_prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;chunk_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# first chunk&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;do_flash_attn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q_states_intra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_states_prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_states_prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flash_result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;remain_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kv_seq_len&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;chunk_len&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;remain_len&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_per_chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;begin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kv_seq_len&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;remain_len&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;curr_chunk_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remain_len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;curr_chunk_len&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# current chunk, intra-chunk attention&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q_states_intra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apply_rotary_pos_emb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:],&lt;/span&gt; &lt;span class="n"&gt;q_cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;position_ids&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k_states_intra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;v_states_intra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;do_flash_attn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q_states_intra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_states_intra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_states_intra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_per_chunk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flash_result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# successive chunk attention&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q_states_succ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apply_rotary_pos_emb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:],&lt;/span&gt; &lt;span class="n"&gt;qc_cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qc_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;position_ids&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;do_flash_attn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q_states_succ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_states_prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_states_prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_per_chunk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flash_result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# inter chunk attention&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k_states_prev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k_states_prev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q_states_inter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apply_rotary_pos_emb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:],&lt;/span&gt; &lt;span class="n"&gt;qc_cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qc_sin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;position_ids&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="n"&gt;chunk_len&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][:,&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;curr_chunk_len&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k_states_inter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;prev_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;v_states_inter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value_states&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;prev_len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;do_flash_attn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q_states_inter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k_states_inter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_states_inter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_per_chunk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flash_result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flash_results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flash_per_chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;k_states_prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k_states_intra&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;v_states_prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v_states_intra&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;remain_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;remain_len&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;chunk_len&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# merge the final results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;attn_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;merge_attn_outputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flash_results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="evaluation"&gt;&lt;a href="#evaluation" class="header-anchor"&gt;&lt;/a&gt;Evaluation
&lt;/h2&gt;&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/DCA_perplexity_evaluation_PG19.png"
width="1202"
height="418"
loading="lazy"
alt="Perplexity evaluation on PG19"
class="gallery-image"
data-flex-grow="287"
data-flex-basis="690px"
&gt;&lt;/p&gt;
&lt;p&gt;作者还分析了一下 DCA 的效率，结果如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/DCA_efficiency_analysis.png"
width="1080"
height="618"
loading="lazy"
alt="Efficiency of DCA"
class="gallery-image"
data-flex-grow="174"
data-flex-basis="419px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，在 &lt;a class="link" href="https://maosong.website/p/notes-on-flashattention/" target="_blank" rel="noopener"
&gt;flash attention&lt;/a&gt; 的基础上加上 DCA 之后，内存占用和推理时间并没有发生太大变化&lt;/p&gt;
&lt;p&gt;作者还分析了三种 attention 对结果的贡献，如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/dual-chunk-attention/DCA_ablation_study.png"
width="1088"
height="404"
loading="lazy"
alt="Ablation study on three modules"
class="gallery-image"
data-flex-grow="269"
data-flex-basis="646px"
&gt;&lt;/p&gt;
&lt;p&gt;结果显示，intra block 的 perplexity 是最低的，但是其在下游任务上表现是最差的。当三者结合在一起之后，perplexity 和下游任务上的表现都是最好的。&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;本文中，我们回顾了 Qwen 系列扩展大模型上下文的方法 Dual Chunk Attention （DCA） 通过将 attention 切分成更小的 chunk，然后将 attention 的计算分为 intra-chunk，inter-chunk 和 successive-chunk，分别处理 chunk 内部，chunk 之间以及相邻 chunk 的 attention，通过这种方式，在无需训练的情况下，我们可以有效将模型上下文长度扩展 4 倍以上。&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/2402.17463" target="_blank" rel="noopener"
&gt;Arxiv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/HKUNLP/ChunkLlama/tree/main" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen2</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2/</link><pubDate>Sat, 12 Jul 2025 10:36:43 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2/</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;2024 年 9 月 Qwen 发布了 Qwen2 系列技术报告，Qwen2 系列包括 4 个 dense 模型（0.5B, 1.5B, 7B, 72B）和一个 MoE 模型（总参数 57B，激活参数 14B），作者主要在架构，数据和长上下文上进行了改进。&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="model"&gt;&lt;a href="#model" class="header-anchor"&gt;&lt;/a&gt;Model
&lt;/h3&gt;&lt;p&gt;对于 dense 模型，Qwen2 在 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen-llm/" target="_blank" rel="noopener"
&gt;Qwen-LLM&lt;/a&gt; 的基础上做了如下改动：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 &lt;a class="link" href="https://maosong.website/p/notes-on-gqa/" target="_blank" rel="noopener"
&gt;Group Query Attention (GQA)&lt;/a&gt; 替换 MHA，来优化 KV cache，提高 throughput&lt;/li&gt;
&lt;li&gt;使用 &lt;a class="link" href="https://maosong.website/p/dual-chunk-attention/" target="_blank" rel="noopener"
&gt;Dual Chunk Attention&lt;/a&gt; 和 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 来提高模型上下文长度和训练效率&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;其余与 Qwen 一致，包括 SwiGLU，RoPE，RMSNorm 和 pre-normalization&lt;/p&gt;
&lt;p&gt;对于 MoE 模型，Qwen2-MoE 基于 &lt;a class="link" href="https://maosong.website/p/dual-chunk-attention/" target="_blank" rel="noopener"
&gt;Qwen1.5&lt;/a&gt; 进行了改进，主要是 3 点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;作者使用了更细粒度的专家个数，作者认为细粒度的专家可以提供更丰富的 combination，这一点与 &lt;a class="link" href="https://maosong.website/p/notes-on-olmoe/" target="_blank" rel="noopener"
&gt;olmoe&lt;/a&gt; 的结论相同&lt;/li&gt;
&lt;li&gt;与 DeepSeek-MoE 一样，作者使用了共享专家和路由专家&lt;/li&gt;
&lt;li&gt;作者使用了类似 upcycling 的方法来初始化模型。假设一共有 $n$ 个专家，每个专家的维度为 $h_E$, 原始 dense 模型的维度为 $h_{FFN}$, 那么我们会把 dense 模型的参数复制 $[nh_E/h_{FFN}]$ 次，这样就可以扩展到任意个数的 MoE 模型上。作者还对参数进行 shuffle，来提高 diversity。最后，作者还对 50% 的参数进行随机初始化，来提高模型的 capacity。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;模型配置如下&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;0.5B&lt;/th&gt;
&lt;th&gt;1.5B&lt;/th&gt;
&lt;th&gt;7B&lt;/th&gt;
&lt;th&gt;72B&lt;/th&gt;
&lt;th&gt;57B-A14B&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hidden Size&lt;/td&gt;
&lt;td&gt;896&lt;/td&gt;
&lt;td&gt;1,536&lt;/td&gt;
&lt;td&gt;3,584&lt;/td&gt;
&lt;td&gt;8,192&lt;/td&gt;
&lt;td&gt;3,584&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;# Layers&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;# Query Heads&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;# KV Heads&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Head Size&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intermediate Size&lt;/td&gt;
&lt;td&gt;4,864&lt;/td&gt;
&lt;td&gt;8,960&lt;/td&gt;
&lt;td&gt;18,944&lt;/td&gt;
&lt;td&gt;29,568&lt;/td&gt;
&lt;td&gt;2,560&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;# Routed Experts&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;# Activated Experts&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;# Shared Experts&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embedding Tying&lt;/td&gt;
&lt;td&gt;True&lt;/td&gt;
&lt;td&gt;True&lt;/td&gt;
&lt;td&gt;False&lt;/td&gt;
&lt;td&gt;False&lt;/td&gt;
&lt;td&gt;False&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vocabulary Size&lt;/td&gt;
&lt;td&gt;151,646&lt;/td&gt;
&lt;td&gt;151,646&lt;/td&gt;
&lt;td&gt;151,646&lt;/td&gt;
&lt;td&gt;151,646&lt;/td&gt;
&lt;td&gt;151,646&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;# Trained Tokens&lt;/td&gt;
&lt;td&gt;12T&lt;/td&gt;
&lt;td&gt;7T&lt;/td&gt;
&lt;td&gt;7T&lt;/td&gt;
&lt;td&gt;7T&lt;/td&gt;
&lt;td&gt;4.5T&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="pre-training"&gt;&lt;a href="#pre-training" class="header-anchor"&gt;&lt;/a&gt;Pre-training
&lt;/h3&gt;&lt;p&gt;预训练阶段的数据基于 Qwen 和 Qwen1.5，数据处理策略如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用基于 heuristic 和 model-based 方法来过滤掉低质量的数据&lt;/li&gt;
&lt;li&gt;加入了 code， math 和 multilingual 的数据&lt;/li&gt;
&lt;li&gt;平衡了各个类别的数据分布&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;初始数据包括 12T token，经过过滤得到 7T token。作者发现，使用 12T token 进行训练，模型的表现不如使用 7B token 训练得到的模型效果好。因此除了 0.5B 的模型，其他模型使用的都是 7T 的 token&lt;/p&gt;
&lt;p&gt;对于 MoE 模型，作者使用了额外的 4.5T token 来进行预训练。&lt;/p&gt;
&lt;p&gt;在训练过程中，作者还加入了 multi-task instruction 数据，来提高模型的上下文学习能力和指令跟随能力。&lt;/p&gt;
&lt;p&gt;作者还将 Qwen2 模型系列的上下文长度从 4096 扩展到 32768，扩展过程中作了三个改动：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;加入了更多高质量的长上下文数据&lt;/li&gt;
&lt;li&gt;将 RoPE 的 frequency 从 10,000 提升到了 1,000,000&lt;/li&gt;
&lt;li&gt;使用了 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt; 来扩展上下文长度&lt;/li&gt;
&lt;li&gt;使用了 &lt;a class="link" href="https://maosong.website/p/dual-chunk-attention/" target="_blank" rel="noopener"
&gt;Dual Chunk Attention&lt;/a&gt; 来优化 attention 的计算&lt;/li&gt;
&lt;/ol&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 包括 SFT 和 RLHF 两个阶段&lt;/p&gt;
&lt;p&gt;数据包括 SFT 数据和 RLHF 使用的偏好数据&lt;/p&gt;
&lt;p&gt;数据标注过程有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 InsTag 对数据进行打标&lt;/li&gt;
&lt;li&gt;选取高质量的 instruction&lt;/li&gt;
&lt;li&gt;构建了一个 self-evolution 策略，来扩展 instruction 数据&lt;/li&gt;
&lt;li&gt;请人类来标注数据&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;作者还合成了一些数据，合成数据的过程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;rejection sampling：对 LLM 进行多次采样，然后保留结论正确的数据作为 SFT 数据，以正确和错误的数据对作为偏好数据&lt;/li&gt;
&lt;li&gt;Execution feedback：对于代码任务，使用 Python 来验证答案的正确性&lt;/li&gt;
&lt;li&gt;Data Repurposing：对于写作类任务，以文档为输入，让 LLM 生成对应的 instruction&lt;/li&gt;
&lt;li&gt;Constitutional Feeback：基于预设的 principle 来生成回答&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最终，SFT 数据包括 500, 000 条样本&lt;/p&gt;
&lt;p&gt;RLHF 的训练包括 offline stage 和 online stage，offline stage 就是用收集到的偏好数据。在 online stage，作者使用 reward model 来给输出的回答进行打分，然后再使用 DPO 进行训练。&lt;/p&gt;
&lt;p&gt;与 Qwen 不同，Qwen2 中作者使用了 Online Merging Optimizer 来解决因为 alignment 导致的性能降低&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;本文提出了 Qwen2 系列，在 Qwen2 中，首次使用了 GQA 代替 MHA，Qwen2 在上下文上做出了初步探索&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="https://arxiv.org/abs/2407.10671" target="_blank" rel="noopener"
&gt;Qwen2 tech report&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen1.5</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen1.5/</link><pubDate>Thu, 03 Jul 2025 17:37:39 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen1.5/</guid><description>&lt;p&gt;Qwen 在 24 年 1 月份发布了 Qwen1.5，包含 0.5B, 1.8B, 4B, 7B, 14B, 32B, 72B, 以及 110B 6 个 size，还有一个 MoE 模型。&lt;/p&gt;
&lt;h2 id="介绍"&gt;&lt;a href="#%e4%bb%8b%e7%bb%8d" class="header-anchor"&gt;&lt;/a&gt;介绍
&lt;/h2&gt;&lt;p&gt;Qwen1.5 的主要特点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;支持 12 中语言&lt;/li&gt;
&lt;li&gt;统一支持 32768 tokens 上下文长度 。&lt;/li&gt;
&lt;li&gt;提供 量化版本 （Int4、Int8、AWQ、GGUF）以适应低资源环境或部署需求。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;训练过程使用了 &lt;a class="link" href="https://maosong.website/p/notes-on-dpo/" target="_blank" rel="noopener"
&gt;DPO&lt;/a&gt; 以及 PPO 来进行对齐&lt;/p&gt;
&lt;h2 id="qwen15-moe"&gt;&lt;a href="#qwen15-moe" class="header-anchor"&gt;&lt;/a&gt;Qwen1.5-MoE
&lt;/h2&gt;&lt;p&gt;Qwen1.5-MoE 的激活参数为 2.7B，一共包含 64 个专家，其中激活 4 个专家，共享 4 个专家&lt;/p&gt;
&lt;p&gt;相比于 Qwen1.5-7B，去训练的 FLOPS 降低了 75%，inference 的速度提高了 174%&lt;/p&gt;
&lt;p&gt;Qwen1.5-MoE 采用了改进的 MoE 架构，主要优化包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;细粒度专家（Fine-grained experts）&lt;/strong&gt; ：通过将 FFN 层划分为多个片段，构建更多专家而不增加参数总量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;初始化策略（Upcycling）&lt;/strong&gt; ：基于 Qwen-1.8B 初始化模型，并引入随机性以加速收敛。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;路由机制（Routing Mechanism）&lt;/strong&gt; ：在每个 MoE 层中使用 64 个专家，其中 4 个共享专家始终激活，60 个路由专家中有 4 个被激活，提高了灵活性和效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="效率对比"&gt;&lt;a href="#%e6%95%88%e7%8e%87%e5%af%b9%e6%af%94" class="header-anchor"&gt;&lt;/a&gt;效率对比
&lt;/h2&gt;&lt;p&gt;作者对比了 throughput (requests processed per second) 以及 tokens per second (TPS):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Throughput&lt;/th&gt;
&lt;th&gt;TPS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen1.5-7B-Chat&lt;/td&gt;
&lt;td&gt;1.15&lt;/td&gt;
&lt;td&gt;2298.89&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen1.5-MoE-A2.7B-Chat&lt;/td&gt;
&lt;td&gt;2.01&lt;/td&gt;
&lt;td&gt;4010.27&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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="https://qwenlm.github.io/blog/qwen-moe/" target="_blank" rel="noopener"
&gt;Qwen1.5 MoE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qwenlm.github.io/blog/qwen1.5/" target="_blank" rel="noopener"
&gt;Qwen 1.5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on YaRN</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-yarn/</link><pubDate>Thu, 03 Jul 2025 14:40:49 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-yarn/</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;YaRN (Yet Another RoPE extentionN method) 时23年9月EleutherAI等提出来的一个扩展LLM上下文长度的方法，后来被Qwen系列模型所应用。&lt;/p&gt;
&lt;h2 id="preliminary"&gt;&lt;a href="#preliminary" class="header-anchor"&gt;&lt;/a&gt;Preliminary
&lt;/h2&gt;&lt;p&gt;作者首先回顾了一下RoPE, 具体内容请参见上一篇&lt;a class="link" href="https://maosong.website/p/notes-on-position-encoding/" target="_blank" rel="noopener"
&gt;blog&lt;/a&gt;。并使用了 $f_{W}(x_m, m, \theta_d)$ 来表示RoPE：&lt;/p&gt;
$$
f_{W}(x_m, m, \theta_{d}) = \Theta_{\theta, m}^d W x_m
$$&lt;p&gt;其中 $\Theta_{\theta, m}^d\in\mathbb{R}^{d\times d}$ 是多维旋转矩阵, $\theta_d=[\theta_{0,d},\dots,\theta_{(d-2)/2,d}]\in\mathbb{R}^{d/2}$, $\theta_{i,d}=\theta^{2i/d}$, $\theta&gt;0$ 是一个超参数，RoPE中设置为 $\theta=10000$, $W\in\{W_q,W_k\}\subset\mathbb{R}^{d\times d}$ 是对应的query/key projection layer的权重矩阵， $x\in\mathbb{R}^{d}$ 是输入的hidden states.&lt;/p&gt;
&lt;p&gt;接下来，作者定义了两个新的变量：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;scaling factor&lt;/strong&gt;
假设预训练的上下文长度为 $L$, 扩展的上下文长度为 $L'&gt;L$, 则我们定义scaling factor 为&lt;/p&gt;
$$
s = \frac{L'}{L}
$$&lt;p&gt;易知 $s&gt;1$.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;wavelength&lt;/strong&gt;
我们将 $\lambda_d$ 定义为 $i$-th 维的RoPE embedding对应的 wavelength：&lt;/p&gt;
$$
\lambda_{i,d} = \frac{2\pi}{\theta_{i,d}} = 2\pi\theta^{2i/d}, \ i=0,\dots,(d-2)/2
$$&lt;p&gt;wavelength描述了对于第$i$ 个维度，RoPE旋转一周 ($2\pi$) 所需要的上下文长度。&lt;/p&gt;
&lt;h2 id="unified-perspective-on-related-work"&gt;&lt;a href="#unified-perspective-on-related-work" class="header-anchor"&gt;&lt;/a&gt;Unified Perspective on Related Work
&lt;/h2&gt;&lt;p&gt;基于 $f_{W}(x_m, m, \theta_d)$, 作者统一了已有的扩展上下文长度的方法，作者将不同的扩展方法使用一个通用函数 $f_W(x_m,g(m), h(\theta_d))$ 来表示，这里 $g(m)$ 和 $h(\theta_d)$ 分别代表了不同的长度外推方法所使用的变换。&lt;/p&gt;
&lt;h3 id="position-interpolation"&gt;&lt;a href="#position-interpolation" class="header-anchor"&gt;&lt;/a&gt;Position Interpolation
&lt;/h3&gt;&lt;p&gt;Position Interpolation (PI) 的核心思想在于，我们可以通过Interpolation，将超过预训练长度的文本给压缩到当前最大长度，以此来避免RoPE外推产生的问题，其对应的公式为&lt;/p&gt;
$$
f'_W(x_m,m,\theta_d) = f_W(x_m, \frac{mL}{L'}, \theta_d)
$$&lt;p&gt;其中 $L'&gt;L$ 为我们扩展之后的上下文长度， $L$ 为我们预训练的上下文长度。使用通用函数表示的话，我们有&lt;/p&gt;
$$
g(m) = \frac{m}{s},\quad h(\theta_d) = \theta_d
$$&lt;h3 id="ntk-aware-interpolation"&gt;&lt;a href="#ntk-aware-interpolation" class="header-anchor"&gt;&lt;/a&gt;NTK-aware Interpolation
&lt;/h3&gt;&lt;p&gt;PI的问题是，并没有考虑不同维度的wavelength。
基于NTK理论，DNN当输入维度比较低，且embedding缺少高频内容时，模型就会很难学习到高频信息。对应到RoPE里面，输入的token position id是低位信息（1维），而输出的RoPE是一个 $d$ 维的复杂向量。因此，当输入token非常相似却距离非常近时，RoPE就会丢失高频的细节信息&lt;/p&gt;
&lt;p&gt;因此，为了解决这个问题，作者对不同的维度使用了不同的缩放策略：&lt;strong&gt;维度比较小时，其缩放的更多，维度比较大是，其缩放的更少。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;基于这个策略，作者提出了NTK-aware interpolation，其定义如下：&lt;/p&gt;
$$
g(m) = m, \quad h(\theta_{i,d}) = \theta'^{-2i/d}, i=0,\dots,(d-2)/2
$$&lt;p&gt;其中&lt;/p&gt;
$$
\theta' = \theta\cdot s^{\frac{d}{d-2}}
$$&lt;p&gt;实际中，这种方法会产生out-of-bound的值，因此最终结果会比PI要差一点，为了解决这个问题，一般会使用比 $s$ 更大的scaling factor.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上式的推导基于一个简单的假设：我们希望最后一个维度的wavelength在scaling之后，是线性变化的，即 $\theta'_{(d-2)/2,d}=s\theta_{(d-2)/2,d}$, 求解之后，我们就得到了上面的定义&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PI 和NTK-aware interpolation的问题在于，我们对不同的维度的处理都是一样的。这类不在乎wavelength的方法被称为&lt;strong&gt;blind interpolation methods&lt;/strong&gt;, 接下来要介绍的就是基于wavelength的方法，即&lt;strong&gt;target interpolation methods&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="ntk-by-parts-interpolation"&gt;&lt;a href="#ntk-by-parts-interpolation" class="header-anchor"&gt;&lt;/a&gt;NTK-by-parts Interpolation
&lt;/h3&gt;&lt;p&gt;与NTK-aware interpolation， NTK-by-parts interpolation基于wavelength来考虑不同维度上所做的变换。&lt;/p&gt;
&lt;p&gt;对于低维度，其 $\theta_{i,d}$ 非常大，因此旋转一周所需要的上下文长度也非常大。实际上就导致某些维度的embedding并不是均匀分布的，（比如说只有 $0\sim\pi$ 这个区间的embedding），这个时候，模型就只能访问到绝对位置信息，而访问不到相对位置信息。
另外，当我们对所有的维度都进行scale的时候，所有的token都会与彼此更加靠近，这损害了模型对于局部信息的获取能力。
基于这些认知，作者基于wavelength，对不同的维度分别进行处理：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果wavelength远小于上下文长度 $L$， 则我们不做任何处理&lt;/li&gt;
&lt;li&gt;如果wavelength等于或者大于上下文长度 $L$， 则我们使用NTK-aware interpolation 进行处理&lt;/li&gt;
&lt;li&gt;对于中间的其他维度，我们进行了一个trade off&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;作者定义了一个ratio $r$ 来描述原始上下文长度 $L$ 和 wavelength 之间的关系&lt;/p&gt;
$$
r(i,d) = \frac{L}{\lambda_{i,d}} = \frac{L}{2\pi\theta'^{2i/d}}
$$&lt;p&gt;基于这个ratio，我们可以定义上面的三种处理方式对应的权重&lt;/p&gt;
$$
\gamma(r) = \begin{cases}
0, &amp;\text{if } r &lt; \alpha\\
1, &amp;\text{if } r &gt; \beta\\
\frac{r-\alpha}{\beta-\alpha}, &amp;\text{otherwise}
\end{cases}
$$&lt;p&gt;其中， $\beta&gt;\alpha&gt;0$ 是超参数， $r&lt;\alpha$, $r&lt;\beta$ 分别代表了上面的第1种，第2种情况。&lt;/p&gt;
&lt;p&gt;最后，NTK-by-parts interpolation的定义如下&lt;/p&gt;
$$
g(m) = m, \quad h(\theta_i) = \left(1-\gamma(r(i,d)\right)\frac{\theta_i}{s} + \gamma(r(i,d))\theta_i
$$&lt;p&gt;作者通过实验发现，在LLaMA上，$\alpha=1$ 和 $\beta=32$ 是一个比较好的选择&lt;/p&gt;
&lt;h3 id="dynamic-ntk-interpolation"&gt;&lt;a href="#dynamic-ntk-interpolation" class="header-anchor"&gt;&lt;/a&gt;Dynamic NTK Interpolation
&lt;/h3&gt;&lt;p&gt;在实际中，一个经常遇到的场景就是sequence length会从1逐步上升到最大上下文长度，比如说inference的时候。对于这种情况，我们有两种解决方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在整个inference周期中，RoPE的scaling factor都设置为 $s=K'/L$, 其中$L'$ 是扩展后的上下文长度&lt;/li&gt;
&lt;li&gt;在每次foward的过程汇总，都更新sclaing factor $s=\max(1, \ell'/L)$, 这里 $\ell'$ 是当前sequence的长度&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;作者发现，方案1在sequence长度小于 $L$的时候性能会下降，并且当上下文长度超过 $L'$ 时，性能下降的更快。
但是，方案2可以让模型的性能下降曲线更平缓。因此，作者将这种inference-time方法称为 &lt;strong&gt;Dynamic Scaling method&lt;/strong&gt;, 当其与NTK-aware方法结合时，就得到了 &lt;strong&gt;Dynamic NTK interpolation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;作者通过实验发现，Dynamic NTK interpolation在$L'=L$ 时，效果非常好&lt;/p&gt;
&lt;h2 id="yarn"&gt;&lt;a href="#yarn" class="header-anchor"&gt;&lt;/a&gt;YaRN
&lt;/h2&gt;&lt;p&gt;在YaRN中，作者针对Dynamic NTK interpolation做了进一步改进，也就是在计算attention softmax时，加入了一个温度参数 $t&gt;0$, 这样attention的计算就变成了&lt;/p&gt;
$$
\mathrm{Attn}(Q, K, V) = \mathrm{softmax}\left(\frac{QK^T}{t\sqrt{d}}\right)V
$$&lt;p&gt;作者发现，通过这种scaling的方式，YaRN可以在不改变代码的前提下，更改attention的机制。并且，其不增加训练和推理的cost&lt;/p&gt;
&lt;p&gt;作者将YaRN定义为&lt;strong&gt;结合了NTK-by-parts interpolation和上述scaling技巧的方法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;对于LLaMA，作者推荐使用如下参数：&lt;/p&gt;
$$
\sqrt{\frac{1}{t}} = 0.1\ln(s) + 1.
$$&lt;p&gt;实验结果如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-yarn/YaRN_temperature_ablation.png"
width="1049"
height="528"
loading="lazy"
alt="Ablation study on temperature"
class="gallery-image"
data-flex-grow="198"
data-flex-basis="476px"
&gt;&lt;/p&gt;
&lt;p&gt;作者发现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对于合适的 $t$, 扩展上下文之后，perplexity会变的更好&lt;/li&gt;
&lt;li&gt;最好的$t$ 对于不同的位置和样本提升都是一样的&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="evaluation"&gt;&lt;a href="#evaluation" class="header-anchor"&gt;&lt;/a&gt;Evaluation
&lt;/h2&gt;&lt;p&gt;实验结果如下&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Extension Method&lt;/th&gt;
&lt;th&gt;Trained Tokens&lt;/th&gt;
&lt;th&gt;Context Window&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Evaluation Context Window Size&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;4096&lt;/td&gt;
&lt;td&gt;6144&lt;/td&gt;
&lt;td&gt;8192&lt;/td&gt;
&lt;td&gt;10240&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PI (s = 2)&lt;/td&gt;
&lt;td&gt;1B&lt;/td&gt;
&lt;td&gt;8k&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;3.92&lt;/td&gt;
&lt;td&gt;3.51&lt;/td&gt;
&lt;td&gt;3.51&lt;/td&gt;
&lt;td&gt;3.34&lt;/td&gt;
&lt;td&gt;8.07&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NTK ($\theta$ = 20k)&lt;/td&gt;
&lt;td&gt;1B&lt;/td&gt;
&lt;td&gt;8k&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;4.20&lt;/td&gt;
&lt;td&gt;3.75&lt;/td&gt;
&lt;td&gt;3.74&lt;/td&gt;
&lt;td&gt;3.59&lt;/td&gt;
&lt;td&gt;6.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YaRN (s = 2)&lt;/td&gt;
&lt;td&gt;400M&lt;/td&gt;
&lt;td&gt;8k&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.91&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.51&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3.35&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6.04&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;可以看到，YaRN使用的数据更少，并且当模型扩展到10240的时候，其表现下降的最慢，这说明了YaRN在扩展上下文长度时的有效性&lt;/p&gt;
&lt;p&gt;原始RoPE，dynamic-PI和dynamic-YaRN的对比&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-yarn/YaRN_comparison_RoPE_PI.png"
width="1154"
height="573"
loading="lazy"
alt="Comparison with RoPE and PI"
class="gallery-image"
data-flex-grow="201"
data-flex-basis="483px"
&gt;&lt;/p&gt;
&lt;p&gt;可以看到，RoPE的上下文扩展能力很差，Dynamic-YaRN的表现最好。&lt;/p&gt;
&lt;h2 id="code"&gt;&lt;a href="#code" class="header-anchor"&gt;&lt;/a&gt;Code
&lt;/h2&gt;&lt;p&gt;YaRN的实现在&lt;a class="link" href="https://github.com/huggingface/transformers/blob/main/src/transformers/modeling_rope_utils.py" target="_blank" rel="noopener"
&gt;HuggingFace/src/transformers/modeling_rope_utils.py&lt;/a&gt; 里的 &lt;code&gt;_compute_yarn_parameters&lt;/code&gt; 函数里，其返回 &lt;code&gt;inv_freq&lt;/code&gt; 以及 &lt;code&gt;attention_factor&lt;/code&gt; 两个量，前者代表了 $\theta_d$, 后者代表 $t\sqrt{d}$.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_mscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_correction_dim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_rotations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_position_embeddings&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Inverse dimension formula to find the dimension based on the number of rotations&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_position_embeddings&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_rotations&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_correction_range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low_rot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high_rot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_position_embeddings&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Find dimension range bounds based on rotations&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;find_correction_dim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low_rot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_position_embeddings&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;find_correction_dim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;high_rot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_position_embeddings&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;linear_ramp_factor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;max&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt; &lt;span class="c1"&gt;# Prevent singularity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;linear_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ramp_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;linear_func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ramp_func&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;YaRNRotaryEmbedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;beta_fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;beta_fast&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;beta_slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;beta_slow&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;head_dim&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;factor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_position_embeddings&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;original_max_position_embeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pos_freqs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;inv_freq_extrapolation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pos_freqs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;inv_freq_interpolation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;factor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pos_freqs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_correction_range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beta_fast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;beta_slow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original_max_position_embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Get n-dimensional rotational scaling corrected for extrapolation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;inv_freq_extrapolation_factor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;linear_ramp_factor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;inv_freq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inv_freq_interpolation&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;inv_freq_extrapolation_factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;inv_freq_extrapolation&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;inv_freq_extrapolation_factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;attention_factor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_mscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;position_ids&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;实际的transformers代码中，Qwen使用的还是默认的RoPE，在inference时如果我们需要扩展上下文，可以通过修改config的形式：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model_name_or_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Qwen/Qwen3-8B&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;text-generation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model_name_or_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;torch_dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;auto&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;device_map&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;auto&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;max_position_embeddings&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;131072&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;rope_scaling&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;rope_type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;yarn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;factor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;original_max_position_embeddings&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32768&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="conclusion"&gt;&lt;a href="#conclusion" class="header-anchor"&gt;&lt;/a&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;在本文中，作者首先构建了一个统一的表征不同上下文长度扩展的形式，接下来作者分析了不同上下文长度扩展的不足，并提出了YaRN这种上下文长度扩展方式，结果发现，YaRN不仅在短上下文长度下面表现很好，当上下文长度扩展之后，其表现依然非常优秀。&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/2309.00071" target="_blank" rel="noopener"
&gt;arxiv YaRN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/pdf/2306.15595" target="_blank" rel="noopener"
&gt;arxiv PI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://qwen.readthedocs.io/en/latest/inference/transformers.html#enabling-long-context" target="_blank" rel="noopener"
&gt;Qwen documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen-LLM</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen-llm/</link><pubDate>Thu, 03 Jul 2025 10:47:27 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen-llm/</guid><description>&lt;p&gt;Qwen 在 23 年 9 月份发布了 Qwen 系列大语言模型，包括 1.8B， 7B，14B 三个 size，训练过程使用了 3T token. 作者还基于 Qwen，构建了 Code-Qwen-Chat，Math-Qwen-Chat 等系列领域大语言模型。&lt;/p&gt;
&lt;h2 id="pre-training"&gt;&lt;a href="#pre-training" class="header-anchor"&gt;&lt;/a&gt;Pre-training
&lt;/h2&gt;&lt;h3 id="data"&gt;&lt;a href="#data" class="header-anchor"&gt;&lt;/a&gt;Data
&lt;/h3&gt;&lt;p&gt;数据一共使用了 &lt;strong&gt;3T token&lt;/strong&gt;，主要是 public web documents, encyclopedia, books, codes, etc，覆盖了中文和英文两种语言&lt;/p&gt;
&lt;p&gt;数据处理：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;语言识别&lt;/li&gt;
&lt;li&gt;去重，包括 MinHash 和 LSH 算法&lt;/li&gt;
&lt;li&gt;质量过滤，包括基于规则和和基于 ML 的方法&lt;/li&gt;
&lt;li&gt;上采样，特定数据会进行上采样&lt;/li&gt;
&lt;li&gt;加入指令数据，提高模型的 zero-shot 和 few-shot 表现&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="tokenization"&gt;&lt;a href="#tokenization" class="header-anchor"&gt;&lt;/a&gt;Tokenization
&lt;/h3&gt;&lt;p&gt;BPE tokenizer，最终的 tokenizer 大小为 152K&lt;/p&gt;
&lt;h3 id="architecture"&gt;&lt;a href="#architecture" class="header-anchor"&gt;&lt;/a&gt;Architecture
&lt;/h3&gt;&lt;p&gt;模型架构基于 LLaMA， 改动：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;tie embdding: input embdding 和 output embdding 使用的权重相同&lt;/li&gt;
&lt;li&gt;position encoding:RoPE, inverse frequency 的精度为 FP32&lt;/li&gt;
&lt;li&gt;bias: 取消了大部分的 bias，增加了 QKV bias，来提高模型的外推能力&lt;/li&gt;
&lt;li&gt;Pre-Norm &amp;amp; RMSNorm&lt;/li&gt;
&lt;li&gt;Activation function: SwiGLU&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="training"&gt;&lt;a href="#training" class="header-anchor"&gt;&lt;/a&gt;Training
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;上下文长度：2048&lt;/li&gt;
&lt;li&gt;attention：&lt;a class="link" href="https://maosong.website/p/notes-on-flashattention/" target="_blank" rel="noopener"
&gt;flash attention&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;optimizer：AdamW， $\beta_1=0.9$, $\beta_2=0.95$, $\epsilon=10^{-8}$.&lt;/li&gt;
&lt;li&gt;data type: BF16&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="context-extention"&gt;&lt;a href="#context-extention" class="header-anchor"&gt;&lt;/a&gt;Context Extention
&lt;/h3&gt;&lt;p&gt;使用了三个技巧：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;NTK-aware position interpolation&lt;/li&gt;
&lt;li&gt;log-N scaling&lt;/li&gt;
&lt;li&gt;window attention&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;后续前两个统一成了 &lt;a class="link" href="https://maosong.website/p/notes-on-yarn/" target="_blank" rel="noopener"
&gt;YARN&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;observation: lower layer 对上下文长度扩展更敏感, 因此作者动态调整了 window size&lt;/p&gt;
&lt;h2 id="post-training"&gt;&lt;a href="#post-training" class="header-anchor"&gt;&lt;/a&gt;Post-training
&lt;/h2&gt;&lt;p&gt;包括 SFT 和 RLHF 两个阶段&lt;/p&gt;
&lt;h3 id="sft"&gt;&lt;a href="#sft" class="header-anchor"&gt;&lt;/a&gt;SFT
&lt;/h3&gt;&lt;p&gt;data： 使用了 ChatML 格式&lt;/p&gt;
&lt;h3 id="rlhf"&gt;&lt;a href="#rlhf" class="header-anchor"&gt;&lt;/a&gt;RLHF
&lt;/h3&gt;&lt;p&gt;PPO 算法&lt;/p&gt;
&lt;p&gt;reward model 构建：基于 Qwen-base model&lt;/p&gt;
&lt;p&gt;RL 训练：先更新 value model 50 steps&lt;/p&gt;
&lt;p&gt;发现：top-p 设置为 0.9 比设置为 1.0 更好&lt;/p&gt;
&lt;h3 id="tool-use-and-agent"&gt;&lt;a href="#tool-use-and-agent" class="header-anchor"&gt;&lt;/a&gt;Tool-use and Agent
&lt;/h3&gt;&lt;p&gt;作者使用了 self-instruct 来进行 SFT，基于 ReAct 构建数据，数据包括 2000 条高质量数据&lt;/p&gt;
&lt;h2 id="specialization"&gt;&lt;a href="#specialization" class="header-anchor"&gt;&lt;/a&gt;Specialization
&lt;/h2&gt;&lt;h3 id="code-qwen"&gt;&lt;a href="#code-qwen" class="header-anchor"&gt;&lt;/a&gt;Code-Qwen
&lt;/h3&gt;&lt;p&gt;code-qwen 基于 qwen continue Pretraining 得到，然后基于 code-qwen 进行 sft 得到 code-qwen-chat，包括 7B 和 14B 两个 size&lt;/p&gt;
&lt;h3 id="math-qwen"&gt;&lt;a href="#math-qwen" class="header-anchor"&gt;&lt;/a&gt;Math-Qwen
&lt;/h3&gt;&lt;p&gt;基于 qwen 直接 SFT 得到，包括 7B 和 14B 两个 size&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;作者在本文中介绍了 Qwen 系列大语言模型，模型使用了 3T token，作者介绍了训练的细节以及如何扩展到领域大语言模型 Code-Qwen 和 Math-Qwen&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="https://spaces.ac.cn/archives/9444" target="_blank" rel="noopener"
&gt;Length exploration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/abs/2309.16609" target="_blank" rel="noopener"
&gt;Arxiv&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen3</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3/</link><pubDate>Thu, 15 May 2025 14:48:11 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3/</guid><description>&lt;p&gt;Qwen 在 2025 年 5 月发布了 Qwen3 系列大语言模型，Qwen3 包括 6 个 dense 模型和 2 个 MoE 模型，主要亮点为多语种能力，自适应快慢思考能力以及支持用户设置 thinking budget.&lt;/p&gt;
&lt;p&gt;Qwen3 包括 6 个 dense 模型和 2 个 MoE 模型，其旗舰模型是一个 235B 的 MoE 模型，激活参数为 22B. Qwen3 系列的主要亮点如下:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;快慢思考融合，模型原生支持在 reasoning/non-reasoning 模式之间切换&lt;/li&gt;
&lt;li&gt;Reasoning budget, 用户可以指定思考需要的 budget，来平衡 latency 和 performance&lt;/li&gt;
&lt;li&gt;Distillation, 使用蒸馏的方法训练小模型，大幅度提高模型的表现&lt;/li&gt;
&lt;li&gt;多语种支持，相比于 Qwen2.5，Qwen3 支持 119 中语言和方言&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="method"&gt;&lt;a href="#method" class="header-anchor"&gt;&lt;/a&gt;Method
&lt;/h2&gt;&lt;h3 id="model"&gt;&lt;a href="#model" class="header-anchor"&gt;&lt;/a&gt;Model
&lt;/h3&gt;&lt;p&gt;Qwen3 的 dense 模型的架构与 &lt;a class="link" href="https://maosong.website/p/notes-on-qwen2.5/" target="_blank" rel="noopener"
&gt;Qwen2.5&lt;/a&gt; 基本一致，包括使用 &lt;a class="link" href="https://maosong.website/p/notes-on-gqa/" target="_blank" rel="noopener"
&gt;GQA&lt;/a&gt; , SwiGLU, RoPE, RMSNorm 和 pre-normalization. Qwen3 进一步移除了 QKV bias, 然 后加入了 &lt;a class="link" href="https://maosong.website/p/notes-on-qk-norm/" target="_blank" rel="noopener"
&gt;QK-Norm&lt;/a&gt; 来提高训练的稳定性。&lt;/p&gt;
&lt;p&gt;Qwen3 的 MoE 架构使用了 128 个专家，激活专家个数为 8 个。与 Qwen2.5-MoE 不同，Qwen3 里没有使用 shard experts。并且，Qwen3 加入了 global-batch load balancing loss,来提高 expert 的特化程度。&lt;/p&gt;
&lt;p&gt;在 tokenizer 方面，Qwen 系列的 tokenizer 一直都是一样的，这也是 Qwen 系列领先的一点。&lt;/p&gt;
&lt;p&gt;模型的具体参数如下两张表所示。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MoE 架构&lt;/strong&gt;：上下文长度为 128K，128 个专家，每个 token 由 8 个专家负责处理&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qwen3-235B-A22B, 总参数 235B，激活参数 22B&lt;/li&gt;
&lt;li&gt;Qwen3-30B-A3B, 总参数 30B，激活参数 3B&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Models&lt;/th&gt;
&lt;th&gt;Layers&lt;/th&gt;
&lt;th&gt;Heads (Q / KV)&lt;/th&gt;
&lt;th&gt;# Experts (Total / Activated)&lt;/th&gt;
&lt;th&gt;Context Length&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-30B-A3B&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;32 / 4&lt;/td&gt;
&lt;td&gt;128 / 8&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-235B-A22B&lt;/td&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;td&gt;64 / 4&lt;/td&gt;
&lt;td&gt;128 / 8&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;dense 架构&lt;/strong&gt;: Qwen3-32B, Qwen3-14B, Qwen3-8B, Qwen3-4B, Qwen3-1.7B, and Qwen3-0.6B&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Models&lt;/th&gt;
&lt;th&gt;Layers&lt;/th&gt;
&lt;th&gt;Heads (Q / KV)&lt;/th&gt;
&lt;th&gt;Tie Embedding&lt;/th&gt;
&lt;th&gt;Context Length&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-0.6B&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;16 / 8&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;32K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-1.7B&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;16 / 8&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;32K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-4B&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;32 / 8&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;32K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-8B&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;32 / 8&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-14B&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;40 / 8&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-32B&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;64 / 8&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="pre-training"&gt;&lt;a href="#pre-training" class="header-anchor"&gt;&lt;/a&gt;Pre-training
&lt;/h3&gt;&lt;p&gt;预训练数据一共包括 &lt;strong&gt;36T token&lt;/strong&gt;，覆盖了 119 种语言。数据包括 coding, STEM, reasoning, books, multilingual texts 以及合成数据。&lt;/p&gt;
&lt;p&gt;为了扩展训练数据，作者微调了 Qwen2.5-VL 来从 PDF 文档中提取文字，然后使用 Qwen2.5 来进行修正。最终收集到了几 T 的 token。另外，作者还使用 Qwen2.5, Qwen2.5-Math, Qwen2.5-Coder 来合成不同格式的数据，包括教科书，QA，指令以及代码片段等。最后，作者加入了更多的多语种数据。&lt;/p&gt;
&lt;p&gt;作者从 educational value, fields, domains 以及 safety 对数据进行了标注。在数据混合时，Qwen3 在 instance 层面进行操作。&lt;/p&gt;
&lt;p&gt;预训练阶段包括 3 个 stage：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;General Stage (S1): 这一阶段的目的是让模型掌握世界知识，使用了 &lt;strong&gt;30T&lt;/strong&gt; 的 token，模型上下文长度为 4096&lt;/li&gt;
&lt;li&gt;Reasoning Stage (S2): 这一阶段的目的是提高模型的推理能力，使用了 &lt;strong&gt;5T&lt;/strong&gt; 的高质量 token，模型上下文长度为 4096，数据包括 STEM, coding, reasoning 以及合成数据&lt;/li&gt;
&lt;li&gt;Long Context Stage (S3): 这一阶段的目的是提升模型的长上下文能力，使用了&lt;strong&gt;几百 B&lt;/strong&gt;的 token，模型上下文长度为 32768.训练时数据混合 75% 的长文档数据，25% 的短文本数据。作者将 RoPE 的 frequency 从 10000 提升到了 1,000,000. 作者还是用 YARN 以及 Dual Chunk Attention 来提高 inference 效率&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对 pre-training 的 base model 进行评测之后，作者发现：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Qwen3-235B-A22B-Base&lt;/code&gt; 超过了其他 base 模型的表现，包括 &lt;code&gt;DeepSeek-V3 Base&lt;/code&gt;, &lt;code&gt;Llama-4-Maverick Base&lt;/code&gt;, &lt;code&gt;Qwen2.5-72B Base&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Qwen3-MoE 模型与相同大小的 Qwen3-Dense 模型参数相比，其只需要 1/5 的参数就可以达到相同的表现&lt;/li&gt;
&lt;li&gt;Qwen3-MoE 模型与 2 倍参数量的 Qwen2.5-MoE 模型表现差不多&lt;/li&gt;
&lt;li&gt;Qwen3-Dense 模型与大一个量级的 Qwen2.5-Dense 模型表现差不多&lt;/li&gt;
&lt;/ol&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;Qwen3 的 post-training 如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3/Qwen3_post-training.png"
width="1355"
height="614"
loading="lazy"
alt="Post-training Pipeline of Qwen3"
class="gallery-image"
data-flex-grow="220"
data-flex-basis="529px"
&gt;&lt;/p&gt;
&lt;p&gt;对于旗舰模型 (&lt;code&gt;Qwen3-235B-A22B&lt;/code&gt;, &lt;code&gt;Qwen3-32B&lt;/code&gt;) 的训练，Qwen3 使用了一个四阶段的训练 pipeline。对于轻量化模型（其他模型）的训练，Qwen3 使用了知识蒸馏。&lt;/p&gt;
&lt;p&gt;旗舰模型的训练包括四个阶段，前两个阶段用于提升模型的 reasoning 能力，后两个阶段用于将 reasoning 和 non-reasoning 能力结合起来。&lt;/p&gt;
&lt;h4 id="flashship-model"&gt;&lt;a href="#flashship-model" class="header-anchor"&gt;&lt;/a&gt;Flashship Model
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;Stage 1 (Long CoT Cold Start)&lt;/strong&gt;
这个阶段的目的是让模型掌握 reasoning 的基础。这个阶段使用了数学，代码，逻辑推理和通用的 STEM 相关问题。每个问题都有参考答案或者 test-cases. 作者使用了 Qwen2.5-72B 来过滤数据，包括 non-verifiable prompts 以及太简单的 prompt. 作者认为，这一阶段应该减少训练使用的样本和训练步数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stage 2 (Reasoning RL)&lt;/strong&gt;
这个阶段的目的是提升模型的 reasoning 能力。该阶段使用了 3,995 条过滤得到的样本，算法为 GRPO. 作者发现提高 batch size 和每个 query 的 rollouts 可以提高模型的表现。作者通过调整模型的 entropy 来控制 exploration 和 exploitation 的平衡&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stage 3 (Thinking Mode Fusion)&lt;/strong&gt;
这一阶段的目的是将 non-reasoning 能力加入到之前的 reasoning 模型中。作者在第二阶段的 model 上进行了 continual SFT，然后构建了一个 chat template 用于融合两种模式。&lt;/p&gt;
&lt;p&gt;reasoning 数据来源于 stage1 的 rejection sampling 和 stage 2 的模型. non-reasoning 数据来源于各种任务，如 coding, math, multilingual 等。为了保证模型的多语种能力，作者还加入了一些翻译相关的数据。&lt;/p&gt;
&lt;p&gt;作者还构建了一个 chat template, 用于统一数据格式。chat template 如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3/Qwen3_chat_template.png"
width="740"
height="320"
loading="lazy"
alt="chat template of Qwen3"
class="gallery-image"
data-flex-grow="231"
data-flex-basis="555px"
&gt;&lt;/p&gt;
&lt;p&gt;作者使用 &lt;code&gt;/think&lt;/code&gt; 和 &lt;code&gt;/no_think&lt;/code&gt; 来标记两种模式，对于 non-reasoning mode, 其 &lt;code&gt;&amp;lt;think&amp;gt;&amp;lt;/think&amp;gt;&lt;/code&gt; 会被置空。模型在默认情况下处于 reasoning mode, 因此作者加入了一些不包含 &lt;code&gt;/think&lt;/code&gt; 的 reasoning 数据。&lt;/p&gt;
&lt;p&gt;作者发现，通过这种 Think mode fusion, 模型可以学会在 reasoning mode 和 non-reasoning mode 下进行回答，因此，模型也可以基于中间结果来给出最终的答案。 当超出 budget 之后，作者使用以下 Instruction&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Considering the limit time by the user. I have to give the solution based on the thinking directly now. \n&amp;lt;/think&amp;gt;.\n\n&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;来让模型直接终止思考二给出最终的答案。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stage 4 (General RL)&lt;/strong&gt;
这个阶段的目的是提升模型在不同场景下的能力。作者构建了一个 reward system 来覆盖 20 多种不同的任务。这些任务包括：instruction following, format following, preference alignment, agent ability 以及 abilities for specialized scenarios.&lt;/p&gt;
&lt;p&gt;作者构建了三种不同的 rewards:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rule-based rewards: 覆盖的任务包括 instruction following 和 format following&lt;/li&gt;
&lt;li&gt;Model-based rewards: 作者使用 Qwen2.5-72B 来判别答案的正确性&lt;/li&gt;
&lt;li&gt;Model-based Reward without reference answer: 作者训练一个 reward model 来给模型的回答进行打分&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="lightweight-model"&gt;&lt;a href="#lightweight-model" class="header-anchor"&gt;&lt;/a&gt;Lightweight Model
&lt;/h4&gt;&lt;p&gt;对于轻量化的模型，作者发现直接通过蒸馏可以有效提高学生模型的表现，并且训练效率也更高。蒸馏训练包括两个阶段：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Off-policy Distillation: 这个阶段的目的是让模型拥有基本的 reasoning 能力并且可以在不同的模式中进行切换。作者使用了教师模型的 reasoning 输出和 non-reasoning 输出来蒸馏学生模型&lt;/li&gt;
&lt;li&gt;On-policy Distillation: 在这个阶段，学生模型生成回答，然后基于教师模型的输出，使用 KL-divergence 来更新学生模型的参数&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="evaluation"&gt;&lt;a href="#evaluation" class="header-anchor"&gt;&lt;/a&gt;Evaluation
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Thinking budget&lt;/strong&gt;. 作者发现当我们提高 Thinking budget 之后，模型的表现是可以持续提升的。结果如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3/Qwen3_thinking_budget_performance.png"
width="1355"
height="938"
loading="lazy"
alt="Performance according to thinking budget"
class="gallery-image"
data-flex-grow="144"
data-flex-basis="346px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Efficiency of distillation&lt;/strong&gt;. 作者发现使用 distillation 可以大幅度提高模型的表现和训练效率。下面是结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3/Qwen3_distillation_ablation.png"
width="1309"
height="200"
loading="lazy"
alt="Comparison between distillation and RL"
class="gallery-image"
data-flex-grow="654"
data-flex-basis="1570px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Effects of Thinking mode fusion and RL&lt;/strong&gt; 作者进一步探究了三个 stage 对模型表现的影响，为此，作者构建了 in-house benchmarks 来评估模型的表现，这些 benchmarks 包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;CounterFactrQA. 问题是不符合事实的，用于评估模型的幻觉&lt;/li&gt;
&lt;li&gt;LengthCtrl. 有长度要求的写作任务，评估生成内容长度和给定长度之间的差别&lt;/li&gt;
&lt;li&gt;ThinkFollow. 多轮对话，每轮对话随机插入 &lt;code&gt;/think&lt;/code&gt; 和 &lt;code&gt;/no_think&lt;/code&gt; flag，评估模型是否能在两种模式之间切换&lt;/li&gt;
&lt;li&gt;Tooluse. 评估模型的工具调用能力&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-qwen3/Qwen3_stage_ablation.png"
width="1358"
height="684"
loading="lazy"
alt="Performance of difference stages"
class="gallery-image"
data-flex-grow="198"
data-flex-basis="476px"
&gt;&lt;/p&gt;
&lt;p&gt;结论如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stage3 可以提高模型在两种 reasoning mode 切换的能力，并且 stage3 还可以提高模型的通用以及 instruction following 能力&lt;/li&gt;
&lt;li&gt;Stage4 进一步提高模型在两种模式下的通用，instruction following 和 agent 能力&lt;/li&gt;
&lt;li&gt;Stage3 和 stage4 并没有显著提高模型在 knowledge, STEM, math 和 coding 相关任务上的表现。甚至在一些竞赛如 AIME24 上模型的表现还有所下降，作者认为这是由于我们提升了模型的通用能力而导致其特化能力下降导致的，作者认为作为一个通用模型，这是可以接受的。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusion"&gt;&lt;a href="#conclusion" class="header-anchor"&gt;&lt;/a&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;在本文中，作者提出了 Qwen3 系列大语言模型，包括 6 个 Dense 模型和 2 个 MoE 模型。Qwen3 模型标志了一个新的 SOTA，其特点主要是快慢思考结合，thinking budget，以及多语种。&lt;/p&gt;
&lt;p&gt;作者认为后续工作有以下几点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用更高质量的数据来进行预训练&lt;/li&gt;
&lt;li&gt;优化模型架构和训练方式，提升模型的上下文&lt;/li&gt;
&lt;li&gt;提高针对 RL 的计算资源，来进一步提高模型的 agent 能力&lt;/li&gt;
&lt;/ol&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="https://arxiv.org/abs/2505.09388" target="_blank" rel="noopener"
&gt;Arxiv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/QwenLM/Qwen3" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen3 blog</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-blog/</link><pubDate>Tue, 29 Apr 2025 11:23:04 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-blog/</guid><description>&lt;h1 id="介绍"&gt;&lt;a href="#%e4%bb%8b%e7%bb%8d" class="header-anchor"&gt;&lt;/a&gt;介绍
&lt;/h1&gt;&lt;p&gt;Qwen3发布，包含两种架构的模型，每种架构均包含对应的base model和post-trained model.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MoE架构&lt;/strong&gt;：上下文长度为128K，128个专家，每个token由8个专家负责处理&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qwen3-235B-A22B, 总参数235B，激活参数22B，&lt;/li&gt;
&lt;li&gt;Qwen3-30B-A3B, 总参数30B，激活参数3B&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Models&lt;/th&gt;
&lt;th&gt;Layers&lt;/th&gt;
&lt;th&gt;Heads (Q / KV)&lt;/th&gt;
&lt;th&gt;# Experts (Total / Activated)&lt;/th&gt;
&lt;th&gt;Context Length&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-30B-A3B&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;32 / 4&lt;/td&gt;
&lt;td&gt;128 / 8&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-235B-A22B&lt;/td&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;td&gt;64 / 4&lt;/td&gt;
&lt;td&gt;128 / 8&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;dense架构&lt;/strong&gt;: Qwen3-32B, Qwen3-14B, Qwen3-8B, Qwen3-4B, Qwen3-1.7B, and Qwen3-0.6B&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Models&lt;/th&gt;
&lt;th&gt;Layers&lt;/th&gt;
&lt;th&gt;Heads (Q / KV)&lt;/th&gt;
&lt;th&gt;Tie Embedding&lt;/th&gt;
&lt;th&gt;Context Length&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-0.6B&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;16 / 8&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;32K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-1.7B&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;16 / 8&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;32K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-4B&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;32 / 8&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;32K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-8B&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;32 / 8&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-14B&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;40 / 8&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen3-32B&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;64 / 8&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;128K&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="亮点"&gt;&lt;a href="#%e4%ba%ae%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;亮点
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;Hybrid Thinking modes
qwen3支持两种思考模式： thinking mode 和 non-thinking mode，前者用于解决复杂的问题，后者用于解决简单的问题&lt;/li&gt;
&lt;li&gt;multilingual support
qwen3支持119中语言和方言&lt;/li&gt;
&lt;li&gt;Improved agentic capabilities
提升了qwen3的coding和agentic能力，并支持MCP&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="训练"&gt;&lt;a href="#%e8%ae%ad%e7%bb%83" class="header-anchor"&gt;&lt;/a&gt;训练
&lt;/h1&gt;&lt;h2 id="pre-training"&gt;&lt;a href="#pre-training" class="header-anchor"&gt;&lt;/a&gt;Pre-training
&lt;/h2&gt;&lt;p&gt;Qwen3使用了36T token进行训练 （与之相比，Qwen2.5使用方的token数量为18T），数据来源于互联网和PDF，作者使用Qwen2.5-VL来提取内容，然后使用Qwen2.5来提升内容质量。作者还基于Qwen2.5-Math和Qwen2.5-Coder来合成数学以及代码数据&lt;/p&gt;
&lt;p&gt;训练包含三个stage：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;上下文长度为4K tokens，训练数据为30T tokens, 目标是让模型掌握初步的语言能力和知识&lt;/li&gt;
&lt;li&gt;上下文长度为4K tokens，训练数据为5T tokens,这部分数据主要是knowledge intensive的数据，比如STEM, coding和reasoning等&lt;/li&gt;
&lt;li&gt;上下文长度扩展到32K tokens，训练数据主要是高质量长上下文的数据&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-blog/qwen3-base.jpg"
width="1554"
height="1058"
loading="lazy"
alt="performance of qwen3 base"
class="gallery-image"
data-flex-grow="146"
data-flex-basis="352px"
&gt;&lt;/p&gt;
&lt;h2 id="post-training"&gt;&lt;a href="#post-training" class="header-anchor"&gt;&lt;/a&gt;Post-training
&lt;/h2&gt;&lt;p&gt;Post-training包含四个阶段，如下图所示
&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen3-blog/post-training.png"
width="4143"
height="1640"
loading="lazy"
alt="post training of qwen3"
class="gallery-image"
data-flex-grow="252"
data-flex-basis="606px"
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stage 1, Long CoT code start: 作者基于math, coding, logical reasoning, STEM等domain的Long CoT数据来微调模型，让模型拥有初步的推理能力，这和Kimi-VL是类似的&lt;/li&gt;
&lt;li&gt;Stage 2, reasoning-based RL: 作者使用rule-based rewards来提供奖励，然后使用RL来训练模型，经一部提高模型的exploration和exploitation能力&lt;/li&gt;
&lt;li&gt;Stage 3, thinking mode fusion: 作者混合了一部分instruction-following和Long CoT数据来提升模型的non-thinking能力，这样可以让模型在两种思考模式之间切换&lt;/li&gt;
&lt;li&gt;Stage 4,general RL： 作者使用RL在20多个general-domain任务上进一步提高模型的通用能力，包括instruction following, format following以及agent capability等&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="future-work"&gt;&lt;a href="#future-work" class="header-anchor"&gt;&lt;/a&gt;Future work
&lt;/h1&gt;&lt;p&gt;作者希望在未来能够在模型架构和训练方式上进行提升，包括：scaling data, increasing model size, extending context length, broadening modalities, advancing RL with environmental feedback for long-horizon reasoning.&lt;/p&gt;
&lt;h1 id="结论"&gt;&lt;a href="#%e7%bb%93%e8%ae%ba" class="header-anchor"&gt;&lt;/a&gt;结论
&lt;/h1&gt;&lt;p&gt;与Gemini2.5 pro，Kimi-VL等reaosning model不同，qwen3可以在快思考和慢思考之间进行转换。感觉未来有两个趋势，一个是如何在快思考和慢思考之间进行切换，切换的逻辑是什么？第二个就是qwen3以及qwen2.5-vl都在强调的agent能力，也就是我们不仅仅是在做一个LLM，而是逐步延伸到了agent这个层面。&lt;/p&gt;
&lt;h1 id="参考文献"&gt;&lt;a href="#%e5%8f%82%e8%80%83%e6%96%87%e7%8c%ae" class="header-anchor"&gt;&lt;/a&gt;参考文献
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qwenlm.github.io/blog/qwen3/" target="_blank" rel="noopener"
&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen2.5 omni</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-omni/</link><pubDate>Tue, 01 Apr 2025 10:29:00 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-omni/</guid><description>&lt;h1 id="介绍"&gt;&lt;a href="#%e4%bb%8b%e7%bb%8d" class="header-anchor"&gt;&lt;/a&gt;介绍
&lt;/h1&gt;&lt;p&gt;2025年3月26号，Qwen团队发布了Qwen2.5 omni，Qwen2.5 omni是一个多模态模型，支持文本、音频、视频、图像等多个模态的输入，支持文本，音频的输出。
作者提出了TMRoPE来对齐不同的模态，然后还是用了Thinker-Talker的架构来同时生成文本和音频。
Thinker是一个大语言模型，Talker是一个dual-track自回归模型，Talker基于Thinker的hideen states来生成audio token，最后通过一个sliding-window DiT来解码audio token&lt;/p&gt;
&lt;p&gt;现有omni-model存在的问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;缺乏一个系统的，联合训练多个不同模态的方法&lt;/li&gt;
&lt;li&gt;需要处理不同模态输出时互相干扰的问题&lt;/li&gt;
&lt;li&gt;不能实时理解或者流式输出多模态信息&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Qwen2.5 omni的解决方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用TMRoPE来对齐不同的模态。作者将audio以及video frame按照时间顺序组织成一个交替的架构，然后使用TMRoPE来对齐&lt;/li&gt;
&lt;li&gt;使用Thinker-Talker的架构来同时生成文本和音频。Thinker负责文本输出，Talker负责音频的流式输出。&lt;/li&gt;
&lt;li&gt;在multimodal encoder中使用Block-wise streaming处理技巧来实现实时理解；在输出时，实现了一个dual-track自回归架构来生成audio token，以及一个DiT模型来解码audio token&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Qwen2.5 omni的贡献：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;提出了Qwen2.5-omni,可以实时理解多模态信息，并流式输出文本和音频&lt;/li&gt;
&lt;li&gt;提出了TMRoPE，一个可以对齐不同模态的RoPE算法&lt;/li&gt;
&lt;li&gt;提出了Thinker-Talker的架构，来完成实时理解和音频输出&lt;/li&gt;
&lt;li&gt;在多个benchmark上取得了SOTA&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="架构"&gt;&lt;a href="#%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;架构
&lt;/h1&gt;&lt;h2 id="总览"&gt;&lt;a href="#%e6%80%bb%e8%a7%88" class="header-anchor"&gt;&lt;/a&gt;总览
&lt;/h2&gt;&lt;p&gt;Qwen2.5-omni的架构如下图所示
&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-omni/architecture.png"
width="1346"
height="1110"
loading="lazy"
alt="architecture of Qwen2.5-omni"
class="gallery-image"
data-flex-grow="121"
data-flex-basis="291px"
&gt;&lt;/p&gt;
&lt;p&gt;其中Talker类似于人的嘴，负责基于脑中的信息来生成对话；Thinker类似于人的大脑，负责理解输入的信息，并生成对话的上下文。&lt;/p&gt;
&lt;h2 id="输入"&gt;&lt;a href="#%e8%be%93%e5%85%a5" class="header-anchor"&gt;&lt;/a&gt;输入
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;text: Qwen的tokenizer&lt;/li&gt;
&lt;li&gt;audio： Qwen2-Audio的tokenizer&lt;/li&gt;
&lt;li&gt;vision： Qwen2.5-VL的vision tokenizer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;视频以及TMRoPE。 对于视频来说，Qwen2.5-omni采取了和Qwen2.5-VL一样的MRoPE算法。只是这里的temporal ID对应40ms&lt;/p&gt;
&lt;p&gt;音频：对于音频来说，Qwen2.5-omni也是以40ms进行采样然后encoding。&lt;/p&gt;
&lt;p&gt;视频+音频：对于视频+音频来说，Qwen2.5-omni将视频和音频的token进行交替的排列，来保证时间上信息一致&lt;/p&gt;
&lt;h2 id="输出"&gt;&lt;a href="#%e8%be%93%e5%87%ba" class="header-anchor"&gt;&lt;/a&gt;输出
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Text：text由Thinker直接输出，这和LLM的输出方式是一样的。&lt;/li&gt;
&lt;li&gt;Speech：Qwen2.5-omni首先构建了&lt;code&gt;qwen-tts-tokenizer&lt;/code&gt;，一个speech codec，用于表示speech的关键信息。
然后基于这些关键信息，Talker通过自回归的方式生成audio tokens以及text tokens。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="流式输出"&gt;&lt;a href="#%e6%b5%81%e5%bc%8f%e8%be%93%e5%87%ba" class="header-anchor"&gt;&lt;/a&gt;流式输出
&lt;/h2&gt;&lt;p&gt;对于流式输出来说，现在的模型存在latency，具体影响因素如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;处理多模态输入的延迟&lt;/li&gt;
&lt;li&gt;TTFT （time to first token）&lt;/li&gt;
&lt;li&gt;将第一段speech token解码为audio的时间&lt;/li&gt;
&lt;li&gt;模型架构导致的latency，如模型参数等&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为了解决这个问题，Qwen2.5-omni采取了以下措施：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Support prefilling. 作者修改了audio以及vision encoder来在temporal dimension上支持block-wise attention.
具体来讲，audio encoder只关注2秒内的信息，而vision encoder和Qwen2.5-VL一样，使用了一个MLP patch merger来压缩视觉token&lt;/li&gt;
&lt;li&gt;Streaming Codec generation. 为了提高流式输出的效率，作者还是用了基于Flow-Matching的DiT，输出的code收线使用Flow-Matching转化为一个mel-spectrogram.
然后再通过一个BigVGAN来重建得到对应的waveform. 作者在这里修改了DiT的attention，将其receptive field 限制为4个block，包括lookback of 2 blocks以及lookahead of 1 block.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-omni/DiT-sliding-window.png"
width="410"
height="433"
loading="lazy"
alt="Sliding Window DiT"
class="gallery-image"
data-flex-grow="94"
data-flex-basis="227px"
&gt;&lt;/p&gt;
&lt;h1 id="pre-training"&gt;&lt;a href="#pre-training" class="header-anchor"&gt;&lt;/a&gt;Pre Training
&lt;/h1&gt;&lt;p&gt;模型参数初始化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLM： 从Qwen2.5进行初始化&lt;/li&gt;
&lt;li&gt;vision encoder：从Qwen2.5-VL的vision encoder进行初始化&lt;/li&gt;
&lt;li&gt;audio encoder：从Whisper-large-v3进行初始化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pretraining和Qwen2.5-VL的训练过程类似，分成了3个stage：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;冻结LLM的参数，仅训练vision encoder和audio encoder， 该阶段使用了audio-text以及image-text pairs来进行训练。 数据：image-text, video-text, video-audio, audio-text以及text corpus，
跟Qwen2-Audio类似，作者将hierarchical tags用自然语言prompt进行替换&lt;/li&gt;
&lt;li&gt;训练所有参数，使用更多的多模态数据进行训练。数据包括800B token的image和Video相关数据，300B token的audio数据，100B token的video-audio相关数据。&lt;/li&gt;
&lt;li&gt;将模型的上下文扩展到32K。前两个阶段的上下文长度为8192，本阶段使用了long video data等数据来将模型的上下文扩展到32K。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="post-training"&gt;&lt;a href="#post-training" class="header-anchor"&gt;&lt;/a&gt;Post Training
&lt;/h1&gt;&lt;h2 id="thinker"&gt;&lt;a href="#thinker" class="header-anchor"&gt;&lt;/a&gt;Thinker
&lt;/h2&gt;&lt;p&gt;数据格式为ChatML，数据类型包括pure text-based dialogue data, visual-modality conversation data, audio-modality conversation data and mix-modality conversation data.&lt;/p&gt;
&lt;h2 id="talker"&gt;&lt;a href="#talker" class="header-anchor"&gt;&lt;/a&gt;Talker
&lt;/h2&gt;&lt;p&gt;包括三个阶段&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ICL training: 训练Talker学习context continuation&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://maosong.website/p/notes-on-dpo/" target="_blank" rel="noopener"
&gt;DPO&lt;/a&gt; training: 提升speech generation的stability&lt;/li&gt;
&lt;li&gt;multi-speaker instruction fine-tuning: 提升模型的naturalness和controllability&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="evaluation"&gt;&lt;a href="#evaluation" class="header-anchor"&gt;&lt;/a&gt;Evaluation
&lt;/h1&gt;&lt;p&gt;Qwen2.5-omni在两类benchmark上进行来的评测，分别时多模态理解（X-&amp;gt;text）以及音频生成(X-&amp;gt; Speech)&lt;/p&gt;
&lt;p&gt;我们这里主要关注一下speech understanding以及speech generation的benchmark.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-omni/audio-to-text-performance.png"
width="1093"
height="1125"
loading="lazy"
alt="Audio-to-Text Performance"
class="gallery-image"
data-flex-grow="97"
data-flex-basis="233px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-omni/zero-shot-speech-generation.png"
width="904"
height="685"
loading="lazy"
alt="Speech Generation Performance"
class="gallery-image"
data-flex-grow="131"
data-flex-basis="316px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-omni/single-speaker-speech-generation.png"
width="864"
height="513"
loading="lazy"
alt="single speaker speech generation"
class="gallery-image"
data-flex-grow="168"
data-flex-basis="404px"
&gt;&lt;/p&gt;
&lt;h1 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h1&gt;&lt;p&gt;Qwen2.5-omni相当于是结合了Qwen2.5-VL以及Mini-omni，跟mini-omni2的输入输出是类似的。不同的点在于，Qwen2.5-omni使用了Thinker-Talker的架构，然后还使用了TMRoPE来对齐不同的模态。总的来说，感觉模型还是更偏重于audio的理解与生成。&lt;/p&gt;
&lt;h1 id="reference"&gt;&lt;a href="#reference" class="header-anchor"&gt;&lt;/a&gt;Reference
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="http://arxiv.org/abs/2503.20215" target="_blank" rel="noopener"
&gt;Qwen2.5-omni&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/abs/2408.16725" target="_blank" rel="noopener"
&gt;Mini-omni&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/pdf/2410.11190" target="_blank" rel="noopener"
&gt;Mini-omni2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Overview of Qwen-VL series</title><link>https://jiangyigithub.github.io/ai.github.io/p/overview-of-qwen-vl-series/</link><pubDate>Sun, 09 Mar 2025 15:11:29 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/overview-of-qwen-vl-series/</guid><description>&lt;h1 id="timeline"&gt;&lt;a href="#timeline" class="header-anchor"&gt;&lt;/a&gt;Timeline
&lt;/h1&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;模型系列&lt;/th&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023.08&lt;/td&gt;
&lt;td&gt;Qwen-VL&lt;/td&gt;
&lt;td&gt;Vision-centric understanding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Multi-lingual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Multi-image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Fine-grained visual understanding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024.09&lt;/td&gt;
&lt;td&gt;Qwen2-VL&lt;/td&gt;
&lt;td&gt;Image understanding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Video understanding (20min)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Agent capability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Multilingual support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025.02&lt;/td&gt;
&lt;td&gt;Qwen2.5-VL&lt;/td&gt;
&lt;td&gt;Document parsing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Object grounding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Long video understadning and grouding (1 hour)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Agent functionality&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="models"&gt;&lt;a href="#models" class="header-anchor"&gt;&lt;/a&gt;Models
&lt;/h1&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;size&lt;/th&gt;
&lt;th&gt;Vision&lt;/th&gt;
&lt;th&gt;Adapter&lt;/th&gt;
&lt;th&gt;LLM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;Qwen-VL&lt;/td&gt;
&lt;td&gt;9.6B&lt;/td&gt;
&lt;td&gt;ViT(1.9B)&lt;/td&gt;
&lt;td&gt;Cross-attention(0.08B)&lt;/td&gt;
&lt;td&gt;Qwen-LLM(7B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.0&lt;/td&gt;
&lt;td&gt;Qwen2-VL-2B&lt;/td&gt;
&lt;td&gt;2B&lt;/td&gt;
&lt;td&gt;ViT(675M)&lt;/td&gt;
&lt;td&gt;MLP(0.0341B)&lt;/td&gt;
&lt;td&gt;Qwen2-LLM(1.5B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Qwen2-VL-7B&lt;/td&gt;
&lt;td&gt;7B&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;MLP(0.0446B)&lt;/td&gt;
&lt;td&gt;Qwen2-LLM(7.6B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Qwen2-VL-72B&lt;/td&gt;
&lt;td&gt;72B&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;MLP(0.0682B)&lt;/td&gt;
&lt;td&gt;Qwen2-LLM(72B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.5&lt;/td&gt;
&lt;td&gt;Qwen2.5-VL-3B&lt;/td&gt;
&lt;td&gt;3B&lt;/td&gt;
&lt;td&gt;ViT(675M)&lt;/td&gt;
&lt;td&gt;MLP(0.1817B)&lt;/td&gt;
&lt;td&gt;Qwen2.5-LLM(3B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Qwen2.5-VL-7B&lt;/td&gt;
&lt;td&gt;7B&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;MLP(0.3179B)&lt;/td&gt;
&lt;td&gt;Qwen2.5-LLM(7.6B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Qwe2.5n-VL-72B&lt;/td&gt;
&lt;td&gt;72B&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;MLP(0.7267B)&lt;/td&gt;
&lt;td&gt;Qwen2.5-LLM(72B)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Remark&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qwen2-VL的MLP使用的是LayerNorm&lt;/li&gt;
&lt;li&gt;Qwen2.5-VL的MLP使用的是RMSNorm&lt;/li&gt;
&lt;li&gt;出了Qwen-VL之外，所有模型均有对应的Instruct版本，这里为了方便没有列出。Qwen-VL对应的是Qwen-VL-chat。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="data--training"&gt;&lt;a href="#data--training" class="header-anchor"&gt;&lt;/a&gt;Data &amp;amp; training
&lt;/h1&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model series&lt;/th&gt;
&lt;th&gt;stage&lt;/th&gt;
&lt;th&gt;data&lt;/th&gt;
&lt;th&gt;Vision&lt;/th&gt;
&lt;th&gt;Adapter&lt;/th&gt;
&lt;th&gt;LLM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen-VL&lt;/td&gt;
&lt;td&gt;pretraining&lt;/td&gt;
&lt;td&gt;1.4B&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Multi-task pretraining&lt;/td&gt;
&lt;td&gt;96.8M&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;SFT&lt;/td&gt;
&lt;td&gt;350K&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2-VL&lt;/td&gt;
&lt;td&gt;pretraining&lt;/td&gt;
&lt;td&gt;600b tokens&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Multi-task pretraining&lt;/td&gt;
&lt;td&gt;800b tokens&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;SFT&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-VL&lt;/td&gt;
&lt;td&gt;Visual Pre-Training&lt;/td&gt;
&lt;td&gt;1.5T token&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Multimodal Pre-Training&lt;/td&gt;
&lt;td&gt;2T token&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Long-Context Pre-Training&lt;/td&gt;
&lt;td&gt;0.6T token&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;td&gt;✅？&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;SFT&lt;/td&gt;
&lt;td&gt;2M samples&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a class="link" href="https://maosong.website/p/notes-on-dpo/" target="_blank" rel="noopener"
&gt;DPO&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Remark&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Qwen2-VL按照技术报告的说法是follow了Qwen-VL的训练方式，因此这里也使用了同样的表示&lt;/li&gt;
&lt;li&gt;带问号的地方代表不确定，为个人猜测。请谨慎参考。&lt;/li&gt;
&lt;li&gt;难以确定的原因是Qwen-VL系列将projection layer和ViT作为一个模块，因此比较难区分是否训练了projection layer&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/overview-of-qwen-vl-series/qwen-vl-training.png"
width="1908"
height="868"
loading="lazy"
alt="qwen-vl-training"
class="gallery-image"
data-flex-grow="219"
data-flex-basis="527px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/overview-of-qwen-vl-series/qwen2-5-training.png"
width="1354"
height="468"
loading="lazy"
alt="qwen2-5-training"
class="gallery-image"
data-flex-grow="289"
data-flex-basis="694px"
&gt;&lt;/p&gt;
&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/pdf/2308.12966" target="_blank" rel="noopener"
&gt;Qwen-VL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/pdf/2409.12191" target="_blank" rel="noopener"
&gt;Qwen2-VL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/pdf/2502.13923" target="_blank" rel="noopener"
&gt;Qwen2.5-VL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on QwQ-32B</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwq-32b/</link><pubDate>Sat, 08 Mar 2025 09:46:16 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwq-32b/</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;通义团队在3月6号发布了QwQ-32B，一个基于RL的，32B参数的reasoning model，QwQ-32B的表现可以与DeepSeek-R1相比&lt;/p&gt;
&lt;h2 id="模型架构"&gt;&lt;a href="#%e6%a8%a1%e5%9e%8b%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;模型架构
&lt;/h2&gt;&lt;p&gt;QwQ-32B基于Qwen2.5-32B开发。主要通过基于outcome-based rewards的RL进行训练。训练过程包括两个stage&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stage 1：本阶段在math和coding domain上进行RL的训练，作者使用了一个verifier来保证最终数学问题结果的正确性，使用了一个code execution server来保证最终生成代码的正确性。&lt;/li&gt;
&lt;li&gt;Stage 2：本阶段在通用领域上进行RL的训练。模型基于general reward model和一些rule-based verifier进行训练。应该是类似 &lt;a class="link" href="https://maosong.website/p/notes-on-deepseek-r1/" target="_blank" rel="noopener"
&gt;DeepSeek-R1&lt;/a&gt; 的规则。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="实验结果"&gt;&lt;a href="#%e5%ae%9e%e9%aa%8c%e7%bb%93%e6%9e%9c" class="header-anchor"&gt;&lt;/a&gt;实验结果
&lt;/h2&gt;&lt;p&gt;实验结果如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwq-32b/qwq-32b-final.jpg"
width="3035"
height="1713"
loading="lazy"
alt="QwQ_evaluation"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="425px"
&gt;&lt;/p&gt;
&lt;h2 id="reference"&gt;&lt;a href="#reference" class="header-anchor"&gt;&lt;/a&gt;Reference
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://qwenlm.github.io/blog/qwq-32b/" target="_blank" rel="noopener"
&gt;blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://chat.qwen.ai/?models=Qwen2.5-Plus" target="_blank" rel="noopener"
&gt;demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Notes on Qwen2.5 VL</title><link>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/</link><pubDate>Tue, 04 Mar 2025 10:46:42 +0800</pubDate><guid>https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/</guid><description>&lt;h1 id="introduction"&gt;&lt;a href="#introduction" class="header-anchor"&gt;&lt;/a&gt;Introduction
&lt;/h1&gt;&lt;p&gt;2025年2月20号Qwen团队发布了Qwen2.5 VL技术报告，Qwen2.5 VL包括3B，7B， 72B三个size。Qwen2.5-VL主要在架构，数据上进行了改进。通过评测，Qwen2.5-VL在多个benchmark上取得了SOTA。&lt;/p&gt;
&lt;p&gt;Qwen2.5 VL认为已有模型的缺点为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;计算复杂度高&lt;/li&gt;
&lt;li&gt;上下文理解能力有限&lt;/li&gt;
&lt;li&gt;细粒度visual perception能力不足&lt;/li&gt;
&lt;li&gt;在不同上下文长度下表现不一致&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Qwen2.5 VL的贡献为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用了一个从零开始训练的ViT作为vision encoder，并且在ViT中使用了window attention，来提高计算效率&lt;/li&gt;
&lt;li&gt;使用了dynamic FPS sampling，用于处理不同采样率的视频输入&lt;/li&gt;
&lt;li&gt;将MRoPE扩展到了temporal domain上，进一步提高了模型在与时间相关任务上的表现&lt;/li&gt;
&lt;li&gt;使用了更高质量的数据集，其中预训练阶段使用了4.1T的token&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Qwen2.5 VL的主要亮点为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优秀的document parsing能力&lt;/li&gt;
&lt;li&gt;精确的object grounding能力&lt;/li&gt;
&lt;li&gt;针对长视频的理解和细粒度grounding能力&lt;/li&gt;
&lt;li&gt;针对UI的agent functionality&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="模型架构"&gt;&lt;a href="#%e6%a8%a1%e5%9e%8b%e6%9e%b6%e6%9e%84" class="header-anchor"&gt;&lt;/a&gt;模型架构
&lt;/h1&gt;&lt;h2 id="总览"&gt;&lt;a href="#%e6%80%bb%e8%a7%88" class="header-anchor"&gt;&lt;/a&gt;总览
&lt;/h2&gt;&lt;p&gt;Qwen2.5 VL和Qwen2 VL的架构基本一致，包括Vision Encoder，Language Encoder，以及projector layer三个部分，其架构图如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/architecture.png"
width="1345"
height="889"
loading="lazy"
alt="Qwen2.5 VL架构图"
class="gallery-image"
data-flex-grow="151"
data-flex-basis="363px"
&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLM： 使用Qwen2.5 LLM作为LLM，并且将1D-RoPE升级为了MRoPE&lt;/li&gt;
&lt;li&gt;Vision Encoder： 使用一个从零开始训练的ViT架构，patch_size为14，position embedding为2D-RoPE， attention为window attention和self-attention的混合，其中，只有四层使用的是self-attention.对于输入的图片，ViT会将图片resize到28的整数倍。&lt;/li&gt;
&lt;li&gt;Projector Layer： 使用的是一个两层的MLP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;模型的参数配置如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/model_config.png"
width="1180"
height="861"
loading="lazy"
alt="Qwen2.5 VL模型参数配置"
class="gallery-image"
data-flex-grow="137"
data-flex-basis="328px"
&gt;&lt;/p&gt;
&lt;h2 id="vision-encoder"&gt;&lt;a href="#vision-encoder" class="header-anchor"&gt;&lt;/a&gt;Vision Encoder
&lt;/h2&gt;&lt;p&gt;Vision encoder的主要改进点为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用了window attention来提升计算效率，window attention的size为 $112\times 112$， 对应为 $8\times 8$ 个patch. 这样做的好处是可以不用对图片做scaling&lt;/li&gt;
&lt;li&gt;使用了2D RoPE来捕捉空间信息，使用3D RoPE来捕捉视频输入的时间信息&lt;/li&gt;
&lt;li&gt;与LLM的结构进行对齐，包括使用RMSNorm替换LayerNorm，使用SwiGLU替换ReLU&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="输入处理"&gt;&lt;a href="#%e8%be%93%e5%85%a5%e5%a4%84%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;输入处理
&lt;/h2&gt;&lt;p&gt;对于图片输入，Qwen2.5 VL使用原始图片的空间信息来构建坐标，而不是将坐标normalize到[0, 1000]之间，这样让模型可以处理不同精度的图片输入。&lt;/p&gt;
&lt;p&gt;对于视频输入，因为使用了3D RoPE，因此Qwen2.5 VL可以处理不同帧率的视频输入，这样就避免了不同帧率视频对模型视频理解带来的影响。这一点和Apollo里的想法是一样的。具体来说，Qwen2.5 VL首先将连续的两帧group到了一起，然后使用了temporal ID来将position和视频所对应的时间进行对齐。这里可以看Qwen2.5 VL的代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Temporal (Time): 3 patches, representing different segments of the video in time.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Height: 2 patches, dividing each frame vertically.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Width: 2 patches, dividing each frame horizontally.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;We also have some important parameters:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fps (Frames Per Second): The video&amp;#39;s frame rate, set to 1. This means one frame is processed each second.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tokens_per_second: This is a crucial parameter. It dictates how many &amp;#34;time-steps&amp;#34; or &amp;#34;temporal tokens&amp;#34; are conceptually packed into a one-second interval of the video. In this case, we have 25 tokens per second. So each second of the video will be represented with 25 separate time points. It essentially defines the temporal granularity.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;temporal_patch_size: The number of frames that compose one temporal patch. Here, it&amp;#39;s 2 frames.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;interval: The step size for the temporal position IDs, calculated as tokens_per_second * temporal_patch_size / fps. In this case, 25 * 2 / 1 = 50. This means that each temporal patch will be have a difference of 50 in the temporal position IDs.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;input_ids: [V V V V V V V V V V V V T T T T T], here V is for vision.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vision temporal position_ids: [0, 0, 0, 0, 50, 50, 50, 50, 100, 100, 100, 100]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vision height position_ids: [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vision width position_ids: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;text temporal position_ids: [101, 102, 103, 104, 105]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;text height position_ids: [101, 102, 103, 104, 105]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;text width position_ids: [101, 102, 103, 104, 105]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Here we calculate the text start position_ids as the max vision position_ids plus 1.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里&lt;code&gt;fps&lt;/code&gt;为1，表示每一帧对应一秒，&lt;code&gt;tokens_per_second&lt;/code&gt;为25，表示每秒包含25个token，&lt;code&gt;temporal_patch_size&lt;/code&gt;为2，表示每个temporal patch包含2个frame。因此一个patch里面，就包含了2frame, 对应50tokens. 然后前面提到连续两帧会被group到一起，因此每个temporal patch对应4个spatial patches. 其position_ids为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h1 id="训练"&gt;&lt;a href="#%e8%ae%ad%e7%bb%83" class="header-anchor"&gt;&lt;/a&gt;训练
&lt;/h1&gt;&lt;h2 id="预训练"&gt;&lt;a href="#%e9%a2%84%e8%ae%ad%e7%bb%83" class="header-anchor"&gt;&lt;/a&gt;预训练
&lt;/h2&gt;&lt;h3 id="数据"&gt;&lt;a href="#%e6%95%b0%e6%8d%ae" class="header-anchor"&gt;&lt;/a&gt;数据
&lt;/h3&gt;&lt;p&gt;预训练阶段使用了4.1T的token，包括image captions, interleaved image-text data, optical character recognition (OCR) data, visual knowledge (e.g., celebrity, landmark, flora, and fauna identification), multi-modal academic questions, localization data, document parsing data, video descriptions, video localization, and agent-based interaction data. 作者详细介绍了以下几种数据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interleaved image-text data： 主要1. 提高模型的上下文学习能力；2. 保持模型的text-only能力；3.包含一些通用信息。数据清洗包括：1. 基于text-only quality过滤； 2. 基于image-text相关性过滤；3. 基于image-text互补程度过滤；4.基于information density balance过滤.&lt;/li&gt;
&lt;li&gt;Grounding data：作者使用了Grounding DINO, SAM等模型来生成一些grounding data.为了提升模型在open-vocabulary detection上的能力，作者将训练数据集扩展到了1万个object category上，作者还使用了一些point-based object grounding data来提升模型的能力&lt;/li&gt;
&lt;li&gt;Document Parsing data：作者基于text,image, music sheets和chemical formulas合成了一些HTML格式的数据，然后根据tag和bounding box来提升模型document parsing的能力&lt;/li&gt;
&lt;li&gt;OCR data：作者使用了开源，合成和in-house的数据集，数据集主要提到multi-lingual以及1M的chart-type数据&lt;/li&gt;
&lt;li&gt;Video data：作者通过pipeline构建了long video caption来提升模型长视频的理解能力&lt;/li&gt;
&lt;li&gt;Agent data：作者收集了一些mobile device和网页的screenshots,然后基于agent框架来合成控制轨迹&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="训练-1"&gt;&lt;a href="#%e8%ae%ad%e7%bb%83-1" class="header-anchor"&gt;&lt;/a&gt;训练
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/pretraining.png"
width="1217"
height="428"
loading="lazy"
alt="Qwen2.5 VL预训练阶段"
class="gallery-image"
data-flex-grow="284"
data-flex-basis="682px"
&gt;&lt;/p&gt;
&lt;p&gt;如上图所示，Qwen2.5 VL的预训练阶段包括了三个阶段：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Visual Pretraining:这一阶段使用了image-caption, knowledge, OCR数据集，旨在提升ViT提取视觉特征的能力&lt;/li&gt;
&lt;li&gt;multimodal pretraining:这一阶段在第一阶段的基础上增加了pure-text, interleaved data, VQA, Video grounding, agent data, 旨在提升模型处理复杂视觉信息的能力&lt;/li&gt;
&lt;li&gt;long-context pretraining: 这一阶段，在第二阶段的基础上，增加了long video, long agent, long document data，旨在提升模型处理长上下文的能力&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="后训练"&gt;&lt;a href="#%e5%90%8e%e8%ae%ad%e7%bb%83" class="header-anchor"&gt;&lt;/a&gt;后训练
&lt;/h2&gt;&lt;h3 id="数据-1"&gt;&lt;a href="#%e6%95%b0%e6%8d%ae-1" class="header-anchor"&gt;&lt;/a&gt;数据
&lt;/h3&gt;&lt;p&gt;SFT阶段使用大概2M的样本进行训练，其中纯文本和多模态数据占比为1:1，语言主要是中文和英文。&lt;/p&gt;
&lt;p&gt;为了保证数据质量，作者提供了一个数据清洗的pipeline，包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;domain-specific categorization: 作者基于Qwen2-VL-72B构建了Qwen2-VL-Instag，用于将QA pair分为8个大类别，30个小类别&lt;/li&gt;
&lt;li&gt;Domain-tailed filtering:作者使用了rule-based和model-based方法来提升数据的质量
&lt;ul&gt;
&lt;li&gt;rule-based filtering: 重复性检测，格式检测等&lt;/li&gt;
&lt;li&gt;model-based filtering: 使用基于Qwen2.5-VL训练的reward model来从多个维度评估QA pair的质量&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为了进一步提升模型的推理能力，作者还是用了rejection sampling来refine 数据集。&lt;/p&gt;
&lt;h3 id="训练-2"&gt;&lt;a href="#%e8%ae%ad%e7%bb%83-2" class="header-anchor"&gt;&lt;/a&gt;训练
&lt;/h3&gt;&lt;p&gt;post-training阶段分为SFT和&lt;a class="link" href="https://maosong.website/p/notes-on-dpo/" target="_blank" rel="noopener"
&gt;DPO&lt;/a&gt;两个小阶段，这个阶段都会冻结VIT. SFT阶段使用大多数的训练数据，而DPO阶段专注于image-text data和pure text data，以更好地进行对齐。具体做法就是基于Grounding truth，使用checkpoint来评估数据的质量，然后只保留答案正确的数据来训练。&lt;/p&gt;
&lt;h1 id="评测"&gt;&lt;a href="#%e8%af%84%e6%b5%8b" class="header-anchor"&gt;&lt;/a&gt;评测
&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;通用VQA
&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/general_vqa.png"
width="1356"
height="656"
loading="lazy"
alt="通用VQA"
class="gallery-image"
data-flex-grow="206"
data-flex-basis="496px"
&gt;&lt;/li&gt;
&lt;li&gt;文档理解和OCR
&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/document_understanding.png"
width="1358"
height="655"
loading="lazy"
alt="文档理解和OCR"
class="gallery-image"
data-flex-grow="207"
data-flex-basis="497px"
&gt;&lt;/li&gt;
&lt;li&gt;空间理解
&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/grounding.png"
width="1324"
height="714"
loading="lazy"
alt="空间理解"
class="gallery-image"
data-flex-grow="185"
data-flex-basis="445px"
&gt;&lt;/li&gt;
&lt;li&gt;视频理解和Grounding
&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/video.png"
width="1320"
height="672"
loading="lazy"
alt="视频理解和Grounding"
class="gallery-image"
data-flex-grow="196"
data-flex-basis="471px"
&gt;&lt;/li&gt;
&lt;li&gt;Agent
&lt;img src="https://jiangyigithub.github.io/ai.github.io/p/notes-on-qwen2.5-vl/agent.png"
width="1374"
height="337"
loading="lazy"
alt="Agent"
class="gallery-image"
data-flex-grow="407"
data-flex-basis="978px"
&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="reference"&gt;&lt;a href="#reference" class="header-anchor"&gt;&lt;/a&gt;Reference
&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/QwenLM/Qwen2.5-VL" target="_blank" rel="noopener"
&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/abs/2502.13923" target="_blank" rel="noopener"
&gt;Paper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>