Confirm: LTX-2.5 video/audio VAE *encoders* are byte-identical to LTX-2.3 (undocumented)
Summary
While integrating LTX-2.5 into a downstream trainer, I compared the standalone
VAE checkpoints shipped with Lightricks/LTX-2.5
(vae/ltx-2.5-video-vae-bf16.safetensors, vae/ltx-2.5-audio-vae-bf16.safetensors)
against the VAE weights bundled inside the LTX-2.3 checkpoint
(ltx-2.3-22b-dev.safetensors, keys vae.* / audio_vae.*).
Every encoder tensor and per-channel normalization stat is byte-for-byte identical between 2.3 and 2.5. The audio decoder is also identical. Only the video decoder differs (consistent with the v1.2.0 release notes' "diffusion-based video VAE decoding" addition, which appears to be a decoder architecture replacement, not a new encoder/latent space).
This is good news for anyone with 2.3-encoded latents cached for training, but I couldn't find it stated anywhere in the README, release notes, or model card, so I'd like to (a) confirm this is intentional/expected rather than a publishing artifact, and (b) suggest documenting it, since it directly answers "can I reuse latents encoded with the old VAE" for anyone upgrading.
Reproduction
import hashlib, torch
from safetensors import safe_open
# sha256 of the downloaded files matched the HF-recorded LFS hashes exactly:
# vae/ltx-2.5-video-vae-bf16.safetensors: 847e14ca7f3355debca0cea4eaa24ac0fbcdf0061da054ac89ca638a869ddba3
# vae/ltx-2.5-audio-vae-bf16.safetensors: c52733d37f6a7fb7949c3dc0fb468c6cb2169e4d836983a73babb9f0d54837a5
f23 = safe_open("ltx-2.3-22b-dev.safetensors", framework="pt") # bundled checkpoint
f25v = safe_open("vae/ltx-2.5-video-vae-bf16.safetensors", framework="pt")
f25a = safe_open("vae/ltx-2.5-audio-vae-bf16.safetensors", framework="pt")
def compare(prefix23, prefix25, f23, f25, label):
keys = sorted(k for k in f23.keys() if k.startswith(prefix23))
n_id = 0
for k in keys:
k2 = prefix25 + k[len(prefix23):]
t1, t2 = f23.get_tensor(k), f25.get_tensor(k2)
if t1.shape == t2.shape and torch.equal(t1, t2):
n_id += 1
print(label, f"{n_id}/{len(keys)} identical")
compare("vae.encoder.", "encoder.", f23, f25v, "VIDEO encoder")
compare("vae.decoder.", "decoder.", f23, f25v, "VIDEO decoder")
compare("audio_vae.encoder.", "audio_vae.encoder.", f23, f25a, "AUDIO encoder")
compare("audio_vae.decoder.", "audio_vae.decoder.", f23, f25a, "AUDIO decoder")
compare("vae.per_channel_statistics.", "per_channel_statistics.", f23, f25v, "VIDEO per-channel stats")
compare("audio_vae.per_channel_statistics.", "audio_vae.per_channel_statistics.", f23, f25a, "AUDIO per-channel stats")Results
| Component | Tensors compared | Identical |
|---|---|---|
| Video VAE encoder | 84 | 84/84 |
| Video VAE decoder | 84 | 0/84 (different key structure/architecture) |
| Audio VAE encoder | 44 | 44/44 |
| Audio VAE decoder | 56 | 56/56 |
| Video per-channel stats (mean-of-means, std-of-means) | 2 | 2/2 |
| Audio per-channel stats (mean-of-means, std-of-means) | 2 | 2/2 |
Sample lovely_tensors view (identical stats/histograms, torch.equal True):
vae.encoder.conv_in.conv.weight
2.3: tensor[128, 48, 3, 3, 3] bf16 x∈[-0.664 | ▁▁▁▁█▁▁▁▁| 0.535] μ=-2.742e-05 σ=0.037
2.5: tensor[128, 48, 3, 3, 3] bf16 x∈[-0.664 | ▁▁▁▁█▁▁▁▁| 0.535] μ=-2.742e-05 σ=0.037
equal: True
vae.per_channel_statistics.mean-of-means
2.3: tensor[128] bf16 x∈[-0.555 |▁ ▁ ▁█▁▁▁▁| 0.428] μ=-0.001 σ=0.082
2.5: tensor[128] bf16 x∈[-0.555 |▁ ▁ ▁█▁▁▁▁| 0.428] μ=-0.001 σ=0.082
equal: TrueQuestions
- Is this intentional — i.e. is LTX-2.5's latent space (for both video and audio) guaranteed to stay compatible with LTX-2.3's for the foreseeable future, or could a future 2.x release change the encoder without a major version bump?
- Could this be called out explicitly in the release notes / model card? It would save anyone with existing 2.3-encoded training data a redundant (and expensive) re-encoding pass.
Happy to share the full comparison script/output if useful.
Source: Lightricks/LTX-2