ACT、Diffusion Policy 面试题解析

ACT(Action Chunking with Transformers)和 Diffusion Policy(扩散策略)是目前具身智能(Embodied AI)和机器人模仿学习(Imitation Learning)领域最经典、最主流的两个基线模型

在面试中,通常会重点考察对多模态动作分布建模、时序依赖处理、以及模型工程落地的理解。

一、 核心原理与架构对比类

1. 请对比 ACT 和 Diffusion Policy 的核心思想、优缺点及适用场景。

参考答案

  • ACT :基于 CVAE(条件变分自编码器) 架构。通过引入隐变量 z 来建模动作的多峰分布 ,结合 Action Chunking 预测动作序列。
    • 优点:推理速度极快(一次前向传播即可输出一个 Chunk),实时性好;架构相对简单,训练稳定。
    • 缺点 :CVAE 的生成能力上限受限于高斯假设,在处理极度复杂、多峰且形状不规则的动作分布时,可能会出现动作模糊(Blurring)。
  • Diffusion Policy (DP) :将动作生成建模为条件去噪扩散过程。通过迭代去噪,从纯噪声中逐步恢复出动作序列
    • 优点:生成质量极高,能完美拟合复杂的多峰分布;生成的动作轨迹非常平滑,符合物理直觉;在长视野(Long-horizon)复杂任务上表现优异。
    • 缺点 :推理需要多步迭代,延迟较高;训练和调参(如噪声调度)相对复杂。
  • 适用场景:ACT 适合对实时性要求高、动作相对连贯的中低频任务(如桌面抓取);DP 适合对动作精度、平滑度要求极高,或任务逻辑极其复杂的场景(如精密装配、柔性物体操作)。
2. 为什么在机器人模仿学习中,直接回归动作(如 MSE Loss)效果不好?ACT 和 DP 是如何解决这个问题的?

考察点 :对模仿学习核心痛点(多峰分布坍塌)的理解。

参考答案

  • MSE 的缺陷 :当面对多模态动作分布时(例如:桌上有个障碍物,机器人可以从左边绕,也可以从右边绕),MSE Loss 会迫使模型预测这两个动作的均值。这个"均值"动作往往会直接撞上障碍物,导致任务失败。
  • ACT 的解决方式引入 CVAE 的隐变量 z。在推理时,从先验分布中采样不同的 z,Decoder 会基于不同的 z 生成完全不同的动作分支,从而避开均值化陷阱。
  • DP 的解决方式 :扩散模型在去噪过程中,模型会根据当前条件(观测)被吸引到不同的数据流形(即不同的动作模式)上,从而自然地输出多峰分布中的某一个合理动作。
3. ACT 中的 Action Chunking(动作分块)具体解决了什么问题?Chunk size 应该怎么选?

考察点:对时序误差累积的理解及超参调优经验。

参考答案

  • 解决的问题
    1. 误差累积(Compounding Error):如果每次只预测单步动作,微小的预测误差会在多步执行后迅速放大。预测一个 Chunk(如 10 步),可以大幅减少模型推理次数,降低累积误差。
    2. 时间相关性(Temporal Correlation):机器人的动作在时间上是高度连续的。Chunking 强制模型在生成动作时考虑未来的时序依赖,使动作更平滑。
  • Chunk size 的选择 :这是一个 Trade-off。
    • 太大:模型难以预测长远的未来,导致 Chunk 后半段动作质量下降;且机器人对环境的突发变化反应迟钝(缺乏闭环反馈)。
    • 太小:失去了减少误差累积的优势,退化为单步预测。
    • 经验值:通常在 10 到 100 步之间(对应 0.5秒 - 5秒),具体取决于任务的控制频率和动态变化程度。
4. 简述 ACT (Action Chunking with Transformers) 的网络结构和 Loss 函数;解释 KL 散度在损失函数中的作用,如果 KL 散度太大或太小会导致什么问题?如何缓解?
  • 考察点:前者是对 ACT 论文细节的掌握;KL散度问题则是对 VAE 底层数学原理及训练 Trick 的掌握(高频考点)
  • 答题要点
    • 结构 :ACT 本质上是一个条件变分自编码器(CVAE) 结合 Transformer。它包含一个 Encoder(处理观测)和一个 Decoder(生成动作 chunk)。引入了一个低维隐变量 z。
    • 前向过程 :观测通过 Encoder 得到后验分布 ,采样得到 z,z 加上位置编码后输入 Transformer Decoder,解码出动作 chunk。
    • Loss 函数 :包含两部分。一是动作重建损失 (如 L1 Loss,计算预测动作与 GT 的差距);二是 KL 散度损失 (约束后验分布 接近先验分布 ,保证隐空间的平滑性)。
    • KL散度在损失函数中的作用 :KL 散度用于正则化隐空间,迫使 Encoder 输出的后验分布 接近先验分布 (通常是标准高斯分布),保证了推理时从 采样出的 z 是有效的。
    • KL 太大 :模型会过度依赖先验 ,而忽略观测 x 和真实动作 a 的信息,导致后验坍塌(Posterior Collapse),生成的动作变得模糊、缺乏细节。
    • KL 太小:隐空间变得不连续,存在大量空洞。推理时从先验采样的 z 很容易落入空洞,导致 Decoder 生成无效或危险动作。
    • 缓解方案
      1. KL 退火(KL Annealing) :训练初期将 KL 权重设为 0 或极小值,让模型先拟合数据(减小重建误差),然后随着训练进行,逐渐将 KL 权重增加到目标值(如 )。
      2. Free bits:限制 KL 散度的下限,防止其过小。

二、 算法对比与场景选择

5. ACT 和 Diffusion Policy 都使用了 Action Chunking,它们在生成动作的机制上有什么本质区别?
  • 考察点:算法底层数学逻辑的对比。
  • 答题要点
    • ACT :基于 CVAE 架构通过一次前向传播(采样隐变量 z + Decoder 解码)直接输出动作 chunk。本质上是单步生成(非自回归),速度快,但多模态表达能力受限于隐变量 z 的维度。
    • Diffusion Policy基于 迭代去噪。从纯高斯噪声开始,经过 T 步(如 10-100 步)迭代逐步去噪生成动作。本质上多步生成,能够拟合极其复杂的多模态分布,但推理速度慢。
6. 在处理"多模态动作分布"(例如:障碍物在左边时可以从右边绕,在右边时可以从左边绕)时,两者分别是如何解决的?
  • 考察点:对多模态(Multimodality)问题的深入理解。
  • 答题要点
    • ACT :通过隐变量 z 来捕获多模态。在推理时,从先验分布 中采样不同的 z,从而生成不同的动作轨迹。但如果 z 维度太低,无法覆盖所有模态;如果太高,又容易过拟合或导致动作不平滑。
    • Diffusion Policy :扩散模型天生具有极强的多模态拟合能力。在推理时,从不同的初始噪声 出发,去噪过程会自然收敛到不同的数据模态上,不需要显式设计隐变量,能更好地覆盖长尾分布。
7. Diffusion Policy 是如何将动作生成 建模为扩散过程的?条件(观测)是如何注入的?
  • 考察点:对扩散模型在控制领域应用的理解。
  • 答题要点
    • 建模 :将动作序列 视为数据。前向过程逐步加入高斯噪声直到变成纯噪声 ;反向过程训练一个神经网络 预测每一步加入的噪声。
    • 条件注入 :将当前观测(图像、本体感觉)通过视觉/状态编码器提取特征,作为条件来引导去噪过程。条件注入方式通常有:*FiLM 层 (对特征进行仿射变换)、Cross-Attention (将观测特征作为 K/V,动作特征作为 Q)、或者直接 **Concat,*拼接后将条件特征注入到 U-Net/Transformer 的去噪网络中。

三、工程实现与调优 Trick

8. Diffusion Policy 的推理延迟较高,在实际机械臂控制(如要求 20Hz,即 50ms 内完成推理)中,有哪些加速方案?

答题要点

  1. 减少采样步数 :放弃 DDPM,使用 DDIM 或更先进的 ODE 求解器(如 DPM-Solver++, UniPC),可以将采样步数从 100 步大幅压缩到 5-10 步。
  2. 动作分块(Action Chunking)+ 滑动窗口:一次预测较长的动作序列(如 16 步),执行时采用滑动窗口(如每次执行 8 步,保留 8 步作为下一步的先验),从而降低模型调用频率。
  3. 模型蒸馏
    • 使用 Consistency Models(一致性模型) 技术,训练一个只需 1-2 步即可生成的蒸馏模型。
    • 将 DP(教师)的知识蒸馏给一个轻量级的 MLP 或小型 Transformer(学生)。
  4. 工程加速:使用 TensorRT 进行算子融合和 FP16/INT8 量化;优化视觉编码器的推理(如使用更小的 ResNet 或 MobileViT)。
9. 手写 ACT 的 CVAE 重参数化 Trick

答题要点:

1) CVAE的重参数化引入:

CVAE 引入了条件 c (在 ACT 语境下,c 通常包含历史状态、观测,甚至动作 Action )。 重参数化 Trick 的核心思想是将随机性从参数中剥离出来,转移到一个固定的外部噪声上。

编码器输出的后验分布是一个高斯分布:,若直接让网络输出均值 和方差 ,然后进行采样 此时 z 的生成过程包含随机采样,梯度无法回传。

重参数化做法(可导):

引入一个外部辅助变量 ,让它服从标准正态分布 。然后通过一个确定性的数学变换来生成 z:

其中,⊙ 表示逐元素相乘。

为什么这样就解决了问题?

  • 随机性外置 :现在的随机性来自于 ,而 是从外部采样的,不依赖于网络参数
  • 计算图连通 :z 变成了关于 确定性函数 (只是简单的加法和乘法)。因此,梯度可以顺畅地通过 z 反向传播到 ,进而更新编码器网络 的参数。
2)pytorch手写实现重参数化:

核心 5 行代码:重参数化 Trick,将不可导的采样操作转化为可导的确定性计算:

python 复制代码
import torch

def reparameterize(mu, logvar):
    """
    CVAE 核心重参数化 Trick
    :param mu: 均值向量 (Batch, Latent_Dim)
    :param logvar: 对数方差向量 (Batch, Latent_Dim),即 log(σ^2)
    :return: 采样后的隐变量 z
    """
    # 1. 计算标准差 σ = exp(0.5 * log(σ^2))
    std = torch.exp(0.5 * logvar)
    
    # 2. 采样标准正态分布噪声 ε ~ N(0, I)
    eps = torch.randn_like(std)
    
    # 3. 重参数化: z = μ + σ * ε
    return mu + eps * std

# 计算 KL 散度 (解析解,不需要重参数化)
def kl_divergence(mu, log_var):
    # -0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
    return -0.5 * torch.sum(1 + log_var - mu.pow(2) - log_var.exp(), dim=-1)







# 越疆 x_trainer 平台的 kl 散度代码详解:https://chat.qwen.ai/c/6948d428-49dc-4680-9db9-ef976250e1fe
# mu 和 logvar 通常是 2D 张量 (batch_size, latent_dim)。
# 如果检测到是 4D 张量,使用 .view() 展平为 2D 张量 (batch_size, channels * height * width)。

def kl_divergence(mu, logvar):
    batch_size = mu.size(0)
    assert batch_size != 0
    if mu.data.ndimension() == 4:
        mu = mu.view(mu.size(0), mu.size(1))
    if logvar.data.ndimension() == 4:
        logvar = logvar.view(logvar.size(0), logvar.size(1))

    # 计算的是每一个样本在每一个隐变量维度上的独立 KL 散度。
    klds = -0.5 * (1 + logvar - mu.pow(2) - logvar.exp())
    # 总 KL 散度 - 用于最终 Loss
    total_kld = klds.sum(1).mean(0, True)

    dimension_wise_kld = klds.mean(0)
    mean_kld = klds.mean(1).mean(0, True)

    return total_kld, dimension_wise_kld, mean_kld 

注意:使用 logvar 而非 var 或 std (数值稳定性 Trick)

代码体现:std = torch.exp(0.5 * logvar)