← Back to project

WilD3DGen · Unified Geo-Tex DiT — the next architecture

one dual-stream DiT · five sampling modes by dialing two timesteps · deep-research-verified recipe · 2026-08-10
designarchitecturedeep-researchnext-arch

0 · TL;DR

Decision: keep the SS flow; merge shape-SLAT + tex-SLAT flows into ONE dual-stream DiT with per-modality timesteps. Joint generation, mesh-only, texture-given-mesh (exact geometry lock) and geo-given-tex all come from the same weights — just dial (t_shape, t_tex) at inference.
Novelty (verified): no published 3D method offers one DiT + switchable mesh-only/tex-only (8 searches + all 16 UniLat3D citations checked). The mechanism is de-risked in 2D: UniDiffuser (ICML'23) + JointDiT (ICCV'25).
Verification depth: a 103-agent deep-research pass extracted 100 claims from 21 sources and adversarially verified the top 25 with 3-vote panels — 24 confirmed / 1 refuted. All formulas below are verbatim-checked against the ICCV paper + supplement.

1 · The gap — why this is worth doing

The literature quadrant: top-right (one DiT + iso-samplable) is empty — verified via citation sweep, not vibes.

2 · Architecture

THE current architecture (Stage-1 final): both specialists stitched, geo frozen bit-exact, tex fully trained, dual attention borrows geo's K/V behind a λ gate, cond stays read-once. The gate matrix's ✗→λ' cell is the entire Stage-2 bidirectional upgrade.
Left: today's 3-model cascade with teacher-forced tex. Right: SS kept, one unified DiT — everything downstream of SS becomes a single training job.
Per-block wiring. The zero-init projection is the warm-start safety: step 0 ≡ the two specialists. Caveat (verified): JointDiT fused ONE frozen backbone + LoRA copy; fusing TWO independent checkpoints is our untested step.

3 · The mode dial — one model, five modes

The whole product surface is timestep geometry: joint = diagonal, conditioning = pin an axis at clean, marginal = pin at noise. No retraining between modes (JointDiT: verbatim-verified, 3-0).

4 · Verified training recipe (what we implement)

#TrickExact form (verified)Vote
T1Timestep-pair sampling50/50 mixture: half diagonal (one shared t ~ f), half independent (f × g, branches swapped). Transform t = 1−σ(z)·s/(1+(s−1)σ(z)), z~N(0,1); s=3.1582 (kohya Flux default, e^1.15) for f, s=0.25 for g. No explicit corner sampling (grep-verified negative).3-0
T2Adaptive scheduling weightsw_x = σ(α(t_y/(t_x+t_y)−½)), α=3 — multiplies the joint cross-attn OUTPUT (feature gate, NOT loss). Noisier stream listens more to the cleaner one. Ablation: both tricks needed (ImageReward Rank1 30.7% vs 21.2% weights-only).3-0
T3Cross-stream connectionUniCon joint cross-attn (Q↔KV exchange) + zero-init linear projection. JointDiT LoRA rank 64 (α=rank/2), 512/1024 at input stage; rank monotone 16/32/64 → AbsRel 9.1/6.6/5.7.3-0
T4Marginal modeOther modality fed pure noise at max-t (Algorithm-2-verified; tokens present, not dropped). Exact under RF where x₁=ε.3-0
T5Conditioning exactnessUniDiffuser theorem: t_cond=clean recovers q(x₀|y₀) at the population optimum — the geometry lock has a proof, not just intuition.3-0
T6Free modality-CFGε̂ = (1+s)·ε(x, y_clean) − s·ε(x, ε_y@max-t) — no null token, no condition-dropout. Composes with (does not replace) our existing DINO/VLM cond-dropout CFG.3-0
Training coverage of the (t_s, t_x) square: the clean-heavy g (s=0.25) pushes one branch toward the conditional corners — that is why JointDiT needs no explicit corner sampling.
Left: the gate — shape listens to tex only when shape is the noisy one. Right: the #1 porting hazard — papers use t=0-noise; TRELLIS uses t=0-clean. Re-derive (denominator becomes 2−t_x−t_y); do NOT sign-flip. JointDiT arXiv v1 even misprinted Eq.7.

5 · Corrections vs our first manual read + honest costs

Open design decisions (no verified evidence exists): ① RF velocity-target validity under mixed timesteps (Diffusion-Forcing-style ELBO not verified for flow matching); ② AdaLN vs prepended timestep-tokens injection; ③ whether shared-coordinate pairing lets per-voxel fusion replace/augment joint cross-attn — our novelty AND our risk; ④ corner-oversampling ratios for product-grade conditional modes.

6 · Gate experiments (round 1)

Full adversarially-verified deep-research dossier (all claims, votes, verbatim evidence, 21 sources): deepresearch_full.json · also archived at BLIP3o/docs/UNIFIED_GEOTEX_DIT_deepresearch.json.

7 · Dual-mode implementation plan — both cond modes in one codebase

Both variants share the assembled 2-stream core; B adds a third (cond) stream behind λ gates while KEEPING cross-attn for warm-start safety. Param bars measured from checkpoint tensor shapes — B nearly doubles the trainable budget for a pathway our own June ablation voted against; it must earn its way in.

8 · Final decision log (2026-08-11, design frozen)

DecisionVerdictBasis
Trainable setFULL tex stream (1.30B), not tail-onlyconcat_cond distribution shift enters at input_layer; MF trains its appended stream fully; tail-only demoted to ablation A4
Dual attention weights100% borrowed (tex Q · geo K/V), zero new projections, λ gates only (+360 scalars)bilinear form needs one trainable side; standard MMDiT semantics (SD3/FLUX/MF add none); A2 bridges queued if the frozen-projection ceiling shows
Implementation of the masked union softmaxtwo standard attention calls + LSE mergemathematically exact; reuses sparse kernels; λ=−∞ makes G0 identity EXACT
Attention budget2L² (cascade) → 3L² (Stage-1 one-way) → 4L² only if bidirectional ever opensblock mask deletes the geo→tex quadrant from computation, not just from the softmax
Bidirectional (geo←tex)default-permanent one-way; trigger-gated, not scheduledchain rule: p(g,t|c)=p(g|c)·p(t|g,c) — one-way loses zero expressiveness for our mode set; MF's leader-first ablation; our negative-results record on speculative coupling. Trigger: G1 shows geo-tex misalignment the cascade lacks AND tex-side fixes fail → then bundle λ' + geo training + tri-modal data + self-distill
Cond injectionread-once cross-attn (A); cond-as-stream (B) only as Stage-2 A/B armJune fairness-controlled ablation: read-once won; B must beat it same-data-same-steps

Engineering source of truth: BLIP3o/docs/UNIFIED_GEOTEX_DIT_DESIGN.md (full recipe, gates G0-G2, ablations A1-A5, footguns).

9 · Training config & time scheduling (finalized)

ItemValueWhy
Timestep sampler40% corner edge t_s=0 · 40% α-band (t_s=g_α(t_x), α~logU[1,16]) · 20% full squaremass follows the product: corner = tex|mesh mode; band = exactly the schedule family inference will run (α stays a free knob); full square = robustness + t_s=1 edge for free shape-CFG. Fixed-lag rejected (kills the α knob, off-path = OOD); full-uniform rejected (below-diagonal is useless for our modes). Band-vs-triangle = ablation A6.
Is wide coverage inefficient?second-order concernstandard diffusion already trains ALL t with one net (1-D "full coverage"); MF/JointDiT/DF all train wide and win — but we still bias 80% of mass onto product-relevant regions.
Timestep-aware MMDiTper-stream AdaLN (own t) [standard] · zero-init t_s→tex mixer [verified: MF] · bridge = borrowed-K/V attention → output projection with zero-init (free initialization, NOT a runtime gate)"Why a gate at all" audit: the projection is needed anyway (basis adapter, UniCon has it); zero-init costs nothing and buys G0-as-assembly-test (strict=False misload history) + no init loss spike (why ControlNet/UniCon/JointDiT/LLaMA-Adapter all zero-init). The true runtime gate w(t) is demoted to A7: JointDiT's "gates needed" evidence predates corner sampling — MF beat it 57% with NO attention gate using corner sampling + modulation mixers, both of which we adopt. A8 = shared-softmax λ variant.
Inference schedulet_x = f_α(t_s), α∈[1,16] sweepable, α→∞ ≡ cascadeMF-verified leader-first ("geo as scratch pad"); the trained band makes the whole family in-distribution without retraining.
Data / mixture293k tex-paired assets, S3 tri-modal mixture KEPT (I1/IM/T)tex specialist is tri-modal; I1-only training would erode IM/T (replay lesson).
Hyperparamseff BS 256 (bs8×ga4×8×H200) · LR 1e-4 · warmup 100 · zero1 · grad-ckpt · EMA · ~3k steps · sbatchinherited from the S3 recipe unchanged.
Trainablefull tex stream 1.30B + λ(t) + t_s mixer; geo frozen, no geo loss§8 decision log.
Step cost≈1.3–1.5× a current tex-stage steptex fwd+bwd (attn +50%) + geo fwd (no_grad).
Extrasbridge-dropout p≈0.1 · (x_t, v-target) convention unit testrobustness + uncond branch; the #1 porting hazard.
Left: training mass follows the product — the corner edge IS mode ②, the α-band IS the inference schedule family, and only the 20% robustness component strays below the diagonal. Right: one trained model serves every α from sync to the cascade limit; 'geometry first' is a free inference dial, not a baked-in choice.

10 · AS-BUILT (2026-08-11) — implementation status, supersedes conflicting details above

Where earlier sections and this one disagree, THIS section is current. Changes driven by: the variant-definition correction (the two first-class variants are COND-injection variants — "mmdit+cross" vs "mmdit joint"; geo↔tex coupling is MMDiT joint attention in both), the provenance audits (every self-invented mechanism deleted or demoted), and a blind line-by-line audit vs all three reference codebases (8 findings, all fixed).
AS-BUILT: the implementation-accurate architecture. The coupling inset + [SCALE] decision diamond is the one open empirical question; everything else is frozen, line-annotated to its reference, and covered by the verification chain on the right. Invented-without-reference mechanisms in the model: zero.

11 · BIDIRECTIONAL PIVOT (2026-08-12) — final S1 topology, supersedes the one-way verdict of §4/§10

User topology decision: geo and tex MUTUALLY attend ("both read 2L") in the joint interior. The one-way analysis of §4 is retained above for the record but no longer describes the trained model.
The corner-masked bidirectional block, final S1 form: mutual K/V reads (std MMDiT) in the joint interior, one-way at the ts=0 corner (cache + geometry lock), stream identity via the float-exact π/2 rotation of RoPE's spare identity pair, and symmetric cross-t mixers so BOTH streams know BOTH timesteps.

12 · S1 RESULTS (2026-08-12) — trained, gated, judged

G2 PASSED and beats the specialist: tex|mesh latent MSE 0.969 vs 1.021 (ratio 0.950, threshold 1.05), and the render grid agrees — one unified model matches specialist texture quality on the flagship mode while also carrying joint and mesh-only.
G1 joint FAILS at finite α: α=4/32 render nearly black on the hard asset, only α=∞ (the literal cascade dispatch) is correct. The bidirectional model is sound — what breaks is the interleaved integration. Open problem, does not block the products.
G2 — tex|mesh with geometry locked. Unified (right) vs the tex specialist (middle) vs GT: indistinguishable on 5 of 6 assets. The thin-pole stand (row 1) loses its base in BOTH columns — an asset-level hard case, not a unified regression.
G1 — the α sweep exposes the open problem: α=4 and α=32 collapse to near-black on the hard asset while α=∞ (cascade dispatch) is correct. Since α=∞ uses the same trained weights, the failure is in the interleaved integration, not in the bidirectional architecture.
Multi-seed tex|mesh: stable and diverse across seeds, with the 3-step warm-start artifacts (compare the earlier smoke grid) fully gone.
deep-research: 103 agents · 100 claims → 25 verified (24 confirmed, 1 refuted) · figures generated from verified formulas · 2026-08-10

13 · TIMESTEP SAMPLING CORRECTED (2026-08-13) — the interior 40% was aimed where inference never goes

The shipped sampler drew the non-corner 40% independently over the FULL (tgeo, ttex) square, so 20% of every batch trained texture AHEAD of geometry — a configuration none of the three product modes ever visits. Corrected mid-S2b: that mass now covers the upper triangle, and only the one useful lower-triangle edge is kept.
The whole argument in one picture. Every inference mode lives in tgeo ≤ ttex: tex|mesh is the left edge, mesh-only is the top edge, and joint rides an α-warp curve between the diagonal and the cascade limit. BEFORE, a fifth of every batch (red) sat below the diagonal where nothing ever runs. AFTER, the interior is uniform over the union of ALL α trajectories, and the only surviving lower-triangle mass is the tgeo=1 edge — which is not waste: it is the uncond branch of UniDiffuser's free modality-CFG.
Both corners are untouched, so the flagship tex|mesh mode and the mesh-only marginal keep their exact training mass. Only the interior is re-aimed: 20% → 35% on the upper triangle, 20% → 0% below the diagonal, 5% reserved for the CFG edge.

14 · UNIFY DiT — FINAL ARCH / CONFIG (2026-08-15)

A from-scratch three-stream sparse MMDiT: geo · tex · cond, N double-stream blocks → merge → 2N shared blocks. Every module is TRELLIS.2’s own or a G0-certified stitching helper; every design choice below names the reference that made the same choice, or is flagged as a deliberate deviation with its reason.
The three streams enter with their own projections, run 8 blocks with their own weights but ONE joint attention, merge into a single sequence for 16 shared-weight blocks, then split. cond is never an output — it exists to be read and rewritten. Inside the shared stack nothing distinguishes a geo token from a tex token except the three per-token mechanisms listed at the bottom: geo and tex sit on identical voxel coordinates, so the segment tag is doing work FLUX and Hunyuan never needed.
Provenance for every element. Blue = reused from TRELLIS.2 unchanged and verified BIT-EXACT against the block's own forward (max|diff| = 0.000e+00); green = matches a reference implementation read in source (Modality Forcing, Hunyuan3D-2.1, FLUX.2); orange = deliberate deviation. The rope row is now genuinely unchanged: TRELLIS's 3-axis config, 21 frequency pairs per spatial axis, freqs tensor bit-identical. An intermediate version of this design gave the segment its own 4th rope axis (Modality Forcing's time_id approach) and that cost each SPATIAL axis 5 of its 21 pairs — a certain loss traded for an ambiguous gain, since a segment-id difference of 1 turned only 3 of that axis's 16 pairs by more than 0.3 rad. Every deviation carries a stated reason — none of them is an accident.
RoPE budget. TRELLIS ropes 63 of head_dim 128’s 64 pairs and leaves ONE unrotated; the segment tag spends exactly that spare pair, so the spatial ladder — which IS the geometry — keeps all 21 pairs per axis. Four segments are four quarter-turns of that pair, applied PER ROW so one cond stream can carry both its DINO and Qwen ids. Every turn is a swap and/or a sign flip: float-exact, and four turns return exactly to the identity (verified). This generalises the warm-started model’s own stream tag (_rotate_pad_pair, G0-certified and trained through S1 and S2b) from one whole-tensor turn to a per-token choice.

Config

knobvalidation (297M)production (1.03B)note
dim / heads768 / 61024 / 8head_dim fixed at 128 — flash-friendly, and 64 rope pairs divide by 4 axes
double : single8 : 1616 : 321:2 (owner); MF uses 1:3, Hunyuan 1:2
params298M1.03Bdouble 57% / single 38%
latentsgeo 32ch, tex 32ch (+32 concat_cond), cond 1024chSLAT widths, measured from the TRELLIS.2 flows
datamatclean v4: 397,235 + 397,156the un-cleaned v4 the old runs used carried 5.4% / 5.9% material-bug assets

The four deliberate deviations

What the sparse latents force that FLUX / Hunyuan never had to solve

Bugs the audit caught (all fixed and re-tested)

Verified by test, not by inspection

14.9 · Line-by-line audit (2026-08-15) — four parallel auditors + a full read

Nine defects, four of which stop the run on step 1 or corrupt it silently. Four auditors with non-overlapping remits (codebase contract · TRELLIS.2 op-for-op equivalence · varlen packing and autograd · every reference claim re-read in source) plus my own read of all 476 lines. Every finding below was reproduced before it was fixed, and re-measured after.
#DefectEffect if shippedHow it was caught
1tex latent width was 64, not 32. The tex config's in_channels: 64 is tex(32)+concat shape(32); out_channels: 32 is the latent.Crash on step 1 (96-wide weight, 64-wide input), and a 64-ch velocity against a 32-ch target.Auditor checked the constant against the authoritative config. My own regression test fed 64-ch tex too, so it was green through every run.
2Freeze audit's allow-list has no cond_flow./cond_t./shared_blocks. prefix.AssertionError before step 1 (~200 names).Contract auditor enumerated the real parameter names against the real allow-list.
3The entry point froze geo_flow (right for a pretrained specialist), and unfreeze_geo() was a documented no-op.Silent: a random geo tower with a zero-init out layer forever ⇒ v_s ≡ 0, geo and distill losses constant with no gradient. The freeze audit cannot see it — it only inspects params that still require grad.Contract auditor traced the flag through to the model.
4Two of three sampler modes called the geo tower as a standalone specialist.Mesh-only and joint(α=∞) crash; G3 unmeasurable.Contract auditor read every sampler call site.
5No dtype/convert_to protocol (SLatFlowModel has one).The sampler runs outside autocast on fp32 latents ⇒ FlashAttention only support fp16 and bf16.Reproduced when the fixed sampler modes were first actually run.
6Packing used new_empty + slice assignment.24 chained CopySlices nodes per block, each cloning the whole packed gradient: measured 2.6× the fwd+bwd of torch.cat (86.4 s vs 33.1 s / 5 iters).Packing auditor benchmarked both forms.
7q, k, v packed separately, then stacked.Four full-size buffers per block instead of one (~1.5 GB transient at B=8), paid twice under checkpointing.Same auditor.
8--geotex_gc wrote per-block flags this model never reads.--geotex_gc 0 silently kept checkpointing all 24 blocks.Contract auditor followed the knob to its consumer.
9Six reference claims wrong or unverifiable: MF does keep a 4-block depth-only decoder; MF's text shares RGB's modality id (it separates by a per-token arange, not a stream id); zeroed adaLN does not make a share_mod block identity (each block adds a randn modulation); a FLUX.1 citation with no FLUX.1 source on this machine; three off-by-one line numbers.Wrong rationale outlives wrong code.Reference auditor re-read every cited file.

What the audit confirmed — measured, not asserted

The generalisable lesson: a test you wrote yourself, from your own idea of the contract, can only prove internal consistency. Defect 1 was green in my own harness through every run because the harness carried the same wrong number. Cross-module constants have to come from the authoritative source (config, checkpoint, or the calling code), never from the author's memory.