Zhangzhe's Blog

The projection of my life.

0%

URL

TL;DR

  • 本文的标题很直白《通过反向传播进行无监督领域自适应》,目标是实现无监督领域自适应。
  • 提出了梯度反转层 (Gradient Reversal Layer, GRL),用于无监督领域自适应任务中,通过在特征提取器和领域分类器之间插入 GRL,实现特征提取器在训练过程中 最大化 领域分类器的损失,从而通过对抗学习到领域不变的特征表示。
  • GAN 的思想有些类似,不过 GAN 的目标是生成,GRL 的目标是表示。

Algorithm

什么是无监督领域自适应

  • 领域自适应 (Domain Adaptation) 是迁移学习 (Transfer Learning) 的核心问题之一,旨在将从源领域 (Source Domain) 学习到的知识迁移到目标领域 (Target Domain)。
    GRL_1.png
  • 比如上图所示,有一批 MNIST 黑底白字的手写数字识别数据集,包含图像和标签,作为源领域;还有一批背景和字体颜色都随机的 MNIST-M 手写数字识别数据集,只有图像没有标签,作为目标领域。- 目标是利用源领域的有标签数据训练一个分类器,并使其在目标领域上也能有较好的性能。

如何实现无监督领域自适应

  • 最直接的方法:在源领域数据上训练,直接迁移到目标领域。但效果显然会很差,因为两个领域的数据分布差异较大。
  • 本文提出的方法:通过对抗训练学习领域不变的特征表示。
    GRL_2.png
  • 模型分成三个部分:
    • 特征提取器 (Feature Extractor, G_f): 提取输入数据的特征表示,上图绿色部分。
    • 标签分类器 (Label Classifier, G_y): 根据特征表示预测标签,上图蓝色部分。
    • 领域分类器 (Domain Classifier, G_d): 根据特征表示预测数据来自哪个领域(源领域或目标领域),上图红色部分。
  • 训练目标:
    • 最小化标签分类器的损失,使其在源领域数据上表现良好。
    • 最大化(注意这里是最大化,不是最小化)领域分类器的损失,使特征提取器学习到领域不变的特征表示。
  • 损失函数:
    • 标签分类器只对源领域数据计算交叉熵损失 LyL_y
    • 领域分类器对源领域和目标领域数据都计算交叉熵损失 LdL_d
    • 两个损失直接求和就是总损失 L=Ly+LdL=L_y + L_d(一定要注意这里没有 λ-\lambda,别被论文带沟里去)。
  • 梯度反转层 (Gradient Reversal Layer, GRL) 如何起作用:
    • 位置:插入在特征提取器和领域分类器之间。
    • 前向传播:GRL 不改变输入,直接将特征传递给领域分类器。
    • 反向传播:GRL 将从领域分类器传回的梯度乘以一个负的常数 ,使得特征提取器在更新时朝着最大化领域分类器损失的方向调整参数。
  • 梯度反转层的数学表达(设输入特征为 xGRL 的输出为 y):
    • 前向传播:y = x
    • 反向传播:dL/dx = -λ * dL/dy
  • 梯度反转层的 PyTorch 实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import torch
from torch import nn
from torch.autograd import Function

class GradientReversal(Function):
@staticmethod
def forward(ctx, x, alpha):
ctx.save_for_backward(x, alpha)
# 啥都不做,透传
return x

@staticmethod
def backward(ctx, grad_output):
grad_input = None
_, alpha = ctx.saved_tensors
if ctx.needs_input_grad[0]:
# 梯度乘以 -alpha 实现反转
grad_input = -alpha * grad_output
return grad_input, None
  • λ\lambda 的调节:从 0 逐渐增加到 1,意义:
    • 训练初期,λ=0\lambda=0,模型主要关注源领域的标签分类任务,确保分类器能学到有用的特征。
    • 随着训练进行,逐渐增加 λ\lambda,模型开始更多地关注领域分类器的对抗任务,促使特征提取器学习到领域不变的特征表示。

Thoughts

  • 很有趣的对抗学习设计,很简单但很有效。
  • 本质就是让领域分类器掌握的领域分类知识泄露给特征提取器,从而让特征提取器不断调整自己提取的特征,使得领域分类器无法区分源领域和目标领域的数据。

URL

TL;DR

  • IndexTTS2BiliBili 提出的一种 TTS 模型,有如下几个特点:
    • 情感表达:能够生成具有特定情感的语音,如快乐、悲伤、愤怒等。
    • 时长控制:可以通过输入一个数字来精确控制生成语音的时长。
    • 零样本学习:无需针对特定说话人进行训练,能够适应新的说话人(常见的 TTS 只提供少量的说话人音色供选择,IndexTTS2 可以适配任何给定样本的音色)。
    • 自回归生成:通过逐步生成语音帧,提升了语音的自然度和连贯性。
  • IndexTTS2 的输入:
    • 源文本 (Source Text):需要转换为语音的文字。
    • 音色提示 (Timbre Prompt):一小段目标说话人的音频,用于提取“音色”特征,决定了合成语音“像谁”。
    • 风格提示 (Style Prompt):一小段带有特定情感的音频,用于提取“情感”特征,决定了合成语音的“情绪”。
    • 语音 Token 数量 (Speech Token Num)(可选):一个数字,用于精确控制生成语音的时长。
  • IndexTTS2 的输出:目标语音 (Target Speech):最终合成的音频波形文件。

Algorithm

0. 基础知识

0.1 语音的表示方法

  • 连续表示:声音的物理基础
    • 数字波形:数字波形(Digital Waveform)是语音最直接、最基础的表示形式。它是通过对连续的模拟声波进行“采样”(Sampling)得到的。采样过程以固定的时间间隔(由采样率决定,如 16000 Hz24000 Hz)测量声波的振幅,从而将连续的信号转换为一个离散的数值序列。这个序列在时间维度上描绘了声音振幅的变化,因此也被称为声音的时域(time domain)表示。
    • 梅尔频谱图:为了解决波形表示的难题,研究者们借鉴了人类听觉系统的特性,提出了一种更高效、更符合感知的表示方法——梅尔频谱图(Mel-Spectrogram)。它是一种时频(time-frequency)表示,描绘了语音信号的能量如何随时间和频率变化。其生成过程大致如下:
      • 分帧与加窗:将长段的音频波形切分成许多短暂的、有重叠的“帧”(frame),并对每一帧应用一个窗函数。
      • 傅里叶变换:对每一帧进行短时傅里叶变换(STFT),得到其频谱,即能量在不同频率上的分布。
      • 梅尔尺度映射:将频谱的频率轴从线性的赫兹(Hz)尺度,映射到梅尔(Mel)尺度。梅尔尺度是一种非线性尺度,它模拟了人耳对频率的感知特性——人耳对低频声音的变化比对高频声音的变化更敏感。
      • 能量取对数:最后,通常会对能量值取对数,使其更符合人类对音量大小的感知。
  • 离散表示:现代语音模型的通用语言
    • 随着自监督学习(Self-Supervised Learning, SSL)的兴起,语音表示领域迎来了第二次、也是更深刻的一次抽象革命:将连续的语音特征离散化为一系列符号,即“语音令牌”(Speech Tokens)。
    • 离散化,或称之为令牌化(Tokenization),是指将连续的高维语音特征向量,映射到一个有限的、离散的符号集合(称为“码本”或“codebook”)中的过程。这个过程通常通过矢量量化(Vector Quantization, VQ)技术实现,例如使用 k-means 聚类算法,将海量语音特征向量聚类成有限个簇,每个簇的中心点就成为了码本中的一个符号(或称为令牌)。
    • 语义令牌(Semantic Tokens):这类令牌旨在捕捉语音的语言学内容,即“说了什么”。它们通常是从大规模自监督学习模型(如HuBERT, WavLM)的中间层特征中提取并聚类得到的。这些 SSL 模型在训练时被要求完成与语音内容相关的任务(如掩码预测),因此其学到的特征富含语义信息,并且在很大程度上与说话人的音色、韵律、口音等无关。
    • 声学令牌(Acoustic Tokens):这类令牌旨在捕捉语音的声学属性,即“听起来怎么样”,包括音色、韵律、音高等信息。它们通常由神经音频编解码器(Neural Audio Codec,如 EnCodec)学习得到。这类模型的训练目标是能够从令牌中高质量地重建原始音频波形,因此令牌必须编码足够丰富的声学细节。

0.2 现代 TTS 模型的架构

  • 端到端流派:输入为文本,输出为波形,中间不做监督。
    • 代表模型为 Char2Wav
    • 缺点:因为原始音频波形的时间分辨率极高(例如,每秒 24000 个采样点),直接建模非常困难。因此难度高、效果差。
  • 两阶段流派
    • 将模型拆分成两个阶段:
      • 一个声学模型(如 Tacotron 2),负责将文本转换为梅尔频谱图这种低维度的声学表示。
      • 一个神经声码器(如 WaveNet, WaveGlow),负责将梅尔频谱图高质量地转换为最终的音频波形。
    • 缺点:如果想在声学模型中加入更多的控制条件(如情感、时长等),会使得声学模型的输入变得非常复杂,难以训练。
  • 三阶段流派
    • 在二阶段的基础上,将声学模型继续拆分成两个子模块:
      • 如文本到语义(Text-to-Semantic, T2S
      • 语义表示到声学表示(如语义令牌到梅尔频谱图,Semantic-to-Mel, S2M
    • 这种三阶段的设计,方便在语义之外加入更多的控制条件(如音色、情感、时长等),并且每个子模块的任务相对单一,易于训练。

1. IndexTTS2 的架构

indextts2_1.png

  • 主要由三部分组成:
    • Text-to-Semantic (T2S):
      • 输入:
        • 文本(待合成的文字)
        • Timbre Prompt(说话人参考音频)
        • Style Prompt(情感参考音频)
        • 可选的 Duration 控制(语义 token 序列长度)
      • 输出
        • 语义 tokensemantic tokens
    • Semantic-to-Mel (S2M):一个基于 flow-matching 的非自回归模型
      • 输入:
        • 语义 tokensemantic tokens
        • 说话人提示 (音色,timbre prompt)
      • 输出:Mel 频谱图
    • Vocoder (BigVGANv2):把 Mel 频谱解码成最终的音频波形

2. Text-to-Semantic 详解

indextts2_2.png

  • 这个模块是模型的核心,采用自回归的 Transformer 架构,负责将文本和其他条件信息转换为中间的语义表征(Semantic Tokens)。
  • 输入:
    • 文本序列 (Text): 经过分词器处理后的文本嵌入 EtextE_{text}
    • 说话人音色提示 (Timbre Prompt): 一段音频,通过预训练的 Speaker Perceiver Conditioner 提取为说话人特征向量 cc
    • 情感风格提示 (Style Prompt): 一段音频,通过 Emotion Perceiver Conditioner 提取为情感嵌入 ee
    • 时长控制信号 (Speech Token Num): 一个可选的数字,指定希望生成的语义令牌数量,被转换为时长嵌入 pp。如果不指定,则用于自由生成。
  • 输出:
    • 语义令牌序列 (Semantic Tokens): 模型预测出的语义令牌序列。
    • GPT 隐层状态 (HGPTH_{GPT}): T2S 模块最后一个 Transformer 层的输出,包含了丰富的文本和上下文信息,会作为增强特征送入后续的 S2M 模块。
  • 监督信号:基准语音 (Ground-Truth Speech)。将基准语音通过语义编码器 (Semantic Codec) 转换成真实的语义令牌序列 EsemE_{sem}
  • 损失函数:交叉熵损失
  • 技巧:使用 GRL + speaker classifier,对抗训练,避免 style 携带 timbre 信息

3. Semantic-to-Mel 详解

indextts2_3.png

  • 该模块基于流匹配 (Flow Matching) 的非自回归框架,负责将 T2S 生成的语义令牌序列合成为梅尔频谱图。
  • 输入:
    • 语义令牌 (QsemQ_{sem}): 来自 T2S 模块的输出。
    • GPT 隐层状态 (HGPTH_{GPT}): 来自 T2S 模块的输出,用于增强语义信息。这两者会通过一个 MLP50% 的概率进行随机融合,形成最终的语义表征 QfinQ_{fin}
    • 说话人嵌入 (Speaker Embedding): 从音色提示音频中提取的说话人特征,以保证音色的一致性。
    • 提示梅尔频谱 (Prompt Mel-spectrograms): 训练时,输入音频会被随机切分为提示段和目标段,提示段的梅尔频谱作为参考。
  • 输出:目标梅尔频谱图 (Target Mel Spectrogram)
  • 训练方式:模型学习一个常微分方程 (ODE),将高斯噪声映射到目标梅尔频谱。训练时,目标段的真实梅尔频谱被完全加噪,模型需要学习去噪并重建它。
  • 监督信号:目标段的真实梅尔频谱图 (ytary_{tar})
  • 损失函数:L1 loss

4. Vocoder 详解

  • 输入:
    • S2M 模块生成的梅尔频谱图 (Mel Spectrogram)。
  • 输出:
    • 最终的音频波形 (Audio Waveform)。
  • 直接使用了训练好的 BigVGANv2 模型

Thoughts

  • TTS 是个很有趣的领域,直觉上看流媒体平台上有大量的语音数据,应该很容易训练一个 TTS 模型,但实际上似乎并不是很容易。
  • GRL 来去除 style 中的 timbre 信息是个不错的想法。

URL

TL;DR

  • 本文主要介绍 Qwen3-Next 架构,由于还没有发正式论文,所以主要参考官方博客和 transformers 实现代码

架构优化

混合架构

qwen3-next.png

  • 与之前使用标准 Scaled Dot-Product Attention(SDPA) 层不同,本次 Qwen3-Next 采用 GatedDeltaNet + GatedAttention 混合的方式构建模型
  • GatedDeltaNet 是一种线性复杂度的注意力机制,在 Mamba2 上改进得到的,详细参考:Gated Delta Networks: Improving Mamba2 with Delta Rule
  • GatedAttention 出自 https://arxiv.org/pdf/2505.06708 ,本质就是在标准 SDPA 之后加入了 Gate 操作:

Output=SDPA(Q,K,V)σ(XWθ)\text{Output}=\text{SDPA}(Q,K,V) \odot \sigma(XW_\theta)

  • 二者层数占比:
    • GatedDeltaNet 占比 75%
    • GatedAttention 占比 25%

极致稀疏 MoE

  • 共有 512 个专家,每次只激活 10 个路由专家 + 1 个共享专家
  • 激活参数只占原参数的 3.7%,因此采用 80B-A3 这种又大又快的模型

训练稳定性友好设计

Zero-Centered RMSNorm

  • GatedAttentionQK Norm (上图中 QKAttention 之前的)用 Zero-Centered RMSNorm

LayerNorm(x)=xμ1N1N(xiμ)2+ϵγ+β\text{LayerNorm}(x) = \frac{x-\mu}{\sqrt{\frac{1}{N}\sum_1^N(x_i-\mu)^2+\epsilon}} \cdot \gamma+\beta

RMSNorm(xi)=x1N1Nxi2+ϵγ\text{RMSNorm}(x_i) = \frac{x}{\sqrt{\frac{1}{N}\sum_1^Nx_i^2+\epsilon}} \cdot \gamma

Zero-Centered RMSNorm(x)=xμ1N1N(xiμ)2+ϵγ\text{Zero-Centered RMSNorm}(x) = \frac{x-\mu}{\sqrt{\frac{1}{N}\sum_1^N(x_i-\mu)^2+\epsilon}} \cdot \gamma

  • 从公式上看 Zero-Centered RMSNorm 本质就是不带 β\betaLayerNorm

MoE router 权重初始化

  • 初始化时归一化了 MoE router 的参数,确保每个 expert 在训练早期都能被无偏地选中,减小初始化对实验结果的扰动

Multi-Token Prediction

  • DeepSeek-V3MTP 的区别是:本 MTP 不仅在训练时候预测多个,推理的时候也预测多个,非常方便 Speculative Decoding

预训练

  • Qwen3-Next 采用的是 Qwen3 36T 预训练语料的一个均匀采样子集,仅包含 15T tokens

Thoughts

  • Qwen3-Next-80B-A3BQwen3-32B 效果更好,速度更快,这主要归功于超稀疏 MoE 带来的计算量显著下降,以及 GatedDeltaNet 带来的平方复杂度到线性复杂度的下降
  • 预训练竟然会对数据做采样使用,这个有点反直觉,后续会关注论文中有没有详细解释

URL

TL;DR

  • 本文提出一种名为 GatedDeltaNet 的神经网络架构,其类型属于状态空间模型 SSM,属于 Mamba2 的改进版本

Algorithms

核心公式

  • 状态更新公式

St=St1(αt(IβtktktT))+βtvtktTS_t=S_{t-1}(\alpha_t(I-\beta_tk_tk_t^T)) + \beta_tv_tk_t^T

  • 输出公式

ot=qtTSto_t = q_t^T S_t

  • 其中:
    • tt:序列位置,0t<L0 \leq t < LLL 为序列长度,之后统称为时间步
    • qtRdq_t\in \mathbb{R}^d:时间步 t 的查询向量
    • ktRdk_t\in \mathbb{R}^d:时间步 t 的键向量
    • vtRdv_t\in \mathbb{R}^d:时间步 t 的值向量
    • StRd×dS_t\in \mathbb{R}^{d \times d}:时间步 t 的状态矩阵,存储的是历史键值相关性矩阵
    • αtR\alpha_t\in \mathbb{R}:时间步 t 的遗忘因子,0<αt10 < \alpha_t \leq 1,控制历史信息的遗忘程度
    • βtR\beta_t\in \mathbb{R}:时间步 t 的更新因子,0βt<10 \leq \beta_t < 1,控制当前信息的更新程度
  • 对比 Mamba2 的状态更新公式

St=αtSt1+vtktTS_t = \alpha_t S_{t-1}+ v_t k_t^T

SSM 结构的优势

  • transformer 的自注意力矩阵是 SRL×LS \in \mathbb{R}^{L \times L},计算和存储成本为 O(L2)O(L^2),其中 LL 是序列长度
  • SSM 的状态矩阵是 SRL×d×dS \in \mathbb{R}^{L\times d \times d},由于 dLd \ll L,计算和存储成本为 O(L)O(L),大大降低了计算复杂度

分块加速

  • 作者对 GatedDeltaNet 的实现做了数学等价的分块加速,repo 名就是 flash-linear-attention
  • 类似 attentionflash-attention 的关系

关于 GatedDeltaNetRWKV-7 两位作者互撕的一些看法

  • 背景:https://zhuanlan.zhihu.com/p/1915054612559426430
  • 省流版本:
    • GatedDeltaNet 的作者 Songlin Yang 在自己的论文中,把 RWKV-7 的表现压的很低,比原论文低很多,然后 RWKV-7 原作者 Peng Bo 质疑 GatedDeltaNet 对比实验中对 RWKV-7 的实现有问题
    • GatedDeltaNet 作者 Songlin Yang 在微信群怒喷 RWKV-7 作者 Peng Bo,让其要么给自己的 fla RepoPR 修复实现,要么闭嘴,随后还将其踢出微信群
  • 个人看法:
    • 对于论文中引用别人论文做 baseline 常出现的无意的有意压低表现的情况,算是行业通病了,但被指出来立正挨打就完了,作者竟然还怒喷对方,要求其帮自己修复实现,合着你发论文,bug 我帮你修?实验我帮你做?这是什么逻辑
    • 虽然 fla 在社区有一些影响力,也有 3.3kstar,但其显然还不是唯一主流的实现库(像 PytorchTransformers 这种级别),写论文必须用 fla 显然不是行业共识,不能要求原作者必须用 fla 去实现自己的算法(who think you are),竟然还要求要么给 PR,要么就把把自己 flaRWKV-7 相关实现全删了。原作者也开源了自己的实现库,这个库可以完全复现论文结果,这一点想必 GatedDeltaNet 作者也清楚
    • 虽然 GatedDeltaNet 能被 Qwen3-Next 这种大模型用上,说明含金量还是有的,但作者的这种行为,实在让人不齿,世界就是一个大的回旋镖,不能等回旋镖打到自己身上才喊疼

URL

TL;DR

  • Agentic Reinforcement Learning (Agentic RL) 是指将大型语言模型(LLM)视作嵌入在交互式决策环境中的可学习策略,而非仅仅作为静态文本生成器来优化单步输出
  • 与常规的基于偏好的序列微调(PBRFT,如 RLHF)只做单回合优化不同,Agentic RL 考虑多回合的状态演化和长期奖励,从单步马尔科夫决策过程(MDP)变成了部分可观测马尔可夫决策过程 (POMDP)

Algorithms

Agentic RL 的定义

  • Agentic Reinforcement Learning (Agentic RL) 是指将大型语言模型(LLM)视作嵌入在交互式决策环境中的可学习策略,而非仅仅作为静态文本生成器来优化单步输出
  • 通过强化学习,Agentic RL 赋予 LLM 规划、推理、工具调用、记忆管理和自我反思等能力,使其在部分可观测、动态环境中产生长期、多步的智能行为

MDP vs POMDP

特性 MDP (马尔可夫决策过程) POMDP (部分可观察马尔可夫决策过程)
可观察性 完全可观察:智能体总是知道它所在的物理状态 部分可观察:智能体无法直接知道物理状态,只能通过观察来推断
决策依据 基于当前物理状态做出决策 基于信念状态(对所有可能物理状态的概率分布)做出决策
状态空间 状态空间由物理状态组成 决策空间在信念空间中,这是一个连续的、更高维度的空间,因此求解起来通常更复杂
计算复杂度 相对较低,有成熟的动态规划算法(如价值迭代、策略迭代) 求解难度更大,通常是 PSPACE-完全问题,因为需要在连续的信念空间中进行规划
适用场景 机器人能用传感器完美定位、国际象棋、简单的棋盘游戏 自动驾驶(传感器有误差)、医疗诊断(医生无法 100% 确定病因)

Agentic RL 和 RLHF 的区别

  • Agentic RL
    • 核心思想:将 LLM 转变为拥有连续交互能力的智能体,而不仅是一次性生成答案的模型
    • Agentic RL 中,智能体在一个 POMDP 中跨越多个时间步进行交互:每次基于当前观测(可能只部分反映真实世界状态)选择行动,环境状态随机转换,并在整个过程中累积稀疏或稠密奖励
  • 传统 RLHF 训练中,一个 Prompt 对应一次输出,训练过程可以形式化为退化的单步 MDP:状态空间仅为给定提示,动作是生成一段文本,动作结束后立即结束回合,奖励依据生成内容质量一次性给出
  • 传统 RLHF 只能优化单句输出的对齐度,而 Agentic RL 则同时涉及多轮规划、动态工具调用、带状态记忆和长程回报的学习,使 LLM 真正成为自主决策的代理人

Agentic RL 的关键组成部分

Agentic RL 智能体通常包括多个相互协作的核心模块,这些模块由 RL 统一优化:

  • 规划 (Planning):规划是在多个步骤上推演行动序列以达成目标。通常情况下是将 LLM 本身视为策略网络,RL 通过与环境的反复试错直接微调其长程规划和执行协调能力
  • 工具使用 (Tool Use)LLM 智能体可以调用外部工具(例如搜索引擎、计算器、代码执行环境等)来扩展能力。传统的 ReAct 风格方法或人工构造的示例往往只能让模型模仿固定的工具调用模式,而 Agentic RL 则通过结果驱动优化,使智能体自主学习何时、如何调用工具
  • 记忆 (Memory):在 Agentic RL 中,记忆不再是被动的内容检索,而是智能体可控制的动态子系统,RL 学习使智能体决定何时存储、检索或删除记忆
  • 推理 (Reasoning)LLM 智能体需要在解决复杂问题时进行多步逻辑推理。通常将推理分为“快推理”(快速、启发式)和“慢推理”(逐步演绎式)
  • 自我改进 (Self-Improvement/Reflection)Agentic RL 强调智能体持续学习和反思自身。智能体能够在执行任务后“自我批评”并改进,具体来说,研究者使用 RLHFDPO 等算法来奖励生成正确/优质轨迹,相当于让模型学会识别和改正错误,从而提高未来推理的可靠性;甚至有尝试让智能体自行生成问题并解答(类似 AlphaZero 的自我博弈),实现无人监督的终身学习循环
  • 感知 (Perception):在多模态环境中,智能体需要感知视觉、听觉等信息并综合语言推理。大型视觉-语言模型(LVLM)通过在视觉输入上附加推理模块,被动感知转向主动视觉认知。Agentic RL 将强化学习应用于视觉-语言任务,使模型在视图下生成多步推理策略

Agentic RL 的奖励设计

  • RLHF 这种稀疏奖励不同,Agentic RL 需要设计更复杂的奖励结构来引导长期行为
  • 如果只在最终任务成功时给予奖励,会出现信用分配问题 (credit assignment),智能体可能难以学习到有效的中间步骤
  • 因此 Agentic RL 更倾向于引入中间奖励 (dense or shaped rewards),往往是基于规则或启发式的,比如:
    • 规划:计划是否合理拆解任务。
    • 记忆:写入/检索是否对最终解答有帮助。
    • 工具使用:API 调用是否成功、是否缩短了解题时间。
    • 推理:中间推理步骤是否能被验证(例如算式对/错)。
  • 这些中间奖励可以是:
    • 显式规则(比如 “子问题答案正确 → +1”)。
    • 自动判别器(比如 单元测试、符号验证器)。
    • 学习的奖励模型(训练一个模型来评估中间步骤质量)。

强化学习算法

  • 还是 PPOGRPODPO 这些常见算法

应用场景与系统实例

  • 搜索与研究助手:智能体利用 RL 优化查询生成和多步检索策略,完成复杂的研究任务
  • 代码生成与软件工程:在编程任务中,执行反馈(如编译成功与否、单元测试结果等)作为奖励信号可直接指导模型优化
  • 视觉与多模态任务:如自动视觉问答、图像编辑与导航等任务,可将视图信息作为环境观测,引入工具(比如画图 API)作为动作
  • 多智能体系统:在需要多个协同或对抗智能体的场景(如游戏博弈、协作代理)中,Agentic RL 将整个系统建模为去中心化 POMDP (Dec-POMDP),并训练每个 LLM 代理的策略

Thoughts

  • 单回合优化 -> 多回合协同优化,听上去很 makes sense,毕竟超集总是更好?
  • Agent 的难点转移到奖励设计上了,每个细粒度的奖励设计和不同奖励的平衡看上去挺难的
  • 如果做成纯稀疏奖励(只在最终结果上打分),那么由于搜索空间太大,训练会非常困难,除非堆海量数据和算力

URL

TL;DR

  • 本文提出了 RT-1 模型,本质是一个输入连续 6 帧图像 + 一句语言指令,输出是 11 维动作空间的 VLA 模型,控制一个有可移动底座和一个手臂的机器人,也就是说,RT-1 实际上是一个 小脑模型(执行控制模型,输入是相对简单的指令,输出是精细动作控制信号)
  • RT-1 首次证明大规模 Transformer 模型在机器人控制的可行性:通过​​任务无关训练​​、​​高效架构设计​​及​​异构数据融合​​,实现 700+任务的 97% 成功率及显著零样本泛化能力
  • 整个模型非常轻量,只有 35M 的参数

Algorithm

网络结构

rt1_2.png

  • 模型大概由四部分组成:
​​模块​​ ​​输入形状​​ ​​输出形状​​ ​​关键说明​​
Universal Sentence Encoder 文本字符串 512维向量 语言语义编码
FiLM EfficientNet-B3 6×300×300×3(图像) + 512 486×512 每帧生成81个视觉Token
TokenLearner 486×512 48×512 压缩至8 Token/帧
Transformer 48×512(+位置编码) 11×256 输出离散化动作分布

模型输出

  • 输出 11 维动作空间,每个动作空间都是离散的 256 个值
  • 11 个动作空间分别表示:
    • 1 个离散维度用于控制模式切换:
      • 控制底座
      • 控制手臂
      • 终止
    • 7 个维度控制机械臂:
      • 末端位置:x, y, z
      • 末端姿态:roll, pitch, yaw
      • 抓夹:开合度
    • 3 个维度控制底座:
      • 位置:x, y
      • 旋转角度:yaw

数据集

Thoughts

  • 模型很简单,数据很简单,训练范式也很简单,但泛化能力很强
  • RT-1 数据开源,推动具身智能社区发展

URL

TL;DR

  • 这篇论文构建了一个单一的通用智能体 Gato,它具有多模态、多任务、多实施方式能力,是一个纯端到端的智能体,甚至可以直接给出机械臂动作控制指令。
  • 模型就是 1.2B 参数的 decoder only Transformer 架构,只用一份权重可以玩 Atari 游戏、给图片加字幕、控制机械手臂堆叠积木等 604 个任务。

Algorithm

Gato.png

编码方案

Gato 将所有模态的输入和输出都编码为整数序列,输出除了不能输出图像之外,其他模态都可以输出。

  • 文本:通过 SentencePiece 方式编码,共 32000 个子单词编码为整数范围 [0, 32000)
  • 图像:按照 ViT 的编码方式,切成不重叠的 16x16patches
  • 离散值:存储为 [0, 1024) 的整数序列
  • 连续值: 离散化为 1024 个箱子,并移到 [32000, 33024) 的范围

训练和部署方案

  1. 使用 decoder only Transformer 架构,做自回归训练,图像切成 16x16patches 后,归一化到 [-1, 1] 之间,再用 Resnet 将图像编码成多个特征向量和其他模态的特征向量拼接起来,作为输入。
  2. 什么参与自回归训练?什么不参与?
    • 参与自回归训练的:文本符元、离散和连续值以及动作
    • 不参与自回归训练的:图像、智能体观测到的非文本信息(比如机械臂的关节参数等)
  3. 训练结束后,模型能做什么?
    • 训练时候没有屏蔽什么,训练收敛的模型就能做什么。
  4. 训练时固定上下文长度为 1024,超过 1024 的数据会被随机截取 1024
  5. 推理时不限制上下文长度
    gato2.png

实验结果

  • 604 项任务中,有 450 项任务能够达到专家分数的 50%
  • 论文中有每个任务类型的详细结果,可以参考论文

Thought

  • 把这么多种任务抽象成一种编码,然后用一个 1.2B 参数的模型来处理,这个想法很厉害
  • 编码方式有点复杂,可以对比下将图片之外的模态转成文本,然后用 tokenizer 编码的最终效果

URL

TL;DR

  • 本文证明传统 SFT 过程常用的 Cross Entropy Loss 的梯度等价于 Reinforcement Learning 中策略梯度更新,但隐含一个病态的奖励结构:稀疏奖励和逆概率权重结合,导致 模型对低概率样本过拟合
  • 解决方案特别简单:在每个 token 的损失前乘当前 token 的概率作为权重

Algorithm

公式角度

  • 传统 SFT 过程的损失函数:

θLSFT(θ)=Ex,yπθ[1πθ(yx)逆概率权重1[y=y]稀疏奖励θlogπθ(yx)]\nabla_{\boldsymbol{\theta}}\mathcal{L}_{\mathrm{SFT}}(\boldsymbol{\theta}) = - \mathbb{E}_{x,y \sim \pi_{\boldsymbol{\theta}}} \left[ \underbrace{\frac{1}{\pi_{\boldsymbol{\theta}}(y \mid x)}}_{\text{逆概率权重}} \cdot \underbrace{\mathbb{1}[y = y^{*}]}_{\text{稀疏奖励}} \cdot \nabla_{\boldsymbol{\theta}} \log \pi_{\boldsymbol{\theta}}(y \mid x) \right]

  • DFT 损失函数:

LDFT=E(x,y)Dt=1ysg(πθ(yty<t,x))logπθ(yty<t,x)\mathcal{L}_{\mathrm{DFT}} = - E_{\left(x, y^{*}\right)\sim\mathcal{D}} \sum_{t=1}^{\left|y^{*}\right|} \mathrm{sg}\left(\pi_{\theta}\left(y_{t}^{*}\mid y_{<t}^{*},x\right)\right) \log\pi_{\theta}\left(y_{t}^{*}\mid y_{<t}^{*},x\right)

  • 注意:这里的 sgstop gradient 操作,即不计算梯度 对应 pytorch 中常用的 .detach() 操作

代码角度

 2025-08-10 154116.png

  • a 表示预测序列中某个位置的的 logits
  • b 表示对应位置的 GT
  • cross entropy loss 就是 -log(softmax(a))[b]
  • DFT 损失函数就是 -(softmax(a) * log(softmax(a)))[b],但注意要 stop gradientsoftmax(a) 只作为系数,反向传播不优化。

函数角度

dft2.png

  • 蓝色是标准 SFT 过程的损失函数(交叉熵)
  • 红色是本文提出的 DFT 损失函数
  • 绿色是我自己脑补的 DFT 函数扩展之后的损失函数,优点是比 DFT 对称性更好,效果怎么样不知道…
  • 从函数角度看,SFT 在某个位置 GT 非常冷门的情况下,-log(softmax(a)) 会趋向于 inf,导致模型对这个冷门的 token 做了过大的参数更新,这是不合理的(因为模型已经经过了预训练,用非常低的概率预测 GT 说明这个 GT 可能是噪声)。
  • DFT 的函数可以看出,模型 优先关注不过分难或过分简单的 token,太难的可能是数据噪声,太简单的本身就没什么好学的。

Thoughts

  • 从函数角度看:太难的我不学,因为太难;太简单的我不学,因为太简单。
  • 郭德纲:我有四不吃…😂😂😂

URL

TL;DR

  • langchainSemi-structured RAGdemo,包含 PDF 的 解析 -> 向量化 -> 存储 -> 检索 -> 回答 的全流程
  • 来自 langchain 官方的 cookbook,值得参考

总体流程

langchain_rag_demo.png

  1. 解析 PDF 文件。用 partition_pdf 工具,将 PDF 文件解析为 chunks,分成文本和表格两种
  2. 总结 chunks。用大模型 API 总结 chunks,得到 summary,用哪家的模型都行
  3. 向量化 summary。调用 embedding 模型 APIsummary 进行向量化,作为索引的 keyvalue 是原始文本/表格),存到 Chroma 数据库中
  4. 问答时自动检索。在问答时,会自动根据问题向量在 Chroma 数据库中检索出最相似的 summary,将 summary 向量对应的原始文本/表格作为 prompt 中的 context 域传给大模型,得到回答

具体实现代码

1. 解析 PDF 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from typing import Any

from pydantic import BaseModel
from unstructured.partition.pdf import partition_pdf

path = "/Users/rlm/Desktop/Papers/LLaMA2/"
# Get elements
raw_pdf_elements = partition_pdf(
filename=path + "LLaMA2.pdf",
# Unstructured first finds embedded image blocks
extract_images_in_pdf=False,
# Use layout model (YOLOX) to get bounding boxes (for tables) and find titles
# Titles are any sub-section of the document
infer_table_structure=True,
# Post processing to aggregate text once we have the title
chunking_strategy="by_title",
# Chunking params to aggregate text blocks
# Attempt to create a new chunk 3800 chars
# Attempt to keep chunks > 2000 chars
max_characters=4000,
new_after_n_chars=3800,
combine_text_under_n_chars=2000,
image_output_dir_path=path,
)

2. 总结 chunks 得到 summary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

# Prompt
prompt_text = """You are an assistant tasked with summarizing tables and text. \
Give a concise summary of the table or text. Table or text chunk: {element} """
prompt = ChatPromptTemplate.from_template(prompt_text)

# Summary chain
model = ChatOpenAI(temperature=0, model="gpt-4")
summarize_chain = {"element": lambda x: x} | prompt | model | StrOutputParser()

# Apply to tables
tables = [i.text for i in table_elements]
table_summaries = summarize_chain.batch(tables, {"max_concurrency": 5})

# Apply to texts
texts = [i.text for i in text_elements]
text_summaries = summarize_chain.batch(texts, {"max_concurrency": 5})

langchain| 符号就可以把多个工具串成一个 chain,非常方便

3. 向量化 summary 并存到 Chroma 数据库中

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import uuid

from langchain.retrievers.multi_vector import MultiVectorRetriever
from langchain.storage import InMemoryStore
from langchain_chroma import Chroma
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings

# The vectorstore to use to index the child chunks
vectorstore = Chroma(collection_name="summaries", embedding_function=OpenAIEmbeddings())

# The storage layer for the parent documents
store = InMemoryStore()
id_key = "doc_id"

# The retriever (empty to start)
retriever = MultiVectorRetriever(
vectorstore=vectorstore,
docstore=store,
id_key=id_key,
)

# Add texts
doc_ids = [str(uuid.uuid4()) for _ in texts]
summary_texts = [
Document(page_content=s, metadata={id_key: doc_ids[i]})
for i, s in enumerate(text_summaries)
]
retriever.vectorstore.add_documents(summary_texts)
retriever.docstore.mset(list(zip(doc_ids, texts)))

# Add tables
table_ids = [str(uuid.uuid4()) for _ in tables]
summary_tables = [
Document(page_content=s, metadata={id_key: table_ids[i]})
for i, s in enumerate(table_summaries)
]
retriever.vectorstore.add_documents(summary_tables)
retriever.docstore.mset(list(zip(table_ids, tables)))

4. 问答时自动检索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from langchain_core.runnables import RunnablePassthrough

# Prompt template
template = """Answer the question based only on the following context, which can include text and tables:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)

# LLM
model = ChatOpenAI(temperature=0, model="gpt-4")

# RAG pipeline
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
)

# run the chain
chain.invoke("What is the number of training tokens for LLaMA2?")

总结

  1. langchain 做了非常多的工具,并给出一种将这些工具非常容易组合使用的方法
  2. 更重要的是,langsmith 提供了非常方便的 trace 功能,可以非常方便地追踪一次问答过程中经过了哪些模型/工具/行为,以及这些模型/工具/行为的 input / output / 耗时等,非常方便

URL

TL;DR

  • Qwen2.5-VLQwen 团队推出的一个多模态大模型,在 Qwen2.5 的基础上,增加了视觉模态的支持,输入支持 textimagevideo 的混合输入,输出为 text

Algorithm

qwen2.5-vl.png

模型架构

  • 视觉编码器(Vision Encoder):基于重新设计的 Vision TransformerViT),处理原生分辨率的图像和视频输入
  • 语言模型(Large Language ModelLLM):基于 Qwen2.5 LLM,负责文本理解和生成,初始化时预训练权重被微调以支持多模态任务
  • 视觉-语言合并器(Vision-Language Merger):一个 MLP-based 模块,压缩视觉特征以匹配文本嵌入维度,减少计算开销

三阶段训练

第一阶段

  • 随机初始化 Vision Encoder 开始训练
  • 使用的 (text, image) 数据如下:
    • Image captions:图像和对应的文本描述
    • Visual knowledge: 涵盖名人、地标、动植物等识别数据,帮助模型积累视觉常识
    • OCR 数据:从图像中提取的文本信息
  • 用了 CLIP 作为优化目标,对齐 ViTQwen2.5text 模态
  • token 长度为 8k,数据规模为 1.5T tokens

第二阶段

  • ViTQwen2.5 的联合预训练
  • token 长度为 8k,数据规模为 2T tokens

第三阶段

  • 长上下文优化,目标是视频/文档序列理解
  • token 长度为 32k,数据规模为 0.6T tokens

关键技术解析

1. 动态 ViT 架构

  • 输入尺寸自适应:图像按 14×14 分块,尺寸调整为 28 的倍数
  • 窗口注意力:32 层中仅 4 层用全局注意力,其余用 112×112 窗口注意力(计算复杂度从 O(n²) 降至 O(n)
  • 位置编码:2D 旋转位置嵌入(RoPE)保留空间关系

2. 多模态动态处理

  • 空间维度:
    • 原生分辨率坐标:直接使用图像实际尺寸表示物体位置(非相对坐标)
    • 支持 JSON/XML 格式输出,兼容开放词汇检测(10,000+ 类别)
  • 时间维度:
    • 动态帧率采样:适应不同速度的视频内容
    • 绝对时间对齐:RoPE 时间 ID 与时间戳直接绑定,理解事件节奏(图1机制)

3. 多模态位置编码(MRoPE)​

  • 三维分解:时间、高度、宽度独立位置 ID
  • 视频处理:时间 ID 按帧递增,空间 ID 与静态图像一致
  • 升级点:时间 ID 关联绝对时间戳,解决 Qwen2-VL 的时序理解局限

性能

  • 共有 3B / 7B / 72B 三个尺寸
    qwen2.5-vl_2.png

Thoughts

  • VLM 将视觉信息融入语言模态,重点还是 LM