MegaThinking

better tokens, better intelligence, contributing superior tokens to models

MiniMax M2 系列技术报告的标题是 The MiniMax-M2 Series: Mini Activations Unleashing Max Real-World Intelligence

NVIDIA 也有一篇部署侧性能文章:MiniMax M2.7 Advances Scalable Agentic Workflows on NVIDIA Platforms for Complex AI Applications

一句话概括:M2 系列不是单纯把模型参数做大,而是在尝试把 低激活 MoE backbone、agent 数据 pipeline、agent-native RL 系统 Forge、长上下文推理优化 组合成一套面向真实 agent workflow 的训练和部署方案。

本文主要整理四类信息:

  • 模型参数和结构;
  • pre-training / post-training 用了哪些技术;
  • Forge 这套 RL 工程系统是什么;
  • M2.7 的指标到底提升在哪里。

模型参数

先看 M2 backbone 的基本配置。

项目 报告口径
架构 decoder-only Transformer + MoE
总参数 229.9B
每 token 激活参数 9.8B
层数 62
hidden size 3072
vocab size 200064
MoE experts 256 fine-grained experts
每 token 激活专家数 8
attention full attention
query heads 48
KV heads 8, GQA
position embedding RoPE
native context 192K tokens
pre-training tokens 29.2T

这个配置体现出一个明确取舍:总参数很大,但每 token 激活参数控制在 10B 左右。agent task 的 token 消耗通常较高,多轮工具调用、长上下文、观察结果、文件内容都会增加 context 长度。因此,每 token 激活成本会直接影响推理和 RL rollout 成本。

因此,M2 的参数信息需要同时看 total params 和 activated params:229.9B total params / 9.8B activated params

MoE 结构

M2 的 FFN 层使用 MoE。报告里强调了三个设计:

  • fine-grained experts;
  • sigmoid gating;
  • expert bias。

fine-grained experts 的意思是使用更多、更小的 experts。M2 使用 256 个 experts,每 token 激活 8 个。这样增加了 expert 组合的多样性,也可以降低不同设备之间 expert utilization 的方差。

sigmoid gating 和常见 softmax top-k gating 的区别在于:softmax 有 zero-sum constraint,一个 expert 得分高,其他 expert 得分就会相对被压下去;sigmoid 则是每个 expert 独立打分。报告认为这样可以让多个 expert 同时以较高置信度被激活,routing dynamics 更平滑。

expert bias 则是在 gating score 上加入 per-expert learnable bias,用来改善 load balancing,并减少对 auxiliary load-balancing loss 的依赖。

报告给了一个小规模消融实验:17.8B total params,2B activated params,500B training tokens。

配置 MATH MMLU ARC-C KorBench HumanEval
baseline 19.6 39.8 27.4 14.1 29.7
+ MTP 21.3 39.7 27.5 15.0 30.1
+ fine-grained experts 24.1 40.2 27.8 14.8 32.5

这里 HumanEval 和 MATH 的提升比较明显。

Attention: full attention

M2 使用 full attention,而不是 hybrid SWA、linear attention 或 sparse attention。

这里的 full attention 需要和 causal attention 分开理解。M2 是 decoder-only language model,所以 attention 仍然是 causal 的:当前位置只能看过去和当前位置,不能看未来。full attention 指的是在 causal mask 下,每个 token 可以看完整历史 token,而不是只看一个局部 sliding window。

也就是:

1
2
3
4
5
causal full attention:
token t can attend to token 1 ... t

causal sliding-window attention:
token t can attend to token max(1, t - W) ... t

报告提到,MiniMax 对 hybrid SWA 做了多组继续预训练实验,包括 SWA/full attention 比例、RoPE 设置、layer 内和 layer 间混合、sink token 等。但在 retrieval、多跳推理、in-context learning 和长上下文 agent task 上,SWA variant 有明显损失。

预训练阶段的一组对比:

Benchmark full attention hybrid SWA
HELMET ICL 75.8 72.7
MMLU 85.5 85.6
MATH 60.3 60.3
RULER 128K CWE 90.0 72.0
RULER 128K MQ 99.0 93.0
RULER 32K CWE 99.0 99.0
RULER 32K MQ 99.0 99.0
MTOB K-e Bleurt 60.0 45.0
MTOB e-k ChrF 44.8 27.2

从这组数据看,32K 内部分任务中 SWA 与 full attention 差距不大;到 128K retrieval 和 long-context ICL 时,局部窗口的覆盖限制开始体现出来。

对于 agent 任务,长上下文通常包含任务描述、工具输出、失败尝试、文件内容、之前的 reasoning state 等信息。如果 attention 机制不能可靠访问完整历史,后续 planning 和 self-correction 会受到影响。

MTP

M2 使用 Multi-Token Prediction。预训练阶段先使用单个 MTP module,K = 1,MTP loss weight 从 0.3 anneal 到 0.1。

在 continued pre-training 的 decay phase,M2 把 MTP module 扩展到 K = 3,用于 multi-step speculative decoding。扩展时不是随机初始化,而是从 main model 复制权重初始化。报告里的解释是:

  • copy initialization 收敛更快;
  • 随机初始化会带来较高 loss,并短暂干扰 main model;
  • 先冻结 main model 训练 MTP modules,loss 稳定后再 joint training。

所以 MTP 在 M2 里有两层作用:

  • 训练阶段提供更丰富的预测信号;
  • 推理阶段作为 speculative decoding 的 draft path。

这个点和 Forge 也有关。RL rollout 期间 policy 在持续更新,如果 MTP draft model 不跟着适配,acceptance rate 会下降。报告提到 Forge 里 MTP modules 会通过 top-K KL divergence loss 和 RL policy 一起 co-train,从而维持 speculative decoding 的效果。

Pre-training 数据

预训练总量是 29.2T tokens。

报告把它分成:

  • constant phase: 19.9T tokens;
  • decay phase: 9.3T tokens。

数据来源包括 web documents、academic literature、books、programming code、structured QA。code、math、STEM 会相对自然分布上采样。

长上下文扩展是多阶段完成的:

1
8K -> 32K -> 192K

长上下文数据主要来自:

  • high-quality code concatenation;
  • naturally long-form PDF documents;
  • thematically related document packing。

从报告结构看,M2 的 pre-training 不只服务于通用 base model 能力,也为后续 agent post-training 提供 192K context backbone。

Post-training 数据

报告真正花篇幅的地方其实是 post-training data collection。

M2 系列的 post-training data 不是普通 chat 数据,而是大量带 workspace、tool、environment、verifiable reward 或 artifact-aligned feedback 的 agent trajectories。

主要分几类:

  • Agentic Coding;
  • Agentic Cowork;
  • Reasoning-intensive tasks;
  • General conversation and writing;
  • Role-play and persona coherence。

但是这里有一个需要注意的点:报告没有披露 post-training 的具体数据规模

也就是说,论文写了很多 pipeline 和数据类型,但没有给出类似下面这样的硬数字:

  • SFT tokens 数;
  • RL tokens 数;
  • agent trajectories 数;
  • SWE/AppDev/Terminal/Cowork 各域样本量;
  • rejection sampling 前后 pass rate;
  • 每个 stage 的 domain mixing ratio。

报告使用的是 large-scale、corpus、trajectories、at scale 这类描述。能看到的硬规模数字主要集中在 pre-training:29.2T tokens,其中 constant phase 19.9T tokens,decay phase 9.3T tokens。

因此,post-training 部分可确认的信息是:M2 披露了 post-training 数据构造方法和验证信号,但没有披露各类 post-training data 的样本规模和 token budget

Agentic Coding

Agentic Coding 又分 SWE、AppDev、Terminal-Gym。

SWE pipeline 从 GitHub PR 和 issue 出发,过滤 merged PR、有测试的 PR,再由 agent 构建 Docker environment。之后按 PR 类型做 task routing,比如 bug fix、feature addition、performance optimization、test/refactor 等。

这里最重要的是 reward construction。不同任务类型用不同的验证信号:

  • bug fix: F2P / P2P tests;
  • feature addition: newly added test points;
  • performance optimization: stable and significant performance difference;
  • code review: secondary LLM consistency check。

AppDev 则是从零构建应用。它用 expert-in-the-loop 生成 meta queries 和 system prompts,再通过 Agent-as-a-Verifier 做 rejection sampling。AaaV 分三层验证:

  • execution layer: 文件、依赖、构建、服务启动、JS error;
  • interaction layer: Playwright 检查核心交互;
  • visual aesthetics layer: 布局、层次、配色、现代 UI 质量。

Terminal-Gym 则从 Stack Overflow 出发,筛选 terminal-compatible、scriptable、verifiable、Docker-relevant 的任务,然后生成 Dockerfile 和 test script,再做 query evolution 和 difficulty calibration。

这几个 pipeline 的共同点是:数据不只包含最终答案,还包含可执行环境,使结果能够被测试、运行或交互验证。

Agentic Cowork

Cowork 覆盖的东西更接近知识工作者任务:

  • deep search and open-web research;
  • knowledge-worker office tasks;
  • financial analysis and spreadsheet operations;
  • slide generation and editing。

这部分的 reward 更复杂。有些任务可以 deterministic check,比如 spreadsheet cell value match、formula recalculation;有些任务需要 rubric-based judge,比如 report、slides、open-ended financial reasoning。

这个方向是 M2.7 相比 M2.5 提升很明显的地方。后面的指标表里,GDPval-AA、MEWC v2、Finance Modeling Pro 都涨得很大。

Reasoning 和 general data

Reasoning data 主要强调 scaling:

  • query-side scaling: 扩展题目覆盖;
  • response-side scaling: 一个 query 采多个正确解法;
  • training-side scaling: 在固定计算预算下调 query expansion / response expansion 比例;
  • QA: query、verifier、answer、response 多阶段质量控制。

General conversation and writing 则用于保持通用对话、写作、多轮理解,以及 tool-augmented / tool-free 两种能力。

SFT: interleaved thinking

M2 的 SFT 目标之一是训练 interleaved thinking。

普通 long CoT 往往是:

1
thinking -> final answer

Agent 场景更像:

1
thinking -> tool call -> observation -> thinking -> tool call -> observation -> final answer

报告把它称为 Plan-Act-Reflect loop。关键点是 reasoning state persistence:前一轮的 thinking block 会保留在 history 里,进入下一轮上下文。

这和 stateless per-turn reasoning 不一样。如果每轮工具调用后都把之前的 reasoning 丢掉,模型就要反复重新推导状态,长程任务里容易 drift。

这个地方也能解释为什么 M2 更坚持 full attention:如果 thinking、action、observation 都保留在 192K context 里,模型必须能可靠地访问完整历史。

Forge

是什么

Forge 是 M2 系列的 agent-native RL training system。

它不是模型结构,也不是单个 RL 算法,而是一套让长程 agent trajectories 能进入 RL 训练闭环的工程系统。

普通 RLHF 或 response-level RL 常见输入是:

1
prompt -> response -> reward

Agent RL 的输入则像:

1
2
3
4
5
6
7
8
9
task
-> reasoning
-> tool call
-> observation
-> reasoning
-> tool call
-> observation
-> artifact / test result / final answer
-> reward

轨迹可能有几十 K 到 192K tokens,中间还有工具调用、Docker、browser、spreadsheet、file system、context management、sub-agent delegation。这要求训练系统处理长序列、异步环境和复杂状态转移。

Forge 的系统拆分为:

1
2
3
4
5
6
7
8
9
10
11
12
13
Agent Side
run agent loop
manage context
call tools / envs
produce trajectories

Middleware
Gateway Server
Data Pool

Training / Inference Side
Rollout Engine
Train Engine

Agent Side 只负责跑任务和记录轨迹。Rollout Engine 负责高吞吐生成。Train Engine 负责策略更新。Gateway 和 Data Pool 把二者解耦。

一个重要抽象是:Forge 把 LLM generation interface 作为 policy 边界,边界之外的 tool execution、context management、memory access、agent harness 都视为 environment dynamics。

这样它就可以支持两类 agent:

  • white-box agent: 训练系统知道它怎么做 context management;
  • black-box agent: 训练系统只看到每次发给模型的 state 和模型输出。

black-box support 很重要。因为真实 agent scaffold 往往各有各的 context rewrite、memory、sub-agent、tool protocol。如果要求所有 agent 都白盒接入,系统扩展性会很差。

RL 算法和 reward

M2 系列 RL 使用 CISPO,Clipped Importance Sampling Policy Optimization。报告里给了 objective 和 importance sampling ratio 的 clipped form。

我先不展开公式,抓几个工程上更重要的点:

第一,训练样本是 (state, action) pair。一个 action 是一次 LLM completion,可以包含 reasoning、tool invocation、context operation、sub-agent communication 等。

第二,credit assignment 仍然按完整 episode 做。也就是说,每个 step 的 advantage 要结合整条 trajectory 的结果。

第三,reward 不是只有最终 outcome,而是 composite reward:

1
2
3
r_t = alpha * process_reward_t
+ beta * speed_reward_t
+ performance_reward_t

process reward 用于中间行为,比如工具调用格式、语言混杂、reasoning 结构。

speed reward 用于 wall-clock completion time。这个点很 agent:两个 trajectory 都完成任务,但一个串行慢慢跑,一个并行调用工具,后者对产品更有价值。

performance reward 则是最终任务质量,比如测试通过、artifact 正确、rubric score。

第四,使用 mixed-domain RL。每个 stage 同时混合 reasoning、coding、agent、general 四类数据。这样可以降低单一 agent task RL 造成的 catastrophic forgetting。

Windowed FIFO

Agent rollout 有一个很现实的问题:任务完成时间差异巨大。

1
2
3
simple API task: seconds
coding task: minutes
ML engineering task: hours

如果严格 FIFO,训练会被长任务卡住。
如果谁先完成就训练谁,前期 batch 会被短任务和简单任务主导,后期才出现长任务和难任务,训练分布会漂。

Forge 用 Windowed FIFO 做折中:

1
2
queue = [T0, T1, T2, T3, T4, T5, ...]
window = [T0, T1, T2, T3]

只允许训练系统消费 window 内已经完成的 trajectories。window 内可以乱序取,window 外即使已经完成也不能提前进入训练。

论文里举的窗口大小例子是 W = 0.3N。这个策略牺牲一点点绝对吞吐,换来更稳定的数据分布。

Prefix tree merging

Prefix tree merging 是 Forge 里最有工程味的优化之一。报告称它最高能带来 40x training speedup,并降低显存占用。

Agent RL 训练中,很多 samples 共享长前缀。例如同一个 rollout group 里可能有:

1
2
3
sample 1 = long context + response A
sample 2 = long context + response B
sample 3 = long context + response C

或者同一条 agent trajectory 被拆成多个 step:

1
2
3
s1 -> a1
s2 = s1 + a1 + obs1 -> a2
s3 = s2 + a2 + obs2 -> a3

如果每个 sample 独立 forward,long context 或历史轨迹会被反复计算。

Prefix tree merging 把这些序列组织成一棵 prefix tree:

1
2
3
4
long shared context
├── response A
├── response B
└── response C

或者:

1
2
3
4
context
└── action1 + obs1
└── action2 + obs2
└── action3 + obs3

共享 prefix 只 forward 一次。到分叉点后,再分别计算 branch。forward 结束后,根据元数据把 tree 拆回原始 sample,loss 仍然按 sample 独立计算。

它成立的原因是 causal attention:prefix token 的 hidden states 不依赖后续 branch tokens。后面的 token 可以看前面,前面的 token 不会看后面。

概念伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
samples = [
ctx + resp_a,
ctx + resp_b,
ctx + resp_c,
]

tree = build_prefix_tree(samples)

def forward_node(node, parent_state):
state = model_forward_segment(
tokens=node.tokens,
parent_state=parent_state,
)

for child in node.children:
forward_node(child, state)

forward_node(tree.root, None)

loss = 0
for sample in samples:
logits = reconstruct_logits(sample, tree)
loss += compute_loss(logits, sample.labels)

loss.backward()

真实实现会复杂很多,要处理 attention mask、position ids、loss mask、MoE routing、activation checkpointing、分布式并行和 backward graph。但核心就是把训练 batch 从独立 sequence list 改成共享前缀树。

这个优化和普通 sequence packing 不同。sequence packing 主要减少 padding;prefix tree merging 则是避免重复计算公共历史。对于 192K context 的 agent RL,这类重复计算会带来较高开销。

Rollout 侧推理优化

Forge 还做了几类 inference acceleration。

MTP speculative decoding

M2 的 MTP modules 可以生成 draft tokens,再由 main model 验证。RL 期间 policy 会更新,所以 MTP modules 也要跟着 co-train,否则 draft acceptance rate 会下降。

Prefill-decode disaggregation

把 prefill 和 decode 分开调度。MoE 模型里 prefill 和 decode 的计算形态不同,混在一起容易互相干扰。拆开后可以分别采用更适合的 parallelism 策略。

Global L3 KV cache pool

Agent 多轮交互里有大量共享 prefix。Forge 使用分布式 KV cache pool,提高 prefix cache hit rate。router 会在 queue delay 和 cache migration cost 之间做权衡。

从报告描述看,Forge 里的 rollout engine 不只是离线采样服务,而是包含长上下文、KV cache、MoE serving、speculative decoding、prefill/decode separation、多版本权重同步等能力的推理系统。

训练系统性能

报告明确给出的硬数字是:prefix tree merging 最高可以达到 40x training speedup,同时降低 memory consumption,使更长 sequence 和更大 batch size 成为可能。

其他 Forge 优化更多是定性描述,比如:

  • Windowed FIFO 用于在 rollout throughput 和 distributional consistency 之间折中;
  • MTP speculative decoding 用于提升 rollout generation throughput;
  • prefill-decode disaggregation 用于提升 global throughput 并降低 tail latency;
  • global L3 KV cache pool 用于提升 prefix cache hit rate。

但是论文没有给出这些优化各自的 ablation 表,比如没有列出 Windowed FIFO 前后吞吐、GPU utilization、tail latency、KV hit rate、MTP acceptance rate 等数字。

实现架构推断

下面是基于报告描述的工程推断,不是官方源码,也不是论文披露的完整实现。


sequenceDiagram
participant T as Task Queue
participant A as Agent Runner
participant E as Tool / Env Servers
participant G as Gateway Server
participant R as Rollout Engine
participant D as Data Pool
participant Tr as Train Engine

T->>A: task / env spec
loop agent rollout
  A->>G: completion request<br/>state + tools + metadata
  G->>R: normalized request<br/>model version attached
  R-->>G: completion<br/>tokens + logprobs
  G-->>A: action / tool call
  A->>E: execute tool call
  E-->>A: observation / artifact
  A->>D: state / action / observation
  E->>D: verification / reward signal
  R->>D: model version / logprobs
end
D->>D: Windowed FIFO<br/>filtering / batching
D->>Tr: training batch
Tr->>Tr: prefix tree merging<br/>CISPO update
Tr-->>R: updated weights

图里的关键边界是 Gateway:Agent Side 可以保持 scaffold 差异,Training / Inference Side 则通过统一的 completion 接口接收请求、记录元数据,并把 rollout 数据回流到 Data Pool。

Prefix tree merging 可以单独画成下面这个形态:


flowchart LR
b1["before: ctx + a"]
b2["before: ctx + b"]
b3["before: ctx + c"]

ctx["after: shared ctx"]
a["branch a"]
b["branch b"]
c["branch c"]

b1 -. same prefix .-> ctx
b2 -. same prefix .-> ctx
b3 -. same prefix .-> ctx

ctx --> a
ctx --> b
ctx --> c

共享 prefix 只做一次 forward,分叉后的 response segment 分别计算;forward 结束后再根据元数据还原到原始 sample 计算 loss。

根据 Forge 的训练需求,Data Pool 可能需要记录这些字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
trajectory_id
task_id
domain
model_version
states
actions
observations
token_ids
old_logprobs
process_rewards
final_reward
wall_clock_time
tool_calls
artifact_paths
verification_result

Train Engine 的处理流程可以抽象为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
trajectories = data_pool.fetch_windowed_fifo_batch()

samples = []
for traj in trajectories:
for step in traj.steps:
samples.append({
"input_ids": step.state_tokens,
"target_ids": step.action_tokens,
"old_logprobs": step.old_logprobs,
"advantage": compute_advantage(traj, step),
})

batch = prefix_tree_merge(samples)
loss = cispo_loss(batch)

loss.backward()
optimizer.step()

rollout_engine.sync_weights(model)

这里的关键是 old logprobs 和 model version。RL rollout 和 training 之间一定存在 policy lag,所以需要知道 trajectory 是哪个旧 policy 采样出来的,再通过 importance sampling ratio 做修正。

性能数据

M2 系列报告里其余性能数据分布比较散,和 Forge 训练系统性能分开看更清晰。

Agent task 运行设置

这些不是系统吞吐,但可以反映任务成本:

  • agent trajectories 最长可到 192K tokens,并可能包含 thousands of intermediate actions;
  • rollout completion time 从 seconds 到 hours;
  • Terminal-Bench 2.0 使用 8 vCPU / 16GB sandbox,2 小时 wall-clock timeout,4 trials;
  • MLE Bench Lite 对 22 个 competitions 运行,每个 competition 在 single-A30 sandbox 中跑 24 小时,最终取 3 个 independent 24-hour trials 的平均 medal rate;
  • VIBE-Pro、HyperTask、MM Claw、MEWC v2、Finance Modeling Pro 等多项 agent / artifact benchmark 使用 3 trials。

Self-evolution 内部效率

  • M2.7 在 RL team workflow 中吸收 30% 到 50% 的 daily iteration workload;
  • 对内部 programming scaffold 做 100-round autonomous iteration;
  • 引入 loop detection 和更好的参数组合后,内部评估有 30% performance gain。

这部分属于内部系统和内部评测,不是外部可复现 benchmark。

部署侧推理性能

来自 NVIDIA 技术博客,而不是 M2 论文主体。NVIDIA 提到在 Blackwell Ultra GPU 上,针对 MiniMax M2 系列在 vLLM / SGLang 集成 QK RMSNorm kernel 和 FP8 MoE kernel 后,在 1K/1K ISL/OSL dataset 上:

  • vLLM throughput 最高提升 2.5x;
  • SGLang throughput 最高提升 2.7x。

这个数据属于部署工程部分,不应和 Forge 训练系统性能混在一起。Forge 是 post-training / RL infrastructure;NVIDIA 这里讲的是 open-source inference framework 的 serving optimization。

指标

论文 Table 4 给了 M2.7、M2.5 和几个闭源 frontier baseline 的对比。这里只摘 M2.7 和 M2.5。

Benchmark M2.7 M2.5
SWE-bench Pro 56.2 55.4
SWE-bench Multilingual 76.5 74.1
Multi-SWE-bench 52.7 51.3
NL2Repo 39.8 26.6
Terminal-Bench 2.0 57.0 51.7
MLE Bench Lite 66.6 51.5
VIBE-Pro 55.6 54.2
HyperTask 67.6 59.4
BrowseComp 77.8 76.3
Wide Search 75.2 70.3
RISE 64.3 50.2
GDPval-AA 50.0 35.0
Toolathlon 46.3 38.3
MM Claw 62.7 57.6
MEWC v2 63.3 49.8
Finance Modeling Pro 57.0 33.8
AIME 2026 94.2 87.2
GPQA-Diamond 89.8 85.2
SciCode 47.0 43.0
IFBench 76.0 72.0
AA-LCR 72.0 65.0
HLE 28.0 19.0
MMLU-Pro 81.8 85.2

从表中可以看到:

  • M2.7 相比 M2.5 的大幅提升集中在 agent / cowork / office / MLE;
  • Finance Modeling Pro 从 33.8 到 57.0;
  • GDPval-AA 从 35.0 到 50.0;
  • MEWC v2 从 49.8 到 63.3;
  • MLE Bench Lite 从 51.5 到 66.6;
  • MMLU-Pro 从 85.2 降到 81.8。

这说明 M2.7 不是所有传统静态知识 benchmark 都提升。报告更强调的是:agent data pipeline 和 Forge RL 对真实 workflow benchmark 的提升。

M2.7 的 self-evolution

报告里还提到 M2.7 的 self-evolution。

MiniMax 的说法是,M2.7 可以在内部 Model Iteration System 里帮助 RL 团队:

  • profile ongoing runs;
  • read logs;
  • diagnose metric anomalies;
  • debug code;
  • adjust configs;
  • generate reports;
  • modify agent scaffold。

报告称它可以吸收 RL 团队日常 30% 到 50% 的 iteration workload。另一个例子是,M2.7 对内部 programming scaffold 做了 100-round autonomous iteration,引入 loop detection 和更好的参数组合,在内部评估上带来 30% performance gain。

这部分高度依赖内部工作流和内部评测,应视为官方披露的内部案例,而不是外部可复现实验结论。

总结

M2 系列报告的重点不只是单个 benchmark,而是一套完整路线:

1
2
3
4
5
6
7
low-activation MoE backbone
-> long-context full attention
-> MTP for training signal and speculative decoding
-> verifiable agent trajectory data
-> interleaved thinking SFT
-> Forge agent-native RL
-> rollout / training / serving co-optimization

如果只看参数,M2 是一个 229.9B total / 9.8B activated 的 MoE 模型。
如果看训练,它是一个围绕可验证 agent trajectories 做 post-training 的模型。
如果看工程,Forge 才是这篇报告里很关键的东西:它把 agent loop、推理服务、轨迹存储、reward、RL trainer 和权重同步接成一个系统。

这也是 M2 系列和很多只讲模型结构的技术报告不同的地方。它把模型能力放在完整 agent workflow 里讲,重点不是“模型会不会回答”,而是“模型能不能在环境里把事情做完,并且这个训练闭环能不能规模化”。

Ray 默认把 object 放进 Plasma object store——每个节点上一个基于 共享内存 的本地 store 进程,worker 通过它读写 object。ray.put()、task / actor 返回值等先落本机 Plasma;跨节点时再由 Ray 的 ownership / scheduling 层协调 fetch,但 各节点本地内存层仍是 Plasma。内存不够时会 spill 到磁盘(默认在 session 临时目录下),需要时再 restore 回 Plasma;ray memory 里的 Plasma memory usage 就是这一层。

task / actor 消费 object 时要反序列化。对 CUDA torch.Tensor 来说,默认路径意味着 GPU → CPU(进 Plasma)→ GPU 的来回拷贝,在 actor 间频繁传 tensor 时开销很大。


graph LR
subgraph N1["节点 1"]
  A1["Producer Actor<br/>GPU tensor"]
  B1["Plasma Store"]
end
subgraph N2["节点 2"]
  A2["Consumer Actor"]
  B2["Plasma Store"]
end
A1 -->|"GPU to CPU, 入 Plasma"| B1
B1 -->|"跨节点 fetch"| B2
B2 -->|"拷贝到 GPU"| A2
A1 -->|"RDT 使用 Gloo/NCCL/NIXL<br/>在 actor 间 send/recv"| A2
style B1 fill:#eee,stroke:#ccc,color:#999
style B2 fill:#eee,stroke:#ccc,color:#999
style A1 fill:#ddeeff,stroke:#338
style A2 fill:#ddeeff,stroke:#338

上:传统 Plasma 路径需多次 CPU/GPU/内存拷贝;下:RDT 经 Gloo/NCCL/NIXL 在 actor 间 send/recv,绕开 Plasma。

Ray Direct Transport (RDT) 是在 ObjectRef 语义上做的增强:tensor 留在 producer actor 侧(GPU 上),consumer 需要时由 Ray 协调两端做 send/recv,绕开 Plasma object store 的序列化与拷贝。底层可选 Gloo / NCCL / NIXL——Gloo、NCCL 是 collective 库,需先建 collective group,再在 group 内走 p2p 传输;NIXL 则是基于 UCX 的 p2p RDMA,无需预建 group,且 ray.get 可走 one-sided 取回。

RDT 目前仍是 alpha,API 和限制都可能变;下文基于 Ray 2.55 文档整理。

基本用法

在返回 torch.Tensor 的 actor method 上加 @ray.method(tensor_transport=...)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import torch
import ray
from ray.experimental.collective import create_collective_group

@ray.remote
class MyActor:
@ray.method(tensor_transport="gloo")
def random_tensor(self):
return torch.randn(1000, 1000)

def sum(self, tensor: torch.Tensor):
return torch.sum(tensor)

sender, receiver = MyActor.remote(), MyActor.remote()
group = create_collective_group([sender, receiver], backend="torch_gloo")

tensor = sender.random_tensor.remote()
result = receiver.sum.remote(tensor)
print(ray.get(result))
  • decorator 只加在产出 tensor 的方法上,消费方不用加(除非它也要返回 RDT tensor)。
  • tensor 存在 producer actor 里,不是 Plasma object store。
  • 传给另一个 actor 时,Ray 自动用指定 transport 做 send/recv。
  • 返回值若未标注 RDT,仍走默认 Plasma object store(上例 sum 的标量结果)。

嵌套结构、多 tensor 返回值也支持,Ray 会递归识别其中的 torch.Tensor

三种 transport

transport 场景 collective group 备注
gloo CPU tensor 需要,backend="torch_gloo" 无 GPU 也能跑通 demo
nccl NVIDIA GPU 需要,backend="nccl" actor 需 num_gpus=1,tensor 在 .cuda()
nixl CPU / GPU 不需要 基于 UCX 的 p2p RDMA;ray.get / ray.put 也可走 NIXL

Gloo / NCCL 是 collective 语义,使用前必须 create_collective_group,且 backendtensor_transport 一致。NIXL 更灵活,actor 环境装好 nixl 即可,适合跨节点 p2p。

NCCL 版几乎就是 Gloo 版三处替换:tensor_transport="nccl"backend="nccl"、tensor 放 GPU。

NIXL 额外支持 driver 侧 ray.put(t, _tensor_transport="nixl"),以及 consumer 内 ray.get(ref) 直接经 NIXL 取回。

collective transport 的 ray.get 若 caller 不在 group 里会报错,需配置 _use_object_store=True 回退。

与 Plasma object store 的语义差异

RDT object 是可变的。 Ray 只持有 tensor 引用,不做 immutable copy。producer 若仍持有同一块 tensor 并在 in-place 修改,后续 consumer 可能看到被改过的数据。这与 Ray Core 默认「actor 返回即拷贝」的行为不同。

传回 同一个 producer actor 时零拷贝,只是引用;若同时再传给别的 actor,in-place 修改会影响 Ray 内部持有的那份,Ray 会打印 warning。

需要 producer 再次写同一块 tensor 时,用 ray.experimental.wait_tensor_freed(tensor) 等 Ray 释放所有引用;注意此时 driver 不要再 ray.get 持有该 ref,否则会死锁。

限制

当前 alpha 状态

  • torch.Tensor,仅 Ray actor(不含普通 task)。
  • 不支持 asyncio(tracking issue)。
  • Gloo / NCCL:
    • 只有 创建 collective group 的进程 能提交返回 / 传递 RDT object 的 actor task。
    • RDT ObjectRef 不能序列化后跨进程传递,只能作为 同 group 内 actor task 的直接参数
    • 每个 actor 在同一 transport 下同时只能属于一个 group。
    • 不支持 ray.put
  • NIXL:同一 actor 上若先后存两个 object、tensor 集合有重叠但不完全相同,当前有已知问题;需等第一个 ObjectRef 出 scope 后再存第二个。

系统级传输错误:Gloo/NCCL collective 失败会 销毁 group 并 kill actor;NIXL 会 abort 并在依赖 task / ray.get 处抛异常。超时可调 RAY_rdt_fetch_fail_timeout_milliseconds

与 RL 训推 infra 的关系

RL 里 actor 间传 rollout buffer、logits、hidden states 若走默认 Plasma object store,GPU 数据会被反复拉到 CPU。RDT 把这条路径收成 actor 间 direct transport,和 NCCL collective、NIXL RDMA 对齐,适合 多 actor 流水线(例如 rollout actor → trainer actor)且 tensor 较大的场景。但 alpha 阶段的 collective group 创建进程限制、可变语义、以及仅 actor 支持,使用前要先对照 workload 评估是否适用。

参考

想着在这个时间点上回顾下模型和模型训练 infra 发展的经历,就以 DS 的技术报告为例吧。

DS 系列模型:

  1. DeepSeek LLM — DeepSeek LLM 7B、DeepSeek LLM 67B Dense(2024/01/05) arXiv:2401.02954
  2. DeepSeek-Coder — 1.3B / 6.7B / 33B(2024/01/25) arXiv:2401.14196
  3. DeepSeekMoE — MoE 语言模型系列 2B / 16B / 145B 等(2024/01/11) arXiv:2401.06066
  4. DeepSeekMath — DeepSeekMath-7B(2024/02/05) arXiv:2402.03300
  5. DeepSeek-V2 — 第二代 MoE 通用大模型(2024/05/07) arXiv:2405.04434
  6. DeepSeek-V2.5 — 通用与代码能力合流迭代(2024/09/06;无单独 arXiv 技术报告,架构见 V2) 官方说明
  7. DeepSeek-V3 — 第三代 MoE 通用大模型(2024/12/27) arXiv:2412.19437
  8. DeepSeek-R1、DeepSeek-R1-Zero(2025/01/22) arXiv:2501.12948

继而再看框架的实现。不是之前不能做,之前这是个浩大的工程。现在借助模型不仅是代码门槛下降了,理解 sota 工作的门槛也下降了,可以抽空广泛的了解起来了,成为新时代的 “全栈” 工程师。

DeepSeek LLM

LLaMA

2T tokens pre train

1M sft, RLHF, SFT → RM → PPO 这条经典 RLHF pipeline

DPO, 不显式训一个单独的 RM、也不做 RL 循环,直接用 偏好对 数据(同一条 prompt 下,人类更喜欢回答 A 而不是 B)去更新语言模型。

SFT -> DPO

模型架构

a Pre-Norm structure with RMSNorm (Zhang and Sennrich, 2019) function

using SwiGLU (Shazeer, 2020) as the activation function

Rotary Embedding (Su et al., 2024) for positional encoding

Grouped Query Attention (GQA)

AdamW optimizer (Loshchilov and Hutter, 2017), with the following hyperparameters: 𝛽1 = 0.9, 𝛽2 = 0.95, and weight_decay = 0.1

HAI-LLM = Megatron 式多并行 + Flash Attention + ZeRO-1 省优化器显存 + 通信计算重叠 + 融合 kernel;数值上用 bf16 算、fp32 攒梯度保稳;最后在 softmax/CE 上用 in-place 省 logits 显存。

DeepSeek-Coder

代码生成和代码补全,专门进行 FIM 代码补全训练

employ HuggingFace Tokenizer library 使用 Byte Pair Encoding 技术在训练语料子集上进行训练得到

基于 DeepSeek LLM 模型架构和训练技术,decode-only transformer, RoPE, GQA, FlashAttention v2

AdamW 优化器

并行策略实现仍然用的自研的 HAI-LLM 框架

超参数 (Hyperparameter) DeepSeek-Coder 1.3B DeepSeek-Coder 6.7B DeepSeek-Coder 33B
隐藏层激活函数 (Hidden Activation) SwiGLU SwiGLU SwiGLU
隐藏层维度 (Hidden size) 2048 4096 7168
中间层维度 (Intermediate size) 5504 11008 19200
隐藏层数 (Hidden layers number) 24 32 62
注意力头数 (Attention heads number) 16 32 56
注意力机制 (Attention) Multi-head Multi-head Grouped-query (8)
批次大小 (Batch Size) 1024 2304 3840
最大学习率 (Max Learning Rate) 5.3×1045.3 \times 10^{-4} (5.3e-45.3\text{e-}4) 4.2×1044.2 \times 10^{-4} (4.2e-44.2\text{e-}4) 3.5×1043.5 \times 10^{-4} (3.5e-43.5\text{e-}4)

DeepSeek-Coder 主系列(1.3B / 6.7B / 33B):from scratch pt 2T -> Base(技术报告:pre-training 含 FIM、context 扩至 16K;DeepSeek-Coder 仓库 README Model Training 两阶段 1.8T@4K + 200B@16K);SFT 2B -> Instruct

DeepSeek-Coder-v1.5(仅 7B):CPT from DeepSeek-LLM 7B,2T@4K(next-token,无 FIM/16K)

DeepSeekMoE

更小(多)的专家 + 共享专家

2B 实验

DeepSeekMath

DeepSeek-V2

DeepSeek-V2.5

DeepSeek-V3

DeepSeek-R1

1. PPO

Proximal Policy Optimization Algorithms

两阶段循环

为什么可以“多轮”

通常情况下,如果对同一批数据进行多轮优化,策略会因为更新过头而崩溃。但 PPO 引入了 Clipped Objective(裁剪目标函数)

  • 安全护栏:在每一轮优化中,PPO 会计算新策略和采样时的旧策略的概率比。如果这个比值超出了设定的范围(比如 0.81.20.8 \sim 1.2),梯度就会被“截断”。
  • 效果:这确保了即使在这一批数据上反复“薅羊毛”优化,新策略也不会跑得离旧策略太远,从而保证了训练的稳定性。

1.1. 采样阶段 (Sampling Phase)

  • 动作:让当前的策略 πθold\pi_{\theta_{old}} 在环境中运行一段时间。
  • 产出:收集一批轨迹数据(包括状态 ss、动作 aa、奖励 rr 等)。
  • 性质:这些数据是“新鲜”的,反映了当前策略的行为模式。

在这个阶段,神经网络的参数是固定不动的(即 θold\theta_{old})。Actor (策略网络):在环境中根据概率分布选择动作。数据收集:把 (st,at,rt,st+1)(s_t, a_t, r_t, s_{t+1}) 存入一个临时的 Buffer。目标:收集足够数量的轨迹(比如 2048 个时间步)。

1.1.1. 计算“标签” (Preprocessing)

在开始训练前,利用收集到的数据计算两个关键值:

  • A^t\hat{A}_t (Advantage):优势函数,用来衡量这个动作比平均水平好多少。
  • RtR_t (Returns):这一步动作带来的累积奖励。

注意到

  • rt(θ)r_t(\theta):新旧策略概率比(用于 Actor)。
  • A^t\hat{A}_t:优势估计(用于 Actor,决定更新方向)。
  • RtR_t:回报目标值(用于 Critic,提升估值精度)。

如果只用即时奖励 rtr_t 作为目标,Critic 就会变得非常“短视”。即时奖励 rtr_t:只代表当前这一步的好坏。回报目标 RtR_t:代表从当前时刻起,在轨迹剩余部分上累计(折现)后的总回报。目标是让 Critic 具备“向前看”的能力,因此用 V(st)V(s_t) 去拟合这个 RtR_t

Rt=A^t+V(st)R_t = \hat{A}_t + V(s_t)

RtR_t (Returns):作为 Critic 网络的监督信号(标签)。

  • 计算逻辑:通过 A^t\hat{A}_t(优势)与采样时旧的 V(st)V(s_t) 相加得到:Rt=A^t+V(st)R_t = \hat{A}_t + V(s_t)
  • 物理意义:它代表了在当前策略下,从状态 sts_t 开始预期能获得的折现总奖励。Critic 的优化目标就是让预测值 Vθ(st)V_\theta(s_t) 尽可能接近这个 RtR_t

这意味着:

  1. 先用 GAE 算出了优势估计 A^t\hat{A}_t
  2. 通过 A^t+V(st)\hat{A}_t + V(s_t),便可反向推导出这一步动作对应的“目标回报” RtR_t
  3. 价值损失 (Value Loss) 就变成了:MSE(Vnew(st),Rt)MSE(V_{new}(s_t), R_t)

1.1.2. 小结

  • Actor:利用 A^t\hat{A}_t(相对好坏)来决定 θ\theta 的更新方向。
  • Critic:利用 RtR_t(绝对得分)来修正自己对世界的认知。

1.2. 优化阶段 (Optimization Phase)

多轮优化 (Several Epochs)

  • 动作:将刚才采样的这一批数据反复输入神经网络进行多次梯度更新。
  • 关键点:在传统的 On-policy 算法(如普通的策略梯度)中,这批数据更新一次就必须扔掉。但 PPO 允许在同一批数据上跑 3 轮、5 轮甚至 10 轮(Epochs)。

要把 Buffer 里的数据,分成更小的 Mini-batches,重复训练 KK 个 Epochs(比如 K=10K=10)。在每一个 Epoch 里的微观操作:计算概率比 rt(θ)r_t(\theta):用当前正在更新的 θ\theta 计算动作概率,除以采样时的 θold\theta_{old} 计算的概率。应用裁剪 CLIPCLIP:如果 rt(θ)r_t(\theta) 偏离 1 太远(比如超过 20%),就强行截断。梯度更新:通过反向传播更新参数 θ\theta

为什么 rt(θ)r_t(\theta) 允许“多轮更新”。PPO 能够从 On-policy 转向近乎 Off-policy 的理论支柱,PPO 本质上是利用了重要性采样技术。

  • 理论背景:优化目标是新策略 πθ\pi_\theta,但训练数据来自旧策略 πθold\pi_{\theta_{old}} 的采样分布。
  • 补偿机制:通过概率比率 rt(θ)r_t(\theta),对数据分布偏差做重要性采样修正。
  • 约束:重要性采样要求两个分布不能差太远,否则方差会爆炸。这正是 LCLIPL^{CLIP} 存在的根本原因——它在数学上维护了重要性采样的有效区间。

1.2.1. 优势估计

通常采用 GAE (Generalized Advantage Estimation)。

简单来说,优势函数 A^t\hat{A}_t 的目标是回答:“在状态 sts_t 下采取动作 ata_t,比平均情况(即 Baseline)好多少?”

1.2.1.1. 计算时序差分残差(Temporal Difference Error)

首先计算每一个时间步的即时偏差 δt\delta_t。它衡量了“实际观测到的奖励 + 下一步的估值”与“当前估值”之间的差距:

δt=rt+γV(st+1)V(st)\delta_t = r_t + \gamma V(s_{t+1}) - V(s_t)

  • rtr_t:当前步获得的奖励。
  • V(st+1)V(s_{t+1}):神经网络(Critic)对下一步状态的估值。
  • V(st)V(s_t):神经网络(Critic)对当前状态的估值。

1.2.1.2. 累加衰减

[0, T)

优势估计 A^t\hat{A}_t 不是只看当前这一步,而是要把未来的 δ\delta 都考虑进来,但要进行指数衰减。公式如下:

A^t=δt+(γλ)δt+1+(γλ)2δt+2++(γλ)T1tδT1\hat{A}_t = \delta_t + (\gamma\lambda)\delta_{t+1} + (\gamma\lambda)^2\delta_{t+2} + \cdots + (\gamma\lambda)^{T-1-t}\delta_{T-1}

这里有两个关键的超参数:

  • γ\gamma (Gamma):折扣因子(通常 0.99),决定了对远期奖励的重视程度。
  • λ\lambda (Lambda):GAE 因子(通常 0.95),用于在偏差(Bias)和方差(Variance)之间做权衡。

实现时,逆序(t)计算

  • 如果 λ=0\lambda = 0A^t=δt\hat{A}_t = \delta_t。这叫 1-step TD。它很稳定(方差小),但如果 VV 函数估值不准,它就会错得离谱(偏差大)。

  • 如果 λ=1\lambda = 1A^t\hat{A}_t 变成了从当前步到截断点 TT 的所有奖励累加。这很真实(无偏差),但环境随机性太强,导致数值跳变剧烈(方差大)。

这就是 λ\lambda 用于在偏差(Bias)和方差(Variance)之间做权衡的物理意义。PPO 选取 λ=0.95\lambda = 0.95 它在“相信神经网络的估值”和“相信实际观测到的奖励”之间取了一个折中。

1.2.1.3. 标准化 (Advantage Normalization)

在算出 TT 个时间步的所有 A^t\hat{A}_t 后,工程上通常会进行一次标准化处理:

A^t=A^tmean(A^)std(A^)+108\hat{A}_t = \frac{\hat{A}_t - \text{mean}(\hat{A})}{\text{std}(\hat{A}) + 10^{-8}}

  • 稳定梯度:在一个 Batch 中,优势值的数值跨度可能很大。标准化后,它们的均值为 0,标准差为 1。
  • 逻辑闭环:这确保了在一个 Batch 里,大约有一半的动作会被认为是“好于平均”(正值,增加概率),另一半是“差于平均”(负值,减小概率)。这对于 Adam 优化器的稳定收敛极其重要。

1.2.1.4. 总结计算流程

rt(θ)=πθ(atst)πθold(atst)r_t(\theta) = \frac{\pi_\theta(a_t | s_t)}{\pi_{\theta_{old}}(a_t | s_t)}

  1. 运行 TT 步采样,收集所有的 rr 概率比例和 VV 状态价值。
  2. 从后往前计算(这样可以用 At+1A_{t+1} 算出 AtA_t):
  • At=δt+(γλ)At+1A_t = \delta_t + (\gamma\lambda) A_{t+1}
  1. 对整个 Batch 进行标准化。
  2. 将算好的 A^\hat{A} 输入 LCLIPL^{CLIP} 进行优化。

1.2.2. 损失函数

优势估计 A^t\hat{A}_t 和概率比率 rt(θ)r_t(\theta) 都准备好了,进入 PPO 执行阶段构建 Loss 函数并进行参数更新

Adam 更新时并不是「三个互不相关的 loss 各算各的」,而是把 策略裁剪项、价值拟合项、熵项 合成 一个标量目标(再按实现约定取正/取负)做一次反传。

总损失函数 LtCLIP+VF+SL^{CLIP+VF+S}_t 通常长这样:

Lttotal(θ)=LtCLIP(θ)c1LtVF(θ)+c2S[πθ](st)L_t^{total}(\theta) = L_t^{CLIP}(\theta) - c_1 L_t^{VF}(\theta) + c_2 S[\pi_\theta](s_t)

其中 价值项前面是减号、熵项前面是加号(与 c1,c2c_1,c_2 一起决定「多拟合价值 / 多鼓励随机」的强度)。如框图里写「L_clip + L_V + 熵」往往只是 并列这三类成分都会进同一轮梯度表示数学上三项都是同号的「单纯相加」——具体 + / - 以代码里 loss = … 的写法为准(常见做法是对「要最大化的 surrogate代理目标:用样本可算的式子近似真实策略改进)」整体取负再交给优化器 minimize)。

LCLIP(θ)=E^t[min(rt(θ)A^t,clip(rt(θ),1ϵ,1+ϵ)A^t)]L^{CLIP}(\theta) = \hat{\mathbb{E}}_t \left[ \min \left( r_t(\theta) \hat{A}_t, \text{clip}(r_t(\theta), 1 - \epsilon, 1 + \epsilon) \hat{A}_t \right) \right]

这三个部分分工明确:

  • LtCLIP(θ)L_t^{CLIP}(\theta) (策略损失):利用 A^t\hat{A}_trt(θ)r_t(\theta) 进行裁剪优化。直观上,它会在优势为正时提高动作概率,同时用 clip 限制单次更新幅度,避免策略变化过快。
  • LtVF(θ)L_t^{VF}(\theta) (价值损失):通常是均方误差 MSE(Vθ(st),Vtarget)MSE(V_\theta(s_t), V_{target})。它负责让 Critic 的状态价值预测更贴近目标回报(更准确)。
  • S[πθ](st)S[\pi_\theta](s_t)entropy bonus,熵奖励 / 熵正则项):在目标里加一项与策略分布的 Shannon 熵 成正比的奖励,鼓励动作分布别太快变成「几乎总选某几个动作」;直观上就是 多留一点随机性、减缓过早收敛(文献与代码里也常写 entropy regularizationpolicy entropy)。

MSE 均方误差

1.2.2.1. 执行 Adam 更新

Adam 优化器, 梯度下降 (Gradient Descent)

有了总损失后,流程如下:

  1. 计算梯度:对总损失关于参数 θ\theta 求导(即之前提到的 L wrt θL \text{ wrt } \theta)。
  2. 反向传播:将梯度传回神经网络。
  3. 参数更新:Adam 优化器根据动量和自适应学习率微调 θ\theta

进入 KK 个 Epoch 的循环

针对同一批采样数据(那 NTNT 个样本),反复进行 KK 次上述的“计算 Loss -> 更新参数”过程。

  • 在第 1 遍时:rt(θold)=1r_t(\theta_{old}) = 1,概率比退化为恒等映射,更新等价于未做分布修正的常规梯度步。
  • 在第 KK 遍时:由于参数已经改了好几次,新旧策略的偏差 rt(θ)r_t(\theta) 可能会很大。这时候 Clipping(裁剪) 就会大显身手,强行把那些偏移过大的梯度归零,防止模型跑飞。

注:虽然 PPO 的理论目标是最大化奖励,但在代码实现中,通常会对总目标函数取负值,将其转化为最小化损失,从而用 Adam 等优化器做梯度更新。

1.2.2.2. 更新旧策略

θoldθ\theta_{old} \leftarrow \theta

KK 次迭代结束,这一批数据的价值就被“榨干”了。
此时,把当前的最新参数 θ\theta 赋值给 θold\theta_{old}。然后清空缓存的数据,回到环境里,开启下一轮 N×TN \times T 的数据采集。

1.3. Hyperparameters 参考

参数 常用值 作用
ϵ\epsilon 0.10.20.1 \sim 0.2 裁剪阈值,限制单次更新步长
γ\gamma 0.990.99 长期奖励折扣因子
λ\lambda 0.950.95 GAE 平衡因子
c1c_1 0.50.5 价值损失权重(MSE 权重)
c2c_2 0.010.01 entropy coefficient(熵项权重):调大则更鼓励探索、策略更「散」;调小则更贴 reward、更易早收敛
KK 3103 \sim 10 每个 Batch 的重复训练次数(Epochs)

2. RLHF 中的 PPO

在很多 LLM 对齐/偏好优化的工程实现里,会看到 “PPO + reference model(参考模型)”。这很容易让人误以为 reference model 是 PPO 论文(Schulman 2017)的一部分;但严格来说,它是 RLHF 场景下额外加入的约束/正则,用来防止策略为了刷 reward 而跑飞(reward hacking、语言退化、分布崩坏等)。

2.1. RLHF 训练 flow

SFT → RM → PPO

可以把最常见的 RLHF 流程理解成三段:

  1. SFT:用高质量指令数据把模型先教会“基本说话方式”,得到 πSFT\pi_{\text{SFT}};它常常也会作为后面的 πref\pi_{ref}(冻结参考模型)
  2. Reward Model(RM):用偏好数据训练一个打分器 R(x,y)R(x,y)(或 rϕ(x,y)r_\phi(x,y)),用于刻画“在相同输入下,哪些输出更受偏好”。
  3. PPO-RLHF:从 πSFT\pi_{\text{SFT}} 初始化可训练策略 πθ\pi_\theta,用 PPO 提高 RR,同时用 KL-to-referenceπθ\pi_\theta 拴在 πref\pi_{ref} 附近。

PPO-RLHF 的实现,通常就是把“文本生成”当成一条轨迹上的序列决策,然后复用前边提到的 PPO 两阶段循环:

  • 自回归 MDP(最常见的设定):第 tt 步的“动作”是下一个 token yty_t;状态可以抽象成 (x,y<t)(x,y_{<t})
  • Rollout:用 πθold\pi_{\theta_{old}} 采样一批 completions(得到 token 轨迹与 logprob)。
  • Reward / shaping:把 RM 分数与 KL shaping 组合成每步可用的标量回报信号(工程上常见是把 KL 摊到 token;RM 可能是序列末一次性给分,也可能有更细的 shaping,取决于实现)。
    • reward shaping 在这里可以直观理解为:不只给“最后好不好”的稀疏信号,而是额外构造/改写一组更密、更及时的逐步回报,让 PPO 在生成过程中更容易学、也更可控;其中 per-token 的 KL 项就是很典型的 shaping。
    • RM shaping 则更具体:指把 reward model 的偏好信号从“只在结尾给一次分”,扩展成更稠密的过程性反馈(例如分段打分、对关键子结构/步骤给增量奖励、或把可验证规则与 RM 组合成逐步项)。不同系统差异很大;设计不当也可能让模型去“刷 RM shaping”而不是真正提升偏好质量,因此通常仍会配合 KL-to-reference 与谨慎的系数/裁剪。
  • Optimization:在同一批数据上算优势(GAE),再按实现把 LCLIPL^{CLIP}、value loss、entropy bonus 合成 一个标量 lossKK 个 epoch;最后更新 θoldθ\theta_{old}\leftarrow\theta,进入下一轮 rollout。

一句话总结:RM 给方向,πref\pi_{ref} + KL 给长期护栏,PPO(尤其 clipping)给短期稳定更新

2.1.1. 模块框图

下图按常见实现,把模块分成两类:

一类是 在进入 PPO 对齐之前就已经训好、此阶段通常不再更新的模型reference(多为 SFT 得到的 πref\pi_{ref},作锚点)与 reward model(在偏好数据上训好的打分器)。工程图里常把它们画成 external / frozen:参数固定,只提供 KL-to-referencereward / scoring 等信号。

另一类是 当前正在被 PPO 更新的策略网络Rolloutπθold\pi_{\theta_{old}} 采样——它不是另一套独立权重,而是与 Actor 同一组参数、上一轮留下的策略快照ActorCritic(常为同一 backbone 上的 policy / value head)把各步里由 RM、KL 等拼出的标量 reward 写成 rtr_t,再经 GAEPPO loss 反传更新 θ\theta;最后 θoldθ\theta_{old}\leftarrow\theta,进入下一轮 rollout

PPO-RLHF 模块关系

2.2. 两个“旧策略”不要混

PPO 里几乎总会涉及旧策略,但它通常指的是:

  • πθold\pi_{\theta_{old}}(PPO 的 old policy):上一轮采样用的策略快照,用于重要性采样比率

    rt(θ)=πθ(atst)πθold(atst)r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)}

    它是 每一轮都会更新 的。

而 RLHF 工程里常说的 reference model 一般是:

  • πref\pi_{ref}(RLHF 的 reference policy/model):冻结的锚点模型(常见做法是 SFT 后的模型),用于给当前策略加一个 “别偏太远” 的约束;它通常在一段训练期间 保持不变 或更新频率很低。

2.3. KL-to-reference:把“别跑飞”写进目标

以 PPO-RLHF 常见写法为例,会把 reward 加上一个 KL 惩罚(或等价的 reward shaping):

R(x,y)=R(x,y)βKL(πθ(x)  πref(x))R'(x, y) = R(x, y) - \beta \, \mathrm{KL}\left(\pi_\theta(\cdot|x)\ \|\ \pi_{ref}(\cdot|x)\right)

这里的符号可以按“一条 RLHF 训练样本”来理解:

  • xx:prompt / 输入上下文(用户问题、题目、对话历史等)
  • yy:response / 输出序列(模型在 xx 条件下生成的整段回答 token 序列)
  • R(x,y)R(x, y):在输入 xx 下输出 yy 的奖励(来自 reward model、规则打分等)
  • KL(πθ(x)  πref(x))\mathrm{KL}(\pi_\theta(\cdot|x)\ \|\ \pi_{ref}(\cdot|x)):在同一个输入 xx 条件下,当前策略相对 reference policy 的分布偏离程度

于是 PPO 实际最大化的是 “奖励 - 偏离 reference 的代价”。直觉上:

  • 如果只追 RR:模型会倾向于钻 reward 的空子,偏离语言先验越来越大。
  • 加上 KL:reference model 提供了一个长期锚点,PPO 的 clipped update 提供了一个短期的“每步别迈太大”,两者一起让训练更稳。

备注:不同实现里 KL 可能以多种形式进入(显式 KL penalty、或把 per-token logprob 差写进 reward),但核心都是 “把策略拴在 πref\pi_{ref} 附近”。

一个常见的工程视角是把 KL “摊平”到 token 级别。设输出序列 y=(y1,,yT)y=(y_1,\dots,y_T),则

在自回归语言模型里,这里的 时间步 tt 通常就是“生成第 tt 个 token 的那一步”(也就是 token index):

  • yty_t:第 tt 步采样得到的那个 token
  • y<t=(y1,,yt1)y_{<t}=(y_1,\dots,y_{t-1}):到第 tt 步之前已经生成的前缀(第 1 步时为空前缀)

因此 TT 就是这条输出序列的长度(token 数)。这和传统 RL 里“环境每走一步”的时间轴可以不同:在 LLM 文本生成里,“一步”往往等价于“再生成一个 token”

logπθ(yx)logπref(yx)=t=1T(logπθ(ytx,y<t)logπref(ytx,y<t))\log \pi_\theta(y|x) - \log \pi_{ref}(y|x) = \sum_{t=1}^T \Big(\log \pi_\theta(y_t|x,y_{<t}) - \log \pi_{ref}(y_t|x,y_{<t})\Big)

如果只关心当前采样到的这条序列(on-policy 轨迹)上的惩罚,那么很多实现会定义一个 token 级别的“KL 代价”:

rtKLβ(logπθ(ytx,y<t)logπref(ytx,y<t))r^{KL}_t \triangleq -\beta\Big(\log \pi_\theta(y_t|x,y_{<t}) - \log \pi_{ref}(y_t|x,y_{<t})\Big)

这里的 logπθ(ytx,y<t)\log \pi_\theta(y_t|x,y_{<t})(logprob)就是:策略模型在时间步 tt 给出的“下一个 token”的条件概率分布 πθ(x,y<t)\pi_\theta(\cdot|x,y_{<t}) 中,取到实际 token yty_t 的概率再取对数(通常取自然对数)。

然后把它加进每一步的 reward(reward shaping)。这样累加起来就是序列级别的 logprob 差惩罚:

t=1TrtKL=β(logπθ(yx)logπref(yx))\sum_{t=1}^T r^{KL}_t = -\beta\Big(\log \pi_\theta(y|x) - \log \pi_{ref}(y|x)\Big)

直觉上:如果某个 token 在当前策略下的概率比 reference 更大(logπθlogπref>0\log \pi_\theta - \log \pi_{ref} > 0),那它会产生负的 shaping reward(惩罚),从而抑制策略在该方向上“越走越远”。

2.4. 推荐阅读

  • Ouyang et al., 2022. Training language models to follow instructions with human feedback (InstructGPT).(SFT → RM → PPO,以及 KL/reference 的由来)
  • Stiennon et al., 2020. Learning to summarize with human feedback.(更早期、端到端的 RLHF 案例)
  • Ziegler et al., 2019. Fine-Tuning Language Models from Human Preferences.(偏好优化 + KL 正则的直观版本)

扩展(对比视角,理解“reference 并非 PPO 专属”):

  • Rafailov et al., 2023. Direct Preference Optimization (DPO).(绕开 RM 与 PPO,但同样体现 anchor/reference 的思想)

3. GRPO:从 PPO / RLHF 再往前走一小步

前文将 PPO 概括为“稳定的策略更新框架”,将 RLHF 概括为“RM + KL-to-reference + PPO”的常见落地形态。进一步地,在 数学推理 / 可验证奖励 这类场景里,训练目标仍然可以用 PPO 的 clipped objective,但 优势(advantage)与 baseline 的估计往往会变得更棘手。

GRPO(Group Relative Policy Optimization) 是在 DeepSeekMath 里提出的、PPO 的一个变体:动机之一是让 RL 在 LLM 场景里更省资源,同时处理 “reward 往往只在序列末出现、但 value 需要 token 级别监督” 这类不匹配。

这一节我按“从 PPO 视角推出来”的方式把 GRPO 的核心写清楚:它仍然用 PPO 的 ratio + clip 来做稳定更新,但把 critic/value baseline 换成了「同题采样组内」的相对基线

  • 仍然很 PPO:整体还是围绕 clipped ratio 的策略更新思路在转(可以把它理解成“骨架仍在 PPO”)。
  • 关键变化:去掉 value模型 / critic:GRPO 不再额外训练一个与 policy 同量级的 value function 来给每个 token 做 baseline。
  • 用 group 做相对基线:对同一个问题 qq,先从旧策略采样一组输出 {o1,,oG}\{o_1,\dots,o_G\},再用 组内相对比较 来构造优势(论文强调这与 reward model 常见的“同题对比训练”更一致)。
  • KL 处理方式也可能不同:论文里也讨论了与 PPO 场景下 KL penalty 不同的正则化思路(读 4.1 小节时对照实现会更清晰)。

3.1. 训练数据形态:同一个 prompt 采样一组

把单条 RLHF 样本写成 (q,o)(q, o)

  • qq:问题 / prompt
  • oo:一次完整的输出序列(completion),长度为 TT

GRPO 的一个关键设定是:对同一个 qq,从旧策略采样 GG 条输出

o1,,oGπθold(q)o_1,\dots,o_G \sim \pi_{\theta_{old}}(\cdot|q)

然后对每条输出打分得到标量奖励(常见是 sequence-level):

riR(q,oi),i=1,,Gr_i \triangleq R(q, o_i),\quad i=1,\dots,G

在数学推理/可验证任务里,RR 往往是 rule-based(对/错、部分分、格式约束等)或 “RM + verifier + 规则” 的组合;它通常更像“末端一次性”信号,而不是密集的 token-level reward。

3.2. 组内相对基线:用同题均值/标准差构造 advantage

在 PPO 里我们常用 critic 给 baseline:A^tQ(st,at)V(st)\hat{A}_t \approx Q(s_t,a_t)-V(s_t)。但对 LLM 这种“奖励末端给、价值却要逐 token 监督”的设置,value 训练既贵又容易引入偏差(尤其当 reward 很稀疏)。

GRPO 的做法是:不训练 VV,直接在同一个 qq 的组内做相对标准化。最直观的一种(也最常见的工程落地)是:

μq=1Gj=1Grj,σq=1Gj=1G(rjμq)2+ε\mu_q = \frac{1}{G}\sum_{j=1}^G r_j,\qquad \sigma_q = \sqrt{\frac{1}{G}\sum_{j=1}^G (r_j-\mu_q)^2} + \varepsilon

AiriμqσqA_i \triangleq \frac{r_i - \mu_q}{\sigma_q}

解释一下这个 AiA_i

  • 它是“相对优势”:同一道题里,高于组均值的输出会得到正优势(鼓励),低于均值的得到负优势(抑制)。
  • 它天然做了尺度归一:不同题的 reward 尺度可能不同(0/1、0/100、log score…),用组内标准差能把不同样本的梯度量级拉到同一量纲。

你可以把它类比成你前面写的 advantage normalization,只是这里的 normalization 不是在“全 batch”,而是在“同 prompt 的 group 内”做。

一个常见的细节:虽然 rir_i 是序列级分数,但优化是 token 级 logprob。工程上通常直接把 同一个 AiA_i 广播到这条序列的每个 token,等价于“这条输出整体好/坏,整条序列的 token 都一起被上调/下调概率”,写成:

Ai,tAi,t=1,,TiA_{i,t} \equiv A_i,\quad t=1,\dots,T_i

3.3. 还是 PPO:ratio + clip 的策略更新目标

对每条输出 oi=(yi,1,,yi,Ti)o_i=(y_{i,1},\dots,y_{i,T_i}),我们可以写出 token 级的 ratio(沿用 PPO 的重要性采样比):

ri,t(θ)πθ(yi,tq,yi,<t)πθold(yi,tq,yi,<t)r_{i,t}(\theta) \triangleq \frac{\pi_\theta(y_{i,t}\mid q, y_{i,<t})}{\pi_{\theta_{old}}(y_{i,t}\mid q, y_{i,<t})}

那么 GRPO 的“PPO 样式” clipped objective 可以写成(对所有样本、所有 token 求平均):

LGRPO(θ)=E^i,t[min(ri,t(θ)Ai,  clip(ri,t(θ),1ϵ,1+ϵ)Ai)]L^{GRPO}(\theta)= \hat{\mathbb{E}}_{i,t}\left[ \min\Big( r_{i,t}(\theta) A_i,\; \text{clip}(r_{i,t}(\theta),1-\epsilon,1+\epsilon)A_i \Big) \right]

你会发现它和你在 1.2.2 写的 LCLIPL^{CLIP} 形状完全一致,只不过:

  • PPO 的 A^t\hat{A}_t 来自 GAE + critic(或至少来自某种时间分解)
  • GRPO 的 AiA_i 来自 同题 group 的相对基线(没有 critic)

3.4. KL 正则:仍然可以用 reference model 作为长期护栏

GRPO 并不排斥 “reference model + KL” 这个工程护栏。常见做法依旧是把 KL 以 shaping 的方式加进 reward 或直接加进目标。

沿用你前面 token 级 logprob 差的写法,对每个 token:

ri,tKLβ(logπθ(yi,tq,yi,<t)logπref(yi,tq,yi,<t))r^{KL}_{i,t} \triangleq -\beta\Big(\log \pi_\theta(y_{i,t}\mid q,y_{i,<t})-\log \pi_{ref}(y_{i,t}\mid q,y_{i,<t})\Big)

然后把序列的“有效奖励”写成:

ri=ri+t=1Tiri,tKLr_i' = r_i + \sum_{t=1}^{T_i} r^{KL}_{i,t}

再用 rir_i' 去算组内的 μq,σq,Ai\mu_q,\sigma_q,A_i(或者只把 KL 当作单独 penalty 项,工程上两种都见过)。直觉上:group 相对基线解决“不要 critic 也能构造稳定方向”,KL 解决“不要跑飞”

3.5. 对比 PPO

把 GRPO 和 PPO-RLHF 放在同一张心智模型里:

  • 相同点(都像 PPO):都有 ratio + clip,所以都允许对同一批 rollout 做多轮 epoch 更新。
  • 不同点 1:baseline 来源
    • PPO:V(s)V(s)(critic)提供 baseline,优势有时间结构(GAE)
    • GRPO:同题 group 的均值/方差提供 baseline,优势更像“同题排序/对比”的信号
  • 不同点 2:资源与稳定性 trade-off
    • 去掉 critic 通常更省显存/算力、实现也更直接
    • 但会更依赖:采样组大小 GG、reward 的区分度、以及 KL/clip 的护栏强度

3.6. 实现要点

  • GG 的作用很关键GG 太小,μq,σq\mu_q,\sigma_q 噪声大;太大则 rollout 成本上升。实践里会把 GG 作为“用采样换稳定”的旋钮。
  • σq\sigma_q 保护:当同组 reward 全相等(比如全错、全对),σq0\sigma_q \approx 0,需要加 ε\varepsilon,否则优势会爆。
  • 长度偏置:如果把同一个 AiA_i 广播到 token,再对 token 平均,长序列会贡献更多项。常见缓解:对每条序列先按 token 平均再按样本平均(或对每条样本按长度归一)。
  • old policy 的 logprob 要缓存:和 PPO 一样,rollout 时必须存 logπθold(yi,tq,yi,<t)\log \pi_{\theta_{old}}(y_{i,t}|q,y_{i,<t}),优化阶段才能算 ratio。
  • reward 在 group 内算 baseline:baseline 的计算单位是 “同一个 qq 的 group”,不要把不同 prompt 混一起算均值/方差(否则失去“相对比较”的意义)。

3.7. 推荐阅读

  • Shao et al., 2024. DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models.(GRPO 提出与动机)
  • 如果你关心“无 critic 的 PPO 变体/相对优势”的谱系,可以把 GRPO 放到“对比学习式偏好信号 + KL 护栏 + clipped update”的框架里去理解:它更像把“对比/排序”当成 advantage 的来源,而不是显式学习 VV

在 KubeRay 里,Ray Job 由 Ray Cluster 承载与管理,真正的难点往往在于 如何把 Ray Job 与 Ray Cluster 的生命周期对齐

rayjob-raycluster

先看通用 Job:常用 init container 拉数据、下发配置等;init 失败即整次 Job 失败,这很直观。

Ray Job 不同:它并不是「那一组实际跑在集群里的 Pod」——资源实体是 Ray Cluster;所谓 Ray Job 的 init container,也落在 Cluster 侧。结果是 Job 侧的 init 语义,会和 Cluster 的 init / bootstrap 语义绑在一起

  • 站在 Cluster 视角:init 失败时反复重试直到 bootstrap 成功,常常说得通——先得把集群建立起来。
  • 站在 Job 视角:Job 是一次性任务,init 失败更合理的预期是 fail fast,而不是长期跟着 Cluster 重试。

也是在借助大模型拆解 issue、梳理场景,并对照代码与线上行为逐项验证的过程中,才逐渐理解:Ray Job 对 init container 的生命周期管理,很难用一套简单直白、一步到位的规则实现。

1h vibe issue, 8h vibe coding
70M tokens cost

https://github.com/ray-project/kuberay/issues/4637

两种典型模式:

  • 新建 Ray Cluster:Ray Job 的 init container 会生效;在这条路径下,它实际就是跑在 Ray Cluster 上的 init container,与 Cluster 的 bootstrap 同一条链路。
  • 使用已有 Ray Cluster:Ray Job 的 init container 不生效;Job 只消费已有 Cluster,不会为本次 Job 再单独跑一轮 init。

Cluster 自身的生命周期也要分开看:

  • Job 新建的 Cluster:可用 Ray Job 的 delete rule 决定在 Job 结束后是否删除 Cluster / Workers 等;默认为保留 Cluster
  • 沿用已有 Cluster:Ray Job 结束 不改变 Cluster 的生命周期(Cluster 可能继续服务其他任务或由别处托管)。

回到 Ray Job 自定义 init 失败——这发生在 Job 新建并绑定的专属 Cluster 上。Job 结束后如果 Cluster 长期保留,语义上确实容易别扭;而更合理的模式通常是 短时间保留现场(以收集日志和进行问题诊断),然后自动回收这个临时 Cluster。这本质上是一种「单次 Job + 一套临时 Cluster」的短生命期部署方式,与长期共用 Cluster 是两套完全不同的心智模型。

不过需要注意,当前 Ray Job 实际上并不支持这样的能力:Job 自定义 init 失败后,Job 仍然处于 initializing 状态,系统还不会自动实现「短暂保留现场再回收 Cluster」的行为。可以继续 vibe issue, 基于 issue vibe coding。

尚未系统整理,先记一个粗判断:整体架构在走向成熟,部署形态普遍解耦——不止训推分离,还出现了 Agent 应用与训推平台、训推 API(如 Tinker API)、训推框架的分层

在这种形态下,常见会并行做两件事:一是用 OpenTelemetry(以 spans 为主) 做标准化 trace,沉淀模型 / Agent 的行为轨迹,再回流进 RL 训练闭环;二是通过 LLM Proxy 统一 Agent 侧使用的模型 API,在训练态把请求 转发到当前正在更新的模型,由它承担 RL 里的推理侧,避免应用侧调用与训练态模型服务两条路径对不齐。

关于轨迹记录与训练回流,直觉上和早年搜索推荐那一套并无本质不同:线上记录与埋点 → 数据回流 → 离线实验与训练

https://www.hiascend.com/document/detail/zh/mindcluster/70rc1/clustersched/dlug/mxdlug_007.html

有如下几类 configmap

  • cmDevice: ns, kube-system; cmName, mindx-dl-deviceinfo-{NodeName}; which is reported by device-plugin
  • cmNode: ns, mindx-dl; cmName, mindx-dl-nodeinfo-{NodeName}; which is reported by nodeD
  • cmPingMesh: ns, cluster-system; cmName, pingmesh-config;
  • cmSuperPodDevice: ns, cluster-system; cmName, super-pod-{SuperPodId}; clusterD 维护
    • 特别的 {RAS_NET_ROOT_PATH}/cluster/super-pod-{SuperPodId}/super-pod-{SuperPodId}.json; clusterD 维护
  • cmPubicFault: mc-consumer-publicfault=true label;

其中 cmDevice configmap mindx-dl-deviceinfo-{NodeName}, 由 device-plugin 上报, 包括如下信息

  • DeviceInfoCfg
  • SwitchInfoCfg

cmPubicFault configmap, 包括如下信息

  • PublicFault

pingmesh-config 的格式为 global pingmesh 任务的配置或者是指定 superpodid 的任务配置

1
2
3
4
{
"activate": "on",
"task_interval": 5
}

node annotation 中包括如下信息

  • product-serial-number
  • superPodID
  • baseDeviceInfos
  • serverType
  • serverIndex

THP

https://alexandrnikitin.github.io/blog/transparent-hugepages-measuring-the-performance-impact/

增加 page 大小, 从而减少 TLB 大小; 由于 walk TLB 开销较大, 所以是个优化

THP 会让 os 申请连续的内存空间大小, 但如果申请不到, 则 os 会开始 compact, reclaim or page out other pages;

That process is expensive and could cause latency spikes (up to seconds)

cat /proc/buddyinfo

Each column represents the number of pages of a certain order which are
available. In this case, there are 0 chunks of 2^0PAGE_SIZE available in
ZONE_DMA, 4 chunks of 2^1
PAGE_SIZE in ZONE_DMA, 101 chunks of 2^4*PAGE_SIZE
available in ZONE_NORMAL, etc…

https://andorian.blogspot.com/2014/03/making-sense-of-procbuddyinfo.html

https://wangcong.net/article/FPandBP.html

pathways

https://blog.research.google/2022/04/pathways-language-model-palm-scaling-to.html

a single model that could generalize across domains and tasks while being highly efficient. An important milestone toward realizing this vision was to develop the new Pathways system to orchestrate distributed computation for accelerators.

few-shot

TPU v4 Pods

Pipelining is typically used with DCN

word to vector, This vector represents the word’s meaning and context within the given language

embedding layer, lookup table

Positional encoding

https://medium.com/@tech-gumptions/transformer-architecture-simplified-3fb501d461c8

This means that the output of a layer is added to the initial input, allowing the model to learn to only make small changes to the input

The decoder’s job is to produce the English sentence based on both the original French sentence and the bits of the English sentence it has generated so far.

Input Embedding: Just as with the Encoder, the input to the Decoder (which is the target sequence during training) is first embedded into continuous vectors.

It’s important to note that this masking is only applied during training. During inference, the decoder can attend to all words in the target sequence, including future words.

To summarize, the Decoder in the Transformer architecture processes its input through self-attention, cross-attention with the Encoder’s output, and position-wise Feed-Forward networks, repeatedly for each stacked block, culminating in a final output sequence after the softmax operation.

https://jalammar.github.io/illustrated-transformer/

https://nlp.seas.harvard.edu/2018/04/03/attention.html

https://jalammar.github.io/illustrated-gpt2/

PPO/GRPO/重要性采样/拒绝采样

megatron 保存 ckpt 原理

多节点测试依赖 mpi。编译时打开 MPI 开头。

测试时配置多节点 ssh 免密。另外如果是 RoCE 网络,注意正确配置 NCCL 无损队列匹配 RoCE 无损队列。

逐渐调大 size 衡量网络带宽情况。

https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html#nccl-algo

NCCL_ALGO=ring 衡量网络带宽时较为稳定。

0%