技术报告 · 2026

X-Cachev1.0

面向少步自回归世界模型的跨段块级缓存

原本生成下一段画面,模型要把所有计算从头跑一遍。X-Cache 把其中大约七成的计算直接跳过——不用重新训练,画面也看不出区别。诀窍很简单:相邻两段画面里大部分东西并没有变,能省的就别再算一次。

DiT 加速
2.7×
块跳过率
71%
7 相机 PSNR
≥ 51 dB
训练成本
0
01 · 难题

想做实时驾驶世界,过去的加速套路基本都用不上了。

做交互式驾驶世界,最自然的做法是「策略给一个动作,模型立刻吐出下一段画面」,一段一段往后接。但要做到「实时」,X-World 这一类模型已经被压缩到只跑 4 步去噪——每一步都很贵,也都跳不掉。

麻烦在于,4 步本身已经不留任何冗余。市面上的缓存方法(TeaCache、DeepCache、ΔDiT、BWCache)思路都一样:相邻两步算出来的东西很像,那就省一步。可压缩到 4 步之后,每一步都在做不同的事,沿这条思路已经没有重复可省。

更头疼的是,画面的「跳变」就在段边界——一脚刹车、一次变道,说来就来。这又是个闭环系统,模型不能提前看下一帧,「先把下一段算好藏起来」这条路也走不通。一句话:过去那些加速思路,在这里基本派不上用场。

02 · 洞察

换一个角度去想。

现实中,驾驶场景变化得很慢。前后两段画面里看到的,几乎是同一个世界——所以模型在同一个位置、同一个步骤里做的运算,前后两段也长得差不多。既然如此,何不把上一段的结果存下来,下一段直接用?

传统思路:跨步省

↦ same chunk · adjacent step

在「同一段画面、相邻两步」之间复用。压缩到 4 步以后,这条路就断了。

X-Cache:跨段省

↧ same step · adjacent chunk

在「相邻两段画面、同一个步骤」之间复用。这条规律来自物理世界本身——跟模型跑几步没关系。

上一段算完,每个位置上「这次算出了什么变化」都被记进缓存。下一段开始时,模型对每个位置自问一句:这次的输入跟上次像不像?像,就直接拿来用;不像,就老老实实重算。

按位置存档

缓存按「第几步 × 第几个块」分格存放,每一格只对自己负责。复用永远只在相同位置之间发生,不会拿这一格去对那一格。

结构 + 动作 双重指纹

对每个块的输入,挑 32 个有代表性的 token,再补一条整体均值和当前的动作向量——这条「指纹」就是用来比相似度的。计算量几乎可以忽略,也不需要训练。

两道关一起把守

余弦相似度负责看「整体方向是否一致」,最大偏差负责看「有没有一两个 token 突变」。两道关都过,才允许跳过;任何一关亮红灯,立刻拉回去重算。

门槛会自己调

每一格的相似度门槛都是动态的:用最近的相似度滑动平均做参考,自动收紧或放宽。再叠一道 0.97 的硬底线——不管前面多平稳,画质永远有个保底。

03 · 流程

看一段画面是怎么从噪声里长出来的。

4 步去噪、30 个块——下面是一段画面从头到尾的完整经过。

01

采样噪声 · 接上上下文

每段都从一片高斯噪声开始;过去几段的记忆放在滚动 KV 缓存里;当前这一帧要做的动作通过 adaLN-Zero 注入到每一个块——铺好底子,开始算。

02

取指纹

对每个块的输入,按比例挑 32 个 token,再拼上整体均值和动作向量。一次取值、一次拉直,几乎没有额外开销。

03

过两道关

把这次的指纹跟缓存里的旧指纹一比:余弦够高、偏差够小,才放行跳过;只要一项不达标,就把这个块从头算一遍,新结果回写到缓存里。

04

KV 更新 · 全程保护

每段最后一步去噪结束时,模型会把一份干净的 K/V 写进长程缓存——这份缓存以后还会被反复读取。这一段我们坚决不省,每个块都老实算,避免任何近似留进未来。

04 · 安全机制

四道保险,把「近似」圈在它该待的地方。

KV 更新保护

写入长程缓存的那一段,每个块都必须实打实地算。这是唯一一道一关掉就翻车的保险——PSNR 直接从 53.4 dB 掉到 21.5 dB,画面基本糊了。

首块永远不跳

块 0 永远从头算。新的动作、新的条件由它带头注入到下游每一个块,旧链路上累积的偏差顺势就被冲掉了。

第一步全算

去噪第一步的所有块都老老实实算——它要写 KV 缓存,跳不得。需要更激进时可以放开它再走一道更严的阈值;默认我们就不冒这个险。

门槛有保底

动态阈值再松也松不过 0.97 这条线。前面再风平浪静,画质都还有保底;遇到分布尾巴,阈值也会被这条底线接住。

05 · 看得清,省得多

拖一下分隔线,画质没有任何下降。

三个场景,两种看法。拖动中间的分隔条:左边是没开缓存的原版,右边是 X-Cache。切到热力图,差别在哪、有多大,一眼就能看清——主要集中在车道线和远处树叶上,平整路面和天空几乎一片漆黑(也就是没区别)。

城市

密集车流、行人、临街商铺。

城市片段——画面里的静态细节是测试集里最多的(车道线、临街招牌、远处楼房)。这种场景下门控几乎一直放行,跳过率稳定在 71.4%,残差只在车道线和远景树叶上看得到。

  • 7 段
  • 每段 264 帧
  • PSNR 51.4 dB
  • 跳过 71.4%
  • 加速 2.7×
frame 0 / 264
跳过 71.4%
加速 2.7×
Baseline · 无缓存 X-Cache · 2.7× 加速
0:00 / 0:22

拖动分隔条 · 拖动时间轴 · ←/→ 单帧步进 · 空格播放/暂停。右上的横条是实时 DiT 块状态:金色 = 不跳、蓝色 = 这次重算、绿色 = 复用上一段、靛蓝 = KV 更新阶段强保护。

高速公路

城市高架与城际高速。

高速片段——景深远、前向运动很快、画面里没什么近物。门控跳过了 71.6%,PSNR 反而比城市还高,到了 54.7 dB——因为大部分像素是天空和路面,本身就比较平整,那点缓存带来的扰动一吸就没了。

  • 3 段
  • PSNR 54.7 dB
  • 跳过 71.6%
  • 加速 2.7×
frame 0 / 264
跳过 71.6%
加速 2.7×
Baseline · 无缓存 X-Cache · 2.7× 加速
0:00 / 0:22

拖动分隔条 · 拖动时间轴 · ←/→ 单帧步进 · 空格播放/暂停。右上的横条是实时 DiT 块状态:金色 = 不跳、蓝色 = 这次重算、绿色 = 复用上一段、靛蓝 = KV 更新阶段强保护。

掉头

整组数据里跨段位移最大的场景。

掉头片段——自车在做大角度转向,相邻两段画面之间的差别是整组数据里最大的。即便如此,跨段指纹依然管用:跳过率 71.3%,逐帧 PSNR 跨过段边界时也没有任何抖动。

  • 3 段
  • PSNR 52.0 dB
  • 跳过 71.3%
  • 加速 2.7×
frame 0 / 264
跳过 71.3%
加速 2.7×
Baseline · 无缓存 X-Cache · 2.7× 加速
0:00 / 0:22

拖动分隔条 · 拖动时间轴 · ←/→ 单帧步进 · 空格播放/暂停。右上的横条是实时 DiT 块状态:金色 = 不跳、蓝色 = 这次重算、绿色 = 复用上一段、靛蓝 = KV 更新阶段强保护。

06 · 数字

同一颗种子、同一组输入,跑完只用四成时间,每一帧都禁得起逐像素核对。

对比没开缓存的基线,分场景列出。每个相机一行:F-C 是前中、F-W 是前广,S-FL/FR/RL/RR 是四侧,Rear 是后视;高亮的 7-cam 行就是上面看到的拼接画面。
Scenario / camera PSNR ↑ (dB) SSIM ↑ LPIPS ↓ Skip DiT Speed
Urban street · n=7
F-C 53.83 0.9988 3.6e-4 71.4 % 1.392 s 2.7×
F-W 50.27 0.9987 4.3e-4
S-FL 49.49 0.9985 5.1e-4
S-FR 48.69 0.9984 5.2e-4
S-RL 48.59 0.9985 4.8e-4
S-RR 48.07 0.9985 5.2e-4
Rear 51.77 0.9986 4.7e-4
7-cam 51.37 0.9990 3.3e-4
Highway · n=3
F-C 54.87 0.9989 2.6e-4 71.6 % 1.365 s 2.7×
F-W 54.38 0.9988 2.3e-4
S-FL 53.08 0.9987 2.8e-4
S-FR 52.20 0.9987 2.9e-4
S-RL 52.48 0.9987 2.5e-4
S-RR 51.90 0.9986 3.0e-4
Rear 53.42 0.9987 3.2e-4
7-cam 54.67 0.9991 1.9e-4
U-turn · n=3
F-C 54.60 0.9987 4.3e-4 71.3 % 1.364 s 2.7×
F-W 51.79 0.9987 3.6e-4
S-FL 49.29 0.9985 4.6e-4
S-FR 49.18 0.9985 4.7e-4
S-RL 48.87 0.9985 4.0e-4
S-RR 48.82 0.9984 4.9e-4
Rear 52.51 0.9986 4.2e-4
7-cam 52.04 0.9990 3.1e-4