1import torch
2from transformers import AutoModel, AutoImageProcessor
3
4model = AutoModel.from_pretrained(
5 "litcoderr/prism", trust_remote_code=True, dtype=torch.bfloat16
6).eval().cuda()
7proc = AutoImageProcessor.from_pretrained(model.config.vision_backbone_name)
8
9frames = [...] # list[PIL.Image], sampled at 4 fps
10pixel_values = proc(images=frames, return_tensors="pt").pixel_values[None]
11pixel_values = pixel_values.to("cuda", torch.bfloat16) # (1, T, 3, 384, 384)
12valid_mask = torch.ones(pixel_values.shape[:2], dtype=torch.bool, device="cuda")
13
14emb = model.encode(pixel_values, valid_mask) # (1, 512), L2-normalizedmodel.encode(pixel_values, valid_mask) | (B, 512) L2-normalized clip embedding, mean-pooled z_vi over valid frames |
model.encode_streams(pixel_values, valid_mask) | {"z_vi_seq", "z_vv_seq"}, each (B, T, 512) per-frame |
pixel_values is (B, T, 3, 384, 384), frames sampled at 4 fps, up to
T = 128 (32 s), preprocessed by the SigLIP2 image processor. valid_mask is (B, T)
bool marking real frames in a padded batch. Both encode paths run under torch.no_grad()
and use the EMA target encoder θ̄.scripts/encode.sh in the code repo.| Method | EgoExo4D Retr. ego→exo | exo→ego | avg | Recog. top-1 | Skill | EgoExoLearn Assoc. avg | Antic. avg | Skill |
|---|---|---|---|---|---|---|---|---|
| CLIP | 19.11 | 12.24 | 15.68 | 10.49 | 54.93 | 15.82 | 38.70 | 73.48 |
| SigLIP2 | 35.08 | 19.72 | 27.40 | 13.86 | 55.57 | 26.6 | 64.60 | 76.03 |
| LaViLa | 34.91 | 12.02 | 23.47 | 26.43 | 54.10 | 27.20 | 62.83 | 68.44 |
| SUM-L | 47.14 | 32.77 | 39.96 | 24.83 | 55.10 | 4.64 | 45.50 | 65.31 |
| ViewpointRosetta | 58.14 | 47.21 | 52.68 | 34.47 | 55.82 | 32.32 | 62.14 | 73.70 |
| PRISM | 75.89 | 50.27 | 63.08 | 41.93 | 55.28 | 43.86 | 69.46 | 68.53 |
| Method | AE2 videos | Frame retr. mAP@10 | Phase order Kendall's τ | Phase class. F1 | Phase prog. R² |
|---|---|---|---|---|---|
| GTA | ✔ | 68.08 | 0.464 | 67.77 | 0.322 |
| AE2 | ✔ | 73.20 | 0.562 | 74.47 | 0.480 |
| SigLIP2 | ✘ | 45.56 | 0.020 | 43.91 | −1.322 |
| ViewpointRosetta | ✘ | 54.17 | 0.047 | 46.93 | −0.150 |
| PRISM | ✘ | 70.53 | 0.601 | 73.57 | 0.647 |
| Component | |
|---|---|
| Vision backbone | google/siglip2-so400m-patch14-384, frozen and not stored here |
| Text backbone | Qwen/Qwen3-Embedding-0.6B, frozen and not stored here |
| Decompositional Encoder θ | 4-layer Q-Former (2 queries → z_vi, z_vv) + 12-layer causal temporal stack per stream |
| Compositional Latent Predictor φ | 4-layer causal transformer over concat(z_vv, z_vi), with cls_head / vi_head / vv_head |
| Target encoder θ̄ | EMA of θ, decay 0.998 |
| Embedding dim | 512 |
L = 1.0 · L_decomp + 0.5 · L_temp, InfoNCE
all-gathered across ranks, sliding-shift augmentation on.Qwen/Qwen3-1.7B. Full recipe in the
code repo.