Trust DeMemWM Plucker geometry metadata
Browse files
algorithms/dememwm/models/dit.py
CHANGED
|
@@ -6,7 +6,6 @@ References:
|
|
| 6 |
"""
|
| 7 |
|
| 8 |
from typing import Optional, Literal
|
| 9 |
-
import logging
|
| 10 |
import torch
|
| 11 |
from torch import nn
|
| 12 |
from torch.nn import functional as F
|
|
@@ -20,15 +19,6 @@ from collections import namedtuple
|
|
| 20 |
from typing import Optional, Callable
|
| 21 |
from .cameractrl_module import SimpleCameraPoseEncoder
|
| 22 |
|
| 23 |
-
logger = logging.getLogger(__name__)
|
| 24 |
-
_FRAME_MEMORY_GEOMETRY_WARNINGS = set()
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
def _warn_frame_memory_geometry_once(key, message):
|
| 28 |
-
if key not in _FRAME_MEMORY_GEOMETRY_WARNINGS:
|
| 29 |
-
_FRAME_MEMORY_GEOMETRY_WARNINGS.add(key)
|
| 30 |
-
logger.warning(message)
|
| 31 |
-
|
| 32 |
|
| 33 |
def modulate(x, shift, scale):
|
| 34 |
fixed_dims = [1] * len(shift.shape[1:])
|
|
@@ -179,27 +169,11 @@ class FrameMemoryReferenceAttention(nn.Module):
|
|
| 179 |
device,
|
| 180 |
dtype,
|
| 181 |
):
|
| 182 |
-
if
|
| 183 |
-
return None, None
|
| 184 |
-
query_rays = geometry_cache.get("query_rays")
|
| 185 |
-
relative_rays = geometry_cache.get("relative_rays")
|
| 186 |
-
if not torch.is_tensor(query_rays) or not torch.is_tensor(relative_rays):
|
| 187 |
-
_warn_frame_memory_geometry_once(
|
| 188 |
-
"missing_ray_tensors",
|
| 189 |
-
"DeMemWM Plucker memory geometry is missing query/relative ray tensors; using content-only memory attention.",
|
| 190 |
-
)
|
| 191 |
-
return None, None
|
| 192 |
-
expected_query_shape = (B, T_target, H, W, 6)
|
| 193 |
-
expected_relative_shape = (B, T_target, T_memory, H, W, 6)
|
| 194 |
-
if tuple(query_rays.shape) != expected_query_shape or tuple(relative_rays.shape) != expected_relative_shape:
|
| 195 |
-
_warn_frame_memory_geometry_once(
|
| 196 |
-
"malformed_ray_tensors",
|
| 197 |
-
"DeMemWM Plucker memory geometry has unexpected ray tensor shapes; using content-only memory attention.",
|
| 198 |
-
)
|
| 199 |
return None, None
|
| 200 |
return (
|
| 201 |
-
query_rays.to(device=device, dtype=dtype),
|
| 202 |
-
relative_rays.to(device=device, dtype=dtype),
|
| 203 |
)
|
| 204 |
|
| 205 |
def forward(self, target_hidden, memory_hidden, memory_mask=None, geometry_cache=None):
|
|
@@ -638,50 +612,18 @@ class DiT(nn.Module):
|
|
| 638 |
return c2w
|
| 639 |
|
| 640 |
def _build_frame_memory_geometry(self, frame_memory_segments, frame_memory_masks, frame_memory_pose, image_hw, grid_h, grid_w, device, dtype):
|
| 641 |
-
if frame_memory_segments is None
|
| 642 |
-
_warn_frame_memory_geometry_once(
|
| 643 |
-
"missing_geometry_metadata",
|
| 644 |
-
"DeMemWM Plucker memory geometry metadata is missing; using content-only memory attention.",
|
| 645 |
-
)
|
| 646 |
return None
|
| 647 |
|
| 648 |
pose = frame_memory_pose.to(device=device)
|
| 649 |
-
if pose.ndim != 3 or pose.shape[-1] != 5:
|
| 650 |
-
_warn_frame_memory_geometry_once(
|
| 651 |
-
"malformed_pose_metadata",
|
| 652 |
-
"DeMemWM Plucker memory geometry pose metadata has an unexpected shape; using content-only memory attention.",
|
| 653 |
-
)
|
| 654 |
-
return None
|
| 655 |
B = pose.shape[0]
|
| 656 |
target_frames = int(frame_memory_segments.get("target", 0))
|
| 657 |
-
expected_pose_frames = target_frames + sum(
|
| 658 |
-
int(frame_memory_segments.get(stream_name, 0))
|
| 659 |
-
for stream_name in ("anchor", "dynamic", "revisit")
|
| 660 |
-
)
|
| 661 |
-
if pose.shape[1] < expected_pose_frames:
|
| 662 |
-
_warn_frame_memory_geometry_once(
|
| 663 |
-
"short_pose_metadata",
|
| 664 |
-
"DeMemWM Plucker memory geometry pose metadata does not cover the packed memory segments; using content-only memory attention.",
|
| 665 |
-
)
|
| 666 |
-
return None
|
| 667 |
image_hw = image_hw if torch.is_tensor(image_hw) else torch.as_tensor(image_hw)
|
| 668 |
image_hw = image_hw.to(device=device)
|
| 669 |
if image_hw.ndim == 1:
|
| 670 |
image_hw = image_hw.unsqueeze(0)
|
| 671 |
-
if image_hw.ndim != 2 or image_hw.shape[-1] < 2:
|
| 672 |
-
_warn_frame_memory_geometry_once(
|
| 673 |
-
"malformed_image_hw_metadata",
|
| 674 |
-
"DeMemWM Plucker memory geometry image size metadata has an unexpected shape; using content-only memory attention.",
|
| 675 |
-
)
|
| 676 |
-
return None
|
| 677 |
if image_hw.shape[0] == 1 and B != 1:
|
| 678 |
image_hw = image_hw.expand(B, -1)
|
| 679 |
-
if image_hw.shape[0] != B:
|
| 680 |
-
_warn_frame_memory_geometry_once(
|
| 681 |
-
"mismatched_image_hw_metadata",
|
| 682 |
-
"DeMemWM Plucker memory geometry image size metadata does not match the batch; using content-only memory attention.",
|
| 683 |
-
)
|
| 684 |
-
return None
|
| 685 |
image_hw = image_hw.contiguous()
|
| 686 |
# Mixed precision can round camera offsets before relative poses/rays are
|
| 687 |
# formed, so keep this local geometry block in fp32 and only cast caches.
|
|
|
|
| 6 |
"""
|
| 7 |
|
| 8 |
from typing import Optional, Literal
|
|
|
|
| 9 |
import torch
|
| 10 |
from torch import nn
|
| 11 |
from torch.nn import functional as F
|
|
|
|
| 19 |
from typing import Optional, Callable
|
| 20 |
from .cameractrl_module import SimpleCameraPoseEncoder
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
def modulate(x, shift, scale):
|
| 24 |
fixed_dims = [1] * len(shift.shape[1:])
|
|
|
|
| 169 |
device,
|
| 170 |
dtype,
|
| 171 |
):
|
| 172 |
+
if geometry_cache is None:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
return None, None
|
| 174 |
return (
|
| 175 |
+
geometry_cache["query_rays"].to(device=device, dtype=dtype),
|
| 176 |
+
geometry_cache["relative_rays"].to(device=device, dtype=dtype),
|
| 177 |
)
|
| 178 |
|
| 179 |
def forward(self, target_hidden, memory_hidden, memory_mask=None, geometry_cache=None):
|
|
|
|
| 612 |
return c2w
|
| 613 |
|
| 614 |
def _build_frame_memory_geometry(self, frame_memory_segments, frame_memory_masks, frame_memory_pose, image_hw, grid_h, grid_w, device, dtype):
|
| 615 |
+
if frame_memory_segments is None:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 616 |
return None
|
| 617 |
|
| 618 |
pose = frame_memory_pose.to(device=device)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
B = pose.shape[0]
|
| 620 |
target_frames = int(frame_memory_segments.get("target", 0))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 621 |
image_hw = image_hw if torch.is_tensor(image_hw) else torch.as_tensor(image_hw)
|
| 622 |
image_hw = image_hw.to(device=device)
|
| 623 |
if image_hw.ndim == 1:
|
| 624 |
image_hw = image_hw.unsqueeze(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 625 |
if image_hw.shape[0] == 1 and B != 1:
|
| 626 |
image_hw = image_hw.expand(B, -1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 627 |
image_hw = image_hw.contiguous()
|
| 628 |
# Mixed precision can round camera offsets before relative poses/rays are
|
| 629 |
# formed, so keep this local geometry block in fp32 and only cast caches.
|