Zhangzhe's Blog

The projection of my life.

0%

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

URL

TL;DR

  • 标题是 “用于端到端分层序列建模的动态分块” ,实际上包含了不少信息量:
    • “端到端”:意味着 token free,真正的端到端语言模型,输入输出都是字节流,不需要 tokenization 过程
    • “分层”:意味着 H-Net 模型结构是 递归 的,H-Net 模型由 encoder + main network + decoder 组成,其中 main network 还可以是 H-Net 模型
    • “动态分块”:意味着 H-Net 模型可以动态地调整 chunk 的大小,可以理解为维护了一个隐式的动态 tokenizer,模型会在学习过程中找到最优的隐式分词方法
  • 本质是一个基于 SSM + Transformer 结构的大模型,抛弃了 tokenization 过程,直接在字节流上进行训练和推理

Algorithm

H-Net 总体结构

hnet.png

现有的分词机制的缺陷

  • 当前主流语言模型(如 ChatGPT )依赖预定义的分词器(如 BPE ),存在以下问题:
    • 语义割裂​​:分词器基于统计规则,无法根据上下文动态调整边界(如将 “product” 错误拆分为 “pro-duct” )
    • 跨语言/模态适配性差​​:在中文、代码或 DNA 序列等缺乏显式分隔符的领域表现不佳
  • 直接字节级建模(如 MambaByte ),计算开销巨大,且性能低于分词模型
  • 一些启发式分块规则(如 MegaByteSpaceByte)依赖​​启发式分块规则​​(如固定步长或空格分隔),无法学习数据驱动的分块策略,限制了模型对复杂信息的表达能力

H-Net 的解决方案

层级化处理架构(U-Net 式设计)​​

  • 三级模块
    • 编码器(E)​​:处理原始字节(小规模 SSM 层,高效捕获细粒度特征)
    • 主网络(M)​​:处理压缩后的语义块(大规模 Transformer 层,学习高层抽象)
    • 解码器(D)​​:恢复原始分辨率(SSM 层)
  • 递归扩展​​:主网络可嵌套 H-Net 自身,形成多级抽象(如字符 → 词 → 短语)

Encoder Network

  1. 路由模块(Routing Module
    • 用相邻向量的余弦相似度判断是否需要分块
    • pt=12(1sim(qt,kt1))p_t=\frac{1}{2}(1-sim(q_t,k_{t-1}))
      • tt 表示 position
      • qq 表示 query
      • kk 表示 key
      • simsim 表示余弦相似度
      • ptp_t 表示当前位置分块概率
    • 当相邻向量语义变化大时,ptp_t 会趋近于 1,表示需要分块
  2. 下采样模块(Downsampler
    • 将上一步分块的序列下采样
    • 具体使用的下采样方式是 只保留路由模块选定的边界向量,其他向量直接丢弃

Main Network

  • 一个最常见的 Transformer 结构
  • 输入是 Encoder Network 输出的下采样后的向量
  • 输出和输入的 shape 相同

Decoder Network

  1. 平滑模块(Smoothing Module
    • 用指数移动平均法解决离散决策的梯度不可导问题
    • zˉt=Pz^t1+(1Pt)zˉt1\bar z_t=P\cdot \hat z_{t-1}+(1-P_t)\cdot \bar z_{t-1}
      • PtP_t 表示当前位置分块概率
      • z^t\hat z_t 表示主网络输出的压缩向量
      • zˉt1\bar z_{t-1} 表示上一步平滑后的向量
      • zˉt\bar z_t 表示平滑后的向量
  2. 上采样模块(Upsampler

    ct={ptif bt=11ptif bt=0c_t=\left\{ \begin{array}{l} p_t & \text{if}\ b_t=1 \\ 1- p_t & \text{if}\ b_t=0 \end{array} \right.

    Upsamplert=STE(ct)z~t\text{Upsampler}_t = STE(c_t)\cdot \tilde z_t

    • btb_t 表示当前位置是否分块,bt=1b_t=1 表示分块,bt=0b_t=0 表示不分块
    • ptp_t 表示当前位置分块概率
    • ctc_t 表示当前位置 main network 输出的置信度
    • z~t\tilde z_t 表示当前位置 main network 输出的向量 复制到原始分辨率

效果

  • 效果比 tokenization 更好
  • 在语言、代码、DNA等异构数据中验证普适性,为多模态基础模型提供新范式

Thoughts

  • 能看出 SSM 模型已经开始改变战略,从正面和 Transformer 硬刚到 曲线救国
  • STE 真是个万金油,哪哪都有它

URL

TL;DR

  • 本文提出一种新的缓存利用机制 CacheBlend,旨在解决 RAG 系统中知识 KV Cache 的可用性,通过一种稀疏近似的方式平衡速度和准确性。

Algorithm

知识注入的两种常见方式

1. 微调

  • 收集知识库中的文档数据,微调模型,使其能够在生成文本时利用这些知识。
  • 优点:推理时不会有额外的延迟。
  • 缺点:
    1. 动态更新困难
    2. 模块化困难(无法要求模型使用哪些知识,不用哪些知识)

2. 知识检索

  • 在推理时,检索相关文档并将其作为上下文输入到模型中。
  • 优点:动态更新知识库,模块化。
  • 缺点:推理时需要额外的延迟,一是因为检索本身的延迟,二是因为模型需要计算额外的上下文注意力。

如何同时解决模块化和速度的问题?

  • 如果在知识检索技术的基础上,检索系统提前缓存了 知识库中文档对应的 KV Cache,那么就可以在推理时直接使用这些 KV Cache 无需计算这部分的注意力(只需要检索延迟)。

这样做有什么问题?

  • 一个很重要的问题是:优于现如今绝大多数 LLMdecoder only 架构,缓存的知识库的 KV Cache 必须作为 prefix 注入到模型中,且只能用一个,否则模型无法利用这些知识。
  • 例如:
    • 记检索到的文档的 KV CacheA,历史对话信息和用户输入为 B
    • 那么模型的输入应该是 A + B,而不是 B + A
    • 因为 KV Cache 位置 i 的值依赖于 0 ~ i-1 位置的值,如果不作为 prefix 注入,那么模型无法利用这些知识。

cacheblend_2.png
cacheblend_3.png

CacheBlend 想要解决的问题

  • CacheBlend 目的就是为了 解决 RAG 系统中知识 KV Cache 只能作为 prefix 注入的问题
  • CacheBlend 做不到和完全重新计算数学上等价,只能是近似
  • 原理本质上讲是平衡,即 在完全重新计算 KV Cache 和完全使用缓存的 KV Cache 之间进行平衡,如下图:

cacheblend.png

CacheBlend 的解决方案

cacheblend_4.png

  • CacheBlend 通过 稀疏近似 的方式,平衡速度和准确性,具体来说,对非 prefixKV Cache,做:
    1. 1 层​​:计算所有 TokenKV 偏差,选择 Top 20% 作为候选 HKVD (High-KV-Deviation) Token
    2. ​后续层​​:仅对前一层的 HKVD Token 计算偏差,从中选择 Top ri% (ri<ri1)Top\ r_i\%\ (r_i < r_{i-1}) 作为当前层 HKVD Token
    3. ​​终止​​:最终每层仅更新约 10-15% Token,偏差显著降低
  • 总体上就是用逐层用新的 KV Cache 替换旧的 KV Cache,替换依据是 KV 偏差,偏差越大的 Token 替换的优先级越高。

CacheBlend 的优势

  • 质量保障​​:仅更新 10-15% Token 即可达到 Full KV Recompute 的质量(F1/Rouge-L 偏差 <0.02
  • ​​延迟隐藏​​:KV 重新计算与 KV 缓存加载流水线并行,使额外延迟近乎为零
  • 提速​​:TTFT (Time To First Token) 降低 2.2 ~ 3.3 倍,吞吐量提升 2.8 ~ 5

Thoughts

  • 稀疏无处不在

URL

TL;DR

  • 大模型并不是全能的,大模型 + 工具可以更好地解决问题,本文提出一种新的训练方法,让大模型可以自我学习使用如何工具。
  • 本文的主要贡献是提出了一种新的训练方法,包括通过大模型构造工具调用数据集、清洗数据集、使用工具调用数据集微调大模型。

Algorithm

ToolFormer 的意义

  1. 众所周知,大模型在很多任务上表现出色,但它们并不是全能的,比如去数 “strawberry” 这个单词中有多少个 “r”。
  2. 工具可以帮助大模型更好地解决问题,比如计算器、日历、知识库等。
  3. 一种常见的大模型和工具结合的方式是:通过 Agent 多角色(user / llm / function)多轮对话 形式调用,简单来说就是:
    1. 大模型在需要调用工具的时候,输出一段特定格式的文本
    2. 外部程序解析这段文本,调用相应的工具,调用得到结果
    3. 新的结果作为 Function 角色的输入,继续和大模型对话
  4. ToolFormer 采用的方式和 Agent 有相似之处,也有不同的地方:
    • 相似点:
      1. 都需要大模型输出一段特定格式的文本来调用工具
      2. 都需要一段 endless loop 程序来解析大模型的输出,调用工具
    • 不同点:
      1. ToolFormer 不是通过 多角色多轮对话 的方式调用工具,而是通过 单角色单轮对话 的方式调用工具
      2. ToolFormer 需要对大模型进行 微调,而 Agent 不需要
  5. ToolFormer 可以将存在确定答案的 专用 任务转化为工具调用任务(例如:计算、翻译、问答等),让大模型可以更专注在 通用 任务上(例如:上下文理解、常识知识运用等)。

ToolFormer 的工作方式

  1. ToolFormer 是经过工具调用微调的大模型,知道有哪些工具可以调用,也知道如何调用这些工具。
  2. 假设模型输入的问题是:
    1
    Pittsburgh is also known as
  3. 这个时候,模型会意识到这个问题可以通过调用 Question Answering 工具来解决,于是模型会续写:
    1
    Pittsburgh is also known as <API>QA(Pittsburgh is also known as)</API>
  4. 输出 </API> 之后,推理进程会暂停推理模型,等待外部监听程序的调用结束。
  5. 外部监听程序会解析模型输出文本中的工具调用指令(通过 <API> </API> 格式),然后调用 Question Answering 工具,得到结果:
    1
    the Steel City
  6. 推理程序将工具调用结果和模型的历史输出(去掉调用相关信息)拼接起来,继续推理模型:
    1
    Pittsburgh is also known as the Steel City.

应该怎么得到 ToolFormer

  1. 假设上面提到的 ToolFormer 工作方式是一个愿景,那么接下来就是考虑应该如何得到一个这样的模型。
  2. 显然,直接拿一个预训练或经过微调的大模型来使用是行不通的,因为它并不知道哪些工具可以用,以及如何调用。
  3. 那么需要做的事就是:通过微调,让大模型自己学习如何使用工具
  4. 最困难的部分就是:如何构造工具调用数据集,因为不存在现成的工具调用数据集,需要自己构造。
  5. 这篇论文花了很大的篇幅就在讲一件事:如何用大模型来构造工具调用数据集

如何构造工具调用数据集

toolformer_1.png

上面这张图展示了如何用大模型来构造工具调用数据集的流程。

  1. 首先,还是用预训练数据做为基础,假设一条预训练数据是:
    1
    Pittsburgh is also known as the Steel City.
  2. 然后,使用大模型(例如:GPT-3)来在数据中找到可以调用工具的位置和工具类型,并给出调用工具的参数,例如:
    1
    Pittsburgh is also known as <API>QA(What other name is Pittsburgh known by?) -> Steel City</API> the Steel City.
    1
    Pittsburgh is also known as <API>QA(Which country is Pittsburgh in?) -> United States</API> the Steel City.
  3. 计算调用工具带来的损失收益,剔除负收益的数据,保留正收益的数据。
    • 损失的计算方式(离调用工具位置越远,损失权重 wjiw_{j-i} 越小):

    Li(z)=j=inwjilogpM(xjz,xi;j1)L_i(z) = -\sum_{j=i}^n w_{j-i}\cdot \log p_M(x_j|z,x_{i;j-1})

    • 调用工具的损失:

    Li+=Li(e(ci,ri))L_i^+=L_i(e(c_i,r_i))

    • 不调用工具 / 调用工具没有返回的损失:

    Li=min(Li(ϵ),Li(e(ci,ϵ)))L_i^- = \min(L_i(\epsilon),L_i(e(c_i,\epsilon)))

    • 只保留调用工具损失收益大于阈值的样本:

    LiLi+>τfL_i^- - L_i^+ > \tau_f

  4. 用筛选后的数据来微调大模型,得到 ToolFormer

toolformer_2.png

  • 上图展示了 ToolFormer 支持的五种工具类型:
    1. Question Answering:问答工具
    2. Wikipedia Search:维基百科搜索工具
    3. Calculator:计算器工具
    4. Calendar:日历工具
    5. Machine Translation:机器翻译工具

Thoughts

  • ToolFormer 这种通过大模型自我学习使用工具的方式感觉挺好的,但似乎在实际使用中没有得到大范围推广,目前主流外挂工具的方式基本还是 Agent 的多角色多轮对话方式。
  • 可能是因为 ToolFormer 的方式需要对大模型进行微调,而 Agent 的方式不需要做工具适配微调,直接使用原模型就可以。