<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>bot..&apos;s ink</title><description>bot..&apos;s ink — 记录技术、生活与思考。</description><link>https://example.com/</link><language>en</language><item><title>论文精读｜DexVLA：先练动作专家，再接入视觉语言模型</title><link>https://example.com/blog/%E8%AE%BA%E6%96%87%E7%B2%BE%E8%AF%BB-dexvla%E5%85%88%E7%BB%83%E5%8A%A8%E4%BD%9C%E4%B8%93%E5%AE%B6%E5%86%8D%E6%8E%A5%E5%85%A5%E8%A7%86%E8%A7%89%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/</link><guid isPermaLink="true">https://example.com/blog/%E8%AE%BA%E6%96%87%E7%B2%BE%E8%AF%BB-dexvla%E5%85%88%E7%BB%83%E5%8A%A8%E4%BD%9C%E4%B8%93%E5%AE%B6%E5%86%8D%E6%8E%A5%E5%85%A5%E8%A7%86%E8%A7%89%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/</guid><description>DexVLA 把扩散动作专家扩到十亿参数，再通过三阶段训练接入视觉语言模型。重点看动作预训练、跨本体输出头和子步骤推理怎样配合，以及实验支持了哪些结论。</description><pubDate>Tue, 03 Nov 2026 00:00:00 GMT</pubDate><content:encoded>&gt; **论文：** DexVLA: Vision-Language Model with Plug-In Diffusion Expert for General Robot Control  
&gt; **作者：** Junjie Wen、Yichen Zhu、Jinming Li、Zhibin Tang、Chaomin Shen、Feifei Feng  
&gt; **发表：** CoRL 2025；本文对应 arXiv v3，修订于 2025 年 8 月 9 日  
&gt; [论文 v3](https://arxiv.org/abs/2502.05855v3) · [项目与演示视频](https://dex-vla.github.io/)

视觉语言模型能理解“把衣服叠好”，但把指令变成连续、协调的双臂运动，还需要学到机器人自己的动作知识。DexVLA 把主要改进放在动作端：**先用机器人数据单独预训练一个十亿参数的扩散动作专家，再把它接到视觉语言模型上，逐步完成本体对齐与任务适配。**

这套方法还有一个与长任务直接相关的设计：让模型自己生成“取出衣服、铺平、折叠、堆放”等子步骤，并用这些表示指导动作。扩散生成动作序列、多视角输入等沿用已有思路，本文重点看动作专家为什么值得单独训练，以及它怎样与语言推理配合。

## 动作专家怎样接入视觉语言模型？

![DexVLA 的架构与训练流程。左侧单独预训练扩散专家；中间接入 VLM 并移除临时感知模块；右侧共享扩散主干，为不同机器人配置独立动作头。斜线区域表示该阶段不参与训练或被移除的组件。来源：原论文 Figure 2，可点击放大。](/images/dexvla/architecture-curriculum.webp)

完整模型使用 Qwen2-VL 2B 作为视觉语言骨干，配合一个 1B 参数的动作专家。这里的十亿参数专指动作模块。专家基于 ScaleDP 的扩散 Transformer，从噪声中逐步生成连续动作序列。

不同机器人共用扩散主干，各自使用一个 MLP 动作输出头。这样，单臂、双臂等数据可以一起训练，而不同的动作维度和控制空间由对应输出头处理。共享的是动作模型的内部表示，输出端仍然保留机器人之间的差异。

VLM 与动作专家之间有两路联系。VLM 输出的动作 token 经过两层线性映射和 LayerNorm，转成动作专家需要的条件表示；推理 token 则通过 FiLM 调制策略特征，让当前子步骤影响动作生成。最终控制量由扩散专家产生，不能把这里的动作 token 直接当成离散化的关节命令。

“Plug-in”对应这种可拆分、可对接的模块结构。要让语言表示真正对应机器人的动作，仍然需要下面的对齐训练。

## 为什么先练动作，再做本体对齐？

DexVLA 将训练分成三个阶段，每个阶段解决的问题不同。

**第一阶段：跨本体预训练动作专家。** 暂时不接入大 VLM，用 ResNet-50 编码图像、DistilBERT 编码语言，再训练共享扩散主干和各本体的动作头。数据约 100 小时，覆盖四种本体、91 项任务。专家先在较轻的感知接口下学习动作，避免一开始就联合优化整个 VLA。这里没有去掉视觉与语言条件，只是暂时使用较小的编码器。

**第二阶段：接入 VLM，针对目标机器人对齐。** 移除第一阶段的临时图像、语言编码模块，换成 Qwen2-VL 提供条件；筛选目标本体的数据，联合训练语言模型、投影层和动作专家，同时冻结 VLM 的视觉编码器。模型由此学习相机观测、语言表示与该机器人控制空间之间的对应关系。论文所说的“无需任务专门适配”，就是在完成这一阶段后评估，仍然用过该本体的数据。

**第三阶段：用高质量示范适配具体任务。** 对更长、更依赖精细操作的任务继续后训练，也用来学习新本体上的技能。已经能完成的简单任务可以停在第二阶段；从一篮揉皱衣服开始整理的 Laundry Folding，则需要第三阶段。

消融直接说明了训练顺序的作用。Table 2 中，只做第二阶段、不预训练动作专家时，平铺衣物折叠得分为 0；先做第一阶段再对齐，得分达到 0.92。长任务 Laundry Folding 在前两阶段后仍为 0，加入第三阶段后才达到 0.40。这些结果支持分阶段训练的必要性，但只对应论文测试的折叠任务。

拆开训练也减少了第一阶段的开销。相同 batch size 下，仅训练动作专家每小时完成 0.89 个 epoch，训练整个 VLA 为 0.32 个，吞吐约为后者的 2.78 倍。这个数字描述的是第一阶段的训练速度，不是整套方法的总成本降幅。

## 子步骤推理怎样影响动作？

“叠好篮子里的衣服”覆盖了很不一样的状态：衣服还在篮子里、已经摊到桌上、袖子需要调整、折好后等待堆放。仅用一句总指令监督所有动作，模型容易跳过中间步骤。

![直接指令与子步骤示例。模型根据观测，将整理衣物、取出烘干机内衣物和物体分类分解为当前要执行的步骤，再据此生成动作。来源：原论文 Figure 3。](/images/dexvla/substep-reasoning.webp)

DexVLA 在训练示范中加入子步骤标注，主要步骤通常持续约五秒或更久。第一阶段先用这些语言条件训练动作专家；第二、三阶段则把子步骤描述作为模型需要生成的中间语言输出，而不是每次由外部直接给出下一条子指令。训练同时优化扩散动作预测与语言 token 预测，生成的推理表示再经 FiLM 进入策略。

因此，部署时只给总指令，模型需要结合当前画面判断接下来做什么，不依赖额外的高层规划器持续派发子任务。这种能力有明确的监督来源：附录使用目标检测、视觉特征和 Gemini 2.0 辅助标注，并对第三阶段数据人工核查。

子步骤监督的贡献很大。Table 7 中，第一、二阶段都使用它时，平铺衣物折叠得分为 0.92；第一阶段只用总指令、第二阶段才加入子步骤监督时，降到 0.07。只在 VLM 对齐时再加入子步骤语言，难以补回动作预训练阶段的差距。

作者将这一现象解释为：子步骤帮助区分不同动作模式，减少多任务之间的干扰。实验支持子步骤监督有效，但“内部参数如何分工”仍属于解释，没有被这些得分直接验证。

## 哪些结果最能说明它的价值？

真实机器人实验主要报告**按任务阶段计分、归一化后的平均得分**，每项任务、每种方法评估 10 次。例如 Laundry Folding 按取出、铺平、折叠、堆放四个阶段给分，所以 0.40 不能直接读成 40% 的整项任务成功率。

| 评估条件                        | 任务                | DexVLA 平均得分 | 对照结果                 |
| ------------------------------- | ------------------- | --------------- | ------------------------ |
| 完成第二阶段，无第三阶段适配    | 折叠已平铺的衣服    | 0.92            | DP、Octo、OpenVLA 均为 0 |
| 新本体，每项任务 100 条示范微调 | 双臂 UR5e 装箱      | 0.95            | DP 为 0.35               |
| 新本体，每项任务 100 条示范微调 | Franka 灵巧手倒饮料 | 0.85            | DP、Octo、OpenVLA 均为 0 |

第一行说明预训练与本体对齐已经能支持较复杂的技能，但任务并非从未出现在训练中。后两行的机器人配置未参与第一、二阶段训练，展示的是每项 100 条示范微调后的适应能力。

![完成第三阶段后，DexVLA 在 Laundry Folding 和使用未见物体的桌面清理任务上，与直接输入总指令的基线比较。图中数值是平均归一化得分。来源：原论文 Figure 9。](/images/dexvla/long-horizon-scores.webp)

长任务更能体现子步骤推理的用途。从揉皱衣物开始整理的 Laundry Folding 中，DexVLA 得分 0.40，直接提示的 π₀ 为 0.20。这里比较的是都只接收总指令的设置，不能据此推断 π₀ 配合外部高层规划器时的表现。

动作专家的容量也有对应证据。Table 3 中，93M 的 U-Net、410M 的扩散专家和 1B 的扩散专家，在平铺衣物折叠上的得分依次为 0.17、0.63、0.92。其中 U-Net 到 Transformer 同时改变了架构与参数量；410M 到 1B 的比较，才更直接支持扩大同类动作专家的收益。

## 这篇论文值得带走什么？

DexVLA 最有参考价值的是训练组织方式：让动作专家先从机器人数据中学到可迁移的动作表示，再让 VLM 与目标机器人的控制空间对齐；子步骤监督贯穿两者，把长任务中的阶段差异带入动作学习。十亿参数动作模块、分阶段训练和语言监督是相互配合的设计。

结果也留下了清楚的边界。100 小时指机器人预训练数据，不包含 Qwen2-VL 已用过的视觉语言预训练数据；新本体的装箱、倒饮料实验仍需要各 100 条示范；最难的 Laundry Folding 得分也只有 0.40。它说明这条路线能够改善长任务控制，还没有证明开放环境下的可靠执行。

若要借鉴到自己的系统，优先值得检查的是：动作端是否有足够的预训练，语言与控制空间是否经过对齐，长任务示范是否标清了关键阶段。论文的消融表明，只把动作网络做大，或者只在末期加入子步骤语言，都不足以复现完整方案的效果。

## 原文与配图来源

本文依据所提供的 DexVLA.pdf（arXiv:2502.05855v3）撰写；数据对应 Figure 6、8、9，Table 2、3、6、7 及附录 C。封面截取 Figure 1 的装箱画面，正文配图来自同版本高清 PDF 的 Figure 2、3、9，仅裁切图外内容，图内数据未改写。图片与原始研究成果归原作者所有。版本与发表信息见[论文页面](https://arxiv.org/abs/2502.05855v3)，任务演示见[作者项目主页](https://dex-vla.github.io/)。</content:encoded><category>论文精读</category><category>具身智能</category><category>机器人操作</category><category>vla</category><category>扩散模型</category><category>dexvla</category></item><item><title>论文精读｜ACT：用动作分块学习双臂精细操作</title><link>https://example.com/blog/%E8%AE%BA%E6%96%87%E7%B2%BE%E8%AF%BB-act%E7%94%A8%E5%8A%A8%E4%BD%9C%E5%88%86%E5%9D%97%E5%AD%A6%E4%B9%A0%E5%8F%8C%E8%87%82%E7%B2%BE%E7%BB%86%E6%93%8D%E4%BD%9C/</link><guid isPermaLink="true">https://example.com/blog/%E8%AE%BA%E6%96%87%E7%B2%BE%E8%AF%BB-act%E7%94%A8%E5%8A%A8%E4%BD%9C%E5%88%86%E5%9D%97%E5%AD%A6%E4%B9%A0%E5%8F%8C%E8%87%82%E7%B2%BE%E7%BB%86%E6%93%8D%E4%BD%9C/</guid><description>从 ALOHA 的双臂示教出发，理解 ACT 如何结合动作分块、时序集成和条件 VAE，学习高频精细操作，并核对网络结构、训练细节与实验边界。</description><pubDate>Mon, 02 Nov 2026 00:00:00 GMT</pubDate><content:encoded>&gt; **论文：** Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware  
&gt; **作者：** Tony Z. Zhao、Vikash Kumar、Sergey Levine、Chelsea Finn  
&gt; **发表：** RSS 2023；arXiv 首次提交于 2023 年 4 月 23 日  
&gt; **方法：** Action Chunking with Transformers（ACT）
&gt;
&gt; [论文](https://arxiv.org/abs/2304.13705) · [项目主页与演示视频](https://tonyzhaozh.github.io/aloha/) · [ACT 代码](https://github.com/tonyzhaozh/act) · [ALOHA 硬件与采集代码](https://github.com/tonyzhaozh/aloha)

把电池放进遥控器，看起来只是一次插入，实际却需要两只手配合：一只手压住遥控器，另一只手把电池的一端送入槽内，再抵住弹簧，把另一端压下去。位置差几毫米，或者压住遥控器的时机稍晚，后续动作就可能全部失效。

ACT 关心的正是这类操作。它用 ALOHA 收集双臂示范，再让策略根据相机图像和关节位置，一次预测一段未来动作。执行时，策略持续接收观测，并融合不同轮次对当前时刻的预测。训练中再引入条件 VAE，处理人类示范里不同的动作路径和节奏。

封面来自原论文 Figure 1。右上方展示的是人类遥操作能力，右下方才是学习策略的示例；两者对应的能力范围需要区分。

## 为什么单步行为克隆容易在精细操作中失手？

行为克隆（Behavior Cloning，BC）把模仿学习写成一个监督学习问题：从专家示范中收集观测与动作，学习在当前观测下应该执行什么动作。

设观测为 $o_t$，专家动作为 $a_t$，常见的单步策略可以写成：

$$
\hat a_t = \pi_\theta(o_t).
$$

问题出在训练和部署看到的状态并不完全相同。训练时，模型面对的是专家走过的轨迹；部署时，它必须接着自己上一步造成的状态往下走。如果第一次抓取偏了一点，物体的位置和姿态就会变化，后面的策略输入也随之偏离示范。预测误差继续累积，机器人可能进入训练数据没有覆盖、自己也不会纠正的状态。这就是模仿学习中的误差累积问题。

在装电池、穿扎带、撬开杯盖这些任务里，误差尤其容易被接触放大。夹爪只是稍微碰偏了物体，物体就可能旋转、滑动或变形。即使单帧动作预测的误差不大，整段任务也未必能完成。

另一个困难来自示范本身。人不会在每次演示里都保持完全相同的速度、停顿和交接位置。例如，递交胶带时，两只夹爪可以在多个位置完成交接；只看一张图像，也未必能判断演示者准备继续移动还是短暂停顿。把每一帧都当成独立的回归样本，会丢掉动作之间的连续关系。

论文由此提出两个相互关联的问题：能否让模型直接学习一段协调的动作，减轻逐步决策的负担？能否同时容纳人类示范中合理的路径与节奏差异？

## ALOHA：先把示范采集这件事做好

这篇论文同时提出了硬件系统 ALOHA 和学习算法 ACT。ALOHA 负责让人方便地操作机器人、记录示范；ACT 负责从这些示范中学出视觉控制策略。

ALOHA 使用两套双臂配置。操作者直接拖动较小的 leader 机械臂，执行任务的 follower 机械臂通过关节空间映射跟随运动。系统还改造了示教手柄、夹爪和重力补偿结构，让操作者更容易连续控制夹爪开合，并完成细小的接触动作。论文报告，整套系统的成本控制在 2 万美元以内；这是论文当时的系统成本口径。

![ALOHA 的相机布局、示教手柄与夹爪，以及 follower 机械臂参数。系统包括前视、俯视和两个腕部相机。来源：原论文 Figure 3。](/images/act/aloha-setup.webp)

策略使用四路 RGB 图像和 follower 当前的关节位置作为观测：

$$
o_t = \bigl(I_t^{(1)}, I_t^{(2)}, I_t^{(3)}, I_t^{(4)}, q_t\bigr).
$$

其中 $q_t\in\mathbb R^{14}$。每只机械臂有 6 个关节和 1 个夹爪控制量，两侧合计 14 维。动作也是 14 维，表示双臂下一步的绝对目标关节位置，由底层控制器负责跟踪。

这里有一个值得保留的采集细节：**动作标签来自 leader 的关节位置，观测中的关节位置来自 follower。** 两者承担不同角色。leader 表达操作者希望机器人到达的位置，follower 记录机器人实际到达的位置。在接触过程中，两者的偏差会通过底层 PID 控制器影响施加的力，因此不能直接把 follower 的实际位置当成全部动作标签。

ALOHA 的控制与数据记录频率为 50 Hz，即每个控制周期约 20 ms。论文附录还说明相机视频流为 30 fps，所以 50 Hz 控制并不意味着每个控制周期都有一张全新的相机帧。

这套系统没有给策略提供物体位姿真值或显式的环境动力学模型。模型需要从图像和自身状态中学会怎样接近物体、建立接触，再根据变化调整动作。

## 动作分块：一次预测未来的一段动作

ACT 把单步动作预测改成动作序列预测。为避免区间端点的歧义，下面把长度为 $k$ 的动作块记为：

$$
A_t = [a_t, a_{t+1}, \ldots, a_{t+k-1}].
$$

每个动作是 14 维，因此 $A_t\in\mathbb R^{k\times14}$。相应的策略变为：

$$
\hat A_t = \pi_\theta(o_t, z),
$$

其中 $z$ 是训练时引入的潜变量，后面再解释。先忽略它，动作分块的含义就是：模型在看到当前观测后，同时预测接下来多个控制周期的目标位置。

### 动作块为什么有帮助？

最直接的执行方式是每隔 $k$ 步观察一次，然后依次执行预测出的 $k$ 个动作。对于长度为 $T$ 的任务，策略生成动作块的次数由大约 $T$ 次减少到 $T/k$ 次。论文把它描述为有效决策时域的缩短。

例如，若 $k=100$、控制频率为 50 Hz，一个动作块覆盖约 2 秒。模型可以在一次预测中组织“靠近电池槽、调整角度、开始压入”这样的连续运动，训练目标也会直接约束这段动作之间的关系。

这里的 $T/k$ 对应按整块执行时的决策次数，实际控制周期并没有变少。动作分块仍然依赖示范覆盖，预测出的序列也可能偏离真实环境，不能由决策次数的减少直接推导成功率的提升幅度。

动作块还能在一定程度上容纳人类示范中的停顿和节奏。模型学习的是一段运动模式，某几帧停住、随后继续的关系可以出现在同一个预测目标中。不过，它不能因此解决所有依赖长历史的部分可观测问题。

### 时序集成如何让机器人持续利用新观测？

整块执行有一个明显代价：块内缺少新的视觉修正，而且切换动作块时可能突然改变运动方向。精细操作恰恰需要持续调整，因此 ACT 在推理时引入时序集成（Temporal Ensembling）。

启用时序集成后，策略在每个控制步重新预测一个动作块。这样，相邻的动作块会相互重叠。假设当前是第 $t$ 步，刚刚生成的动作块包含对 $t$ 的预测，上一轮生成的动作块也包含对 $t$ 的预测，更早的若干轮同样如此。ACT 收集这些都指向当前执行时刻的动作，再加权得到最终命令。

![动作分块与时序集成。上半部分每隔一个动作块重新预测；下半部分每步预测，并对同一执行时刻的重叠预测加权。来源：原论文 Figure 5。](/images/act/action-chunking-temporal-ensemble.webp)

记 $\hat a_t^{(s)}$ 为第 $s$ 步生成、计划在第 $t$ 步执行的动作，当前有效预测的生成时刻集合为：

$$
\mathcal S_t = \{\max(0,t-k+1),\ldots,t\}.
$$

将这些预测按生成时间从早到晚排列为 $s_0,\ldots,s_{n-1}$，集成后的动作可以写成：

$$
a_t^{\mathrm{exec}} =
\frac{\sum_{i=0}^{n-1}w_i\hat a_t^{(s_i)}}
{\sum_{i=0}^{n-1}w_i}.
$$

权重采用指数形式 $w_i=\exp(-mi)$，其中 $m$ 为控制权重衰减的超参数。

**参与平均的动作都对应同一个执行时刻。** 如果把已经执行的 $a_{t-1}$ 和准备执行的 $a_t$ 混在一起平滑，就改变了原来的时间对应关系，也不是论文这里使用的方法。

权重方向也容易看反。原文明确规定 $w_0$ 对应最早生成的预测，所以在 $m&gt;0$ 时，较早预测的权重更大。减小 $m$ 会让新旧预测的权重更接近，使新观测更快影响执行结果。[官方推理代码](https://github.com/tonyzhaozh/act/blob/main/imitate_episodes.py)也按这个顺序计算指数权重。阅读其他实现时，需要同时检查缓存顺序和指数公式。

因此，启用时序集成后，ACT 仍会每步查询策略；分块的作用体现在连续动作的联合预测上。时序集成则在推理阶段协调重叠预测，改善运动连续性，同时带来额外的推理计算。

## 条件 VAE：怎样学习不完全一致的人类示范？

在空中交接胶带时，操作者可以在偏左或偏右的位置完成交接。只要两只手配合得当，这些轨迹都可能成功。但如果只对不同示范做确定性的逐元素回归，模型可能学到一个并不对应完整示范的折中序列。

ACT 将动作块建模为条件 VAE（Conditional Variational Autoencoder，CVAE）。模型由训练时使用的后验编码器和真正输出动作的策略网络组成。

![ACT 的整体架构。左侧 CVAE 编码器从关节位置与示范动作序列推断潜变量；右侧策略结合多视角图像、关节位置和潜变量，预测未来动作块。来源：原论文 Figure 4。](/images/act/act-architecture.webp)

### 训练时，用潜变量表示示范的差异

训练时，编码器可以看到当前关节位置 $q_t$ 和专家未来动作块 $A_t$，输出一个对角高斯分布：

$$
q_\phi(z\mid A_t,q_t)
=\mathcal N\bigl(\mu_\phi,\operatorname{diag}(\sigma_\phi^2)\bigr).
$$

这里的 $\mu_\phi$ 和 $\sigma_\phi$ 都由 $A_t$ 与 $q_t$ 决定。为了减少训练计算，论文中的这个后验编码器不接收图像。它通过重参数化采样潜变量：

$$
z = \mu_\phi + \sigma_\phi\odot\epsilon,
\qquad \epsilon\sim\mathcal N(0,I).
$$

随后，策略根据当前完整观测和 $z$ 重建专家动作块：

$$
\hat A_t = \pi_\theta(o_t,z).
$$

论文把 $z$ 称为动作序列的“风格变量”。它用于容纳示范中路径、节奏等差异；这些含义由训练形成，论文没有为潜变量的每一维指定可解释的控制语义。

训练损失包含动作重建和 KL 正则两部分：

$$
\begin{aligned}
\mathcal L &amp;= \mathcal L_{\mathrm{rec}}
+\beta\mathcal L_{\mathrm{KL}},\\
\mathcal L_{\mathrm{rec}}
&amp;= \mathbb E_{z\sim q_\phi}
\left[\|A_t-\pi_\theta(o_t,z)\|_1\right],\\
\mathcal L_{\mathrm{KL}}
&amp;=D_{\mathrm{KL}}\left(q_\phi\,\|\,\mathcal N(0,I)\right).
\end{aligned}
$$

这里为简洁起见，将后验 $q_\phi(z\mid A_t,q_t)$ 缩写为 $q_\phi$。重建项要求预测动作贴近示范，KL 项把后验分布约束到标准高斯先验附近。$\beta$ 控制两者的相对权重；论文默认设为 10。按作者的解释，更大的 $\beta$ 会限制 $z$ 携带的信息量。

这里的重建项使用 L1。原论文 Algorithm 1 的伪代码写的是 MSE，但第 IV-C 节明确说明实际实现采用 L1，并报告它更有利于精确建模动作序列。理解方法和复现时，应注意这处正文与伪代码的差异。

### 推理时，把潜变量固定为零

部署时没有专家未来动作，后验编码器无法继续使用。ACT 将它移除，把潜变量设为先验均值：

$$
z=0,\qquad \hat A_t=\pi_\theta(o_t,0).
$$

因此，论文中的标准推理流程是确定性的，不需要每次从潜变量分布随机采样。CVAE 在这里首先是一种训练动作模型、处理示范差异的方法；不能仅凭使用了生成模型，就认为部署时会主动探索多条轨迹。$z=0$ 对应先验均值，也不意味着输出一定是概率最高的动作序列。

## Transformer 具体怎样生成动作块？

ACT 里有两层容易混淆的“编码器与解码器”。CVAE 的编码器负责推断 $z$，CVAE 的解码器就是动作策略；而这个动作策略内部，又包含视觉骨干、Transformer encoder 和 Transformer decoder。

先看训练专用的后验编码器。它把一个可学习的 `[CLS]` token、当前关节位置，以及长度为 $k$ 的动作序列映射到特征空间，组成 $k+2$ 个 token。Transformer 处理后，取 `[CLS]` 对应的输出预测 $z$ 的分布参数。

动作策略则按下面的过程处理观测：

| 环节                | 论文中的输入与输出                                                                 | 作用                              |
| ------------------- | ---------------------------------------------------------------------------------- | --------------------------------- |
| 图像编码            | 每路 $480\times640\times3$ RGB 图像，经 ResNet18 得到 $15\times20\times512$ 特征图 | 提取各相机视角的视觉信息          |
| 视觉序列            | 每路展平为 $300\times512$，四路共 $1200\times512$，加入二维位置编码                | 保留图像内的空间位置信息          |
| 状态与潜变量        | 关节位置和 $z$ 分别投影为 512 维 token                                             | 提供机器人状态和动作风格条件      |
| Transformer encoder | 共 $1202\times512$ 的输入特征                                                      | 融合多视角视觉、关节状态与潜变量  |
| Transformer decoder | $k$ 个动作位置查询，通过交叉注意力读取融合特征                                     | 同时生成未来 $k$ 个动作位置的表示 |
| 动作输出头          | $k\times512\rightarrow k\times14$                                                  | 得到双臂绝对目标关节位置          |

这些动作查询分别对应未来序列中的不同位置。模型可以一次输出整个动作块，无需先生成第一个动作，再把它作为输入逐个生成后续动作。

论文附录 Table III 给出的主要超参数如下：

| 参数                      | 设置          |
| ------------------------- | ------------- |
| 动作块长度 $k$            | 100           |
| 隐藏维度                  | 512           |
| Transformer encoder 层数  | 4             |
| Transformer decoder 层数  | 7             |
| 注意力头数                | 8             |
| 前馈网络维度              | 3200          |
| 学习率 / batch size       | $10^{-5}$ / 8 |
| KL 权重 $\beta$ / dropout | 10 / 0.1      |

原文报告模型约有 8000 万参数，每个任务单独训练；在单张 RTX 2080 Ti 上训练约需 5 小时，单次推理约 0.01 秒。这些是作者在特定设置下测得的运行开销，迁移到其他设备时仍需要实测。

项目主页演示视频注明固定动作块长度为 90，论文附录的默认值则是 100。两处对应各自的实验或演示设置，引用参数时应注明来源。

## 实验结果：六个真实任务的难度并不相同

论文评估了六个真实世界任务和两个 MuJoCo 仿真任务。真实任务涉及拉开密封袋、装电池、开调料杯盖、穿魔术贴扎带、处理胶带和穿鞋，很多步骤都要求双臂在接触中配合。

![六个真实世界任务及各自的初始状态和操作阶段，从上到下依次为 Slide Ziploc、Slot Battery、Open Cup、Thread Velcro、Prep Tape 和 Put On Shoe。来源：原论文 Figure 6，可点击放大查看。](/images/act/real-world-tasks.webp)

### 训练数据和评估口径

每个真实任务通常收集 50 条示范，Thread Velcro 使用 100 条。单条示范约 8–14 秒，对应 400–700 个控制步。论文将每项任务的示范总量概括为约 10–20 分钟；如果计入环境复位和操作者失误，实际采集约需 30–60 分钟。

所以，“约十分钟示范”描述的是记录下来的演示数据量，不能当成完整的采集或训练耗时。论文也没有证明所有任务都能靠完全相同的数据量学会。

真实实验中，物体初始位置主要沿桌面的 15 cm 参考线变化；仿真任务在指定二维区域随机初始化。这些设置能够检验一定范围内的初始状态变化，但没有覆盖任意新物体、房间或相机布置。

真实任务使用 1 个训练随机种子，每项评估 25 次；仿真任务使用 3 个种子，每个种子评估 50 次。阅读成功率时，需要连同这些样本量和环境条件一起看。

### 真实任务：装电池 96%，穿扎带仍只有 20%

下面只取 Table I、II 中最后一个子任务的成功率，表示完整任务的完成情况：

| 任务                              | 示范条数 | ACT 完整任务成功率 | BeT 完整任务成功率 |
| --------------------------------- | -------- | ------------------ | ------------------ |
| Slide Ziploc：拉开密封袋          | 50       | 88%                | 0%                 |
| Slot Battery：装入电池            | 50       | 96%                | 0%                 |
| Open Cup：打开调料杯盖            | 50       | 84%                | 0%                 |
| Thread Velcro：穿魔术贴扎带       | 100      | 20%                | 0%                 |
| Prep Tape：取下一段胶带并挂在盒边 | 50       | 64%                | 0%                 |
| Put On Shoe：穿鞋并固定魔术贴     | 50       | 92%                | 0%                 |

前两个真实任务还比较了 BC-ConvMLP、RT-1 和 VINN，它们的最终成功率也均为 0%。其余四个任务只与 BeT 比较。这里的 RT-1 指论文在该数据与任务设置下训练、评估的基线，结果不能直接外推到 RT-1 在其他数据规模下的能力。

这些结果说明，ACT 在论文设置的精细双臂任务上明显优于所比较的方法，同时也暴露出任务之间的差距。Thread Velcro 的阶段成功率从抬起扎带的 92%，降到空中抓取的 40%，最终穿入只剩 20%。作者观察到的失败包括右夹爪过早闭合、没抓住扎带尾部，以及插入位置不准。

黑色扎带与桌面背景对比度低，在图像中占据的区域也小。即使采用动作分块，如果视觉输入不能准确支持接触判断，后续序列仍然容易失败。

### 仿真任务：人类示范与脚本示范要分开看

![两个仿真任务。左侧是将红色方块从一只夹爪交给另一只，右侧是双臂分别持有插头与插座并完成插入；初始位置在指定区域随机化。来源：原论文 Figure 7。](/images/act/simulation-tasks.webp)

论文为每个仿真任务分别准备了脚本示范和人类遥操作示范，每种各 50 条。下表同样只保留完整任务成功率：

| 方法       | Cube Transfer：脚本 / 人类 | Bimanual Insertion：脚本 / 人类 |
| ---------- | -------------------------- | ------------------------------- |
| BC-ConvMLP | 1% / 0%                    | 1% / 0%                         |
| BeT        | 27% / 1%                   | 3% / 0%                         |
| RT-1       | 2% / 0%                    | 1% / 0%                         |
| VINN       | 3% / 0%                    | 1% / 0%                         |
| ACT        | 86% / 50%                  | 32% / 20%                       |

ACT 在这些对比中表现最好，但双臂插入仍然困难。从脚本数据换成人类数据后，ACT 的成功率也下降了。数据中存在更多路径和节奏变化时，模仿学习的难度会增加；“使用人类示范”并不会自动带来更高的策略成功率。

## 消融实验：哪些设计真正贡献了收益？

![ACT 的消融与用户研究。a 比较动作块长度，b 比较时序集成，c 比较 CVAE，d 比较不同遥操作频率下的人类完成时间。来源：原论文 Figure 8。](/images/act/ablations.webp)

动作分块的收益最直接。为单独考察分块，作者关闭时序集成，并在“两个仿真任务 × 两种示范来源”共四个设置上取平均。ACT 的平均成功率随 $k$ 变化如下：

| 动作块长度 $k$ | 1   | 10  | 100 | 200 | 400 |
| -------------- | --- | --- | --- | --- | --- |
| 平均成功率     | 1%  | 21% | 44% | 42% | 41% |

从单步预测改到长度为 100 的动作块，收益很大；继续增加长度则没有进一步提升。作者将后面的回落归因于反馈减少，以及长序列更难建模。BC-ConvMLP 和 VINN 加上动作分块后也有提升，说明收益并非只能由 Transformer 获得。

时序集成的作用更有限，也更依赖方法。在论文分别调参后比较的设置中，ACT 的平均成功率从 44% 提升到 47.3%，增加 3.3 个百分点；BC-ConvMLP 从 25% 到 29%。VINN 则从 37% 降至 17%。因此，时序集成不能被当成对所有策略都有效的通用补丁。作者认为参数化模型可能从预测误差的平滑中获益，而直接检索示范动作的 VINN 未必有同样的收益，这仍属于对实验现象的解释。

CVAE 消融回答的是另一个问题。在两个仿真任务上汇总结果后，脚本数据训练的成功率在去掉 CVAE 时只从 59% 变为 58%；人类示范训练则从 35.3% 降至 2%。这支持 CVAE 在该实验中处理人类示范差异的作用。它没有进一步证明究竟是哪一种示范变化造成了主要困难，也不能说明每个数据集都会出现同样幅度的收益。

图中最后一项是人类遥操作用户研究。6 名参与者分别在 5 Hz 和 50 Hz 下完成穿扎带、分开套叠杯子两个任务，降低频率后，完成时间总体增加约 62%。这个结果支持高频反馈对这些精细操作的价值，但它测量的是人的遥操作表现，没有直接给出 ACT 在所有控制频率下的成功率曲线。

## ACT 的边界，以及值得带走的设计思路

ACT 的效果依赖于示范质量、感知能力和硬件条件。它没有通过动作分块消除分布偏移，也没有让双指夹爪具备任意精细操作能力。

论文报告，ALOHA 对需要多指配合、大力矩或类似指甲动作的任务仍然受限。例如，夹爪难以完成某些需要一边按压一边旋开的瓶盖操作，低成本电机也难以支持较大的接触力。这些限制不能单靠换一个动作模型解决。

学习本身也有失败案例。作者尝试用 50 条示范学习拆糖果包装，初步的 10 次测试中，策略能全部抓起糖果，却没有一次成功完全拆开。它经常在不存在包装接缝的位置尝试剥开。把评估放宽为每颗糖果最多尝试 10 次后，5 颗中成功拆开了 3 颗，这与单次尝试的成功率是不同的评估口径。另一个任务是打开平放的小密封袋：策略能够捡起袋子，却难以稳定完成后续空中操作。作者将这些困难与感知、数据不足及物体形变联系起来，并提出预训练、更多数据和更好的感知可能有帮助；这些方向在本文中尚未得到验证。

从这些结果看，ACT 值得借鉴的地方，是把高频控制中的连续动作组织成一个合适的学习目标：动作块约束一段运动的内部关系，CVAE 训练目标容纳示范差异，时序集成协调反复生成的预测。三项设计各自解决的问题不同，消融结果也显示它们的收益并不相同。

如果要复现或迁移 ACT，动作的定义和数据对应关系需要先核对清楚：输入是机器人实际状态，输出是绝对目标关节位置；训练时的后验编码器能看到未来示范动作，部署时要移除它并令 $z=0$；动作块长度决定预测范围，查询频率决定何时使用新观测；时序集成必须对齐到同一个执行时刻。这些细节会直接改变控制行为。

ACT 给出的证据是，在有限数据、特定硬件和任务范围内，学习连续动作块可以比逐帧动作预测更有效地完成精细操作。读到“约十分钟示范”和“80–90% 成功率”时，再回到具体任务、采集时间、测试次数和失败阶段，才能判断这个结果对自己的任务有多大参考价值。

## 原文与配图来源

本文依据所提供的 ACT.pdf（arXiv:2304.13705v1）撰写，实验数据对应原论文 Table I–III 与 Figure 8；封面及正文配图均从该 PDF 截取，仅裁去图外空白与英文图注，图内内容未改写。图片与原始研究成果归原作者所有。

- [原论文与版本信息](https://arxiv.org/abs/2304.13705)：方法、实验和附录细节的主要来源。
- [作者项目主页](https://tonyzhaozh.github.io/aloha/)：RSS 2023 信息、任务视频与动作块长度为 90 的演示设置。
- [ACT 官方代码仓库](https://github.com/tonyzhaozh/act)：训练和推理实现，时序集成见 `imitate_episodes.py`。
- [ALOHA 官方代码仓库](https://github.com/tonyzhaozh/aloha)：硬件使用、遥操作与数据采集相关实现。</content:encoded><category>论文精读</category><category>具身智能</category><category>机器人操作</category><category>模仿学习</category><category>act</category><category>aloha</category></item><item><title>论文精读｜DP3：当 Diffusion Policy 遇上 3D 点云</title><link>https://example.com/blog/%E8%AE%BA%E6%96%87%E7%B2%BE%E8%AF%BB-dp3%E5%BD%93-diffusion-policy-%E9%81%87%E4%B8%8A-3d-%E7%82%B9%E4%BA%91/</link><guid isPermaLink="true">https://example.com/blog/%E8%AE%BA%E6%96%87%E7%B2%BE%E8%AF%BB-dp3%E5%BD%93-diffusion-policy-%E9%81%87%E4%B8%8A-3d-%E7%82%B9%E4%BA%91/</guid><description>沿着观测表示、点云编码、扩散动作生成和实验验证，理解 DP3 为什么能用少量示范学习操作技能，以及三维表示的收益究竟来自哪里。</description><pubDate>Thu, 29 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&gt; **论文：** 3D Diffusion Policy  
&gt; **作者：** Yanjie Ze、Gu Zhang、Kangning Zhang、Chenyuan Hu、Muhan Wang、Huazhe Xu  
&gt; **发表：** RSS 2024；首次公开于 2024 年 3 月 6 日  
&gt; [本文对应的 arXiv v1](https://arxiv.org/abs/2403.03954v1) · [现行论文](https://arxiv.org/abs/2403.03954) · [代码](https://github.com/YanjieZe/3D-Diffusion-Policy) · [项目与演示视频](https://3d-diffusion-policy.github.io/)

版本说明：本文依据 2024 年 3 月 6 日的 arXiv v1 解读，实验表中的“相对提升 55.3%”来自该版 Table I。v7 摘要报告的是 24.2%，下文保留 v1 的实验口径，不混用两版数字。

DP3 想解决的问题是：示范很少时，策略能否更容易学到“物体在哪里、机器人该往哪里动”？它保留了 Diffusion Policy 生成动作序列的方式，把视觉输入换成稀疏点云，再用一个小型编码器提取几何特征。这个改动把一部分原本需要从像素中学习的空间关系，放进了输入表示里。

但“给策略加上深度”还不足以解释它的效果。论文里，深度图、RGB-D 和体素都弱于点云；换成更复杂的点云编码器，成绩甚至会明显下降。因此，DP3 真正值得研究的是：怎样把三维观测压缩成适合控制的条件，以及实验能否把表示、编码器和动作模型的作用区分开。

## 从一张深度图到一段动作，DP3 做了什么？

![DP3 的完整流程：单视角点云经过裁剪和最远点采样，由轻量编码器提取三维特征，再与机器人状态一起作为条件，迭代去噪生成动作序列。感知和动作模型通过示范端到端训练。来源：v1 Figure 2。](/images/dp3/overview.webp)

一次策略查询可以分成两个映射：先把点云和机器人状态编码成条件，再根据这个条件生成动作块。记点云为 $P_t$、机器人自身状态为 $q_t$，则有：

$$
v_t=f_\phi(P_t),\qquad r_t=g_\psi(q_t),
$$

$$
c_t=[v_t;r_t]\in\mathbb R^{128}.
$$

其中，点云特征 $v_t$ 和状态特征 $r_t$ 都是 64 维。策略使用两个观测时刻的条件信息，从随机噪声中生成一个动作序列。这里的扩散模型生成的是机器人动作；点云本身只经过确定性的预处理与编码。

这种拆法也划清了贡献范围：DP3 的感知模块负责提供几何条件，动作模块沿用基于卷积网络的 Diffusion Policy。它没有额外学习物体动力学，也不需要先预测关键帧位姿、再交给运动规划器完成整段运动。

### 点云预处理承担了哪些工作？

论文在仿真和真实实验中都使用单视角、$84\times84$ 的深度观测，结合相机内外参转换为点云。每个点仅保留 XYZ 坐标，不输入 RGB；随后用预设空间包围盒裁掉无关区域，再通过最远点采样（FPS）保留 512 或 1024 个点。

这几步各有用途。裁剪限制了策略需要解释的空间范围；FPS 用有限点数覆盖剩余几何结构，减少采样随机性；去掉颜色则降低对纹理和颜色的依赖。最终网络看到的是一个大小为 $N\times3$ 的坐标集合，而不是原始深度像素网格。

![同一真实场景的 RGB、深度图、带颜色点云和无颜色点云。深度图仍按像素排列，点云则把深度转换成显式三维坐标；图中点云的伪彩色用于展示，不代表策略使用 RGB 通道。来源：v1 Figure 11。](/images/dp3/visual-modalities.webp)

关键区别在于几何关系怎样表达。深度图里的相邻像素未必属于相邻表面，同样的像素位移也可能对应不同的空间距离；转换为点云后，三维位置关系可以直接由坐标表达。模型仍需学习哪些位置和形状会影响动作，但无需完全依赖二维纹理去推断这些关系。

点云没有替策略解决所有感知问题。它只包含单个视角能看到的表面，遮挡和深度缺失仍然存在；坐标也依赖标定与变换。输入三维坐标，更不意味着网络自动具备平移或旋转不变性。

## 编码器为什么这么小，还能保留控制所需的信息？

DP3 Encoder 对每个点应用共享 MLP，维度依次为 $3\rightarrow64\rightarrow128\rightarrow256$，每层线性变换后接 LayerNorm 和 ReLU。然后在点的维度上取最大值，最后用 Linear 和 LayerNorm 把 256 维全局特征投影为 64 维：

$$
h_i=\operatorname{MLP}(p_i),\qquad h_i\in\mathbb R^{256},
$$

$$
v_t=\operatorname{LN}\!\left(W\max_i h_i+b\right).
$$

这里的最大池化按特征通道独立进行：不同通道的最大值可以来自不同的点。它把点的数量消去，并使最终表示对输入点的排列顺序保持不变。共享 MLP 本身保留逐点输出的对应关系，真正得到全局排列不变表示的是池化步骤。

这个结构没有显式建立局部邻域，也没有逐点自注意力。它的归纳偏置比较直接：先从绝对坐标提取逐点特征，再聚合场景中响应最强的几何信息。对于需要根据物体与机器人相对位置采取动作的任务，保留位置相关信息有实际意义。物体识别往往希望同一物体换个姿态仍被识别为同一类，控制策略却需要让不同姿态对应不同动作，两类任务未必需要同样的特征变换。

机器人状态由另一个 MLP 编码，结构是 $D_q\rightarrow64\rightarrow64$，中间使用 ReLU。它与视觉特征共同决定动作：同一场景下，机械臂已经靠近物体还是仍在远处，下一步控制量当然不同。单个观测的联合特征是 128 维，历史观测的信息再作为去噪网络的条件。

### 空间泛化的证据是什么？

![MetaWorld Reach 的空间测试。红点对应 5 条训练示范，蓝点表示成功到达的测试位置；从左到右为 BC-RNN、IBC、Diffusion Policy 和 DP3。来源：v1 Figure 3。](/images/dp3/reach-generalization.webp)

Reach 实验给了一个直观例子：只用 5 条示范训练，在三维空间测试 1000 次，BC-RNN、IBC、Diffusion Policy 和 DP3 分别成功 0、285、327、415 次。DP3 的成功位置覆盖了更广的空间，但其成功率仍是 41.5%。这个结果支持“点云表示有助于少样本空间外推”，并没有证明策略已能在整个工作空间可靠泛化。

## 动作生成：训练预测干净动作，推理执行短动作块

感知部分回答“根据什么行动”，扩散模型回答“生成怎样的一段连续动作”。DP3 使用基于卷积网络的条件去噪模型，同时更新整个动作序列，无需逐个动作自回归生成。

设归一化后的专家动作块为 $A^0$，扩散噪声等级为 $k$。为了说明实际使用的 sample prediction，可以把训练过程写成：

$$
A^k=\sqrt{\bar\alpha_k}A^0
+\sqrt{1-\bar\alpha_k}\epsilon,
$$

$$
\hat A^0=f_\theta(A^k,k,C_t),
\qquad \epsilon\sim\mathcal N(0,I).
$$

$C_t$ 表示两帧观测形成的条件信息，$k$ 表示噪声等级，与机器人执行的物理时刻 $t$ 不同。训练要求网络从带噪动作中恢复原始动作块，目标可写为 $\mathbb E\|A^0-\hat A^0\|_2^2$。

原文公式 (2) 使用了预测噪声的写法，但 Implementation Details 明确说明，实际采用 **sample prediction，即直接预测干净动作**。两者都属于扩散模型的参数化方式；解读实现时，需要以实际采用的目标为准。Figure 7 显示 sample prediction 通常收敛更快，去掉它后的六任务平均分从 63.2 降至 59.0；epsilon prediction 仍能学到策略，不能将它描述为失效。

部署时，模型从高斯噪声开始，用 DDIM 做 10 次去噪更新，得到动作块；训练噪声调度则包含 100 个时间步。这里的“10 步”是一次策略查询内部的计算迭代，和下表里的动作执行长度是两回事。

| 参数 | 论文设置 | 含义 |
| --- | --- | --- |
| 观测长度 $N_{\mathrm{obs}}$ | 2 | 每次查询使用两个时刻的观测 |
| 预测长度 $H$ | 4 | 一次生成长度为 4 的动作序列 |
| 执行长度 $N_{\mathrm{act}}$ | 3 | 执行时间对齐后的最后 3 个动作，再接收新观测 |
| 训练 / 推理扩散步数 | 100 / 10 | 噪声调度长度与 DDIM 去噪迭代数 |

所以，H=4 不能直接理解成“从当前时刻开始，未来 4 步全部开环执行”。策略执行短动作段后重新查询，历史观测和预测序列之间还需要保持时间对齐。论文也比较了较长配置 $H=16,N_{\mathrm{act}}=8$：六任务上 DP3 从 63.2 变为 64.2，短窗口并未明显损失整体表现，因此作者选择较短窗口来保留对环境变化的响应机会。

复现时还有一个容易漏掉的细节：附录要求把各动作维度和观测维度按各自最小、最大值缩放到 $[-1,1]$。作者特别强调动作归一化，因为所用 DDPM/DDIM 实现会把预测裁剪到这个区间。若直接用未归一化的物理控制量训练，再让采样器执行裁剪，动作幅度就可能被破坏。

## 消融实验：收益来自几何、编码器，还是扩散模型？

这一节的对比都应先确认任务集合。论文主要消融只使用 Adroit 的 Hammer、Door、Pen，以及 MetaWorld 的 Assembly、Basketball、Shelf Place，共 6 个任务，每项 10 条示范；它们的平均分不能直接当成 72 项主实验的平均成绩。

### 深度信息有用，但表示形式同样重要

保持动作模型为扩散策略，更换视觉表示及相应编码器，v1 Table IV 得到：

| 视觉表示 | RGB 图像 | RGB-D | 深度图 | 体素 | 点云（DP3） |
| --- | --- | --- | --- | --- | --- |
| 六任务平均分 | 28.7 | 27.8 | 42.0 | 39.5 | 63.2 |

深度图比 RGB 更好，但仍明显低于点云。这个对比支持点云及其编码方式的价值，同时需要看到：实验替换了表示，也替换了编码器，并非只隔离了输入数据格式这一个变量。

“二维基线分辨率太低”也不能完整解释差距。Table IX 将 RGB 基线从 $84\times84$ 提高到 $128\times128$ 和 $256\times256$，六任务平均分分别为 28.7、30.2、29.5，仍低于 DP3 的 63.2。这只排除了所测配置下单纯提高像素数的解释，不代表二维视觉已经没有改进空间。

### 更强的通用点云编码器，未必更适合这组控制任务

把视觉输入固定为点云，替换编码器，v1 Table V–VI 的部分结果如下：

| 编码器或改动 | 六任务平均分 |
| --- | --- |
| DP3 Encoder | 63.2 |
| PointNet | 17.7 |
| PointNet 去掉 T-Net 与 BatchNorm | 59.5 |
| PointNet++ / PointNeXt / Point Transformer | 2.2 / 2.3 / 1.0 |
| 预训练 PointNet++ / 预训练 PointNeXt | 6.8 / 8.8 |

最有解释力的结果是 PointNet 的逐项改造：去掉 T-Net 和 BatchNorm 后，成绩从 17.7 接近到 59.5。作者认为，固定相机下的控制任务未必需要 T-Net 提供的特征变换；但论文没有定位其他复杂编码器失败的完整原因。因此，更稳妥的结论是“面向识别或分割设计的表示，不能未经验证就当作合适的控制表示”，而不是“网络越小越好”或“预训练无用”。

其他设计也不应统称为成功率改进。Table VII 中，去掉点云裁剪使平均分从 63.2 降至 51.3，影响较大；去掉 LayerNorm 为 61.3，去掉投影头为 62.2。加入颜色反而得到 63.7，与默认配置接近。**去颜色的主要取舍是降低外观依赖，投影头的主要用途是压缩特征与加快推理，二者都没有被证明必然提高原任务成功率。**

三维表示也不能替代动作建模。另一组 10 任务对比中，BCRNN 加入 DP3 Encoder 后平均分从 1.8 升到 18.8，IBC 从 5.2 升到 18.7；同一组任务上的 DP3 为 65.3。点云能帮助其他策略，但“点云加任意动作头”并没有复现 DP3 的结果。

## 主实验怎么读：示范数量、评估方法和例外都重要

v1 的 72 项仿真实验覆盖 7 个任务域，既包含夹爪操作，也包含最高 52 维动作控制。除 DexDeform 使用人类遥操作数据外，其余域主要由强化学习专家生成成功轨迹，同一任务的不同方法使用相同示范。

| 任务域 | 任务数 | 每任务示范数 | Diffusion Policy | DP3 |
| --- | --- | --- | --- | --- |
| Adroit | 3 | 10 | 31.7 | 68.3 |
| Bi-DexHands | 6 | 10 | 61.3 | 70.2 |
| DexArt | 4 | 100 | 49.0 | 68.5 |
| DexDeform | 6 | 10 | 90.5 | 87.8 |
| DexMV | 2 | 10 | 95.0 | 99.5 |
| HORA | 1 | 100 | 49.0 | 71.0 |
| MetaWorld Easy | 28 | 10 | 59.7 | 90.1 |
| MetaWorld Medium | 11 | 10 | 26.9 | 61.0 |
| MetaWorld Hard | 6 | 10 | 9.8 | 43.2 |
| MetaWorld Very Hard | 5 | 10 | 17.8 | 56.6 |
| 全部任务 | 72 | 其中 67 项使用 10 条 | 47.6 | 73.9 |

表中数值照录 v1 Table I，MetaWorld 按原表分成四个难度组。HORA 使用归一化回报，其余主要使用成功率，所以跨 72 项的平均值严格说是论文报告的汇总指标。原文报告整体从 47.6 到 73.9，增加 26.3 个百分点，相对提升约 55.3%；DexDeform 则略有下降，不能概括成每个域都提升。

评估协议同样影响数字的含义：每项实验运行 3 个随机种子，每隔 200 个 epoch 评估 20 个 episode，取最高 5 次评估成绩的平均，再汇总不同种子。它反映训练过程中多次评估后的较好表现，不能与只测最终 checkpoint 一次的结果直接混比。

![在 10 个仿真任务上增加示范数量后的学习表现。部分困难 MetaWorld 任务中，二维 Diffusion Policy 即使获得更多示范，仍落后于 DP3；不同任务的收益幅度并不相同。来源：v1 Figure 6。](/images/dp3/demo-scaling.webp)

“数据效率高”还包含两个不同观察。Figure 5 中，DP3 通常收敛更快；Figure 6 中，DP3 在若干任务上用较少示范就达到较好的表现。更快收敛衡量的是训练过程，少样本表现衡量的是数据需求，二者不应合并成一个含糊的“更高效”。这里也没有直接证明成功轨迹之外的失败示范、不同质量的人工示范会带来同样收益。

## 真实机器人与泛化：85% 是怎样得到的？

真实实验使用 Franka 机械臂搭配 Allegro 灵巧手或平行夹爪，以 RealSense L515 获取深度观测。每个任务收集 40 条人类遥操作示范，测试 10 次。前三项任务的动作维度为 22，Pour 为 7。

![四个真实任务的阶段和终态：包裹并捏合橡皮泥、持电钻接触目标方块、多次卷起橡皮泥，以及抓碗、倾倒和放回。来源：v1 Figure 10。](/images/dp3/real-world-tasks.webp)

| 方法 | Roll-Up | Dumpling | Drill | Pour | 平均 |
| --- | --- | --- | --- | --- | --- |
| RGB Diffusion Policy | 0% | 30% | 70% | 40% | 35% |
| 深度图 Diffusion Policy | 40% | 20% | 10% | 10% | 20% |
| DP3 | 90% | 70% | 80% | 100% | 85% |

这张表最直接的含义是：在相同示范数量下，DP3 在四个任务上都能取得较好的结果，且两个二维基线各有擅长和失效的任务。它并不说明深度图在所有任务中都优于 RGB，也不说明 85% 可以外推到任意操作任务。每项只有 10 次测试，一次成败就对应 10 个百分点。

泛化测试进一步改变训练条件之外的位置、外观、实例或视角，但每个新条件都只试一次：

| 泛化类型 | 实际改变的条件 | DP3 的观察结果 |
| --- | --- | --- |
| 空间，Pour | 碗放在 5 个训练外位置 | 成功 4/5，两个基线均为 0/5 |
| 外观，Drill | 将绿色目标方块换成 5 种颜色 | 成功 5/5，两个基线均为 0/5 |
| 实例，Drill | 用鼠标、玩具、杯子等 5 个物体替换目标方块 | 成功 5/5 |
| 视角，Roll-Up | 相机轻微改变至 3 个新视角 | 成功 3/3；手动调整了点云裁剪范围 |

![Drill 的实例泛化：替换的是电钻要接触的目标方块，电钻仍是原来的工具。测试目标包括鼠标、玩具、两类杯子和玩具手。来源：v1 Table XIII。](/images/dp3/target-instances.webp)

这里有两条边界尤其影响解读。实例泛化测的是“持电钻接触不同目标”，并未检验能否抓稳不同型号的电钻。视角泛化则包含人工调整裁剪范围，不能等同于在任意相机位置上直接部署。这些单次测试展示了成功案例，还不足以估计各条件下稳定的成功概率。

论文还统计了需要人为终止、以避免硬件损坏的安全违规：RGB 策略平均为 32.5%，深度图策略为 25%，DP3 为 0%。这是上述真实实验中的观察，模型没有因此获得安全约束或形式化保证。它提示更合适的观测表示可能改善控制行为，但不能取代部署时的硬件保护。

## 对复现与后续研究有什么启发？

DP3 的证据支持一个具体判断：在这些少样本操作任务里，显式几何坐标、适合控制的小型点云编码器和扩散动作生成结合起来，比论文比较的二维策略更有效。它的收益不能单独归给深度传感器，也不能用一个“更复杂的模型”来解释。

复现应先核对数据链路：深度到点云的标定与坐标变换是否一致，裁剪是否保留了任务所需的物体和机器人，采样点数和颜色通道是否匹配，动作是否正确归一化，历史观测与执行切片是否对齐。这些设置会改变策略实际看到和执行的内容，优先级往往高于直接更换编码器。

方法的取舍也很清楚。稀疏单视角 XYZ 能减少外观干扰，却缺少遮挡表面、颜色语义与触觉接触信息；64 维全局池化特征计算便宜，但论文没有证明它保留了所有精细接触所需的局部结构。作者还明确指出，极长时程任务没有在本文中展开。把 DP3 用到依赖颜色选择目标、严重遮挡或多阶段长任务时，需要重新检查观测与任务是否匹配，不能只照搬原实验的平均分。

## 资料与配图来源

正文的方法、超参数及表格均以 [arXiv:2403.03954v1](https://arxiv.org/abs/2403.03954v1) 为依据。封面取自该版 Figure 1 的真实任务区域，正文图片取自 Figure 2、3、6、10、11 及 Table XIII，仅裁剪图外内容，图内数据与标注未改写。

[现行 v7 论文](https://arxiv.org/abs/2403.03954)与[项目主页](https://3d-diffusion-policy.github.io/)可用于查阅后续版本和演示；[官方代码仓库](https://github.com/YanjieZe/3D-Diffusion-Policy)提供实现。理解其扩散动作模型时，可结合 [Diffusion Policy 原论文与项目](https://diffusion-policy.cs.columbia.edu/)阅读。图片与研究成果归原作者所有。</content:encoded><category>论文精读</category><category>具身智能</category><category>机器人操作</category><category>模仿学习</category><category>diffusion policy</category><category>三维点云</category></item><item><title>主题特色与特性</title><link>https://example.com/blog/features/</link><guid isPermaLink="true">https://example.com/blog/features/</guid><description>从设计理念到功能清单：astro-theme-ink 的一切，一文看全。</description><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>astro-theme-ink 是一款基于 [Astro 5](https://astro.build) 与 [UnoCSS](https://unocss.dev) 构建的纯静态个人博客主题。本文把它的设计理念与全部特性讲清楚。

## 设计理念：墨落纸上

主题的英文名是 &quot;ink on paper&quot; —— 墨色文字落在纸上。它体现在三件事上：

- **单一强调色**：全站只有 accent 一个彩色，其余全部交给灰阶分层与留白
- **衬线标题 + 无衬线正文**：标题用衬线字体营造&quot;印刷页面&quot;的呼吸感
- **克制的动效**：只在你最注意的地方出现 —— 悬停划线、入场淡入、滚动渐显

## 两套配色 × 明暗模式

主题内置两套配色，互相独立，又可与明暗模式任意组合（共 4 种观感）：

| 配色      | 气质               | 浅色纸面             | 深色纸面            |
| --------- | ------------------ | -------------------- | ------------------- |
| **ink**   | 暖调纸感           | 米白 `42 35% 97%`    | 暖黑 `32 18% 8%`    |
| **fresh** | 雾霾蓝清新（默认） | 淡蓝白 `212 28% 97%` | 深夜蓝 `215 25% 9%` |

顶栏的调色板按钮（羽毛 / 叶子）切换配色，月亮按钮在 亮色 → 暗色 → 跟随系统 之间循环，选择都会记住。切换时有 300ms 的柔和过渡；页面顶部还有一层极淡的&quot;天际光晕&quot;渐变，随配色自动变化。

## 首页：全部配置驱动

首页的每个分区都由 `src/site-config.ts` 里的 `home` 配置块驱动，**改配置即改页面，无需碰组件**：

- 英雄区：tagline、位置、个人简介、按钮、社交入口
- 最近文章（数量可配）
- 教育经历时间线
- 技能分组
- 可选：标签云、友链预览

## 阅读体验

文章页针对长文做了很多设计：

- **目录**：桌面端右侧吸顶、滚动高亮当前位置；移动端折叠在文章开头
- **阅读进度条**：顶部一条细线随滚动推进
- **上一篇 / 下一篇**：按发布时间自动取相邻文章
- **封面图**：`heroImage` 字段即可
- **正文排版**：悬停划入的链接下划线、自定义圆点/衬线序号列表、内嵌墨条引用块、渐变分割线、行悬停高亮的表格

## 代码块

代码块走的是构建期 Shiki 管线，与很多成熟主题一致：

- 粘性行号 + 左侧条带，横向滚动时行号不消失
- 支持标题（`lang title=&quot;文件名&quot;`）
- 右上角语言标签，悬停切换为复制按钮（带 &quot;Copied!&quot; 气泡）
- 超过 15 行自动折叠，底部 &quot;Show all&quot; 展开
- 支持 `[!code highlight]` 高亮、`[!code ++]` / `[!code --]` diff 标记

## 搜索与评论

- **站内搜索**：构建时生成 JSON 索引，前端本地过滤 + 关键词高亮，**无任何外部服务**
- **评论**：Waline（自部署，Vercel + LeanCloud 即可），配置里填上服务器地址即启用
- **浏览量**：同一 Waline 服务器提供文章页访问计数

## SEO 与分享

- 每篇文章自动输出 JSON-LD `BlogPosting` 结构化数据
- Open Graph / Twitter Card / canonical / theme-color 齐全
- RSS + sitemap 开箱即用（构建时生成）

## 技术底座

- **Astro 5** 纯静态输出（`output: &apos;static&apos;`），构建产物可直接托管到任意平台
- **UnoCSS**（presetWind3 + presetTypography + presetIcons）：按需生成，几乎不产生冗余 CSS
- 零运行时框架、无 jQuery 之类的依赖，页面体积很小

## 目录结构

```
src/
├── site-config.ts        # 所有配置（站点、首页、评论、友链…）
├── content.config.ts     # 内容集合 schema
├── assets/styles/        # 设计 token（两套配色）+ 全局样式
├── components/           # 布局组件（Header/Footer/卡片/目录/评论…）
├── layouts/              # BaseLayout / PostLayout
├── pages/                # 首页、博客、标签、归档、友链、关于、搜索、RSS…
├── plugins/              # Shiki 代码块管线（移植自 astro-theme-pure）
├── utils/                # 工具函数（日期、阅读时长、搜索索引…）
└── content/blog/         # 你的文章（Markdown）
```

下一步：[从零开始：安装与使用](../getting-started/) 会带你把它跑起来。</content:encoded><category>主题</category><category>文档</category></item><item><title>从零开始：安装与使用</title><link>https://example.com/blog/getting-started/</link><guid isPermaLink="true">https://example.com/blog/getting-started/</guid><description>环境准备、下载安装、跑起开发服务器、写第一篇文章、构建部署——完整的上手流程。</description><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>本文带你从零把 astro-theme-ink 跑起来，并完成第一篇文章和一次部署。

## 1. 环境准备

需要 Node.js 22+ 和 pnpm：

```bash
node -v   # v22.0.0+
pnpm -v   # v10+
```

## 2. 获取主题

把仓库 clone 到本地（或者直接下载 ZIP 解压）：

```bash
git clone &lt;你的仓库地址&gt; my-blog
cd my-blog
```

&gt; 如果是从 GitHub 模板仓库创建，也可以直接用 &quot;Use this template&quot;。

## 3. 安装依赖并启动

```bash
pnpm install
pnpm dev
```

打开 http://localhost:4321 就能看到主题首页。开发模式下改文件会热更新。

## 4. 写第一篇文章

在 `src/content/blog/` 下新建一个 Markdown 文件，例如 `hello.md`：

```markdown
---
title: &apos;你好，世界&apos;
description: &apos;我的第一篇文章。&apos;
publishDate: 2026-08-17
tags: [随笔]
---

这里是正文。支持标准 Markdown 语法。
```

保存后刷新浏览器，文章就会出现在首页的&quot;最近文章&quot;和 `/blog` 列表里。

**Frontmatter 字段速查：**

| 字段          | 必填 | 说明                                                                                                     |
| ------------- | ---- | -------------------------------------------------------------------------------------------------------- |
| `title`       | ✅   | 标题（≤80 字）                                                                                           |
| `description` | ✅   | 一句话摘要（≤200 字）                                                                                    |
| `publishDate` | ✅   | 发布日期                                                                                                 |
| `updatedDate` | —    | 更新日期（显示&quot;Updated&quot;）                                                                                |
| `tags`        | —    | 标签数组                                                                                                 |
| `heroImage`   | —    | 封面图：`heroImage: { src: ../../assets/cover.png, alt: &apos;…&apos; }`（相对文章文件的本地资源，构建时自动压缩） |
| `draft`       | —    | `true` 时仅在 URL 可见，不进列表                                                                         |
| `comment`     | —    | 单篇关闭评论                                                                                             |

## 5. 配置个人信息

编辑 `src/site-config.ts`，把站点改成你的：

```ts
site: {
  title: &quot;Hansen&apos;s ink&quot;,   // 站点标题
  author: &apos;Hansen W.&apos;,      // 作者名
  description: &apos;……&apos;,
  lang: &apos;en&apos;,               // 语言
  avatar: &apos;/avatar.png&apos;,    // 首页头像（放 public/）
  palette: &apos;fresh&apos;          // 默认配色：&apos;ink&apos; 或 &apos;fresh&apos;
}
```

首页内容（简介、教育、技能等）改 `home` 配置块，评论和浏览量在 `comment` / `pageview` 里填你的 Waline 服务器地址。

## 6. 构建与部署

```bash
pnpm build      # 产物在 dist/
pnpm preview    # 本地预览构建结果
```

**重要**：部署前把 `astro.config.ts` 里的 `site: &apos;https://example.com&apos;` 换成你的真实域名 —— sitemap、canonical 和 RSS 都依赖它。

纯静态产物可以部署到任何平台：

- **Vercel / Netlify**：连上仓库自动构建（build 命令 `pnpm build`，输出目录 `dist`）
- **Cloudflare Pages**：同上
- **GitHub Pages**：构建后把 `dist/` 内容推送到 pages 分支

## 7. 更新主题（主题与博客分开时）

如果把主题放在 `D:/Code/astro-theme-ink`，而真实文章和个人配置放在 `D:/Code/Blog`，主题升级时使用同步脚本，而不是直接复制文件：

```powershell
cd D:/Code/astro-theme-ink
pnpm theme:sync --target ../Blog
pnpm theme:sync --target ../Blog --apply

cd ../Blog
pnpm test
pnpm build
```

第一条只列出变更，第二条才写入。脚本会保留文章、个人图片、域名、部署设置和个人站点配置；将生成的 `.theme-sync.json` 一起提交。需要解决 `REVIEW` 或 `CONFLICT` 时，阅读仓库中的 `docs/theme-sync.md`。

也可以执行 `pnpm theme:sync:ui` 打开本机同步面板，在浏览器中完成目录选择、预览和确认应用。

## 8. 清理演示内容

把 `src/content/blog/` 下的示例文章删掉或改写，把 `public/avatar.png`、`favicon/` 换成你自己的，就完成了。

遇到问题？可以看[主题特色与特性](../features/)了解功能，或去[深度定制](../customize/)调整细节。</content:encoded><category>主题</category><category>文档</category></item><item><title>深度定制指南</title><link>https://example.com/blog/customize/</link><guid isPermaLink="true">https://example.com/blog/customize/</guid><description>从站点信息、首页内容、评论系统到配色、排版、代码块语法与部署——把主题完全调成你的样子。</description><pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate><content:encoded>主题的几乎一切定制都收拢在几个文件里。本文按&quot;配置 → 样式 → 内容 → 部署&quot;的顺序完整过一遍。

## 1. 站点信息：`src/site-config.ts`

```ts title=&quot;site-config.ts&quot;
site: {
  title: &quot;Hansen&apos;s ink&quot;,   // 站点标题（浏览器标签、页头品牌）
  author: &apos;Hansen W.&apos;,      // 作者名（首页与页脚版权）
  description: &apos;……&apos;,        // 站点描述（meta description）
  lang: &apos;en&apos;,               // html lang 与 RSS language
  favicon: &apos;/favicon/favicon.ico&apos;,
  avatar: &apos;/avatar.png&apos;,    // 首页头像（public/ 下）
  ogImage: &apos;/og-card.svg&apos;,  // 社交分享卡片
  palette: &apos;fresh&apos;,         // 默认配色 &apos;ink&apos; | &apos;fresh&apos;
  titleDelimiter: &apos; · &apos;     // 标题分隔符
}
```

## 2. 页头与导航

```ts title=&quot;site-config.ts&quot;
header: {
  menu: [
    { title: &apos;Blog&apos;, link: &apos;/blog&apos; },
    { title: &apos;Tags&apos;, link: &apos;/tags&apos; },
    { title: &apos;Links&apos;, link: &apos;/links&apos; },
    { title: &apos;About&apos;, link: &apos;/about&apos; }
  ]
}
```

菜单项在桌面端内联展示，移动端自动变成顶栏下方的横向滚动条。当前页会高亮（带 `aria-current`）。

## 3. 页脚

```ts title=&quot;site-config.ts&quot;
footer: {
  copyright: &apos;© 2020 - 2026 Hansen W.&apos;,   // 自定义版权行；不写则默认 © 年份 作者
  links: [{ title: &apos;RSS&apos;, url: &apos;/rss.xml&apos; }],  // 版权行后的链接
  social: {
    github: { label: &apos;GitHub&apos;, url: &apos;https://github.com/willimt&apos; }
    // 支持 github/gitlab/rss/mail/x/weibo
  }
}
```

## 4. 首页内容：配置驱动

首页完全由 `home` 配置块驱动，**填了内容分区就出现，清空就消失**：

```ts title=&quot;site-config.ts&quot;
home: {
  hero: {
    tagline: &apos;Developer / Designer / Photographer&apos;, // 名字上方的小字
    location: &apos;China / QingDao&apos;,                    // 位置徽标
    about: &apos;一段关于你的介绍……&apos;,
    buttons: [{ title: &apos;More about me&apos;, link: &apos;/about&apos; }]
  },
  recentPosts: 5,                                   // 0 隐藏文章区
  education: [
    { school: &apos;某大学&apos;, major: &apos;专业&apos;, degree: &apos;学历&apos;, date: &apos;Aug 2021 - Jul 2024&apos; }
  ],
  skills: [
    { title: &apos;Program&apos;, items: [&apos;Python&apos;, &apos;Java&apos;, &apos;C&apos;] }
  ],
  showTags: false,      // 首页是否显示标签云
  showFriends: false    // 首页是否显示友链预览
}
```

## 5. 评论系统（Waline）

主题的评论和浏览量共用一个 **Waline** 服务器（自部署、无平台绑定）。部署方法：

1. 按 [Waline 官方文档](https://waline.js.org/guide/get-started/) 部署到 Vercel + LeanCloud（或自托管），拿到形如 `https://your-waline.vercel.app/` 的服务器地址
2. 填进 `site-config.ts`：

```ts title=&quot;site-config.ts&quot;
comment: {
  provider: &apos;waline&apos;,
  server: &apos;https://your-waline.vercel.app/&apos;   // 填上即启用评论
}
```

评论框会出现在文章末尾。`server` 留空则整块隐藏。

### 文章浏览量

同一 Waline 服务器还提供浏览量：把地址填进 `pageview.server`，文章页的 meta 行就会显示当前文章的浏览量：

```ts title=&quot;site-config.ts&quot;
pageview: {
  server: &apos;https://你的-waline-服务器/&apos; // 留空则隐藏
}
```

实现原理：向 `{server}/article` 发送 POST（`{path, type: &apos;time&apos;, action: &apos;inc&apos;}`）计数并取回最新值——这是 Waline 3 的计数语义（v2 是 GET 计数，组件会自动回退兼容），无额外依赖；请求失败时显示 0。没有 Waline 的话也可以用不蒜子（busuanzi）之类的服务，自行接入即可。

### 全站访问量

`pageview.siteWide`（默认 `true`）开启时，页脚会显示&quot;**total visits**&quot;全站总访问量：每个页面每被打开一次就 +1，数据同样来自 Waline 服务器（固定虚拟路径 `/site-pv`），与文章阅读量互不干扰。不需要时设 `siteWide: false` 即可。

## 6. 搜索开关

```ts title=&quot;site-config.ts&quot;
search: {
  enabled: true
}
```

关闭后顶栏的搜索入口和 `/search` 页内容都会消失（搜索索引也不再生成）。

## 7. 配色与字体：`src/assets/styles/tokens.css`

两套配色的全部颜色都在这里，直接改 HSL 三元组即可调出你自己的色板：

```css title=&quot;tokens.css&quot;
:root {
  /* ink · 浅色 */
  --paper: 42 35% 97%;
  --accent: 22 46% 44%; /* 强调色，改这一个就能换整体气质 */
}
.fresh {
  /* fresh · 浅色 */
  --paper: 212 28% 97%;
  --accent: 213 30% 45%;
}
.dark {
  /* ink 深色 */
}
.fresh.dark {
  /* fresh 深色 */
}
```

字体栈也在这里（`--font-serif/--font-sans/--font-mono`），想换字体改这三行即可。

## 8. 排版与组件：`uno.config.ts`

- `theme.colors`：把 token 映射成工具类（`bg-paper`、`text-ink`…）
- `shortcuts`：`paper-card`（卡片）、`chip`（胶囊）、`link-ink`（链接）、`icon-link`（图标按钮）
- `presetTypography`：正文排版的全部细节（标题、链接动效、列表标记、引用块、表格…）

## 9. 代码块语法

代码块支持标题、高亮和 diff 标记：

````markdown
```bash title=&quot;deploy.sh&quot;
git pull --ff-only            # [!code highlight]
systemctl restart my-app      # [!code ++]
rm -rf /var/cache             # [!code --]
```
````

- `title=&quot;文件名&quot;`：显示标题条
- `[!code highlight]`：高亮该行
- `[!code ++]` / `[!code --]`：标记新增 / 删除行
- 超过 15 行自动折叠；右上角悬停出复制按钮

## 10. 写文章

Frontmatter 字段详见[安装与使用](../getting-started/)。补充几个技巧：

- `draft: true`：草稿只通过 URL 访问，不进列表和搜索
- `heroImage: { src: ../../assets/cover.png, alt: &apos;…&apos; }`：文章封面。必须是相对文章文件的本地资源，构建时会被 sharp 压缩并生成响应式尺寸（不会布局抖动）
- 正文支持：标题锚点（悬停显示 `#`）、表格、引用、脚注、图片圆角投影；正文里的图片自动懒加载、点击可放大（lightbox）
- 数学公式：行内 `$E = mc^2$`、独立公式 `$$...$$`，KaTeX 渲染，自动适配暗色模式（长公式可横向滚动）

## 11. 部署细节

- 把 `astro.config.ts` 的 `site` 改成真实域名（sitemap / canonical / RSS 依赖它）
- `pnpm build` 输出纯静态 `dist/`，任意平台可托管
- 备案/ICP 之类的页脚文字写在 `footer.links` 里即可

## 12. 移除演示内容清单

- `src/content/blog/` 下的示例文章（welcome / features / getting-started / customize / markdown-guide）可全部删除
- `public/avatar.png`、`public/favicon/`、`public/og-card.svg` 换成你的
- `site-config.ts` 里的演示配置改为你的信息

## 常见问题

**改了颜色没生效？**

确认改的是 `tokens.css` 里的 HSL 三元组（空格分隔，不是逗号），并重新 `pnpm dev` 或构建。

**头像显示不出来？**

`site.avatar` 必须是 `public/` 目录下的真实路径（如 `/avatar.png`），放 `src/` 下拿不到。

**评论框不出现？**

`comment.server` 为空即关闭。按 Waline 文档部署好服务器后把地址填进 `comment.server`（和 `pageview.server`）再构建。

**想加新的页面类型？**

复制 `src/pages/` 下已有的页面（如 `links/index.astro`）改内容，再在 `header.menu` 加一行导航。

**如何让默认就是雾霾蓝？**

`site.palette: &apos;fresh&apos;`。访问者之后也能在顶栏自由切换，选择会记住。</content:encoded><category>主题</category><category>文档</category></item><item><title>Markdown 语法速查</title><link>https://example.com/blog/markdown-guide/</link><guid isPermaLink="true">https://example.com/blog/markdown-guide/</guid><description>本文演示主题对常见 Markdown 语法的渲染效果：标题、引用、代码、表格等。</description><pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate><content:encoded>本文用来展示主题对 Markdown 的排版效果。

## 文本

**加粗**、_斜体_、`行内代码`，以及[链接](https://astro.build)。

## 引用

&gt; 墨水有它的脾气：落在纸上之前，谁也不知道它会洇开多少。
&gt;
&gt; —— 佚名

## 代码块

```ts
// 一个简单的类型
interface Post {
  title: string
  description: string
  publishDate: Date
  tags: string[]
}
```

```bash
pnpm dev
```

## 列表

有序列表：

1. 打开终端
2. 安装依赖
3. 开始写作

无序列表：

- 温暖纸感配色
- 衬线标题
- 轻量搜索

## 表格

| 功能 | 状态 | 备注          |
| ---- | ---- | ------------- |
| RSS  | ✅   | 开箱即用      |
| 搜索 | ✅   | 本地索引      |
| 评论 | ⚙️   | 需配置 Waline |

## 图片

本地图片会被自动懒加载并居中、圆角展示；推荐用 HTML 标签写上宽高避免布局抖动：

&lt;img src=&quot;../../og-card.svg&quot; alt=&quot;占位图片&quot; width=&quot;1200&quot; height=&quot;630&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;

## 长代码块折叠

超过 15 行的代码块会自动折叠，点击底部的 &quot;Show all&quot; 展开：

```bash
# 一个很长的部署脚本示例（用于演示代码块折叠）
set -euo pipefail

APP_DIR=&quot;/opt/my-app&quot;
BACKUP_DIR=&quot;/var/backups/my-app&quot;

log() {
  echo &quot;[$(date +&apos;%Y-%m-%d %H:%M:%S&apos;)] $*&quot;
}

backup() {
  log &quot;Backing up $APP_DIR ...&quot;
  mkdir -p &quot;$BACKUP_DIR&quot;
  tar -czf &quot;$BACKUP_DIR/app-$(date +%Y%m%d%H%M%S).tar.gz&quot; -C &quot;$APP_DIR&quot; .
  log &quot;Backup done.&quot;
}

deploy() {
  log &quot;Pulling latest code ...&quot;
  cd &quot;$APP_DIR&quot; &amp;&amp; git pull --ff-only
  log &quot;Restarting service ...&quot;
  systemctl restart my-app
  log &quot;Service restarted.&quot;
}

main() {
  backup
  deploy
  log &quot;All done. Exiting.&quot;
}

main &quot;$@&quot;
```</content:encoded><category>markdown</category><category>写作</category></item><item><title>欢迎使用 astro-theme-ink</title><link>https://example.com/blog/welcome/</link><guid isPermaLink="true">https://example.com/blog/welcome/</guid><description>一款温暖纸感风格的 Astro 博客主题：墨色文字落在米白纸上。</description><pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate><content:encoded>欢迎来到 **astro-theme-ink** —— 一款温暖纸感风格的个人博客主题。

## 设计理念

墨落在纸上。全站只使用一种强调色（赭石色），其余全部交给灰阶分层与留白：

- 米白/奶油底色，暖墨色文字
- 衬线字体标题，营造&quot;印刷页面&quot;的感觉
- 克制的微交互：卡片悬停、箭头滑动、滚动渐隐

## 功能特性

- 📝 文章列表分页、标签、按年归档
- 🔍 内置轻量全文搜索（构建时生成索引，无外部依赖）
- 💬 Waline 评论 + 浏览量（可选，共用一个服务器）
- 📡 RSS 订阅
- 🌗 亮色 / 暗色 / 跟随系统 三种主题
- 📖 文章目录（桌面端侧栏）
- 🚀 纯静态输出，可部署到任意平台

## 快速开始

```bash
pnpm install
pnpm dev
```

构建并预览：

```bash
pnpm build
pnpm preview
```

## 写一篇文章

在 `src/content/blog/` 下新建一个 Markdown 文件即可：

```markdown
---
title: &apos;文章标题&apos;
description: &apos;一句话摘要&apos;
publishDate: 2026-08-16
tags: [标签一, 标签二]
---

这里是正文。
```

&gt; 提示：`draft: true` 可以让文章只在 URL 下可见、不出现在列表中。

## 主题文档系列

- [主题特色与特性](../features/) —— 设计理念与全部功能
- [从零开始：安装与使用](../getting-started/) —— 环境、安装、写文章、部署
- [深度定制指南](../customize/) —— 配置、配色、代码块语法、FAQ

祝写作愉快。</content:encoded><category>主题</category><category>astro</category><category>unocss</category></item></channel></rss>