<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Huanyu Yang</title><link>https://qingzhou-yanghy.github.io/</link><description>Recent content on Huanyu Yang</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Huanyu Yang</copyright><lastBuildDate>Wed, 22 Jul 2026 21:00:00 +0800</lastBuildDate><atom:link href="https://qingzhou-yanghy.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>Lora</title><link>https://qingzhou-yanghy.github.io/p/lora/</link><pubDate>Wed, 22 Jul 2026 21:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/lora/</guid><description>&lt;h3 id="技术产生原因"&gt;技术产生原因
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://arxiv.org/abs/2106.09685" target="_blank" rel="noopener"
&gt;LoRA: Low-Rank Adaptation of Large Language Models&lt;/a&gt;&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;h3 id="原理"&gt;原理
&lt;/h3&gt;&lt;h4 id="数学表达"&gt;数学表达
&lt;/h4&gt;&lt;p&gt;对于原始权重矩阵 W₀（维度为 d×k），全参数微调是直接更新为 W₀+ΔW，ΔW与W₀维度相同&lt;/p&gt;
&lt;p&gt;LoRA的做法是冻结W₀不变，将ΔW分解为两个低秩矩阵的乘积：&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;ΔW = B × A
&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;/p&gt;
&lt;ul&gt;
&lt;li&gt;A 的维度为 r×k&lt;/li&gt;
&lt;li&gt;B 的维度为 d×r&lt;/li&gt;
&lt;li&gt;r 是秩（rank），是一个远小于d和k的超参数，常见取值为4、8、16、32、64
前向传播时的计算变为：&lt;/li&gt;
&lt;/ul&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;h = W₀x + ΔWx = W₀x + BAx
&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;训练时只更新A和B这两个小矩阵，W₀始终冻结不参与梯度更新&lt;/p&gt;
&lt;p&gt;e.g.
假设原矩阵维度为 d=k=4096（常见于大模型的注意力层），全参数微调需要更新 4096×4096 ≈ 1677万参数&lt;/p&gt;
&lt;p&gt;若取 r=8，LoRA只需更新：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A矩阵：8×4096 = 32768&lt;/li&gt;
&lt;li&gt;B矩阵：4096×8 = 32768&lt;/li&gt;
&lt;li&gt;合计：65536参数
参数量减少约256倍。这直接导致：&lt;/li&gt;
&lt;li&gt;梯度计算量大幅减少&lt;/li&gt;
&lt;li&gt;优化器状态占用大幅减少&lt;/li&gt;
&lt;li&gt;最终保存的权重文件只需保存A、B两个小矩阵，通常几MB到几十MB&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="初始化方式"&gt;初始化方式
&lt;/h4&gt;&lt;p&gt;训练开始时，A矩阵通常用高斯随机初始化，B矩阵初始化为全零矩阵。这样保证训练刚开始时 BA=0，即ΔW=0，模型初始状态等价于原始预训练模型，不会因为随机初始化破坏原有能力，训练过程平稳&lt;/p&gt;
&lt;h4 id="推理时的处理"&gt;推理时的处理
&lt;/h4&gt;&lt;p&gt;训练完成后，可以将 B×A 直接加到W₀上得到新的权重矩阵 W₀+BA，这一步是简单的矩阵加法运算。这意味着推理时不会引入额外的计算延迟，因为最终使用的还是一个完整的d×k权重矩阵，结构和原模型完全一致&lt;/p&gt;
&lt;p&gt;如果不合并，也可以保持A、B独立存在，前向传播时并行计算W₀x和BAx后相加，这样便于同一个基座模型加载不同任务的多组A、B，实现快速切换&lt;/p&gt;
&lt;h4 id="作用位置"&gt;作用位置
&lt;/h4&gt;&lt;p&gt;LoRA通常不作用于模型的全部权重矩阵，而是选择性地作用于特定层，最常见的是Transformer结构中注意力模块的权重矩阵（Query、Key、Value、Output的投影矩阵），也可以扩展到前馈网络层。作用的层数量和位置是可配置的超参数，会影响效果和训练开销的平衡&lt;/p&gt;
&lt;h3 id="关键超参数"&gt;关键超参数
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;strong&gt;r（秩）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;决定低秩矩阵的维度，r越大表达能力越强，但参数量和计算量也越大，同时也越接近全参数微调&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;alpha（缩放系数）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;用于控制ΔW对原始输出的影响程度，实际计算中会有一个缩放因子 alpha/r 乘在BAx上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;target_modules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;指定对哪些权重矩阵施加LoRA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dropout&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;在LoRA模块中加入的dropout比例，用于防止过拟合&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="常用框架与工具"&gt;常用框架与工具
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;PEFT（Parameter-Efficient Fine-Tuning）&lt;/strong&gt;：由HuggingFace开发的库，是目前最主流的LoRA实现工具，支持与Transformers库无缝结合，同时支持LoRA的多个变体（如AdaLoRA、QLoRA等）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;QLoRA&lt;/strong&gt;：在LoRA基础上结合量化技术，将基座模型量化为4-bit精度存储，同时保持LoRA部分为可训练的浮点参数，进一步降低显存占用，使得在消费级显卡上微调较大模型成为可能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLaMA-Factory&lt;/strong&gt;：国内团队开发的开源训练框架，封装了包括LoRA在内的多种微调方法，提供命令行和Web界面，适合快速上手。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="常见变体"&gt;常见变体
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;QLoRA&lt;/strong&gt;：结合4-bit量化，降低显存占用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AdaLoRA&lt;/strong&gt;：训练过程中动态调整不同层的秩分配，而非固定统一的r值&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DoRA（Weight-Decomposed Low-Rank Adaptation）&lt;/strong&gt;：将权重分解为幅度和方向两部分分别处理，是2024年提出的改进方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="qlora"&gt;QLoRA
&lt;/h3&gt;&lt;p&gt;解决显存占用问题
&lt;a class="link" href="https://arxiv.org/abs/2305.14314" target="_blank" rel="noopener"
&gt;QLoRA&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="核心思路"&gt;核心思路
&lt;/h4&gt;&lt;p&gt;把基座模型压缩到4-bit存储，同时保持LoRA部分的训练精度不变&lt;/p&gt;
&lt;h4 id="原理-1"&gt;原理
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;NF4量化：一种专门针对正态分布权重设计的4-bit数据类型，量化区间根据正态分布的分位数划分，而不是简单等间距划分，因此在权重数值集中的区域（0附近）保留更多精度，整体量化误差更小&lt;/li&gt;
&lt;li&gt;双重量化：量化过程中每个数据块需要存储一个32位的缩放常数，双重量化把这些缩放常数本身也压缩为8位，进一步减少显存占用&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="计算过程"&gt;计算过程
&lt;/h4&gt;&lt;p&gt;基座权重以4-bit存储，但实际做矩阵乘法时会临时反量化为bf16精度参与计算，计算完立即释放，不常驻高精度副本。真正被训练更新的仍然只有LoRA新增的A、B矩阵，且这两个矩阵全程保持bf16精度，不参与量化&lt;/p&gt;
&lt;h3 id="adalora"&gt;AdaLoRA
&lt;/h3&gt;&lt;p&gt;论文里明确指出它要解决的问题是：&lt;strong&gt;原始LoRA给所有层统一分配相同的秩r，忽略了不同权重矩阵对下游任务的重要性差异&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://arxiv.org/abs/2303.10512" target="_blank" rel="noopener"
&gt;AdaLoRA&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="奇异值分解svd"&gt;奇异值分解（SVD）
&lt;/h4&gt;&lt;p&gt;奇异值分解（Singular Value Decomposition，简称SVD）是线性代数中的一个基本定理：任意一个矩阵，都可以分解成三个矩阵的乘积&lt;/p&gt;
&lt;h4 id="重要性打分"&gt;重要性打分
&lt;/h4&gt;&lt;p&gt;敏感度(wij) = |wij × ∇wij L|&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果只用其中某一步的值来判断这个参数重不重要，结果会很不稳定&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;滑动平均（Exponential Moving Average, EMA）：&lt;/p&gt;
&lt;p&gt;I(t)(wij) = β1 × I(t-1)(wij) + (1-β1) × I(t)(wij)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这个公式的意思是：新的平滑值 = 85%的历史平滑值 + 15%的这一步新值&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;ldquo;不确定性&amp;rdquo;，衡量的是&amp;quot;这一步的新值，跟历史平滑值差了多少&amp;quot;：
U(t)(wij) = β2 × U(t-1)(wij) + (1-β2) × |I(t)(wij) - I(t)(wij)|
这个不确定性指标的作用：如果一个参数每一步的值都跟历史平滑值差得很远（U值一直很大），说明这个参数的重要性评估很不稳定，不能完全信任；如果每一步的值都很接近历史平滑值（U值很小），说明这个参数的重要性评估很稳定可靠&lt;/p&gt;
&lt;p&gt;最终打分：两者相乘
s(t)(wij) = I(t)(wij) × U(t)(wij)
意思是：一个参数只有当它本身敏感度高（I大），同时最近又出现了明显的变化（U大，说明它的重要性正在剧烈调整、可能正处在关键的学习阶段），才会被认为是最值得关注的参数&lt;/p&gt;
&lt;p&gt;从&amp;quot;单个参数打分&amp;quot;组合成&amp;quot;一个方向（triplet）的打分&amp;quot;
Si = s(λi) + (1/d1)Σ(k=1到d1) s(Pki) + (1/d2)Σ(k=1到d2) s(Qik)
这个公式在算的是：第i个方向（也就是Λ对角线上第i个位置）的总重要性得分&lt;/p&gt;
&lt;p&gt;把全模型所有方向的Si放在一起排序,排名靠后的方向对应的λi直接置零，实现动态裁剪&lt;/p&gt;
&lt;h4 id="步骤"&gt;步骤
&lt;/h4&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;1&lt;/td&gt;
&lt;td&gt;给每个目标权重矩阵（如每层的Wq、Wk、Wv、Wo）各自初始化一组P、Λ、Q，Λ的初始秩通常偏大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Λ里每个对角线位置代表一个独立的&amp;quot;方向&amp;quot;，训练时每个方向单独计算敏感度分数并做滑动平均&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;把全模型所有矩阵、所有方向的分数汇总到一起统一排序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;按照预设的全局总预算，分数最低的方向逐步置零，不区分它属于哪一层&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;训练结束后，不同层、不同矩阵保留的实际有效方向数量各不相同，重要的层保留得多，不重要的层保留得少&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/AdaLoRA.png"
loading="lazy"
alt="AdaLoRA"
&gt;&lt;/p&gt;
&lt;p&gt;具体改进包含两部分：&lt;/p&gt;
&lt;h4 id="改进点1把δw参数化为svd形式"&gt;改进点1：把ΔW参数化为SVD形式
&lt;/h4&gt;&lt;p&gt;原始LoRA：ΔW = BA（B、A没有正交约束）&lt;/p&gt;
&lt;p&gt;AdaLoRA：ΔW = PΛQ（P、Q近似正交，Λ的对角线是&amp;quot;奇异值&amp;quot;）&lt;/p&gt;
&lt;p&gt;相对于&amp;quot;直接对BA做结构化剪枝&amp;quot;（整组丢弃某个doublet）的优势：BA的B和A不是正交的，各个doublet之间可能存在依赖关系，如果直接丢弃一个doublet会导致矩阵变化剧烈，训练不稳定；而PΛQ形式下，只需要把不重要的奇异值置零，对应的奇异向量（P、Q的那一列/行）仍然保留着，未来如果发现这个方向其实重要，还有&amp;quot;复活&amp;quot;的可能，训练也更平稳&lt;/p&gt;
&lt;h4 id="改进点2重要性打分机制"&gt;改进点2：重要性打分机制
&lt;/h4&gt;&lt;p&gt;不是简单用奇异值大小 |λᵢ| 判断重要性，而是把奇异值本身的大小，加上它对应的P列、Q行里每个参数的敏感度（参数值×梯度，并做了平滑+不确定性调整），三者加权组合成综合得分。消融实验证明这个组合打分比单纯用|λᵢ|或单纯用敏感度效果更好&lt;/p&gt;
&lt;h4 id="改进点3全局预算调度器global-budget-scheduler"&gt;改进点3：全局预算调度器（Global Budget Scheduler）
&lt;/h4&gt;&lt;p&gt;不是一开始就按目标预算裁剪，而是先给一个比目标预算略高的初始预算（如1.5倍），warm-up之后按三次方曲线逐渐降到目标值。让模型先探索完整参数空间，再逐步聚焦到重要权重，提高训练稳定性&lt;/p&gt;
&lt;h3 id="igu-lora--相对于adalora的改进"&gt;IGU-LoRA —— 相对于AdaLoRA的改进
&lt;/h3&gt;&lt;p&gt;用积分梯度（Integrated Gradients, IG）替代瞬时梯度敏感度&lt;/p&gt;
&lt;p&gt;AdaLoRA的敏感度公式：|wᵢⱼ × ∇wᵢⱼL|，只看当前这一步的梯度&lt;/p&gt;
&lt;p&gt;敏感度(wij) = |wij × ∫₀¹ ∂L(α·ΔW)/∂wij dα|&lt;/p&gt;
&lt;h4 id="流程"&gt;流程
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;正常训练A、B（跟普通LoRA一样）&lt;/li&gt;
&lt;li&gt;每个mini-batch训练完，顺便对AB做一次SVD，得到PΛQ&lt;/li&gt;
&lt;li&gt;用当前这个mini-batch随机采样到的α点，算一次积分梯度的抽样估计（针对P、Q里每个参数）&lt;/li&gt;
&lt;li&gt;一个epoch跑完后，把这个epoch内所有mini-batch的抽样估计取平均，得到这一epoch的聚合敏感度&lt;/li&gt;
&lt;li&gt;用滑动平均+不确定性量化，算出最终的SNR打分&lt;/li&gt;
&lt;li&gt;结合每个奇异值本身的大小，算出每个方向（每个triplet）的综合重要性得分&lt;/li&gt;
&lt;li&gt;全局排序，挑出分数最高的前b个方向保留，其余的对应奇异值置零&lt;/li&gt;
&lt;li&gt;把保留下来的部分重新组装回A、B两个矩阵，继续下一轮训练&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="revisiting-weight-regularization"&gt;Revisiting Weight Regularization
&lt;/h3&gt;&lt;p&gt;持续学习（Continual Learning）场景下怎么避免遗忘之前学过的任务的问题&lt;/p&gt;
&lt;p&gt;维护一个Fisher信息矩阵，记录&amp;quot;之前的任务认为哪些位置的权重变化很重要&amp;quot;，在训练新任务时，往损失函数里加一个正则化项，惩罚在这些重要位置上的大幅改动&lt;/p&gt;</description></item><item><title>Be a good engineer</title><link>https://qingzhou-yanghy.github.io/p/be-a-good-engineer/</link><pubDate>Fri, 30 Jan 2026 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/p/be-a-good-engineer/</guid><description>&lt;h2 id="成为一个好的工程师"&gt;成为一个好的工程师
&lt;/h2&gt;&lt;h3 id="基本功笔记"&gt;基本功笔记
&lt;/h3&gt;&lt;p&gt;主流并行框架（DDP/DeepSpeed/Megatron）均基于 SPMD（Single Program Multiple Data）架构：所有进程执行相同代码逻辑，通过环境变量差异自主确定行为模式，无需中心调度节点。灵活性不如single-controller模式。&lt;/p&gt;
&lt;p&gt;计算GPU称为Worker，梯度聚合GPU称为Server&lt;/p&gt;
&lt;h4 id="allreduce"&gt;AllReduce
&lt;/h4&gt;&lt;p&gt;目前最通用的AllReduce方法：Ring-AllReduce。它由百度最先提出，非常有效地解决了数据并行中通讯负载不均的问题，使得DDP得以实现&lt;/p&gt;
&lt;p&gt;Ring-ALLReduce(&amp;ldquo;先富带动后富&amp;quot;思想)则分两大步骤实现该目标：Reduce-Scatter(圆排列转一圈后所有参数都有一个位置已经都更新完成)和All-Gather(把每一部分更新完的参数更新到其他的)&lt;/p&gt;
&lt;p&gt;Ring-AllReduce的方法，因为在之后的ZeRO，Megatron-LM中，它将频繁地出现，是分布式训练系统中重要的算子&lt;/p&gt;
&lt;h4 id="zerodp"&gt;ZeRO(DP)
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/617133971" target="_blank" rel="noopener"
&gt;图解大模型训练之：数据并行上篇(DP, DDP与ZeRO)&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/618865052" target="_blank" rel="noopener"
&gt;图解大模型训练之：数据并行下篇(DeepSpeed ZeRO，零冗余优化)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ZeRO是模型并行的形式，数据并行的实质&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模型并行，是指在forward和backward的过程中，我只需要用自己维护的那块W来计算就行。即同样的输入X，每块GPU上各算模型的一部分，最后通过某些方式聚合结果。
但对ZeRO来说，它做forward和backward的时候，是需要把各GPU上维护的W聚合起来的，即本质上还是用完整的W进行计算。它是不同的输入X，完整的参数W，最终再做聚合。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对activation的存储是灵活的。不像optimizer states，gradients和parameters对模型更新是必须的，activation只是起到加速梯度计算的作用。因此，在哪几层保存activation，保存哪些activation都是可以灵活设置的。&lt;/p&gt;
&lt;p&gt;ZeRO-Offload&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;forward和backward计算量高，因此和它们相关的部分，例如参数W（fp16），activation，就全放入GPU。&lt;/li&gt;
&lt;li&gt;update的部分计算量低，因此和它相关的部分，全部放入CPU中。例如W(fp32)，optimizer states（fp32）和gradients(fp16)等。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="tp"&gt;TP
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/622212228" target="_blank" rel="noopener"
&gt;图解大模型训练之：张量模型并行(TP)，Megatron-LM&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在之前的内容中，已经介绍过流水线并行(PP)、数据并行(DP，DDP和ZeRO)。下面将要介绍最重要，也是目前基于Transformer做大模型预训练最基本的并行范式：来自NVIDIA的张量模型并行(TP)。它的基本思想就是把模型的参数纵向切开，放到不同的GPU上进行独立计算，然后再做聚合。&lt;/p&gt;
&lt;h4 id="关于随机种子设定的一般结论"&gt;关于随机种子设定的一般结论
&lt;/h4&gt;&lt;p&gt;一般在TP/PP组内，设定不同的随机种子。而在DP组内，设定相同的随机种子。这只是一个一般结论，我们可以根据实际情况去调整&lt;/p&gt;
&lt;h4 id="python杂谈"&gt;python杂谈
&lt;/h4&gt;&lt;p&gt;语言本身没有任何限制。在Python中，可以通过给对象属性名添加前缀下划线的方式来说明属性的访问可见性，例如，可以用__name表示一个私有属性，_name表示一个受保护属性。&lt;/p&gt;
&lt;p&gt;下划线(_)开头表示Python中的私有变量, 但私有变量在Python中不存在, 只需遵循一些规范即可&lt;/p&gt;
&lt;p&gt;除了对象方法之外，类中还可以有静态方法和类方法，这两类方法是发给类的消息，二者并没有实质性的区别&lt;/p&gt;
&lt;p&gt;可以直接使用类名.方法名的方式来调用静态方法和类方法，二者的区别在于，类方法的第一个参数是类对象本身，而静态方法则没有这个参数&lt;/p&gt;
&lt;p&gt;简单的总结一下，对象方法、类方法、静态方法都可以通过类名.方法名的方式来调用，区别在于方法的第一个参数到底是普通对象还是类对象，还是没有接受消息的对象。静态方法通常也可以直接写成一个独立的函数，因为它并没有跟特定的对象绑定&lt;/p&gt;
&lt;p&gt;super().&lt;strong&gt;init&lt;/strong&gt;()来调用父类初始化方法，super函数是Python内置函数中专门为获取当前对象的父类对象而设计的&lt;/p&gt;
&lt;p&gt;子类继承父类的方法后，还可以对方法进行重写（重新实现该方法），不同的子类可以对父类的同一个方法给出不同的实现版本，这样的方法在程序运行时就会表现出多态行为（调用相同的方法，做了不同的事情）&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;在没有特殊处理的情况下，函数的参数都是位置参数，也就意味着传入参数的时候对号入座即可&lt;br&gt;
调用函数时，如果希望函数的调用者必须以参数名=参数值的方式传参，可以用命名关键字参数（keyword-only argument）取代位置参数。所谓命名关键字参数，是在函数的参数列表中，写在*之后的参数&lt;/p&gt;
&lt;p&gt;在函数的参数列表中可以使用可变参数*args来接收任意数量的参数&lt;br&gt;
关键字参数会将传入的带参数名的参数组装成一个字典，参数名就是字典中键值对的键，而参数值就是字典中键值对的值&lt;/p&gt;
&lt;p&gt;不带参数名的参数（位置参数）必须出现在带参数名的参数（关键字参数）之前&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id="理论推导"&gt;理论推导
&lt;/h4&gt;&lt;h4 id="语言模型language-model中最经典的交叉熵损失函数cross-entropy-loss"&gt;语言模型（Language Model）中最经典的交叉熵损失函数（Cross-Entropy Loss）
&lt;/h4&gt;&lt;p&gt;在概率论和深度学习中，给概率 $P$ 取对数（$\log$）绝不是为了让公式看起来更高级，而是出于数学稳定性、计算效率以及优化便利性的深度考量&lt;/p&gt;
&lt;p&gt;语言模型的目标是最大化整个序列出现的概率。假设一个序列有 $T$ 个词，其联合概率是每一个词出现的条件概率的连乘：&lt;/p&gt;
$$P(x_1, x_2, \dots, x_T) = \prod_{t=1}^{T} P(x_t | x_{&lt;t})$$&lt;p&gt;证明:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;p&gt;$P(x_1, x_2, x_3) = P(x_1, x_2) \cdot P(x_3 | x_1, x_2)$&lt;/p&gt;
&lt;p&gt;$P(x_1, x_2) = P(x_1) \cdot P(x_2 | x_1)$&lt;/p&gt;
&lt;p&gt;=&amp;gt;$P(x_1, x_2, x_3) = P(x_1) \cdot P(x_2 | x_1) \cdot P(x_3 | x_1, x_2)$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;递归进行约分&lt;/p&gt;
&lt;p&gt;$P(x_1, \dots, x_T) = P(x_1, \dots, x_{T-1}) \cdot P(x_T | x_1, \dots, x_{T-1})$&lt;/p&gt;
&lt;p&gt;$P(x_1, \dots, x_{T-1}) = P(x_1, \dots, x_{T-2}) \cdot P(x_{T-1} | x_1, \dots, x_{T-2})$&lt;/p&gt;
&lt;p&gt;&amp;hellip;&amp;hellip;&lt;/p&gt;
&lt;p&gt;直到拆到 $P(x_1)$&lt;/p&gt;
&lt;p&gt;两边约分 =&amp;gt; $P(x_1, \dots, x_T) = P(x_1) \cdot P(x_2|x_1) \cdot P(x_3|x_{1,2}) \dots P(x_T|x_{&amp;lt;T}) = \prod_{t=1}^{T} P(x_t | x_{&amp;lt;t})$&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;注：当 $t=1$ 时，$x_{&amp;lt;1}$ 为空集，即起始词概率 $P(x_1)$。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id="sft"&gt;SFT
&lt;/h4&gt;&lt;p&gt;next token loss或者叫lm loss，这是现代语言模型最原始、最直接的训练方式：&lt;/p&gt;
&lt;p&gt;$\mathcal{L}&lt;em&gt;{lm} = -\frac{1}{T} \sum&lt;/em&gt;{t=1}^{T} log P(x_t | x_{&amp;lt;t})$&lt;/p&gt;
&lt;h4 id="dpo"&gt;DPO
&lt;/h4&gt;&lt;p&gt;优化目标是最大化给定 $x$,$y_l$,$y_w$下，好answer优于坏answer的概率&lt;/p&gt;
&lt;p&gt;$\mathcal{L}&lt;em&gt;{DPO} = -\mathbb{E} \left[ \log \sigma \left( \beta \log \frac{\pi&lt;/em&gt;\theta(y_w|x)}{\pi_{ref}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)} \right) \right]$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;其中 $\pi_\theta$,$\pi_{ref}$分别表示正在训练的模型和冻住不训的参考模型，
$x$,$y_l$,$y_w$分别表示prompt，较差的answer和较好的answer。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前工业界稳定跑通的DPO，很多用的都是下面这个公式：&lt;br&gt;
$\mathcal{L}&lt;em&gt;{DPO} = -\mathbb{E} \left[ \log \sigma \left( \beta \log \frac{\pi&lt;/em&gt;\theta(y_w|x)}{\pi_{ref}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)} \right) + \alpha \log \pi_\theta(y_w|x) \right]$&lt;/p&gt;
&lt;p&gt;另外额外提一嘴，DPO训练的时候 $\pi(y|x)$ 是 $\sum_{t=1}^{T} P(y_t|x_{&amp;lt;t})$ ，而不是 $\frac{1}{T} \sum_{t=1}^{T} P(y_t|x_{&amp;lt;t})$ ，这个原理我没有细究，因为我用的也不多。&lt;/p&gt;
&lt;h4 id="rstrejection-sampling-fine-tuning"&gt;RST(Rejection Sampling Fine-tuning)
&lt;/h4&gt;&lt;p&gt;我们希望充分利用偏好对训练出来的 $\pi^&lt;em&gt;$ 模型，但是 $\pi^&lt;/em&gt;$ 又是个判别模型。既然判别模型做不了生成，那就找个生成的模型来采样，判别模型负责拒绝就可以了，于是也就有了拒绝采样的训练&lt;/p&gt;
&lt;p&gt;offline RST的一般流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用经过SFT 的模型或few shot的 pretrain 模型回答 SFT 所有训练数据的问题，得到模型answer&lt;/li&gt;
&lt;li&gt;用奖励模型对SFT数据中原始的answer和模型生成answer进行打分&lt;/li&gt;
&lt;li&gt;得分 top1 的answer 去替换SFT数据中的原始answer，产生新的一版训练数据&lt;/li&gt;
&lt;li&gt;新的数据去训练1中用来生成answer的模型&lt;/li&gt;
&lt;li&gt;重复1-4：模型回答SFT数据-&amp;gt;打分-&amp;gt;top1替换得到新版数据-&amp;gt;训练模型-&amp;gt;模型回答SFT数据-&amp;gt;打分-&amp;gt;&amp;hellip;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="attention"&gt;Attention
&lt;/h3&gt;&lt;p&gt;定义&lt;/p&gt;
$$\mathbf{q}_i, \mathbf{k}_i, \mathbf{v}_i, \mathbf{o}_i \in \mathbb{R}^{d \times 1} $$$$\mathbf{Q} = [\mathbf{q}_1, \mathbf{q}_2, \dots, \mathbf{q}_n]^\top \in \mathbb{R}^{n \times d} $$$$\mathbf{K} = [\mathbf{k}_1, \mathbf{k}_2, \dots, \mathbf{k}_n]^\top \in \mathbb{R}^{n \times d} $$$$\mathbf{V} = [\mathbf{v}_1, \mathbf{v}_2, \dots, \mathbf{v}_n]^\top \in \mathbb{R}^{n \times d} $$$$\mathbf{O} = [\mathbf{o}_1, \mathbf{o}_2, \dots, \mathbf{o}_n]^\top \in \mathbb{R}^{n \times d}$$&lt;h4 id="softmax-attention"&gt;Softmax Attention
&lt;/h4&gt;&lt;p&gt;Softmax Attention通常指 Attention is all you need 中的Attention机制&lt;/p&gt;
$$\mathbf{O} = \text{softmax}(\mathbf{Q}\mathbf{K}^\top + \log \mathbf{M})\mathbf{V}$$$$o_t = \sum_{j=1}^{t} \left( \underbrace{\frac{\exp(\boldsymbol{q}_t^\top \boldsymbol{k}_j)}{\sum_{j=1}^{t} \exp(\boldsymbol{q}_t^\top \boldsymbol{k}_j)}}_{\text{权重 } \alpha_{tj}} \right) \cdot \boldsymbol{v}_j= \frac{\sum_{j=1}^{t} \exp(\mathbf{q}_t^\top \mathbf{k}_j) \mathbf{v}_j}{\sum_{j=1}^{t} \exp(\mathbf{q}_t^\top \mathbf{k}_j)}$$&lt;blockquote&gt;
&lt;p&gt;里面的分母可以提出来，每一项那部分都是常数&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;如果对最终输出O进行RMSNorm(Root Mean Square Layer Normalization)，分母会被消去，所以认为重点是分子部分&lt;/p&gt;
$$\mathbf{O} = \exp(\mathbf{Q}\mathbf{K}^\top + \log \mathbf{M})\mathbf{V} = (\exp(\mathbf{Q}\mathbf{K}^\top) \odot \mathbf{M})\mathbf{V} $$&lt;blockquote&gt;
&lt;p&gt;其中⊙是hadmard积(逐元素积,相同形状的矩阵对应位置元素相乘)&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id="linear-attention"&gt;Linear Attention
&lt;/h4&gt;&lt;p&gt;一开始的Linear Attention是模拟softmax attention,一种最简单的做法是去掉exp &lt;/p&gt;
$$\mathbf{O} = (\mathbf{Q}\mathbf{K}^\top \odot \mathbf{M})\mathbf{V}$$&lt;p&gt;对于非Causal的注意力计算(没有$\mathbf{M}$)，可以通过矩阵交换律改变计算顺序得到线性的计算 &lt;/p&gt;
$$\mathbf{O} = \mathbf{Q}(\mathbf{K}^\top \mathbf{V})$$&lt;blockquote&gt;
&lt;p&gt;原本$QK^\top$的时间复杂度是$O(n^{2}d)$，现在$K^\top V$的时间复杂度是$O(nd^{2})$，与Q相乘仍然是$O(nd^{2})$&lt;/p&gt;&lt;/blockquote&gt;
$$
\mathbf{o}_t = \sum_{j=1}^{t} \mathbf{v}_j (\mathbf{k}_j^\top \mathbf{q}_t) = \sum_{j=1}^{t} (\mathbf{v}_j \mathbf{k}_j^\top) \mathbf{q}_t = \left( \sum_{j=1}^{t} \mathbf{v}_j \mathbf{k}_j^\top \right) \mathbf{q}_t
$$&lt;p&gt;下图手证 $\mathbf{o}&lt;em&gt;t = \sum&lt;/em&gt;{j=1}^{t} \mathbf{v}_j (\mathbf{k}_j^\top \mathbf{q}_t)$ ,记住矩阵有结合律和分配律, 没有交换律和消去律&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/be-a-good-engineer/image/linear_o_t.jpg"
width="4096"
height="3072"
srcset="https://qingzhou-yanghy.github.io/p/be-a-good-engineer/image/linear_o_t_hu_a8461dbdbd422eee.jpg 480w, https://qingzhou-yanghy.github.io/p/be-a-good-engineer/image/linear_o_t_hu_c38bb4eb534f65f2.jpg 1024w"
loading="lazy"
alt="linear_o_t"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;p&gt;将括号部分标记为 $S_t$ ,有 &lt;/p&gt;
$$
\mathbf{o}_t = \mathbf{S}_t \mathbf{q}_t, \quad \mathbf{S}_t = \mathbf{S}_{t-1} + \mathbf{v}_t \mathbf{k}_t^\top
$$&lt;h4 id="deltanet"&gt;DeltaNet
&lt;/h4&gt;&lt;p&gt;最早的线性Attention对应的损失函数是 $-v^T(Sk)$&lt;/p&gt;
&lt;p&gt;一个更理想更直接的损失可能是MSE/L2 Loss，即 $\frac{1}{2} |Sk - v|^2$ DeltaNet便使用了这样的损失&lt;br&gt;
&lt;/p&gt;
$$o_t = f(S_t; q_t), \quad S_t = S_{t-1} - \underbrace{\eta_t (S_{t-1} k_t - v_t) k_t^\top}_{\nabla_{S_{t-1}} \frac{1}{2} \| S_{t-1} k_t - v_t \|^2}$$&lt;p&gt;
​
$ \eta_t $是一个常数，不妨设其为1方便分析
将式子拆开可以得到&lt;/p&gt;
$$
\begin{aligned}
S_t &amp;= S_{t-1} - (S_{t-1}\boldsymbol{k}_t - \boldsymbol{v}_t)\boldsymbol{k}_t^\top \\
&amp;= S_{t-1} - (S_{t-1}\boldsymbol{k}_t)\boldsymbol{k}_t^\top + \boldsymbol{v}_t\boldsymbol{k}_t^\top \\
&amp;= S_{t-1}(\boldsymbol{I} - \boldsymbol{k}_t\boldsymbol{k}_t^\top) + \boldsymbol{v}_t\boldsymbol{k}_t^\top
\end{aligned}
$$&lt;p&gt;相比于一开始的状态更新，DeltaNet的状态更新之前先减去了一个 $(S_{t-1}\boldsymbol{k}_t)\boldsymbol{k}&lt;em&gt;t^\top, \quad S&lt;/em&gt;{t-1}\boldsymbol{k}_t$ 是模型对v的预测，所以这里就有点像是 去除模型的旧知识，加入正确的新知识。这个规则称为Delta Rule，也是Delta的来源&lt;/p&gt;
&lt;p&gt;联想记忆（Associative Memory） 或 线性注意力 机制中，如何从存储矩阵 $S$ 中通过键 $k_j$ 检索出对应值 $v_j$ 的数学原理，以及为什么会产生误差?&lt;/p&gt;
$$S = \sum_{i=1}^{n} v_i k_i^\top$$&lt;p&gt;
&lt;/p&gt;
$$Sk_j = \left( \sum_{i=1}^{n} v_i k_i^\top \right) k_j = \sum_{i=1}^{n} v_i (k_i^\top k_j)$$&lt;p&gt;为了看清检索结果准不准，我们将求和拆分为“目标项”（$i=j$）和“干扰项”（$i \neq j$）：当 $i = j$ 时：项为 $v_j (k_j^\top k_j)$。如果键向量是单位向量（即 $k_j^\top k_j = 1$），这一项就直接等于 $v_j$。当 $i \neq j$ 时：项为 $\sum_{i \neq j} (k_i^\top k_j) v_i$。这些是其他存储项对当前检索的干扰&lt;/p&gt;
$$Sk_j = v_j + \underbrace{\sum_{i \neq j} (k_i^\top k_j) v_i}_{\text{retrieval error}}$$&lt;h4 id="gated-deltanet"&gt;Gated DeltaNet
&lt;/h4&gt;&lt;p&gt;Gated DeltaNet将遗忘门加入到了DeltaNet中，它的引入方式为
&lt;/p&gt;
$$
\boldsymbol{S}_t = \alpha_t \boldsymbol{S}_{t-1} (\boldsymbol{I} - \beta_t \boldsymbol{k}_t \boldsymbol{k}_t^\top) + \beta_t \boldsymbol{v}_t \boldsymbol{k}_t^\top
$$&lt;h3 id="训练经验"&gt;训练经验
&lt;/h3&gt;&lt;h4 id="个人实战经验"&gt;个人实战经验
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;PEFT（Parameter-Efficient Fine-Tuning，参数高效微调）,就是我们常说的Lora&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;model = get_peft_model(model, config)&lt;/code&gt;&lt;/p&gt;
&lt;h4 id="他人经验"&gt;他人经验
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/721492096" target="_blank" rel="noopener"
&gt;LLM实践&amp;ndash;支线：拯救Continue Pretrain的数据&lt;/a&gt; 这里面评论区提到的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SFT确实是可以注入知识的，只不过必须全参，lora完全不行，lora训十轮也学不进去，全参训一轮就学得差不多了，之前看各种文章无脑推荐高效微调法，其实是一个很大的误区。知识在整句话中其实只占很小的一部分，属于次要奇异值，lora会把这些东西忽略掉，导致学习一些hacking，比如格式、行文。所以我也说sft注入没有不可以，多样性一定保证，也要避免hacking。平时工作我也从来不用lora，因为次要奇异值往往更重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/4547529049" target="_blank" rel="noopener"
&gt;LLM实践&amp;ndash;拒绝采样&lt;/a&gt; 评论区&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有的后训练改进过程都是在解决LM LOSS不等于预期LOSS的问题，试图去稳定性量化预期LOSS，目前的所有技术都只是通过尝试来试图接近，这是token-based paradigm的必然问题。解决这个问题的终极方案是从next-token LM model转为semantic model，用semantic loss来替代Lm loss。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="面向进程编程"&gt;面向进程编程
&lt;/h3&gt;&lt;p&gt;整份脚本处理的是发生在1个进程上的事情。这样做的好处是，我们只需要维护1份脚本，然后将其发去不同机器的各张卡上执行，就能实现全局的并行。&lt;/p&gt;
&lt;h3 id="megatron"&gt;Megatron
&lt;/h3&gt;&lt;p&gt;Megatron还是要看的&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/613196255" target="_blank" rel="noopener"
&gt;图解大模型训练之：流水线并行（Pipeline Parallelism），以Gpipe为例&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/617133971" target="_blank" rel="noopener"
&gt;图解大模型训练之：数据并行上篇(DP, DDP与ZeRO)&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/618865052" target="_blank" rel="noopener"
&gt;图解大模型训练之：数据并行下篇(DeepSpeed ZeRO，零冗余优化)&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/622212228" target="_blank" rel="noopener"
&gt;图解大模型训练之：张量模型并行(TP)，Megatron-LM&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/629121480" target="_blank" rel="noopener"
&gt;图解大模型系列之：Megatron源码解读1，分布式环境初始化&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/634377071" target="_blank" rel="noopener"
&gt;图解大模型训练之：Megatron源码解读2，模型并行&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/662700424" target="_blank" rel="noopener"
&gt;图解大模型训练系列之：Megatron源码解读3，分布式混合精度训练&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="pretrain部分code大致流程"&gt;pretrain部分code大致流程
&lt;/h4&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;/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;def pretrain(
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; train_valid_test_dataset_provider,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; model_provider,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; forward_step_func,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; valid_forward_step_func=None,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; extra_args_provider=None,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; args_defaults={},
&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; # 1.初始化分布式环境(源码解读1内容)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; initialize_megatron(
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; extra_args_provider=extra_args_provider, args_defaults=args_defaults
&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; # 2、模型并行：定义模型架构，并切割模型（本文重点）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; model, optimizer, lr_scheduler = setup_model_and_optimizer(model_provider)
&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; # 3、构造train/val/test数据集（下一篇将讲述）
&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; train_data_iterator,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; valid_data_iterator,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; test_data_iterator,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ) = build_train_valid_test_data_iterators(train_valid_test_dataset_provider)
&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; # 4、训练（下下一篇将讲述）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; iteration = train(
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; forward_step_func,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; valid_forward_step_func,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; model,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; optimizer,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; lr_scheduler,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; train_data_iterator,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; valid_data_iterator,
&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&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;h4 id="crossentropy"&gt;CrossEntropy
&lt;/h4&gt;&lt;p&gt;在语言模型训练中，我们需要计算预测分布与真实标签之间的交叉熵损失。对于单个样本，交叉熵损失定义为：&lt;/p&gt;
$$
L = -\log P(y|x) = -\log\left(\frac{e^{s_y}}{\sum_{j=1}^{V} e^{s_j}}\right) = \log\left(\sum_{j=1}^{V} e^{s_j}\right) - s_y
$$&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$s = [s_1, s_2, \ldots, s_V]$ 是模型输出的 logits（未归一化的对数概率）&lt;/li&gt;
&lt;li&gt;$V$ 是词汇表大小&lt;/li&gt;
&lt;li&gt;$y$ 是真实标签&lt;/li&gt;
&lt;li&gt;$s_y$ 是真实类别对应的 logit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;数值稳定性处理&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为了数值稳定性，我们在计算 softmax 前先减去最大值：&lt;/p&gt;
$$
\text{logits}' = s - \max(s)
$$&lt;p&gt;这样做的理由：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;防止 $\exp(s)$ 溢出&lt;/li&gt;
&lt;li&gt;不改变 softmax 结果（分子分母同时乘以 $e^{-\max(s)}$）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;词汇表并行（Vocab Parallel）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在张量并行中，词汇表被切分到多个 GPU 上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;假设有 $N$ 个 GPU，词汇表大小为 $V$&lt;/li&gt;
&lt;li&gt;每个 GPU 维护 $V/N$ 个词的 logits&lt;/li&gt;
&lt;li&gt;需要通过通信（AllReduce）来计算全局的 softmax 和 loss&lt;/li&gt;
&lt;/ul&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;span class="lnt"&gt; 48
&lt;/span&gt;&lt;span class="lnt"&gt; 49
&lt;/span&gt;&lt;span class="lnt"&gt; 50
&lt;/span&gt;&lt;span class="lnt"&gt; 51
&lt;/span&gt;&lt;span class="lnt"&gt; 52
&lt;/span&gt;&lt;span class="lnt"&gt; 53
&lt;/span&gt;&lt;span class="lnt"&gt; 54
&lt;/span&gt;&lt;span class="lnt"&gt; 55
&lt;/span&gt;&lt;span class="lnt"&gt; 56
&lt;/span&gt;&lt;span class="lnt"&gt; 57
&lt;/span&gt;&lt;span class="lnt"&gt; 58
&lt;/span&gt;&lt;span class="lnt"&gt; 59
&lt;/span&gt;&lt;span class="lnt"&gt; 60
&lt;/span&gt;&lt;span class="lnt"&gt; 61
&lt;/span&gt;&lt;span class="lnt"&gt; 62
&lt;/span&gt;&lt;span class="lnt"&gt; 63
&lt;/span&gt;&lt;span class="lnt"&gt; 64
&lt;/span&gt;&lt;span class="lnt"&gt; 65
&lt;/span&gt;&lt;span class="lnt"&gt; 66
&lt;/span&gt;&lt;span class="lnt"&gt; 67
&lt;/span&gt;&lt;span class="lnt"&gt; 68
&lt;/span&gt;&lt;span class="lnt"&gt; 69
&lt;/span&gt;&lt;span class="lnt"&gt; 70
&lt;/span&gt;&lt;span class="lnt"&gt; 71
&lt;/span&gt;&lt;span class="lnt"&gt; 72
&lt;/span&gt;&lt;span class="lnt"&gt; 73
&lt;/span&gt;&lt;span class="lnt"&gt; 74
&lt;/span&gt;&lt;span class="lnt"&gt; 75
&lt;/span&gt;&lt;span class="lnt"&gt; 76
&lt;/span&gt;&lt;span class="lnt"&gt; 77
&lt;/span&gt;&lt;span class="lnt"&gt; 78
&lt;/span&gt;&lt;span class="lnt"&gt; 79
&lt;/span&gt;&lt;span class="lnt"&gt; 80
&lt;/span&gt;&lt;span class="lnt"&gt; 81
&lt;/span&gt;&lt;span class="lnt"&gt; 82
&lt;/span&gt;&lt;span class="lnt"&gt; 83
&lt;/span&gt;&lt;span class="lnt"&gt; 84
&lt;/span&gt;&lt;span class="lnt"&gt; 85
&lt;/span&gt;&lt;span class="lnt"&gt; 86
&lt;/span&gt;&lt;span class="lnt"&gt; 87
&lt;/span&gt;&lt;span class="lnt"&gt; 88
&lt;/span&gt;&lt;span class="lnt"&gt; 89
&lt;/span&gt;&lt;span class="lnt"&gt; 90
&lt;/span&gt;&lt;span class="lnt"&gt; 91
&lt;/span&gt;&lt;span class="lnt"&gt; 92
&lt;/span&gt;&lt;span class="lnt"&gt; 93
&lt;/span&gt;&lt;span class="lnt"&gt; 94
&lt;/span&gt;&lt;span class="lnt"&gt; 95
&lt;/span&gt;&lt;span class="lnt"&gt; 96
&lt;/span&gt;&lt;span class="lnt"&gt; 97
&lt;/span&gt;&lt;span class="lnt"&gt; 98
&lt;/span&gt;&lt;span class="lnt"&gt; 99
&lt;/span&gt;&lt;span class="lnt"&gt;100
&lt;/span&gt;&lt;span class="lnt"&gt;101
&lt;/span&gt;&lt;span class="lnt"&gt;102
&lt;/span&gt;&lt;span class="lnt"&gt;103
&lt;/span&gt;&lt;span class="lnt"&gt;104
&lt;/span&gt;&lt;span class="lnt"&gt;105
&lt;/span&gt;&lt;span class="lnt"&gt;106
&lt;/span&gt;&lt;span class="lnt"&gt;107
&lt;/span&gt;&lt;span class="lnt"&gt;108
&lt;/span&gt;&lt;span class="lnt"&gt;109
&lt;/span&gt;&lt;span class="lnt"&gt;110
&lt;/span&gt;&lt;span class="lnt"&gt;111
&lt;/span&gt;&lt;span class="lnt"&gt;112
&lt;/span&gt;&lt;span class="lnt"&gt;113
&lt;/span&gt;&lt;span class="lnt"&gt;114
&lt;/span&gt;&lt;span class="lnt"&gt;115
&lt;/span&gt;&lt;span class="lnt"&gt;116
&lt;/span&gt;&lt;span class="lnt"&gt;117
&lt;/span&gt;&lt;span class="lnt"&gt;118
&lt;/span&gt;&lt;span class="lnt"&gt;119
&lt;/span&gt;&lt;span class="lnt"&gt;120
&lt;/span&gt;&lt;span class="lnt"&gt;121
&lt;/span&gt;&lt;span class="lnt"&gt;122
&lt;/span&gt;&lt;span class="lnt"&gt;123
&lt;/span&gt;&lt;span class="lnt"&gt;124
&lt;/span&gt;&lt;span class="lnt"&gt;125
&lt;/span&gt;&lt;span class="lnt"&gt;126
&lt;/span&gt;&lt;span class="lnt"&gt;127
&lt;/span&gt;&lt;span class="lnt"&gt;128
&lt;/span&gt;&lt;span class="lnt"&gt;129
&lt;/span&gt;&lt;span class="lnt"&gt;130
&lt;/span&gt;&lt;span class="lnt"&gt;131
&lt;/span&gt;&lt;span class="lnt"&gt;132
&lt;/span&gt;&lt;span class="lnt"&gt;133
&lt;/span&gt;&lt;span class="lnt"&gt;134
&lt;/span&gt;&lt;span class="lnt"&gt;135
&lt;/span&gt;&lt;span class="lnt"&gt;136
&lt;/span&gt;&lt;span class="lnt"&gt;137
&lt;/span&gt;&lt;span class="lnt"&gt;138
&lt;/span&gt;&lt;span class="lnt"&gt;139
&lt;/span&gt;&lt;span class="lnt"&gt;140
&lt;/span&gt;&lt;span class="lnt"&gt;141
&lt;/span&gt;&lt;span class="lnt"&gt;142
&lt;/span&gt;&lt;span class="lnt"&gt;143
&lt;/span&gt;&lt;span class="lnt"&gt;144
&lt;/span&gt;&lt;span class="lnt"&gt;145
&lt;/span&gt;&lt;span class="lnt"&gt;146
&lt;/span&gt;&lt;span class="lnt"&gt;147
&lt;/span&gt;&lt;span class="lnt"&gt;148
&lt;/span&gt;&lt;span class="lnt"&gt;149
&lt;/span&gt;&lt;span class="lnt"&gt;150
&lt;/span&gt;&lt;span class="lnt"&gt;151
&lt;/span&gt;&lt;span class="lnt"&gt;152
&lt;/span&gt;&lt;span class="lnt"&gt;153
&lt;/span&gt;&lt;span class="lnt"&gt;154
&lt;/span&gt;&lt;span class="lnt"&gt;155
&lt;/span&gt;&lt;span class="lnt"&gt;156
&lt;/span&gt;&lt;span class="lnt"&gt;157
&lt;/span&gt;&lt;span class="lnt"&gt;158
&lt;/span&gt;&lt;span class="lnt"&gt;159
&lt;/span&gt;&lt;span class="lnt"&gt;160
&lt;/span&gt;&lt;span class="lnt"&gt;161
&lt;/span&gt;&lt;span class="lnt"&gt;162
&lt;/span&gt;&lt;span class="lnt"&gt;163
&lt;/span&gt;&lt;span class="lnt"&gt;164
&lt;/span&gt;&lt;span class="lnt"&gt;165
&lt;/span&gt;&lt;span class="lnt"&gt;166
&lt;/span&gt;&lt;span class="lnt"&gt;167
&lt;/span&gt;&lt;span class="lnt"&gt;168
&lt;/span&gt;&lt;span class="lnt"&gt;169
&lt;/span&gt;&lt;span class="lnt"&gt;170
&lt;/span&gt;&lt;span class="lnt"&gt;171
&lt;/span&gt;&lt;span class="lnt"&gt;172
&lt;/span&gt;&lt;span class="lnt"&gt;173
&lt;/span&gt;&lt;span class="lnt"&gt;174
&lt;/span&gt;&lt;span class="lnt"&gt;175
&lt;/span&gt;&lt;span class="lnt"&gt;176
&lt;/span&gt;&lt;span class="lnt"&gt;177
&lt;/span&gt;&lt;span class="lnt"&gt;178
&lt;/span&gt;&lt;span class="lnt"&gt;179
&lt;/span&gt;&lt;span class="lnt"&gt;180
&lt;/span&gt;&lt;span class="lnt"&gt;181
&lt;/span&gt;&lt;span class="lnt"&gt;182
&lt;/span&gt;&lt;span class="lnt"&gt;183
&lt;/span&gt;&lt;span class="lnt"&gt;184
&lt;/span&gt;&lt;span class="lnt"&gt;185
&lt;/span&gt;&lt;span class="lnt"&gt;186
&lt;/span&gt;&lt;span class="lnt"&gt;187
&lt;/span&gt;&lt;span class="lnt"&gt;188
&lt;/span&gt;&lt;span class="lnt"&gt;189
&lt;/span&gt;&lt;span class="lnt"&gt;190
&lt;/span&gt;&lt;span class="lnt"&gt;191
&lt;/span&gt;&lt;span class="lnt"&gt;192
&lt;/span&gt;&lt;span class="lnt"&gt;193
&lt;/span&gt;&lt;span class="lnt"&gt;194
&lt;/span&gt;&lt;span class="lnt"&gt;195
&lt;/span&gt;&lt;span class="lnt"&gt;196
&lt;/span&gt;&lt;span class="lnt"&gt;197
&lt;/span&gt;&lt;span class="lnt"&gt;198
&lt;/span&gt;&lt;span class="lnt"&gt;199
&lt;/span&gt;&lt;span class="lnt"&gt;200
&lt;/span&gt;&lt;span class="lnt"&gt;201
&lt;/span&gt;&lt;span class="lnt"&gt;202
&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;_VocabParallelCrossEntropy&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;autograd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Function&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="nd"&gt;@staticmethod&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="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vocab_parallel_logits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&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;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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; - vocab_parallel_logits: [batch_size, seq_len, partition_vocab_size]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 当前 GPU 上维护的部分词汇表 logits
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - target: [batch_size, seq_len]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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; - loss: [batch_size, seq_len]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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;&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;# ============ 第一步：数值稳定性处理 ============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 在词汇表维度上找到最大值（只在当前 GPU 的分区上找）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# logits_max: [batch_size, seq_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;# 数学表达：m_i = max(s_i) 其中 s_i 是第 i 个样本的 logits&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logits_max&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;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vocab_parallel_logits&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="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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 通过 AllReduce 获取全局最大值（跨所有 GPU）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这样确保所有 GPU 使用相同的最大值进行归一化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：m_global = max(m_1, m_2, ..., m_N) 其中 N 是 GPU 数量&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&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distributed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_reduce&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;logits_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="n"&gt;op&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;distributed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReduceOp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&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="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;get_tensor_model_parallel_group&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&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;# logits&amp;#39; = logits - max(logits)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这样可以防止 exp(logits) 溢出，同时不改变 softmax 结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：s&amp;#39;_ij = s_ij - m_global&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vocab_parallel_logits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logits_max&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unsqueeze&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="c1"&gt;# ============ 第二步：确定当前 GPU 的词汇表范围 ============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 获取当前 GPU 负责的词汇表索引范围&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 例如：V=10000, N=4, rank=0 -&amp;gt; [0, 2500), rank=1 -&amp;gt; [2500, 5000), ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;get_vocab_range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VocabUtility&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vocab_range_from_per_partition_vocab_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;partition_vocab_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vocab_parallel_logits&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;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 当前 GPU 的词汇表分区大小&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_tensor_model_parallel_rank&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 当前 GPU 的 rank&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;world_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_tensor_model_parallel_world_size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 总 GPU 数量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vocab_start_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vocab_end_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_vocab_range&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;partition_vocab_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world_size&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&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;# 判断哪些目标在当前 GPU 的词汇表范围内&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# target_mask=True 表示目标不在当前 GPU 的词汇表范围内&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：mask_i = 1 if (target_i &amp;lt; start) or (target_i &amp;gt;= end), else 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;target_mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;vocab_start_index&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="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;vocab_end_index&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;# 将全局目标索引转换为当前 GPU 的局部索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：target&amp;#39;_i = target_i - vocab_start_index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;masked_target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;vocab_start_index&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;# 将不在当前范围内的目标设为 0（之后会被 mask 掉）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;masked_target&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target_mask&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;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="c1"&gt;# ============ 第四步：提取目标位置的 logit ============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 将 logits 展平为 2D：[batch_size * seq_len, partition_vocab_size]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 将 target 展平为 1D：[batch_size * seq_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;# 这样方便使用高级索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logits_2d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vocab_parallel_logits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&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="n"&gt;partition_vocab_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;masked_target_1d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;masked_target&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&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="c1"&gt;# 创建行索引 [0, 1, 2, ..., batch_size * seq_len - 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;arange_1d&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&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;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logits_2d&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logits_2d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 提取每个样本对应目标位置的 logit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：s&amp;#39;_target = logits[arange_1d, masked_target_1d]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 即取出每个样本在其目标词汇位置的 logit 值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;predicted_logits_1d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logits_2d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;arange_1d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;masked_target_1d&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;predicted_logits_1d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;predicted_logits_1d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contiguous&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;# 恢复原始形状：[batch_size, seq_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;predicted_logits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;predicted_logits_1d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view_as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&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;# 将不在当前 GPU 范围内的目标的 logit 设为 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这样做是因为之后会通过 AllReduce 求和，只需要贡献自己的部分&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;predicted_logits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target_mask&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.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="c1"&gt;# 通过 AllReduce 从所有 GPU 收集目标的 logit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 每个 GPU 只贡献自己分区内的目标 logit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 最终得到所有目标位置的完整 logit 值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：s_y = Σ(s&amp;#39;_y_i) 对所有 GPU 求和&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&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distributed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_reduce&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;predicted_logits&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;op&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;distributed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReduceOp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SUM&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;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;get_tensor_model_parallel_group&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# ============ 第五步：计算归一化项（log-sum-exp）============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 计算 exp(logits&amp;#39;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：e&amp;#39;_ij = exp(s&amp;#39;_ij)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;exp_logits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vocab_parallel_logits&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&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vocab_parallel_logits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;exp_logits&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;# 在当前 GPU 的词汇表维度上求和&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：E&amp;#39;_i = Σ(e&amp;#39;_ij) 对当前 GPU 的词汇表维度求和&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sum_exp_logits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exp_logits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&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="c1"&gt;# 通过 AllReduce 从所有 GPU 收集完整的指数和&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：E_i = Σ(E&amp;#39;_i) 对所有 GPU 求和&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这就是 softmax 的分母：Σ(exp(s_j))&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&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distributed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_reduce&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;sum_exp_logits&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;op&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;distributed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReduceOp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SUM&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;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;get_tensor_model_parallel_group&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&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;# 交叉熵损失：L = log(sum(exp(logits))) - predicted_logit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：L = log(E_i) - s_y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 这对应：L = log(Σ(exp(s_j))) - s_y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 即：L = -log(exp(s_y) / Σ(exp(s_j))) = -softmax_y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loss&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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum_exp_logits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;predicted_logits&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;# ============ 第七步：保存反向传播所需的中间变量 ============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 计算 softmax 并保存，用于反向传播&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：softmax_ij = exp(s&amp;#39;_ij) / E_i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;exp_logits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;div_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum_exp_logits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unsqueeze&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="c1"&gt;# 保存 softmax、target_mask 和 masked_target_1d 用于反向传播&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_for_backward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exp_logits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_mask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;masked_target_1d&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;return&lt;/span&gt; &lt;span class="n"&gt;loss&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="nd"&gt;@staticmethod&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;backward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grad_output&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;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 反向传播：计算交叉熵损失对 logits 的梯度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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; 数学推导：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; 前向传播：L = log(Σ(exp(s_j))) - s_y
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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; 对 logits 的梯度：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; ∂L/∂s_i = softmax_i - 1_{i=y}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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; 其中：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - softmax_i = exp(s_i) / Σ(exp(s_j))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - 1_{i=y} 是指示函数，当 i=y 时为 1，否则为 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&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; 在词汇表并行的场景下：
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - 当前 GPU 只计算自己分区内的梯度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - 对于目标位置：grad = softmax - 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; - 对于非目标位置：grad = softmax
&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;&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;# ============ 第一步：恢复前向传播保存的中间变量 ============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# softmax: [batch_size, seq_len, partition_vocab_size]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# target_mask: [batch_size, seq_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;# masked_target_1d: [batch_size * seq_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;softmax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_mask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;masked_target_1d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;saved_tensors&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;# ============ 第二步：初始化梯度 ============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 交叉熵损失的梯度基础是 softmax 值&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 对于所有位置，梯度从 softmax 开始&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：∂L/∂s_i = softmax_i （基础项）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;grad_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;softmax&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;# 为了方便索引，转换为 2D 格式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# grad_2d: [batch_size * seq_len, partition_vocab_size]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;partition_vocab_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;softmax&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;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;grad_2d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;grad_input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&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="n"&gt;partition_vocab_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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&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;# 对于目标位置，需要减去 1（指示函数）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 数学表达：∂L/∂s_y = softmax_y - 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 其中 1 是真实标签的指示函数 1_{i=y}&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;# 创建行索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;arange_1d&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;start&lt;/span&gt;&lt;span class="o"&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;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;grad_2d&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;grad_2d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device&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;# 对目标位置的梯度进行调整：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 1. 如果目标在当前 GPU 的词汇表范围内（target_mask=False）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# grad = softmax - 1 （减 1）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 2. 如果目标不在当前范围内（target_mask=True）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# grad = softmax - 0 （不减 1，因为目标在其他 GPU 上）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&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;# ∂L/∂s_y = softmax_y - (1 - mask_y)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 其中 mask_y = 1 表示目标不在当前 GPU，mask_y = 0 表示目标在当前 GPU&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;grad_2d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;arange_1d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;masked_target_1d&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 class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;target_mask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float&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;# ============ 第四步：乘以上层梯度 ============&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&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;# 数学表达：∂L_total/∂s = (∂L/∂s) × (∂L_total/∂L)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 其中 grad_output 是 ∂L_total/∂L&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;grad_input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mul_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;grad_output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unsqueeze&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="c1"&gt;# 返回梯度（第二个输入 target 不需要梯度，返回 None）&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;grad_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;None&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;def&lt;/span&gt; &lt;span class="nf"&gt;vocab_parallel_cross_entropy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vocab_parallel_logits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&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;Helper function for the cross entropy.&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="n"&gt;_VocabParallelCrossEntropy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vocab_parallel_logits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&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;h4 id="精度问题"&gt;精度问题
&lt;/h4&gt;&lt;p&gt;从占用存储角度看，fp16占据2 bytes，bf16占据2 bytes，fp32占据4 bytes&lt;br&gt;
从数值表达范围来看：fp32 = bf16 &amp;gt; fp16&lt;br&gt;
从数值表达精度来看：fp32 &amp;gt; fp16 &amp;gt; bf16&lt;/p&gt;
&lt;p&gt;最好理解每一部分精度转换的原因和整个流程，算是基本功&lt;/p&gt;
&lt;p&gt;老样子，放一些写的好的文章可以学一学&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/662700424" target="_blank" rel="noopener"
&gt;图解大模型训练系列之：Megatron源码解读3，分布式混合精度训练&lt;/a&gt;&lt;br&gt;
megatron/training.py的pretrain 函数。其中，函数setup_model_and_optimizer调用了optimizer/&lt;strong&gt;init&lt;/strong&gt;.py/下的get_megatron_optimizer，因此它就是混合精度训练的入口函数&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/624740065" target="_blank" rel="noopener"
&gt;分析transformer模型的参数量、计算量、中间激活、KV cache&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;两种做Loss Scale的方法：常量损失放大和动量损失放大&lt;/p&gt;
&lt;h3 id="deepspeed"&gt;DeepSpeed
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://huggingface.co/docs/transformers/deepspeed" target="_blank" rel="noopener"
&gt;DeepSpeed官方文档&lt;/a&gt;👈官方文档&lt;br&gt;
&lt;a class="link" href="https://www.deepspeed.ai/docs/config-json/" target="_blank" rel="noopener"
&gt;DeepSpeed配置JSON&lt;/a&gt;👈使用只需要JSON配置文件&lt;br&gt;
&lt;a class="link" href="https://www.youtube.com/watch?v=mpuRca2UZtI&amp;amp;t=2925s" target="_blank" rel="noopener"
&gt;【利用多張GPU訓練大型語言模型】 - YouTube&lt;/a&gt;👈李宏毅老师YouTube视频讲解（约一个小时）&lt;br&gt;
&lt;a class="link" href="https://huggingface.co/spaces/nanotron/ultrascale-playbook" target="_blank" rel="noopener"
&gt;The Ultra-Scale Playbook:Training LLMs on GPU Clusters&lt;/a&gt;👈并行训练高质参考资料&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;hugging face经常有高质量实验总结，可以多关注一下&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;一开始会有batch-size个prompt去做rollout，每个prompt rollout出n个response，之后每mini-batch-size个prompt及其rollout出来的response会去做一次梯度下降，batch-size / mini-batch-size次梯度下降之后一个step结束&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Batch Size Related Parameters
&lt;strong&gt;train_batch_size&lt;/strong&gt; = &lt;strong&gt;train_micro_batch_size_per_gpu&lt;/strong&gt; * &lt;strong&gt;gradient_accumulation_steps&lt;/strong&gt; * &lt;strong&gt;number of GPUs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;train_batch_size: [integer]
代表着one step.Example:32&lt;/li&gt;
&lt;li&gt;train_micro_batch_size_per_gpu: [integer]
一次更新的batch_size，所以叫micro_batch_size.&lt;/li&gt;
&lt;li&gt;gradient_accumulation_steps: [integer]
积累几次&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一开始会有batch-size个prompt去做rollout，每个prompt rollout出n个response，之后每mini-batch-size个prompt及其rollout出来的response会去做一次梯度下降，batch-size / mini-batch-size次梯度下降之后一个step结束&lt;/p&gt;
&lt;h3 id="监控平台"&gt;监控平台
&lt;/h3&gt;&lt;p&gt;可以使用TensorBoard,wandb,Comet等，因为个人使用所以只介绍swanlab(wandb的国内镜像)&lt;br&gt;
注册登录，设置 project_name 和 experiment_name 就可以在电脑上/手机上看了&lt;br&gt;
很好用的监控平台！&lt;br&gt;
&lt;a class="link" href="https://docs.swanlab.cn/" target="_blank" rel="noopener"
&gt;swanlab官方文档&lt;/a&gt;👈官方文档&lt;/p&gt;
&lt;h3 id="verl框架使用方法快速上手"&gt;veRL框架使用方法/快速上手
&lt;/h3&gt;&lt;p&gt;知乎上收藏了一些轮椅教程&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/29149216967" target="_blank" rel="noopener"
&gt;OpenRLHF&amp;amp;Verl参数转换指南&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;更深入的：&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/24682036412" target="_blank" rel="noopener"
&gt;HybridFlow / veRL 原文浅析&lt;/a&gt;很干，对system理解有很大帮助&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/27676081245" target="_blank" rel="noopener"
&gt;[AI Infra] VeRL 框架入门&amp;amp;代码带读&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/30876678559" target="_blank" rel="noopener"
&gt;从零开始的verl框架解析&lt;/a&gt;&lt;/p&gt;</description></item><item><title>NLP</title><link>https://qingzhou-yanghy.github.io/p/nlp/</link><pubDate>Mon, 19 Jan 2026 10:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/nlp/</guid><description>&lt;h2 id="生成式人工智慧與機器學習導論2025第3講解剖大型語言模型representation"&gt;【生成式人工智慧與機器學習導論2025】第3講：解剖大型語言模型representation
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://www.youtube.com/watch?v=Xnil63UDW2o" target="_blank" rel="noopener"
&gt;https://www.youtube.com/watch?v=Xnil63UDW2o&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Token Embedding 是在Layer 1输入的那个， Contextualized Embedding(也就是我们说的representation表征) 指的是经过Layer 1输出的那个.&lt;/p&gt;
&lt;p&gt;Representation Engineering, Activation Engineering, Activating Steering&amp;hellip;&lt;/p&gt;
&lt;h3 id="logit-lens"&gt;Logit Lens
&lt;/h3&gt;&lt;p&gt;对每一层进行 Unembedding ,可以看每一层的思考所对应的文字，窥探语言模型的思考过程&lt;/p&gt;
&lt;h3 id="patchscopes"&gt;Patchscopes
&lt;/h3&gt;&lt;p&gt;把一个向量（一个token/字）替换成一句话&lt;/p&gt;
&lt;h3 id="layer解读使用transformer架构的解读"&gt;Layer解读（使用Transformer架构的解读）
&lt;/h3&gt;&lt;p&gt;Layer 中还有 Layer.&lt;/p&gt;
&lt;p&gt;首先过 Self-attention Layer (attention layer), 考虑上下文就是因为 attention layer, 输出经过几个 Feed Forward Layer&lt;/p&gt;
&lt;p&gt;典中典，要求手撕 Attention Layer ,&lt;/p&gt;
&lt;p&gt;自己跟自己也要进行dot product&lt;/p&gt;
&lt;p&gt;dot product 叫 Attention weight, 要所有的 weight 过 Softmax&lt;/p&gt;
&lt;h4 id="positional-embedding"&gt;Positional Embedding
&lt;/h4&gt;&lt;p&gt;Llama 用 Rope , 旋转位置编码, 为了把位置的咨询加入到计算中&lt;/p&gt;
&lt;h4 id="multi-head-attention"&gt;Multi-head Attention
&lt;/h4&gt;&lt;p&gt;每一个 head 的作用不一样
&lt;img src="https://qingzhou-yanghy.github.io/p/nlp/head1.png"
width="1920"
height="1080"
srcset="https://qingzhou-yanghy.github.io/p/nlp/head1_hu_5c2f61de8fa1895a.png 480w, https://qingzhou-yanghy.github.io/p/nlp/head1_hu_7082b3b93c16b72d.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/nlp/head2.png"
width="1920"
height="1080"
srcset="https://qingzhou-yanghy.github.io/p/nlp/head2_hu_83133a53ace293d4.png 480w, https://qingzhou-yanghy.github.io/p/nlp/head2_hu_55132687d139d9b4.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/nlp/head_sum.png"
width="1920"
height="1080"
srcset="https://qingzhou-yanghy.github.io/p/nlp/head_sum_hu_e51fd46eca1988c9.png 480w, https://qingzhou-yanghy.github.io/p/nlp/head_sum_hu_4be7b5a6e054e9f4.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;&lt;/p&gt;
&lt;p&gt;目前的语言模型大多数都是 Causal Attention, 这样计算方便(Autogressive)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/nlp/neuron.png"
width="1920"
height="1080"
srcset="https://qingzhou-yanghy.github.io/p/nlp/neuron_hu_4bcc0684b5ad4793.png 480w, https://qingzhou-yanghy.github.io/p/nlp/neuron_hu_3fd78a0647b41cb5.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;&lt;/p&gt;
&lt;h3 id="实做环节"&gt;实做环节
&lt;/h3&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;model.num_parameters()会告诉我们 model 的参数量
&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;深度学习模型的参数通常以多个矩阵 (Matrix) 和向量 (Vector) 的形式存储。向量、矩阵等统称为张量(Tensor)&lt;/p&gt;
&lt;p&gt;Llama3 有28层，Gemma4B 有44层&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;model.state_dict() 可以实际把参数拿出来看看
&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="一文看懂大模型推理过程"&gt;一文看懂大模型推理过程
&lt;/h2&gt;&lt;p&gt;内容特别简单，适合感兴趣的小白简单阅读&lt;br&gt;
&lt;a class="link" href="https://zhuanlan.zhihu.com/p/1931115470431454357" target="_blank" rel="noopener"
&gt;https://zhuanlan.zhihu.com/p/1931115470431454357&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="ttfttime-to-first-token"&gt;TTFT（Time To First Token）
&lt;/h3&gt;&lt;p&gt;Tokenizer + Prefill&lt;/p&gt;
&lt;p&gt;一般是推理过程里耗时最多的一步，尤其当输入内容多、模型参数大时&lt;/p&gt;
&lt;h3 id="tpottime-per-output-token"&gt;TPOT（Time Per Output Token）
&lt;/h3&gt;&lt;p&gt;Decoding Loop中的每一次推理&lt;/p&gt;
&lt;p&gt;模型每“说”一个字/词的时间&lt;br&gt;
TPOT 越低，响应越流畅。&lt;br&gt;
但模型越大，TPOT 越高；&lt;br&gt;
GPU 负载越高、token越复杂，TPOT 也会变慢。&lt;/p&gt;
&lt;h3 id="itlinference-time-latency"&gt;ITL（Inference Time Latency）
&lt;/h3&gt;&lt;p&gt;Tokenizer + Prefill + Decoding Loop + Post-processing&lt;/p&gt;
&lt;p&gt;ITL = 从你提问到回答完整输出的总耗时。&lt;/p&gt;
&lt;p&gt;它 = TTFT + n × TPOT&lt;/p&gt;
&lt;h2 id="engram"&gt;Engram
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/1994328242795090231" target="_blank" rel="noopener"
&gt;https://zhuanlan.zhihu.com/p/1994328242795090231&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="微调技术"&gt;微调技术
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/636481171" target="_blank" rel="noopener"
&gt;https://zhuanlan.zhihu.com/p/636481171&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-big-llm-architecture-comparison"&gt;The Big LLM Architecture Comparison
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://magazine.sebastianraschka.com/p/the-big-llm-architecture-comparison" target="_blank" rel="noopener"
&gt;https://magazine.sebastianraschka.com/p/the-big-llm-architecture-comparison&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="understanding-reasoning-llms"&gt;Understanding Reasoning LLMs
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://magazine.sebastianraschka.com/p/understanding-reasoning-llms" target="_blank" rel="noopener"
&gt;https://magazine.sebastianraschka.com/p/understanding-reasoning-llms&lt;/a&gt;&lt;/p&gt;</description></item><item><title>SJTU-research-intern</title><link>https://qingzhou-yanghy.github.io/p/sjtu-research-intern/</link><pubDate>Thu, 23 Oct 2025 10:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/sjtu-research-intern/</guid><description>&lt;img src="https://qingzhou-yanghy.github.io/p/sjtu-research-intern/SJTU.jpg" alt="Featured image of post SJTU-research-intern" /&gt;&lt;h4 id="20251023"&gt;2025/10/23
&lt;/h4&gt;&lt;p&gt;实习第一天&lt;/p&gt;
&lt;h4 id="20251027"&gt;2025/10/27
&lt;/h4&gt;&lt;p&gt;周六凌晨开始跑的论文复现，当时为了图速度就没有顾虑太多。今天学姐问我一些实验过程中的指标变化等等来对比idea的实验是否正常工作，只能回去手动复制tmux里面的内容。&lt;/p&gt;
&lt;p&gt;每跑一次实验都要记得能留日志就留日志，能上wandb/Swanlab就上，跑完的实验数据等等都要保存，留着。后续可能会用到。&lt;/p&gt;
&lt;p&gt;千万不要一味地追求速度，图省事！&lt;/p&gt;
&lt;p&gt;解决了submodule问题，具体的流程为删掉子仓库中的.git，移除本地缓存（觉得他是子module），从.gitmodule中移除（当然我本地没有）。&lt;/p&gt;
&lt;p&gt;解决了关于代码冲突的问题（需要手动进行修改），在git pull中是常见问题，总结关于这种多人协作常出现的问题，注意事项及解决方案&lt;/p&gt;</description></item><item><title>Flash-Attention安装常见问题及其解决方案</title><link>https://qingzhou-yanghy.github.io/p/flash-attention%E5%AE%89%E8%A3%85%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E5%8F%8A%E5%85%B6%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</link><pubDate>Thu, 09 Oct 2025 10:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/flash-attention%E5%AE%89%E8%A3%85%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E5%8F%8A%E5%85%B6%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</guid><description>&lt;h3 id="终端服务器挂代理百分百解决无论是直接安装pip源还是wheel"&gt;终端/服务器挂代理百分百解决,无论是直接安装pip源还是.wheel
&lt;/h3&gt;&lt;h3 id="尝试过的解决方案"&gt;&lt;a class="link" href="https://www.cnblogs.com/coldchair/p/18615384" target="_blank" rel="noopener"
&gt;尝试过的解决方案&lt;/a&gt;👈
&lt;/h3&gt;</description></item><item><title>Ray分布式训练因进程耗尽导致SSH断开连接</title><link>https://qingzhou-yanghy.github.io/p/ray%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83%E5%9B%A0%E8%BF%9B%E7%A8%8B%E8%80%97%E5%B0%BD%E5%AF%BC%E8%87%B4ssh%E6%96%AD%E5%BC%80%E8%BF%9E%E6%8E%A5/</link><pubDate>Thu, 09 Oct 2025 10:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/ray%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83%E5%9B%A0%E8%BF%9B%E7%A8%8B%E8%80%97%E5%B0%BD%E5%AF%BC%E8%87%B4ssh%E6%96%AD%E5%BC%80%E8%BF%9E%E6%8E%A5/</guid><description>&lt;img src="https://qingzhou-yanghy.github.io/p/ray%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83%E5%9B%A0%E8%BF%9B%E7%A8%8B%E8%80%97%E5%B0%BD%E5%AF%BC%E8%87%B4ssh%E6%96%AD%E5%BC%80%E8%BF%9E%E6%8E%A5/Ray.jpg" alt="Featured image of post Ray分布式训练因进程耗尽导致SSH断开连接" /&gt;&lt;h3 id="问题详情--解决方案"&gt;&lt;a class="link" href="https://github.com/ray-project/ray/issues/57556" target="_blank" rel="noopener"
&gt;问题详情 + 解决方案&lt;/a&gt;👈
&lt;/h3&gt;</description></item><item><title>STILL3</title><link>https://qingzhou-yanghy.github.io/p/still3/</link><pubDate>Thu, 02 Oct 2025 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/p/still3/</guid><description>&lt;p&gt;重新认真地读一遍STILL3(LLMs慢思维技术报告III )，补充知识点&lt;/p&gt;
&lt;h1 id="an-empirical-study-on-eliciting-and-improving-r1-like-reasoning-models"&gt;An Empirical Study on Eliciting and Improving R1-like Reasoning Models
&lt;/h1&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/RUCAIBox/Slow_Thinking_with_LLMs" target="_blank" rel="noopener"
&gt;慢思考模型仓库&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;缺乏可验证问题的领域:如DeepSeek-R1,基于规则和训练的奖励模型的联合使用&lt;/p&gt;
&lt;p&gt;随着训练的进行，可以观察到三个主要特征：&lt;strong&gt;增加训练奖励&lt;/strong&gt;、&lt;strong&gt;增加响应长度&lt;/strong&gt;和&lt;strong&gt;涌现推理模式&lt;/strong&gt;。些因素是扩大强化学习训练成功的&lt;strong&gt;关键指标&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在本报告中，首先深入研究了强化学习&lt;strong&gt;设置对训练效果的影响&lt;/strong&gt;。接下来，通过强化学习训练直接激励基础模型发展复杂的推理能力，&lt;strong&gt;观察到模型逐渐花费更多的时间“思考”并表现出高级推理行为（例如，验证或反思）&lt;/strong&gt;。最后，为了进一步增强微调模型的推理能力，探索了&lt;strong&gt;强化学习和工具增强作为提高模型推理性能的策略&lt;/strong&gt;，在小型（1.5B）和中型LLM（32B）中都取得了显著的改进。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;on-policy learning strategy被证明是关键因素！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;response length是RL训练成功的重要指标，这是结果，不是原因&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设计专门的奖励函数来鼓励模型产生更长的响应可能会导致奖励黑客攻击等问题，这不能从本质上增强模型的推理能力&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;无论是短CoT还是长CoT，还是蒸馏过的模型，强化学习都可以提高能力&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过fine-tuning，LRM可以获得操纵外部工具的能力，从而提高模型的性能。这种能力只需少量高质量的训练实例即可激活。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/RUCAIBox/Slow_Thinking_with_LLMs" target="_blank" rel="noopener"
&gt;复现点这里找资源&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="实验设置"&gt;实验设置
&lt;/h1&gt;&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/still3/config.jpg"
width="735"
height="494"
srcset="https://qingzhou-yanghy.github.io/p/still3/config_hu_70515ab103a2c7ca.jpg 480w, https://qingzhou-yanghy.github.io/p/still3/config_hu_ec0a84f70a7f3d4a.jpg 1024w"
loading="lazy"
alt="config"
class="gallery-image"
data-flex-grow="148"
data-flex-basis="357px"
&gt;&lt;/p&gt;
&lt;h2 id="训练框架"&gt;训练框架
&lt;/h2&gt;&lt;p&gt;OpenRLHF和veRL&lt;/p&gt;
&lt;h2 id="骨干模型"&gt;骨干模型
&lt;/h2&gt;&lt;p&gt;各种版本的QWEN2.5模型&lt;/p&gt;
&lt;p&gt;DEEPSEK-R1-DISTILL系列的1.5B和32B QWEN2.5&lt;/p&gt;
&lt;p&gt;在微调模型上进行实验，微调数据由自己合成。&lt;/p&gt;
&lt;h2 id="训练数据"&gt;训练数据
&lt;/h2&gt;&lt;h4 id="多样性"&gt;多样性
&lt;/h4&gt;&lt;p&gt;AIME,MATH,NuminaMath,Open Reasoner Zero&lt;/p&gt;
&lt;h4 id="可验证性"&gt;可验证性
&lt;/h4&gt;&lt;p&gt;删除了多选题，证明题，概念题，开放式问题和有多个子问题的问题&lt;br&gt;
再把答案不可能的数据删掉&lt;/p&gt;
&lt;h4 id="困难程度"&gt;困难程度
&lt;/h4&gt;&lt;p&gt;基于模型的过滤，QWEN-7B-INSTRUCT正确率过高或者零通过率的题目删掉&lt;/p&gt;
&lt;p&gt;最后剩下90k个examples&lt;/p&gt;
&lt;h2 id="reward-design"&gt;Reward Design
&lt;/h2&gt;&lt;p&gt;设计并验证了一组不同的奖励，并分析了它们对模型性能的影响，包括输出奖励、格式奖励、长度奖励和动作奖励。&lt;/p&gt;
&lt;p&gt;输出奖励评估 最终答案是否与ground truth匹配。如果答案正确，我们将奖励设置为1，否则设置为0。&lt;/p&gt;
&lt;p&gt;如果模型未能将其最终答案放入\boxed{}中，则奖励设置为0。&lt;br&gt;
使用格式奖励来指导基础模型正确构建其响应。&lt;/p&gt;
&lt;p&gt;探索了新的辅助奖励，包括鼓励更长反应的长度奖励和激励复杂推理行为的行动奖励。&lt;/p&gt;
&lt;h2 id="evaluation-benchmarks"&gt;Evaluation Benchmarks
&lt;/h2&gt;&lt;p&gt;评估了各种数学推理任务的模型性能，包括MATH-OAI[13]、AIME、Omni-MATH[17]、LiveAOP[18]和HMMT。&lt;br&gt;
iveAOP利用AoPS论坛的帖子创建了一个由3863个示例组成的抗污染评估集。&lt;/p&gt;
&lt;h2 id="compute-environment"&gt;Compute Environment
&lt;/h2&gt;&lt;p&gt;实验主要在DataCanvas的旗舰计算编排平台Alaya NeW AI操作系统上进行。&lt;/p&gt;
&lt;h1 id="rl-experiments-on-the-base-model"&gt;RL Experiments on the Base Model
&lt;/h1&gt;&lt;p&gt;直接将RL应用于预训练的基础模型进行实验，而不需要任何中间的SFT阶段。这种方法旨在探索LLM是否可以通过纯粹的RL驱动的自我提升来自主发展推理能力&lt;/p&gt;
&lt;h4 id="考察了四个关键维度"&gt;考察了四个关键维度
&lt;/h4&gt;&lt;h3 id="1训练超参数的影响"&gt;1.训练超参数的影响
&lt;/h3&gt;&lt;h3 id="2比较不同的基础模型并将其与具有短cot推理能力的微调模型进行对标来分析骨干模型的效果"&gt;2.比较不同的基础模型并将其与具有短CoT推理能力的微调模型进行对标，来分析骨干模型的效果
&lt;/h3&gt;&lt;h3 id="3快速设计对rl训练中基础模型推理能力的影响"&gt;3.快速设计对RL训练中基础模型推理能力的影响
&lt;/h3&gt;&lt;h3 id="4代表性推理模式如验证或反射的出现"&gt;4.代表性推理模式（如验证或反射）的出现
&lt;/h3&gt;&lt;h2 id="exploring-the-settings-of-rl-training"&gt;Exploring the Settings of RL Training
&lt;/h2&gt;&lt;p&gt;重点分析两个关键方面的影响：超参数和训练提示。&lt;/p&gt;
&lt;h3 id="influence-of-training-hyper-parameters"&gt;Influence of Training Hyper-parameters
&lt;/h3&gt;&lt;h4 id="train-batch-sizetbs"&gt;Train Batch Size(TBS)
&lt;/h4&gt;&lt;p&gt;TBS=128 v.s.1024&lt;br&gt;
更大的TBS可以显著提高训练效率，使模型在早期训练阶段能够快速提高性能。此外，与较小批量相比，较大批量的训练表现出更大的稳定性，训练指标的波动显著减少&lt;/p&gt;
&lt;h4 id="learning-strategy-on-policy-vs-off-policy"&gt;Learning Strategy: On-policy vs. Off-policy
&lt;/h4&gt;&lt;p&gt;on-policy 鼓励更多的探索；在训练过程中，模型自然快速地增加了响应长度，而更新较少的非策略学习在长度增长方面遇到了瓶颈&lt;/p&gt;
&lt;h4 id="rollout-parameters"&gt;Rollout Parameters
&lt;/h4&gt;&lt;p&gt;主要研究两个rollout parameters（rollout times和rollout temperature）&lt;br&gt;
更大的推出数量和更高的温度通常表示更大程度的探索&lt;/p&gt;
&lt;h4 id="coefficient-of-kl-penalty"&gt;Coefficient of KL Penalty
&lt;/h4&gt;&lt;p&gt;动态KL退火具有很好的综合性&lt;/p&gt;
&lt;h4 id="effect-of-backbone-models"&gt;Effect of Backbone Models
&lt;/h4&gt;&lt;p&gt;上述实验基于QWEN2.5-7B。此外，还对较小的QWEN2.5-1.5B模型、监督微调QWEN2.5-7B-INSTRUCT模型和数学专用QWEN2.5-math-7B模型进行了实验。&lt;/p&gt;
&lt;p&gt;在上述设置下，我们的实验表明，与QWEN2.5-1.5B相比，QWEN2.5-7B表现出更强的探索能力，并且在强化学习训练中遵循与QWEN2.5.7B-INSTRUCT类似的趋势。&lt;/p&gt;
&lt;h2 id="impact-of-the-prompt"&gt;Impact of the Prompt
&lt;/h2&gt;&lt;p&gt;使用两种基本模型（即QWEN2.5-1.5B和QWEN2.5-7B）和两种类型的提示进行实验&lt;br&gt;
第一种是短提示，类似于DeepSeek-R1-Zero中使用的提示。此外，为了更好地引出基础模型的推理能力，我们设计了一个新的提示，其中包括关于推理过程的详细说明，称为长提示&lt;/p&gt;
&lt;p&gt;这个新提示保留了对特定推理格式的要求，同时添加了对推理过程的全面描述。这包括在推理过程中可以应用的策略（例如，分析问题、总结发现）以及在整个过程中使用的推荐表达和词汇（例如，“等待”、“替代”）&lt;/p&gt;
&lt;p&gt;在本实验中将learning rate、train batch size、rollout temperature和number of rollout times设置为1×10−6、128、1.0和8，并执行on-policy训练策略。我们将KL penalty和entropy loss的系数设置为0.0，有效地消除了模型上的约束。这使得可以更清楚地观察到各种提示导致的性能差异&lt;/p&gt;
&lt;h3 id="实验结果"&gt;实验结果
&lt;/h3&gt;&lt;p&gt;对于QWEN2.5-1.5B，在短提示下训练的模型在测试集上的性能高于在长提示上训练的模型。这可能是因为1.5B大小的基本模型容量相对有限，难以遵循详细提示中的复杂说明。&lt;/p&gt;
&lt;p&gt;当在不同的提示下训练时，7B大小的模型在下游任务上显示出类似的性能。然而，在长提示上训练的模型会产生更短的响应，这表明它通过遵守提示中提供的指导方针来学习更有效的推理&lt;/p&gt;
&lt;p&gt;因此，我们得出结论，更详细的提示可以引导模型更有效地思考，提高推理效率。然而，它们不一定能提高下游任务的性能。&lt;/p&gt;</description></item><item><title>LRM-RL-survey</title><link>https://qingzhou-yanghy.github.io/p/lrm-rl-survey/</link><pubDate>Wed, 24 Sep 2025 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/p/lrm-rl-survey/</guid><description>&lt;img src="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/sky.jpg" alt="Featured image of post LRM-RL-survey" /&gt;&lt;h1 id="a-survey-of-reinforcement-learning-for-large-reasoning-models"&gt;A Survey of Reinforcement Learning for Large Reasoning Models
&lt;/h1&gt;&lt;h2 id="background"&gt;Background
&lt;/h2&gt;&lt;p&gt;RL在推进LLM能力的前沿方面取得了显著成功，特别是在解决数学和编码等复杂逻辑任务方面。因此，RL已成为将LLM转化为LRM的基础方法。&lt;/p&gt;
&lt;p&gt;需要探索提高强化学习向人工超级智能（ASI）的可扩展性的策略。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/history.jpg"
width="1313"
height="621"
srcset="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/history_hu_fd91b4e2f759ffa.jpg 480w, https://qingzhou-yanghy.github.io/p/lrm-rl-survey/history_hu_493c3c9057a75b6c.jpg 1024w"
loading="lazy"
alt="这两年的发展"
class="gallery-image"
data-flex-grow="211"
data-flex-basis="507px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/overview.jpg"
width="1304"
height="615"
srcset="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/overview_hu_5f42649c3469429c.jpg 480w, https://qingzhou-yanghy.github.io/p/lrm-rl-survey/overview_hu_9c488682e473c029.jpg 1024w"
loading="lazy"
alt="具体包含的模块"
class="gallery-image"
data-flex-grow="212"
data-flex-basis="508px"
&gt;&lt;/p&gt;
&lt;p&gt;回顾一下大致流程吧！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/agentProgress.jpg"
width="762"
height="339"
srcset="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/agentProgress_hu_4d7c597a2ebaeebd.jpg 480w, https://qingzhou-yanghy.github.io/p/lrm-rl-survey/agentProgress_hu_b9f415b03c60b5a9.jpg 1024w"
loading="lazy"
alt="agentProgress"
class="gallery-image"
data-flex-grow="224"
data-flex-basis="539px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/LMProgress.jpg"
width="479"
height="394"
srcset="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/LMProgress_hu_1f5e4f08ac92e4f2.jpg 480w, https://qingzhou-yanghy.github.io/p/lrm-rl-survey/LMProgress_hu_7cd98ff41913c5e4.jpg 1024w"
loading="lazy"
alt="LMProgress"
class="gallery-image"
data-flex-grow="121"
data-flex-basis="291px"
&gt;&lt;/p&gt;
&lt;h2 id="简单讲解一下rl应用到语言模型的时候这些概念映射到了哪里"&gt;简单讲解一下RL应用到语言模型的时候，这些概念映射到了哪里
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Prompt/Task（x）：对应于初始状态或环境上下文，从数据分布中提取，对应于数据集D。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Policy (πθ):表示语言模型，它根据提示生成一个长度为T的序列，表示为y=（y1，…，yT）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;State (st):定义为提示以及到目前为止生成的令牌，即st=（x，a1:t−1）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Action (at):在步骤t从动作空间A中选择的单元。根据粒度，动作可以是整个序列y（序列级）、∈V处的令牌（令牌级）或 片段&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transition Dynamics (P):在LLM的上下文中，状态转换通常是确定的，因为st+1=[st，at]，其中[·，·]表示字符串连接。当状态包含EOS令牌时，策略将转换为终端状态，这意味着轨迹结束。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reward (R(x, y) or rt):基于动作粒度进行分配，例如，轨迹末端的序列级别R（x，y），每个令牌的令牌级别rt=R（x、a1:t），或每个分段的步长级别rk=R（x、y（1:k））。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Return (G):提示x的整个轨迹y的累积奖励（通常在有限时间内γ=1）。它通过序列级奖励简化为单个标量R（x，y），否则按每个令牌/步骤聚合奖励&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="frontier-models"&gt;Frontier Models
&lt;/h2&gt;&lt;p&gt;按时间顺序排列在三个主要方向上：LRM、agentic LRMs和多模态LRM。&lt;br&gt;
一个大型推理模型，OpenAI的o1[2024]系列，建立了将训练时间RL和测试时间计算扩展到更强大的推理能力的有效性，在数学、编码和科学基准测试方面取得了领先成果。&lt;br&gt;
DeepSeek的旗舰模型R1[2025a]是第一个在基准测试中与o1性能相匹配的开源模型。它采用多阶段训练管道来确保全面的模型能力，并探索了没有监督微调的纯RL路线（即Zero RL）。&lt;br&gt;
其他专有模型发布紧随其后：Claude-3.7-Sonnet[2025a]以混合推理为特色，Gemini 2.0和2.5[2025]引入了更长的上下文长度，Seed Thinking 1.5[2025b]以跨领域的泛化为特色，o3[2025a]系列展示了越来越先进的推理能力。最近，OpenAI推出了他们的第一个开源推理模型gpt-oss-120b[2025a]，随后推出了GPT5[2025a]，这是他们迄今为止最强大的人工智能系统，可以在高效模型和更深入的推理模型gpt-5思维之间灵活切换。并行的开源努力继续扩大了格局。在Qwen家族中，QwQ-32B[2025g]与R1的表现相匹配，其次是Qwen3[2025a]系列，代表性型号Qwen3-235B进一步提高了基准分数。Skywork-OR1[2025d]模型套件基于R1蒸馏模型，并通过有效的数据混合和算法创新实现了可扩展的RL训练。Minimax-M1[2025a]是第一个有效地将混合注意力引入尺度RL的模型。其他作品包括Llama Nemotron Ultra[2025]，旨在平衡准确性和效率；Magistral 24B[2025]，通过RL从头开始训练，而不是从先前的模型中提炼；以及种子OSS[2025a]，强调长上下文推理能力。等等&amp;hellip;&lt;/p&gt;
&lt;p&gt;过去的一年发展迅速啊！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/models.jpg"
width="1297"
height="677"
srcset="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/models_hu_8b9f390b6a5af111.jpg 480w, https://qingzhou-yanghy.github.io/p/lrm-rl-survey/models_hu_2544bbbdc362202a.jpg 1024w"
loading="lazy"
alt="models"
class="gallery-image"
data-flex-grow="191"
data-flex-basis="459px"
&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="foundational-components"&gt;Foundational Components
&lt;/h2&gt;&lt;h3 id="reward-design"&gt;Reward Design
&lt;/h3&gt;&lt;p&gt;在1.1中，我们对LRM RL中的奖励设计进行了全面的考察。从可验证的奖励开始，DeepSeek-R1的成功就是例证，它通过可验证的奖励机制证明了RL的可扩展性。&lt;/p&gt;
&lt;p&gt;在1.2中，我们考察生成性奖励，其中模型用于验证或直接生成奖励信号。&lt;/p&gt;
&lt;p&gt;然而，可验证和生成性奖励通常都表示为稀疏的数值反馈。一个重要的互补维度在于奖励信号的密度。&lt;/p&gt;
&lt;p&gt;1.3相应地考察了包含密集奖励的方法。另一个分类轴涉及奖励是根据外部真实情况计算的，还是由模型直接估计的。&lt;/p&gt;
&lt;p&gt;这一区别促使我们在1.4中讨论无监督奖励。&lt;/p&gt;
&lt;p&gt;在这四个类别的基础上，我们在1.5中转向奖励塑造，在那里我们分析了组合或转换不同奖励信号以促进学习的策略。&lt;/p&gt;
&lt;h3 id="verifiable-rewards"&gt;Verifiable Rewards
&lt;/h3&gt;&lt;p&gt;基于规则的奖励通过利用准确性和格式检查，为RL提供可扩展和可靠的训练信号，特别是在数学和代码任务中。&lt;/p&gt;
&lt;p&gt;Verifier定律强调，具有清晰和自动验证的任务可以实现高效的RL优化，而主观任务仍然具有挑战性。&lt;/p&gt;
&lt;h3 id="rule-based-rewards"&gt;Rule-based Rewards
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Accuracy rewards:对于具有确定性结果的任务（例如数学），策略必须在规定的分隔符（通常为\boxed{…}）内产生最终解决方案。然后，自动检查器将此输出与地面实况进行比较。对于编码任务，单元测试或编译器提供通过/失败信号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Format rewards:这些奖励施加了一个结构约束，要求模型将其私有思想链放置在&lt;think&gt;和&lt;/inthink&gt;之间，并在单独的字段中输出最终答案（例如&lt;answer&gt;…&lt;/answer&gt;）。这提高了大规模RL中的可靠解析和验证&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rule-based-verifier"&gt;Rule-based Verifier
&lt;/h3&gt;&lt;p&gt;基于规则的奖励通常来自基于规则的验证器。这些依赖于大量手动编写的等价规则来确定预测的答案是否与基本事实相匹配。目前，广泛使用的数学验证器主要基于Python库Math-Verify1和SymPy2构建。此外，一些作品，如DAPO[2025d]和DeepScaleR[2025c]，也提供了开源和成熟的验证器。最近，Huang等人[2025e]强调了与基于规则和基于模型的验证器相关的独特局限性，为设计更可靠的奖励系统提供了信息。&lt;/p&gt;
&lt;h4 id="训练人工智能系统执行任务的难易程度与任务的可验证程度成正比"&gt;训练人工智能系统执行任务的难易程度与任务的可验证程度成正比
&lt;/h4&gt;&lt;h3 id="generative-rewards"&gt;Generative Rewards
&lt;/h3&gt;&lt;h4 id="这里着重说明-generative-rewards-for-non-verifiable-tasks"&gt;这里着重说明 Generative Rewards for Non-Verifiable Tasks
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Reasoning Reward Models (Learning to Think)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rubric-based Rewards (Structuring Subjectivity)：强调细粒度奖励&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Co-Evolving Systems (Unifying Policy and Reward):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Self-Rewarding：自我奖励，一个模型既充当policy model，也充当reward model&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Co-Optimization：policy和reward模型共同训练&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dense-rewards"&gt;Dense Rewards
&lt;/h3&gt;&lt;p&gt;dense rewards 和 verifiers对于open-domain还是太难了&lt;/p&gt;
&lt;p&gt;Scaling remains challenging for tasks like open-domain text generation due to the difficulty of defining dense rewards or using verifiers.&lt;/p&gt;
&lt;p&gt;Granularity细粒度分为：Trajectory（整个序列），Token，Step，Turn（Agent）&lt;br&gt;
这几个信号可以相互转换，比如把globa returns 转换成 localized signals，奖励的重新分配&lt;br&gt;
可以理解为从每次交互中直接分配和从结果中分解得出的回合级别奖励&lt;/p&gt;
&lt;h3 id="unsupervised-rewards"&gt;Unsupervised Rewards
&lt;/h3&gt;&lt;p&gt;cluster：聚类（也有集群的意思）&lt;/p&gt;
&lt;p&gt;majority vote：多数投票&lt;/p&gt;
&lt;p&gt;Heuristic Rewards（启发式奖励）：这种方法构成了另一种基于规则的奖励形式，采用基于输出属性（如长度或格式）的简单预定义规则作为质量的代理。由DeepSeek-R1开创。不会提高模型真正能力？（质疑）&lt;/p&gt;
&lt;h3 id="rewards-shaping"&gt;Rewards Shaping
&lt;/h3&gt;&lt;p&gt;Rewards Shaping将稀疏信号丰富为稳定的、信息丰富的梯度，用于LLM训练&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Rule-based Reward Shaping&lt;br&gt;
最简单的：把rule-based verifier和reward model组合起来生成overall reward signal。通常有一个constant coefficient平衡the contributions of the reward model and the rule-based component，不是所有正确的responses都是同样的scores，这样可以把所有的responses重新排序，避免无效的学习梯度&lt;/p&gt;
&lt;p&gt;这种启发式组合策略在开放域任务中得到了广泛的应用，提供了更多的信息和有效的奖励信号。&lt;/p&gt;
&lt;p&gt;另一种方法是DeepSeek-R1中实现结果级奖励和格式奖励，能让LLM学习长思维链推理，用于解决LLM输出中的各种异常。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Structure-based Reward Shaping
Pass@k在推导和分析优势和有效近似值时，将集合级目标分解回单个样本信用分配。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="policy-optimization"&gt;Policy Optimization
&lt;/h3&gt;&lt;p&gt;最近的研究把on-policy RL和offline datasets结合在一起来进行optimization同时使用各种regularization techniques（正则化技术）比如entropy和KL防止overfitting&lt;/p&gt;
&lt;h4 id="environmentthe-context-in-rl-for-llms"&gt;environment:the context in RL for LLMs
&lt;/h4&gt;&lt;h4 id="policythe-distribution-of-the-next-level-prediction"&gt;policy:the distribution of the next-level prediction
&lt;/h4&gt;&lt;h4 id="由于llm中的大量参数llm的rl策略优化算法大多是基于一阶梯度的算法"&gt;由于LLM中的大量参数，LLM的RL策略优化算法大多是基于一阶梯度的算法
&lt;/h4&gt;&lt;h3 id="notations符号"&gt;Notations（符号）
&lt;/h3&gt;&lt;h4 id="当前状态s的预期积累奖励表示为vvalue函数"&gt;当前状态s的预期积累奖励表示为V（value）函数
&lt;/h4&gt;&lt;h4 id="当前状态动作对应的预期积累表示为qquality函数"&gt;当前状态动作对应的预期积累表示为Q（quality）函数
&lt;/h4&gt;&lt;h4 id="优势函数as-a--qs-a--v-s该优势衡量的是与现有政策相比当前行动在预期总回报方面有多大改进"&gt;优势函数：A(s, a) = Q(s, a) − V (s).该优势衡量的是与现有政策相比，当前行动在预期总回报方面有多大改进。
&lt;/h4&gt;&lt;h3 id="优化算法的历程"&gt;优化算法的历程
&lt;/h3&gt;&lt;p&gt;PPO算法[Schulman等人，2017b]首次被提出作为TRPO算法[Schurman等人，2015a]的计算高效近似。&lt;br&gt;
&lt;img src="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/algorithm.jpg"
width="1161"
height="795"
srcset="https://qingzhou-yanghy.github.io/p/lrm-rl-survey/algorithm_hu_ab70d2da1d0a05a6.jpg 480w, https://qingzhou-yanghy.github.io/p/lrm-rl-survey/algorithm_hu_bddcdd47c9c7c11e.jpg 1024w"
loading="lazy"
alt="algorithm"
class="gallery-image"
data-flex-grow="146"
data-flex-basis="350px"
&gt;&lt;/p&gt;
&lt;h3 id="critic-based-algorithms"&gt;Critic-based Algorithms
&lt;/h3&gt;&lt;p&gt;critic需要和LLM一起run和update，这样会导致巨大的计算开销，而且对于复杂的任务来说，扩展性不好&lt;/p&gt;
&lt;h3 id="critic-free-algorithms"&gt;Critic-Free Algorithms
&lt;/h3&gt;&lt;p&gt;只需要sequence-level rewards for training&lt;/p&gt;
&lt;p&gt;对于RLVR任务可以防止reward hacking等问题，这使得Critic-Free Algorithms更具有可扩展性&lt;/p&gt;
&lt;p&gt;最近的研究表明response-level足以用于RL的可扩展推理任务&lt;/p&gt;
&lt;p&gt;最受欢迎的critic-free approach是GRPO，新推出的GSPO[Zheng等人，2025a]，用序列级剪切代替了逐符号剪切的重要性采样率&lt;/p&gt;
&lt;p&gt;SPO引入了一种无组、单流策略优化，用持久的KL自适应值跟踪器和全局优势归一化来替换每组基线，从而产生比GRPO更平滑的收敛和更高的精度&lt;/p&gt;
&lt;h4 id="importance-sampling-for-policy-optimization"&gt;Importance Sampling for Policy Optimization
&lt;/h4&gt;&lt;p&gt;TRPO引入了RL中重要性抽样的第一个版本，其中在目标中引入了令牌式重要性比wi，t&lt;br&gt;
这种方法在最近的工作中被广泛采用，如GRPO。由于无法在CoT的长上下文中有效计算实际分布比率，因此这种方法仅限于token-level重要性比率&lt;/p&gt;
&lt;p&gt;token-level重要性采样在RL算法中引入了另一种偏差，因为实际采样分布给定的策略是针对状态-动作对定义的，而token-level方法只考虑当前动作。GMPO[赵等人，2025f]通过引入几何平均来寻求缓解，以提高具有极端重要性采样率的token的训练鲁棒性&lt;/p&gt;
&lt;p&gt;在GSPO的最新工作中[Zheng等人，2025a]，计算了序列级重要性抽样因子。GSPO添加了一个唯一的归一化因子，以确保可以计算概率比，但这种方法也是对实际重要性抽样因子的有偏估计&lt;/p&gt;
&lt;h3 id="off-policy-optimization"&gt;Off-policy Optimization
&lt;/h3&gt;&lt;p&gt;Off-policy RL通过把data collection 和 policy learning解耦，实现了从历史、异步或离线数据集进行训练，从而提高了样本效率&lt;/p&gt;
&lt;p&gt;选择性地replay 早期的推理traces可以提高exploration for LLM reasoning&lt;/p&gt;
&lt;p&gt;现在很多都在对数据进行处理来提升exploration&lt;/p&gt;
&lt;h3 id="regularization-objectives"&gt;Regularization Objectives
&lt;/h3&gt;&lt;p&gt;Objective-specific regularization helps balance explration and exploitation,boosting RL effiency and policy performance.&lt;/p&gt;
&lt;p&gt;KL,entropy and length regularization remain open questions,each affects policy optimization and scalability&lt;/p&gt;
&lt;p&gt;Length Penalty建议应用基于问题难度的自适应长度惩罚来保持模型的能力&lt;/p&gt;
&lt;h3 id="sampling-hyper-parameters"&gt;Sampling Hyper-parameters
&lt;/h3&gt;&lt;h4 id="exploration-and-exploitation-dynamics"&gt;Exploration and Exploitation Dynamics
&lt;/h4&gt;&lt;p&gt;一些工作提出了一种动态方法，例如分阶段提高温度(e.g., 1.40 → 1.45 → 1.50 for a 4B model, 0.7 → 1.0 → 1.1 for a 7B model)&lt;/p&gt;
&lt;p&gt;entropy 在0.3被发现是最佳平衡&lt;/p&gt;
&lt;p&gt;其他的工作只是倡导提高一个固定的温度（例如1.0或1.2）来鼓励初步探索，同时指出它本身不足以防止长期的熵下降&lt;/p&gt;
&lt;h4 id="length-budgeting-and-sequence-management"&gt;Length Budgeting and Sequence Management
&lt;/h4&gt;&lt;p&gt;几乎所有的work都在努力管理生成响应的长度，以平衡性能和成本。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This involves starting RL with a short context window (e.g., 8k) before progressively increasing it to 16k, 24k, or 32k in later stages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;初始的短上下文阶段被认为是必不可少的，因为它迫使模型学习更简洁、更具令牌效率的推理模式&lt;/p&gt;
&lt;h2 id="foundational-problems"&gt;Foundational Problems
&lt;/h2&gt;&lt;h3 id="rls-role-sharpening-or-discovery"&gt;RL’s Role: Sharpening or Discovery
&lt;/h3&gt;&lt;h3 id="rl-vs-sft-generalize-or-memorize"&gt;RL vs. SFT: Generalize or Memorize
&lt;/h3&gt;&lt;p&gt;发现RL擅长巩固和增强现有能力，而SFT在引入新知识或新模型能力方面更有效&lt;/p&gt;
&lt;h3 id="model-prior-weak-and-strong"&gt;Model Prior: Weak and Strong
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;R1-Zero：直接将大规模基于规则的RL应用于基本模型，产生新兴的长期推理&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;R1：包含冷启动&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基础模型先验比指导模型更适合强化学习，通常会产生比从高度一致的指导模型开始时观察到的更平滑的改进轨迹，其中根深蒂固的格式和服从先验可能会干扰奖励的形成&lt;/p&gt;
&lt;h4 id="model-family-differences"&gt;Model Family Differences
&lt;/h4&gt;&lt;h3 id="reward-type-process-or-outcome"&gt;Reward Type: Process or Outcome
&lt;/h3&gt;&lt;h2 id="training-resources"&gt;Training Resources
&lt;/h2&gt;&lt;h3 id="static-corpus"&gt;Static Corpus
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Math&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Code&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;STEM&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Agent&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mixture&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rl-infrastructure--framework"&gt;RL Infrastructure &amp;amp; Framework
&lt;/h3&gt;&lt;p&gt;e.g.OpenRLHF/veRL/AReaL/slime/TRL&lt;/p&gt;
&lt;h3 id="dynamic-environment"&gt;Dynamic Environment
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Rule&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Code&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Game&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Model&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensemble&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="applications"&gt;Applications
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1.Agentic Tasks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2.Coding Tasks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.Multimodal Tasks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.Robotics Tasks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;5.Multi-Agent Systems&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;6.Medical Tasks&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;</description></item><item><title>Pass@k论文复现</title><link>https://qingzhou-yanghy.github.io/p/pass@k%E8%AE%BA%E6%96%87%E5%A4%8D%E7%8E%B0/</link><pubDate>Sun, 21 Sep 2025 16:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/pass@k%E8%AE%BA%E6%96%87%E5%A4%8D%E7%8E%B0/</guid><description>&lt;img src="https://qingzhou-yanghy.github.io/p/pass@k%E8%AE%BA%E6%96%87%E5%A4%8D%E7%8E%B0/ByteDance.jpg" alt="Featured image of post Pass@k论文复现" /&gt;&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/pass@k%E8%AE%BA%E6%96%87%E5%A4%8D%E7%8E%B0/Seed.jpg"
width="400"
height="400"
srcset="https://qingzhou-yanghy.github.io/p/pass@k%E8%AE%BA%E6%96%87%E5%A4%8D%E7%8E%B0/Seed_hu_2d5c39b72441c640.jpg 480w, https://qingzhou-yanghy.github.io/p/pass@k%E8%AE%BA%E6%96%87%E5%A4%8D%E7%8E%B0/Seed_hu_e08f665f0403ee6b.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="100"
data-flex-basis="240px"
&gt;&lt;/p&gt;
&lt;h1 id="passk-training-for-adptively-balancing-eplortion-and-exploitation-of-lrms"&gt;Pass@k Training for Adptively Balancing Eplortion and Exploitation of LRMs
&lt;/h1&gt;&lt;h2 id="passk论文解读"&gt;Pass@k论文解读
&lt;/h2&gt;&lt;p&gt;policy探索能力的指标：the natural prevention of the decrease in the entropy of policy distribution&lt;/p&gt;
&lt;p&gt;Pass@1和Pass@k之间的主要区别在于奖励计算和优势估计过程。&lt;/p&gt;
&lt;p&gt;vanilla：原来的&lt;br&gt;
Ground Truth是正确答案（标准答案）&lt;/p&gt;
&lt;h4 id="探索能力"&gt;探索能力:
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;the entropy of policy distribution处在一个较高的水平&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the answer diversity of the negative response处在一个较高的水平&lt;br&gt;
Pass@k的entropy在RLVR procedure的200step左右开始上升&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="k值影响passk训练"&gt;k值影响Pass@k训练
&lt;/h3&gt;&lt;p&gt;实验中从4，8，16中调整k值&lt;/p&gt;
&lt;p&gt;无论k的值是多少，随着训练的进行，训练奖励都可以提高到相对较高的水平，这表明k的值不是帮助LLMs逃脱局部最优解的关键性因素&lt;/p&gt;
&lt;h4 id="k值越大训练效率越慢k值越大优势值越小导致优化步骤越短训练效率越低"&gt;k值越大，训练效率越慢（k值越大，优势值越小，导致优化步骤越短，训练效率越低）
&lt;/h4&gt;&lt;h3 id="训练效率的影响因素"&gt;训练效率的影响因素
&lt;/h3&gt;&lt;p&gt;实验在N = 32 和 k = 8的设置下使用{1 x 10-6,2 x 10-6,4 x 10-6}learning rate&lt;/p&gt;
&lt;h4 id="随着学习率的提高拐点出现得更早表明训练效率更高"&gt;随着学习率的提高，拐点出现得更早，表明训练效率更高
&lt;/h4&gt;&lt;h4 id="最大优势值不是帮助模型表现优异的关键性因素"&gt;最大优势值不是帮助模型表现优异的关键性因素
&lt;/h4&gt;&lt;h4 id="为更难的问题分配更大的优化强度可以有效地提高训练效率"&gt;为更难的问题分配更大的优化强度可以有效地提高训练效率
&lt;/h4&gt;&lt;p&gt;根据the entropy of policy distribution的高低，区分high-exploration和low-exploration。&lt;/p&gt;
&lt;p&gt;high-exploration使用Pass@1 advantage fuction来exploit prior exploration，low-exploration使用Pass@k advantage function来encourage further exploration。&lt;/p&gt;
&lt;h4 id="implicit-reward-design隐式奖励设计可以控制优化过程"&gt;Implicit reward design（隐式奖励设计）可以控制优化过程
&lt;/h4&gt;&lt;p&gt;具体地说，结合或动态调整不同形式的优势估计，可以同时提高exploration and exploitation能力&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="passk论文复现"&gt;Pass@k论文复现
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://arxiv.org/abs/2508.10751" target="_blank" rel="noopener"
&gt;arxiv文章&lt;/a&gt;👈&lt;br&gt;
&lt;a class="link" href="https://github.com/RUCAIBox/Passk_Training" target="_blank" rel="noopener"
&gt;github仓库&lt;/a&gt;👈&lt;br&gt;
&lt;a class="link" href="https://huggingface.co/datasets/RUC-AIBOX/Passk_Training_Maze" target="_blank" rel="noopener"
&gt;Datasets&lt;/a&gt;👈&lt;/p&gt;
&lt;h3 id="maze"&gt;Maze
&lt;/h3&gt;&lt;p&gt;每个迷宫由文本表示，包含n行和n列，总共n∗n个字符&lt;/p&gt;
&lt;p&gt;四个字符“S”、“E”、“.”和“*”中的一个，分别表示起点、目的地、可用地点和不可用地点&lt;/p&gt;
&lt;p&gt;给定迷宫，LLM可以首先生成思维或推理过程，然后生成最终答案，其中包括四个动作“U”、“D”、“L”和“R”中的一个，分别表示向上、向下、向左和向右移动&lt;/p&gt;
&lt;p&gt;对于训练数据，我们构建了大小为9×9、11×11、13×13和15×15的迷宫，以增加训练数据的多样性&lt;/p&gt;
&lt;p&gt;对于测试数据，为了评估RLVR过程的泛化能力，我们不仅使用训练数据集进行相同大小的迷宫，还收集了大小为7×7、17×17、19×19和21×21的迷宫&lt;/p&gt;
&lt;p&gt;为了确保实验的有效性，我们在生成训练和测试数据后进行了严格的重复数据删除操作&lt;/p&gt;
&lt;p&gt;Training Set 都是10,000;Test Set除了7 * 7,剩下的都是100&lt;/p&gt;
&lt;h3 id="implementation-details"&gt;Implementation Details
&lt;/h3&gt;&lt;h4 id="training"&gt;Training
&lt;/h4&gt;&lt;p&gt;backbone model:Qwen2.5-7B-Instruct和Qwen2.5-32B Instruct&lt;/p&gt;
&lt;p&gt;DAPO&lt;/p&gt;
&lt;p&gt;εlow=0.2和εhigh=0.28&lt;/p&gt;
&lt;p&gt;token-level policy gradient loss&lt;/p&gt;
&lt;p&gt;remove other optimizations&lt;/p&gt;
&lt;p&gt;learning rate:1 × 10−6&lt;/p&gt;
&lt;p&gt;warmup:10&lt;/p&gt;
&lt;p&gt;prompt batch size(BS prompt):128&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prompt Batch Size：是模型推理生成的粒度。它决定在一次性并行处理多少个独立的提示词（例如，多少个用户问题），并同时为它们生成文本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;mini-batch size(BS mini):32&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mini-batch Size：是模型权重更新的粒度。它决定在计算一次梯度下降时，使用多少条训练数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;rollout times:32&lt;/p&gt;
&lt;p&gt;positive reward Rpos = 1&lt;/p&gt;
&lt;p&gt;negative reward Rneg = 0&lt;/p&gt;
&lt;p&gt;do not employ any regularization methods, such as KL or Entropy regularization&lt;br&gt;
temperature:1.0&lt;/p&gt;
&lt;p&gt;Top_P:0.95&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从概率最高的词开始累加它们的概率，直到累积概率达到或刚刚超过你设定的 top_p 值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For each question,we sample 32responses for Maze task and sample 8 responses for other tasks&lt;/p&gt;
&lt;h3 id="versionsdependencies"&gt;Versions/Dependencies
&lt;/h3&gt;&lt;p&gt;Python 3.10.18&lt;br&gt;
Ray 2.49.1&lt;br&gt;
grpcio 1.75.0&lt;br&gt;
Ubuntu 24.04.2 LTS&lt;/p&gt;
&lt;h3 id="如何从huggingface上下载数据集和模型"&gt;如何从huggingface上下载数据集和模型
&lt;/h3&gt;&lt;p&gt;从huggingface上下载文件有2种方式，一种是直接登录后在网页上下载；一种是通过huggingface-cli命令下载。&lt;/p&gt;
&lt;p&gt;本文介绍的是第二种下载方式。&lt;/p&gt;
&lt;h3 id="安装"&gt;安装
&lt;/h3&gt;&lt;p&gt;对于huggingface-cli命令的下载直接通过pip命令安装即可：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pip install -U huggingface_hub[hub_transfer]&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;对于国内用户还可以通过设置镜像网站的方式加速下载：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;#linux
export HF_ENDPOINT=https://hf-mirror.com&lt;br&gt;
#windows&lt;br&gt;
set HF_ENDPOINT=https://hf-mirror.com&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;使用命令行下载&lt;/p&gt;
&lt;h4 id="模型"&gt;模型
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;huggingface-cli download &amp;ndash;resume-download [1] &amp;ndash;local-dir [2] &amp;ndash;local-dir-use-symlinks False&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id="数据集"&gt;数据集
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;huggingface-cli download &amp;ndash;repo-type dataset &amp;ndash;resume-download [3] &amp;ndash;local-dir [4] &amp;ndash;local-dir-use-symlinks False &amp;ndash;token hf_***&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;格式为：[1]和[3]表示项目的路径，格式为用户名/项目，比如mistralai/Mistral-7B-Instruct-v0.2表示的是mistralai下的7B instruct v0.2权重。[2]和[4]表示的是本地的保存地址。&lt;/p&gt;
&lt;p&gt;需要的注意的是有些仓库需要登录才可以下载，形如–token hf_***为huggingface的token配置。token的生成需要在huggingface个人页面生成.&lt;/p&gt;</description></item><item><title>ray.init()初始化挂起/失败问题的解决</title><link>https://qingzhou-yanghy.github.io/p/ray.init%E5%88%9D%E5%A7%8B%E5%8C%96%E6%8C%82%E8%B5%B7/%E5%A4%B1%E8%B4%A5%E9%97%AE%E9%A2%98%E7%9A%84%E8%A7%A3%E5%86%B3/</link><pubDate>Sat, 20 Sep 2025 10:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/ray.init%E5%88%9D%E5%A7%8B%E5%8C%96%E6%8C%82%E8%B5%B7/%E5%A4%B1%E8%B4%A5%E9%97%AE%E9%A2%98%E7%9A%84%E8%A7%A3%E5%86%B3/</guid><description>&lt;img src="https://qingzhou-yanghy.github.io/p/ray.init%E5%88%9D%E5%A7%8B%E5%8C%96%E6%8C%82%E8%B5%B7/%E5%A4%B1%E8%B4%A5%E9%97%AE%E9%A2%98%E7%9A%84%E8%A7%A3%E5%86%B3/Ray.jpg" alt="Featured image of post ray.init()初始化挂起/失败问题的解决" /&gt;&lt;h2 id="abstract"&gt;Abstract
&lt;/h2&gt;&lt;p&gt;此文章发布约一周前就已经发现该问题了，但是由于专注看官方文档和仓库进行规范 + 课内事情，一直没有得到解决。&lt;/p&gt;
&lt;p&gt;在发文前一天发现此问题需要重点解决（无法避免），询问了师兄（论文作者）并咨询了相关团队，未果，所以花了两整天才解决这一个bug。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="issue"&gt;Issue
&lt;/h2&gt;&lt;h3 id="what-happened--what-you-expected-to-happen"&gt;What happened + What you expected to happen
&lt;/h3&gt;&lt;p&gt;Running the following snippet will hang indefinitely&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;/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;gt;&amp;gt;&amp;gt; import ray
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt;&amp;gt;&amp;gt; ray.init()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2025-09-20 11:44:47,741 INFO worker.py:1538 -- Started a local Ray instance.
&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;Sometimes it will fail instead&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;[2025-09-20 11:50:22,050 E 31652 31652] core_worker.cc:179: Failed to register worker 01000000ffffffffffffffffffffffffffffffffffffffffffffffff to Raylet. IOError: [RayletClient] Unable to register worker with raylet. No such file or directory
&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;h3 id="versionsdependencies"&gt;Versions/Dependencies
&lt;/h3&gt;&lt;p&gt;Python 3.10.18&lt;br&gt;
Ray 2.49.1&lt;br&gt;
grpcio 1.75.0&lt;br&gt;
Ubuntu 24.04.2 LTS&lt;/p&gt;
&lt;h3 id="reproduction-script"&gt;Reproduction script
&lt;/h3&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;/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;import ray
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ray.init()
&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;h3 id="issue-severity"&gt;Issue Severity
&lt;/h3&gt;&lt;p&gt;High: It blocks me from completing my task.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;上面全英是因为当时要提issue或者给Ray框架作者发邮件，但是后来解决了，就打算留下来了，这样后来的人可以模仿一下这个写法。&lt;/p&gt;
&lt;h2 id="可能的问题"&gt;可能的问题
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;1.workers实际上并没有启动。（可以看一下&lt;code&gt;/tmp/ray/session_latest/raylet.out&lt;/code&gt;,如果在&lt;code&gt;/tmp/ray/session_latest/&lt;/code&gt;看到有前缀&lt;code&gt;python-core-worker-&lt;/code&gt; 的可以看一下，因为这个能了解工作进程可能发生了什么）&lt;/li&gt;
&lt;li&gt;2.系统中进程数/线程数设置错误（可以通过cat /proc/sys/kernel/threads-max查看系统中一个进程可以创建多少个线程）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="可能的方法"&gt;可能的方法
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;1.在&lt;code&gt;import ray&lt;/code&gt;之后加上&lt;code&gt;ray.init(num_cpus=56, num_gpus=2)&lt;/code&gt;。具体参数需要根据服务器进行自定义。
作者根据这个方法对自己进行了适配解决了问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="具体操作yhyverltrainerconfigppo_traineryaml配置文件中对num_cpus0修改成num_cpus10-num_gpus1进行定义"&gt;具体操作：&lt;code&gt;/yhy/verl/trainer/config/ppo_trainer.yaml&lt;/code&gt;配置文件中对&lt;code&gt;num_cpus=0&lt;/code&gt;修改成&lt;code&gt;num_cpus=10&lt;/code&gt;, &lt;code&gt;num_gpus=1&lt;/code&gt;进行定义。
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;2.升级&lt;code&gt;grpcio&lt;/code&gt;,2023年的时候安装&lt;code&gt;grpcio 1.48.1&lt;/code&gt; 版本是有用的,相应的&lt;code&gt;venv&lt;/code&gt;是 &lt;code&gt;CentOS 7,Python 3.7.11，Ray 2.5.1,grpcio1.48.1&lt;/code&gt;。&lt;br&gt;
但我进行升级的时候，无法解决该问题，并且会导致包之间的冲突。（是一个opencv的包，已经&lt;code&gt;pip install&lt;/code&gt;了）&lt;/li&gt;
&lt;li&gt;3.添加&lt;code&gt;ulimit -n 65536&lt;/code&gt;语句，因为分布式训练一开始可能会开成千上万个进程，默认是4096，所以会导致线程创建失败。&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="感觉这点也是有用的但可能不是主要因素"&gt;感觉这点也是有用的，但可能不是主要因素？
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;4.一定要设置参数,只是用&lt;code&gt;ray.init()&lt;/code&gt;就会崩溃。需要手动设置&lt;code&gt;num_cpus&lt;/code&gt;。&lt;br&gt;
这点和1重复了，可以说是大家实验得到的结论？（也许）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="近期其他人也遇到过该问题"&gt;近期其他人也遇到过该问题
&lt;/h2&gt;&lt;p&gt;2024.1.16也有在&lt;code&gt;Ubuntu 20.04&lt;/code&gt;上遇到同样的问题 &lt;code&gt;venv: ray == 2.7.1,grpcio == 1.59.2,python == 3.11.5&lt;/code&gt;&lt;br&gt;
2024.4.2有在&lt;code&gt;ubuntu 22.04.3&lt;/code&gt;（docker内部）上遇到同样的问题，但是他只是失败，而不是挂起。在docker之外运行良好（他的M1 MacBook上）&lt;/p&gt;
&lt;p&gt;2024.4.14，2024.4.17，2024.7.11等等太多人遇到同样的问题了&lt;/p&gt;
&lt;h2 id="至此问题的解决方案已经讲述完毕"&gt;至此，问题的解决方案已经讲述完毕。
&lt;/h2&gt;&lt;hr&gt;
&lt;h3 id="回顾解决问题的流程"&gt;回顾解决问题的流程
&lt;/h3&gt;&lt;p&gt;刚遇到这个问题，我先看了一下是不是自己遇到过的，发现没有就交给了copilot，发现copilot无法解决，给了chatgpt5，同样无法解决，又给了Gemini看看能不能有些新意（其实这步可以忽略），上述方法都不行，问了师兄是否遇到过。&lt;/p&gt;
&lt;p&gt;发现他们都没有遇到过，我只能去Ray官方仓库里面的issue进行查看。感觉现在人们都不怎么用StackOverflow等等论坛了，所以就只能去issue里面找了。&lt;/p&gt;
&lt;p&gt;幸运的是发现了很多人遇到了同样的问题和报错，我就开始追根溯源，发现从17.18年就有人提出了这个问题，当时也有相应的解决办法，但是随着版本更新变得不适用。&lt;br&gt;
我就开始收集所有对这个问题的理解和解决方案，逐个尝试，很幸运的是我debug成功了！&lt;/p&gt;
&lt;p&gt;因为论文中没有常见的问题的解决方案，如果有的话应该是第一步先去看的。&lt;/p&gt;
&lt;p&gt;这就是我整个解决这个问题的流程，大体上看似乎没有太大问题。但是还是可以优化一下，下次遇到类似比较“偏”的问题可以更快，心态更平和地解决这个问题。&lt;/p&gt;
&lt;h3 id="看到这里了祝你遇到像我遇到的这样比较偏门的问题时也可以顺利并更快地解决"&gt;看到这里了，祝你遇到像我遇到的这样比较“偏门”的问题时，也可以顺利并更快地解决！
&lt;/h3&gt;</description></item><item><title>RUC-research-intern</title><link>https://qingzhou-yanghy.github.io/p/ruc-study-framework/</link><pubDate>Tue, 16 Sep 2025 10:00:00 +0800</pubDate><guid>https://qingzhou-yanghy.github.io/p/ruc-study-framework/</guid><description>&lt;img src="https://qingzhou-yanghy.github.io/p/ruc-study-framework/RUC.jpg" alt="Featured image of post RUC-research-intern" /&gt;&lt;p&gt;&lt;img src="https://qingzhou-yanghy.github.io/p/ruc-study-framework/AI-Box.jpg"
width="200"
height="200"
srcset="https://qingzhou-yanghy.github.io/p/ruc-study-framework/AI-Box_hu_dd5bef9123c22f74.jpg 480w, https://qingzhou-yanghy.github.io/p/ruc-study-framework/AI-Box_hu_3cf40d827e974d65.jpg 1024w"
loading="lazy"
alt="AI Box小组"
class="gallery-image"
data-flex-grow="100"
data-flex-basis="240px"
&gt;&lt;/p&gt;
&lt;h1 id="科研日记"&gt;科研日记
&lt;/h1&gt;&lt;p&gt;用来记录我远程实习的日子&lt;/p&gt;
&lt;h4 id="20250716"&gt;2025.07.16
&lt;/h4&gt;&lt;p&gt;成为赵老师的本科实习生，暑假跟着师兄做了一个横向&lt;/p&gt;
&lt;h5 id="家里网好差本来服务器就慢还是要在学校多用功"&gt;家里网好差（本来服务器就慢），还是要在学校多用功
&lt;/h5&gt;&lt;p&gt;暑假一共6周，还有各种事情，加上休息吃饭探亲balabala也做不了太多事情。确定了方向，看了一些知乎上的论文解读（后面发现如果要通透还是要看原文）。&lt;/p&gt;
&lt;h4 id="20250916"&gt;2025.09.16
&lt;/h4&gt;&lt;p&gt;近期在搞论文复现的实验，跟上课题组的进度&lt;/p&gt;
&lt;p&gt;今天在修改run_dapo.sh脚本的时候发现了几个常见的问题&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.sh的格式十分严格&lt;/li&gt;
&lt;li&gt;Parquet文件格式&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a class="link" href="https://zhuanlan.zhihu.com/p/680143641" target="_blank" rel="noopener"
&gt;Parquet文件格式讲解&lt;/a&gt;👈&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;vibe coding脚本是无比正确的。&lt;br&gt;
不知不觉已经两个月了，但对我而言收获是颇多的。&lt;/p&gt;
&lt;h5 id="选择一个好组是十分重要的软院tic高瓴ai-box让我深刻感受到了好的氛围成套的培养体系"&gt;选择一个好组是十分重要的！软院TIC，高瓴AI BOX让我深刻感受到了好的氛围，成套的培养体系！
&lt;/h5&gt;&lt;h5 id="希望自己可以平衡好课内科研还有生活等等其他方面"&gt;希望自己可以平衡好课内＋科研，还有生活等等其他方面
&lt;/h5&gt;&lt;p&gt;晚上睡前简单看了一下verl官方文档里面Config Explanation的Data部分&lt;/p&gt;
&lt;h5 id="梯度下降的三种常见形式"&gt;梯度下降的三种常见形式
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;1.Batch Gradient Descent（批量梯度下降）&lt;/li&gt;
&lt;li&gt;2.Stochastic Gradient Descent (SGD，随机梯度下降)&lt;/li&gt;
&lt;li&gt;3.Mini-batch Gradient Descent（小批量梯度下降）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;几个epoch就是过几次数据集，实践中把 “batch” 这个词用得比较宽：在框架/代码里 batch_size 常指 mini-batch 的大小，所以容易混淆 “batch gradient descent” 与 “mini-batch”。&lt;/p&gt;
&lt;h5 id="prompt_key"&gt;prompt_key
&lt;/h5&gt;&lt;p&gt;这个不是学术上固定的术语，而是很多框架（比如 HuggingFace、VERL、LangChain 等）里常见的实现细节。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 字典 / JSON / 配置文件 里，用来标记某个 prompt 的 键名（key）。&lt;/li&gt;
&lt;li&gt;这样做可以在代码里快速查找/复用不同的 prompt 模板。&lt;/li&gt;
&lt;/ul&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;/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;prompts = {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;translation&amp;#34;: &amp;#34;Translate the following English text into Chinese: {text}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;summarization&amp;#34;: &amp;#34;Summarize the following paragraph: {text}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;qa&amp;#34;: &amp;#34;Answer the question based on the context: {context}\nQuestion: {question}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&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;这里 &amp;ldquo;translation&amp;rdquo;, &amp;ldquo;summarization&amp;rdquo;, &amp;ldquo;qa&amp;rdquo; 就是 prompt_key，
而它们对应的 value 就是具体的 prompt 模板。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Prompt = 给模型的输入提示，引导它完成任务。&lt;br&gt;
Prompt_key = 在程序里标记或索引 prompt 模板的“名字/键”，方便管理和调用。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;RM（Reward Model，奖励模型）：在 RLHF 里给生成结果打分的模型。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果使用基于模型的 RM，并且策略和 RM 的聊天模板不同，则需要设置data.return_raw_input_ids=True
data.return_full_prompt=True
用户输入：你好，介绍一下强化学习
返回：[INST] 你好，介绍一下强化学习 [/INST]
data.return_raw_chat=True
用户输入：你好，介绍一下强化学习
返回的就是:你好，介绍一下强化学习&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id="20250917"&gt;2025.09.17
&lt;/h4&gt;&lt;p&gt;早晨起来去工位继续看verl&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;actor_rollout_ref.hybrid_engine：是否是混合引擎，目前只支持混合引擎.&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Dropout 是一种 正则化方法，用来防止神经网络过拟合。在训练时，随机“丢弃”一部分神经元（让它们暂时不参与计算和更新）。推理时,不再丢弃任何神经元，只是使用完整的输出。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;actor_rollout_ref.model.use_remove_padding一般都选true移除&lt;code&gt;&amp;lt;PAD&amp;gt;&lt;/code&gt;来加速推理，但是多模态或者大工程里仍有人使用false&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Temperature （温度）。T = 1 → 正常分布。T &amp;gt; 1 → 分布更平滑，增加随机性，容易生成多样化甚至跑偏的内容。T &amp;lt; 1 → 分布更尖锐，模型更确定（更倾向选概率最高的 token，输出保守）。&lt;br&gt;
Top-k：从 softmax 排序后的前 k 个 token 中随机抽样。&lt;br&gt;
Top-p：动态选择前 累计概率 ≥ p 的最小 token 集合，从里面采样。&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Actor:负责 更新参数&lt;br&gt;
Ref (Reference Model):负责 对比/约束。它是冻结的（不更新），通常是最初的预训练模型。&lt;br&gt;
Rollout:负责 产生输出（推理采样）&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;EOS = End Of Sequence（序列结束标记）。在 tokenizer 里，EOS 往往是个特殊的 &lt;code&gt;&amp;lt;/s&amp;gt;&lt;/code&gt; 或 &lt;code&gt;&amp;lt;eos&amp;gt;&lt;/code&gt; 符号。ignore_eos=True 在训练中一般少用，除非你需要 生成固定长度序列，或者想收集超过 EOS 的 rollouts 数据。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id="20250919"&gt;2025.09.19
&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;一个深度学习训练任务中，nodes 指的是计算机，而 gpus-per-node 指的是每台计算机上安装的 GPU 数量。&lt;br&gt;
可以把 nodes 理解为一台台服务器，每台服务器里可以插上多张显卡（GPU）。&lt;br&gt;
nnodes: 1：你正在使用一台计算机来运行任务。&lt;br&gt;
n_gpus_per_node: 8：这台计算机上插了 8 张 GPU。&lt;br&gt;
所以，这个配置的意思是，你用一台装有 8 张 GPU 的服务器来运行你的任务。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;verl官方文档看完了，嗯。。还是要去看仓库&lt;/p&gt;
&lt;p&gt;都在赶iclr导致服务器又变得卡卡的&lt;/p&gt;
&lt;p&gt;实验复现遇到了问题导致一直是卡住的状态&lt;/p&gt;
&lt;p&gt;神器：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pkill -9 -u $USER -f ray&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id="20250920"&gt;2025.09.20
&lt;/h4&gt;&lt;p&gt;ray官方仓库，试图解决Ray实例后ray.init()挂起/失败问题&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;import ray
ray.init()
2025-09-20 11:44:47,741 INFO worker.py:1538 &amp;ndash; Started a local Ray instance.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;有时候会卡住&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;python
import ray
ray.init()
2025-09-20 11:44:47,741 INFO worker.py:1538 &amp;ndash; Started a local Ray instance.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;有时候会失败&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[2025-09-20 11:50:22,050 E 31652 31652] core_worker.cc:179: Failed to register worker 01000000ffffffffffffffffffffffffffffffffffffffffffffffff to Raylet. IOError: [RayletClient] Unable to register worker with raylet. No such file or directory&lt;/p&gt;&lt;/blockquote&gt;
&lt;h5 id="versionsdependencies"&gt;Versions/Dependencies
&lt;/h5&gt;&lt;p&gt;Python 3.10
Ray
grpcio
OS:&lt;/p&gt;
&lt;h5 id="reproduction-script"&gt;Reproduction script
&lt;/h5&gt;&lt;blockquote&gt;
&lt;p&gt;import ray
ray.init()&lt;/p&gt;&lt;/blockquote&gt;
&lt;h5 id="issue-severity"&gt;Issue Severity
&lt;/h5&gt;&lt;p&gt;High:It blocks me from completing my task.&lt;/p&gt;
&lt;p&gt;可能的原因:1.workers实际上没有启动
2.系统中一个进程可以创建多少个线程？（可以通过cat /proc/sys/kernel/threads-max查看）&lt;/p&gt;
&lt;p&gt;可能的方法:1.在import ray后添加 ray.init(num_cpus=56, num_gpus=2) 这个方法很多人似乎有帮助，但不是一个好的解决方案
2.可以看一下/tmp/ray/session_latest/raylet.out,如果在/tmp/ray/session_latest/看到有前缀python-core-worker- 的可以看一下，因为这个能了解工作进程可能发生了什么
3.升级grpcio,2023年的时候安装grpcio 1.48.1 版本是有用的,相应的venv是 CentOS 7,Python 3.7.11，Ray 2.5.1,grpcio1.48.1
4.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;#!/bin/bash
ulimit -n 65536
python3 -m verl.trainer.main_ppo &amp;hellip;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;5.一定要设置参数,只是用ray.init()就会崩溃。需要手动设置num_cpus&lt;/p&gt;
&lt;p&gt;其他人：
2024.1.16也有在Ubuntu 20.04上遇到同样的问题 venv: ray == 2.7.1,grpcio == 1.59.2,python == 3.11.5
2024.4.2有在ubuntu 22.04.3（docker内部）上遇到同样的问题，但是他只是失败，而不是挂起。在docker之外运行良好（他的M1 MacBook上）&lt;/p&gt;
&lt;p&gt;2024.4.14，2024.4.17，2024.7.11等等太多人遇到同样的问题了&lt;/p&gt;
&lt;p&gt;15点左右,/yhy/verl/trainer/config/ppo_trainer.yaml配置文件中进行修改&lt;/p&gt;
&lt;h5 id="问题已解决在import-ray后添加-rayinitnum_cpus56-num_gpus2"&gt;问题已解决！在import ray后添加 ray.init(num_cpus=56, num_gpus=2)
&lt;/h5&gt;&lt;p&gt;自己看issue，扒仓库源码等等解决了这个问题&lt;/p&gt;
&lt;h4 id="20251022"&gt;2025.10.22
&lt;/h4&gt;&lt;p&gt;结束了第一段实习，收获满满！&lt;br&gt;
谢谢师兄！谢谢赵老师！&lt;br&gt;
期待后续再合作！&lt;/p&gt;</description></item><item><title>第一篇文章</title><link>https://qingzhou-yanghy.github.io/p/%E7%AC%AC%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/</link><pubDate>Mon, 15 Sep 2025 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/p/%E7%AC%AC%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/</guid><description>&lt;img src="https://qingzhou-yanghy.github.io/p/%E7%AC%AC%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/first-blog-cover.jpg" alt="Featured image of post 第一篇文章" /&gt;&lt;p&gt;欢迎你能来到我的第一篇文章！&lt;/p&gt;
&lt;h2 id="为什么要写博客"&gt;为什么要写博客？
&lt;/h2&gt;&lt;p&gt;写博客对我来说有着特殊的意义：&lt;/p&gt;
&lt;h3 id="对自己"&gt;对自己
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;记录笔记&lt;/strong&gt;：把学到的东西都记下来，以后可以复习&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;积攒经验&lt;/strong&gt;：积攒宝贵的经验&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记录进步&lt;/strong&gt;：记录自己的进步&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="对他人"&gt;对他人
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;感谢师父&lt;/strong&gt;：感谢文聪学长的帮助，永远的师傅！&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;传承精神&lt;/strong&gt;：希望后来者能够更快速地入门&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分享内容&lt;/strong&gt;：希望其他人能够更快地了解我&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="博客内容规划"&gt;博客内容规划
&lt;/h2&gt;&lt;p&gt;我计划我的文章中记录以下内容：&lt;/p&gt;
&lt;h3 id="笔记-notes"&gt;笔记 (Notes)
&lt;/h3&gt;&lt;p&gt;可能比较杂，什么都有。但重点是关于llm的内容&lt;/p&gt;
&lt;h3 id="理论-theory"&gt;理论 (Theory)
&lt;/h3&gt;&lt;p&gt;一些理论知识&lt;/p&gt;
&lt;h3 id="日记-diary"&gt;日记 (Diary)
&lt;/h3&gt;&lt;p&gt;记录一些自己的日常，探讨人生&lt;/p&gt;
&lt;h2 id="结语"&gt;结语
&lt;/h2&gt;&lt;p&gt;写博客是一个长期的过程，也应该是一个很开心的过程！&lt;/p&gt;
&lt;p&gt;&lt;em&gt;这篇文章写于 2025年9月15日，是我博客的第一篇文章。希望它能成为一个美好的开始。&lt;/em&gt;&lt;/p&gt;</description></item><item><title>About</title><link>https://qingzhou-yanghy.github.io/about/</link><pubDate>Wed, 01 Jan 2025 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/about/</guid><description>&lt;p&gt;Hi, I&amp;rsquo;m Huanyu Yang (杨环宇), an undergraduate at Dalian University of Technology.&lt;/p&gt;
&lt;p&gt;I work on &lt;strong&gt;LLM agents&lt;/strong&gt;. My interests center on agent systems and post-training, and I spend a fair amount of time with the infrastructure that makes them run: reinforcement learning, vLLM, and vLLM-omni.&lt;/p&gt;
&lt;p&gt;This blog is where I write up what I&amp;rsquo;m reading and building: paper notes, implementation deep-dives, and the things I wish someone had explained to me earlier.&lt;/p&gt;
&lt;h2 id="focus"&gt;Focus
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Agent development&lt;/li&gt;
&lt;li&gt;Post-training&lt;/li&gt;
&lt;li&gt;Inference and RL infrastructure (vLLM / vLLM-omni)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="contact"&gt;Contact
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Email: &lt;a class="link" href="mailto:3868850350@qq.com" &gt;3868850350@qq.com&lt;/a&gt; / &lt;a class="link" href="mailto:yhy3868850350@gmail.com" &gt;yhy3868850350@gmail.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a class="link" href="https://github.com/QingZhou-YangHY" target="_blank" rel="noopener"
&gt;QingZhou-YangHY&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Archives</title><link>https://qingzhou-yanghy.github.io/archives/</link><pubDate>Tue, 28 May 2019 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/archives/</guid><description/></item><item><title>Links</title><link>https://qingzhou-yanghy.github.io/links/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/links/</guid><description>&lt;p&gt;友链整理中。A collection of sites and people worth a visit is on the way.&lt;/p&gt;</description></item><item><title>Search</title><link>https://qingzhou-yanghy.github.io/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://qingzhou-yanghy.github.io/search/</guid><description/></item></channel></rss>