HayrettinIscan commited on
Commit
28eb85c
·
verified ·
1 Parent(s): ca3f598

Faz2 dep: code/meshai_bridge/latent_adapter.py

Browse files
Files changed (1) hide show
  1. code/meshai_bridge/latent_adapter.py +126 -0
code/meshai_bridge/latent_adapter.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Latent adapter R&D scaffold (requires real TRELLIS/Hunyuan model tensors)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from dataclasses import dataclass, field
7
+ from datetime import datetime, timezone
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ try:
12
+ import torch
13
+ import torch.nn as nn
14
+ except ImportError: # pragma: no cover - optional for preprocess-only runs
15
+ torch = None # type: ignore
16
+ nn = None # type: ignore
17
+
18
+
19
+ def _utc_now() -> str:
20
+ return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
21
+
22
+
23
+ @dataclass
24
+ class LatentShapeLogger:
25
+ """Log tensor shapes until real model hooks are wired."""
26
+
27
+ log_path: Path | None = None
28
+ records: list[dict[str, Any]] = field(default_factory=list)
29
+
30
+ def log(self, name: str, tensor: Any, *, source: str = "unknown") -> dict[str, Any]:
31
+ if torch is not None and isinstance(tensor, torch.Tensor):
32
+ shape = list(tensor.shape)
33
+ dtype = str(tensor.dtype)
34
+ device = str(tensor.device)
35
+ elif hasattr(tensor, "shape"):
36
+ shape = list(getattr(tensor, "shape"))
37
+ dtype = str(getattr(tensor, "dtype", "?"))
38
+ device = "numpy"
39
+ else:
40
+ shape = []
41
+ dtype = type(tensor).__name__
42
+ device = "?"
43
+
44
+ entry = {
45
+ "name": name,
46
+ "source": source,
47
+ "shape": shape,
48
+ "dtype": dtype,
49
+ "device": device,
50
+ "logged_at": _utc_now(),
51
+ }
52
+ self.records.append(entry)
53
+ if self.log_path is not None:
54
+ self.log_path.parent.mkdir(parents=True, exist_ok=True)
55
+ with open(self.log_path, "a", encoding="utf-8") as handle:
56
+ handle.write(json.dumps(entry, ensure_ascii=False) + "\n")
57
+ return entry
58
+
59
+ def summary(self) -> dict[str, Any]:
60
+ return {
61
+ "count": len(self.records),
62
+ "shapes": {r["name"]: r["shape"] for r in self.records},
63
+ "updated_at": _utc_now(),
64
+ }
65
+
66
+
67
+ if nn is not None:
68
+
69
+ class TrellisHunyuanLatentAdapter(nn.Module):
70
+ """Small MLP adapter: TRELLIS structured latent -> Hunyuan conditioning latent."""
71
+
72
+ def __init__(
73
+ self,
74
+ trellis_dim: int,
75
+ hunyuan_dim: int,
76
+ *,
77
+ hidden_dim: int = 512,
78
+ depth: int = 2,
79
+ adapter_type: str = "mlp",
80
+ ) -> None:
81
+ super().__init__()
82
+ self.adapter_type = adapter_type
83
+ self.trellis_dim = trellis_dim
84
+ self.hunyuan_dim = hunyuan_dim
85
+ layers: list[nn.Module] = []
86
+ in_dim = trellis_dim
87
+ for _ in range(max(depth - 1, 0)):
88
+ layers.extend([nn.Linear(in_dim, hidden_dim), nn.GELU()])
89
+ in_dim = hidden_dim
90
+ layers.append(nn.Linear(in_dim, hunyuan_dim))
91
+ self.net = nn.Sequential(*layers)
92
+ self.logger = LatentShapeLogger()
93
+
94
+ def forward(self, trellis_latent: "torch.Tensor") -> "torch.Tensor":
95
+ self.logger.log("trellis_latent_in", trellis_latent, source="trellis")
96
+ flat = trellis_latent.reshape(trellis_latent.shape[0], -1)
97
+ if flat.shape[-1] != self.trellis_dim:
98
+ raise ValueError(
99
+ f"Expected trellis_dim={self.trellis_dim}, got {flat.shape[-1]}"
100
+ )
101
+ out = self.net(flat)
102
+ self.logger.log("hunyuan_latent_out", out, source="adapter")
103
+ return out
104
+
105
+ else:
106
+
107
+ class TrellisHunyuanLatentAdapter: # type: ignore[no-redef]
108
+ def __init__(self, *args, **kwargs) -> None:
109
+ raise ImportError("torch required for TrellisHunyuanLatentAdapter")
110
+
111
+
112
+ def research_notes() -> dict[str, Any]:
113
+ """Document planned losses and integration points for future real-model wiring."""
114
+ return {
115
+ "status": "rd_only",
116
+ "requires": [
117
+ "trellis_structured_latent_export",
118
+ "hunyuan_denoising_conditioning_hook",
119
+ ],
120
+ "candidate_losses": [
121
+ "texture_view_reconstruction",
122
+ "uv_consistency",
123
+ "normal_curvature_texture_consistency",
124
+ ],
125
+ "adapter_variants": ["linear", "mlp", "cross_attention"],
126
+ }