How to Debug Common TRELLIS.2 Issues: Artifacts and Generation Failures
Set log_level=DEBUG, validate latent vectors for NaNs, reduce dt in flow_euler.py, and visualize intermediate voxel grids with vis_utils.py to isolate whether artifacts stem from data loading, VAE collapse, flow integration instability, or renderer misconfigurations.
TRELLIS.2 is Microsoft's open-source framework for structured 3D shape generation using latent diffusion and flow matching. When debugging TRELLIS.2 artifacts and generation failures, you need to trace issues through its modular pipeline: data ingestion → latent encoding → flow/diffusion generation → rendering. This guide walks through the specific source files, diagnostic techniques, and code snippets that reveal where problems originate.
Understanding the TRELLIS.2 Pipeline and Failure Points
Each stage has distinct failure modes with recognizable symptoms. The table below maps components in the microsoft/TRELLIS.2 repository to their typical problems.
| Stage | Primary Module | What Can Go Wrong | Typical Symptoms |
|---|---|---|---|
| Data ingestion | trellis2/datasets/structured_latent_shape.py |
Missing tensors, mismatched voxel resolutions | RuntimeError on load, empty voxels |
| Latent encoding | trellis2/trainers/vae/shape_vae.py |
KL-divergence collapse, overflow/underflow | Loss spikes, NaN latents, uniform output |
| Flow/diffusion generation | trellis2/pipelines/samplers/flow_euler.py |
Unstable ODE integration, step-size issues | Sudden artifact patches, blank generations, crashes |
| Mesh reconstruction | trellis2/renderers/voxel_renderer.py |
Topology errors, axis misalignment | Dangling faces, holes, self-intersections |
| Post-processing | o-voxel/o_voxel/serialize.py |
Format conversion errors | Corrupted .ply/.glb files |
Diagnosing the Four Most Common TRELLIS.2 Failure Types
1. VAE Latent Collapse Causing Blank or Noisy Output
The KL-divergence regularizer in loss_utils.py can dominate training if the learning-rate schedule is too aggressive. This produces collapsed latents that generate uniform or noisy geometry.
Diagnostic check: Inspect checkpoint tensors for near-zero values.
import torch
# Load your trained encoder
checkpoint = torch.load('path/to/checkpoint.pt')
latent_mean = checkpoint['latent.mean']
latent_logvar = checkpoint['latent.logvar']
print(f"Mean range: {latent_mean.min():.4f} to {latent_mean.max():.4f}")
print(f"Logvar mean: {latent_logvar.mean():.4f}")
# Collapsed prior indicators
if latent_mean.abs().mean() < 0.01 and latent_logvar.mean() < -5:
print("WARNING: VAE collapse detected - KL weight too high")
Fix: Reduce KL weight, lower learning rate, or apply gradient clipping via grad_clip_utils.py.
2. Flow Integration Instability Producing Spiky Artifacts
flow_euler.py uses explicit Euler integration. When the step size dt exceeds the Lipschitz bound of the learned flow, integration diverges—creating large-scale spikes that appear as mesh artifacts.
Diagnostic check: Enable debug mode and monitor velocity norms.
from trellis2.pipelines.samplers.flow_euler import FlowEulerSampler
sampler = FlowEulerSampler(
dt=0.01, # Try reducing this first
max_steps=10, # Reduce for debugging
debug=True # Logs max velocity at each step
)
output = sampler(latent)
# Look for velocity_norm values that explode between steps
# Typical stable range: 0.1-10.0; values >100 indicate divergence
Fix: Decrease dt (try 0.005 or 0.001) or switch to a higher-order integrator in the sampler mix-in.
3. Voxel Grid Misalignment Creating Ghost Artifacts
data_utils.py and mesh_utils.py convert point clouds to sparse 3D grids. Off-by-one errors in voxel_origin or voxel size cause shifted geometry—thin, ghost-like artifacts after rendering.
Diagnostic check: Visualize before reconstruction.
from trellis2.utils.vis_utils import dump_voxel_grid
# Dump intermediate voxel grid before feeding to generator
dump_voxel_grid(output['voxel'], filename='debug_voxel.ply')
# Open in MeshLab/Blender to verify alignment with expected geometry
# Misalignment shows as offset or duplicated thin structures
Fix: Verify voxel_origin matches your dataset's coordinate system; use mesh_utils.align_grid if needed.
4. Renderer Tensor Layout Mismatches Causing Holes
voxel_renderer.py expects shape [B, C, D, H, W]. Swapped axes corrupt the marching-cubes algorithm, yielding holes or duplicated faces.
Diagnostic check: Validate tensor shape before extract_mesh.
from trellis2.renderers.voxel_renderer import VoxelRenderer
print(f"Voxel tensor shape: {output['voxel'].shape}")
# Expected: [batch, channels, depth, height, width]
renderer = VoxelRenderer()
mesh = renderer.render(output['voxel']) # Fails silently if shape wrong
mesh.export('debug_mesh.glb')
Fix: Transpose with tensor.permute(0, 1, 4, 3, 2) if channels/axes are swapped; adjust iso_level (default 0.5) if faces are missing.
Step-by-Step Debugging Workflow for TRELLIS.2
Follow this sequence to isolate TRELLIS.2 generation failures from data through final output.
Step 1: Enable Verbose Logging
import logging
logging.basicConfig(level=logging.DEBUG)
# All trainers and pipelines now emit per-step loss and ODE statistics
Step 2: Validate Dataset Integrity in Isolation
from trellis2.datasets.structured_latent_shape import StructuredLatentShape
ds = StructuredLatentShape(split='train')
sample = ds[0] # Raises immediately if source files corrupted
print(f"Voxel: {sample['voxel'].shape}, Image: {sample['image'].shape}")
Step 3: Check Latent Vector Health Post-Encoding
import torch
latent = encoder(sample['image'])
assert not torch.isnan(latent).any(), "NaNs in latent - VAE unstable"
assert not torch.isinf(latent).any(), "Infs in latent - gradient explosion"
print(f"Latent stats: mean={latent.mean():.3f}, std={latent.std():.3f}")
Step 4: Step Through Flow Sampler with Reduced Steps
from trellis2.pipelines.samplers.flow_euler import FlowEulerSampler
sampler = FlowEulerSampler(dt=0.01, max_steps=10, debug=True)
output = sampler(latent)
# Examine logged velocity norms; reduce dt if max_norm grows exponentially
Step 5: Visualize Intermediate Voxel State
from trellis2.utils.vis_utils import dump_voxel_grid
dump_voxel_grid(output['voxel'], filename='debug_voxel.ply')
# Inspect in external viewer before mesh extraction
Step 6: Render Known-Good Voxel for Comparison
from trellis2.renderers.voxel_renderer import VoxelRenderer
renderer = VoxelRenderer()
mesh = renderer.render(output['voxel'])
mesh.export('debug_mesh.glb')
# If artifacts persist here, problem is in renderer or post-processing
Quick Reference: Symptom-to-Fix Mapping
| Symptom | Root Cause | Fix in Source |
|---|---|---|
| Blank output / all zeros | VAE KL collapse | Reduce KL weight in shape_vae.py; add clipping via grad_clip_utils.py |
| Spiky, jagged surfaces | dt too large in Euler integration |
Decrease dt in flow_euler.py or use higher-order sampler |
| Mis-aligned ghost geometry | voxel_origin mismatch |
Fix in data_utils.py; call mesh_utils.align_grid |
| Missing faces / holes | Marching-cubes threshold | Adjust iso_level in voxel_renderer.py |
| Corrupted export files | Wrong tensor layout | Ensure [B, C, D, H, W] before voxel_renderer.py |
Key Source Files for Debugging
| Component | File Path |
|---|---|
| VAE trainer (shapes) | trellis2/trainers/vae/shape_vae.py |
| Euler flow sampler | trellis2/pipelines/samplers/flow_euler.py |
| Voxel-to-mesh renderer | trellis2/renderers/voxel_renderer.py |
| Structured shape dataset | trellis2/datasets/structured_latent_shape.py |
| Voxel visualization | trellis2/utils/vis_utils.py |
| Gradient stabilization | trellis2/utils/grad_clip_utils.py |
| Training entry point | train.py |
| Inference example | example.py |
Summary
- TRELLIS.2 artifacts typically originate in four areas: VAE latent collapse, flow integration instability, voxel grid misalignment, or renderer tensor mismatches.
- Systematic isolation requires validating dataset integrity, checking latent vectors for NaNs/overflow, stepping through samplers with debug logging, and visualizing intermediate voxel states.
- Critical hyperparameters to adjust: KL weight (VAE stability),
dtstep size (flow integration),voxel_origin(spatial alignment), andiso_level(mesh extraction quality). - Always verify tensor shapes before rendering—
[B, C, D, H, W]is required byvoxel_renderer.py.
Frequently Asked Questions
Why does TRELLIS.2 produce completely blank outputs?
Blank outputs indicate VAE latent collapse, where the KL-divergence term dominates and pushes latent distributions toward the prior. Check latent.mean and latent.logvar in your checkpoint—values near zero with very negative logvar confirm collapse. Reduce the KL weight in your training config or apply gradient clipping via grad_clip_utils.py to stabilize training.
How do I fix spiky artifacts on generated meshes?
Spiky artifacts stem from unstable flow integration in flow_euler.py. The explicit Euler step diverges when dt exceeds the flow's Lipschitz bound. Enable debug=True in the sampler and watch for exploding velocity norms. Decrease dt from 0.01 to 0.005 or 0.001, or switch to a higher-order integrator available in the sampler mix-ins.
What causes holes or missing faces in TRELLIS.2 outputs?
Holes typically result from marching-cubes threshold issues or tensor axis misalignment. First verify your voxel tensor has shape [B, C, D, H, W] before passing to voxel_renderer.py—swapped axes silently corrupt extraction. If shape is correct, lower the iso_level parameter below its default 0.5 to capture more surface geometry.
How do I debug dataset loading failures in TRELLIS.2?
Run the dataset loader in isolation using StructuredLatentShape from trellis2/datasets/structured_latent_shape.py. Access a single sample with ds[0]—this raises immediately on corrupted source files. Check that voxel resolutions match between your data and model config, and verify file paths in your dataset configuration YAML.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →