How to Debug Sampling Failures or Artifacts in TRELLIS.2 Generated Geometry

Enable verbose sampling, inspect intermediate tensors from the Euler integrator, and validate conditioning data shapes to isolate the root cause of empty outputs or structural artifacts.

TRELLIS.2 is Microsoft's open-source framework for reconstructing and generating high-quality 3D geometry using flow-matching and VAE models. When you encounter empty meshes, noisy textures, or structural deformities during inference, the issue typically originates in the sampling pipeline's configuration, conditioning inputs, or Euler integration hyperparameters.

Understanding the Core Sampling Pipeline

The generation process relies on the FlowEulerSampler class in trellis2/pipelines/samplers/flow_euler.py. This sampler implements an Euler integrator that iteratively refines a noisy tensor x_t into a clean output x_0 over a series of discrete steps. The sampler returns an edict object containing intermediate predictions (pred_x_t, pred_x_0) and the final denoised samples.

According to the Microsoft/TRELLIS.2 source code, sampling failures cascade from five primary layers: sampler configuration, conditional inputs, model loading, data pipeline integrity, and post-processing rendering.

Common Sources of Sampling Failures

Sampler Configuration Errors

Improper hyperparameters in the flow-matching schedule cause the most common artifacts. Ensure sigma_min is set between 0 and 1.0 (inclusive of 0, exclusive of 1) to maintain noise schedule stability. If geometry appears overly coarse or collapses to a single shape, increase the steps parameter (e.g., from 50 to 100). For classifier-free guidance, keep guidance_strength and guidance_interval within the range [0, 1] to prevent semantic divergence.

Conditional Input Mismatches

The cond and neg_cond tensors must match the model's expected channel dimensions. Mismatched shapes trigger silent broadcasting bugs that manifest as color bleeding or empty meshes. Always verify that text embeddings or image conditioning are correctly pre-processed by the dataset pipeline before reaching the sampler's sample() method.

Model Checkpoint Incompatibility

Confirm that loaded checkpoints match the FlowEulerSampler architecture, which expects flow-matching models outputting velocity v. When loading on CPU-only machines, use torch.load(..., map_location='cpu') to prevent device mismatch errors and NaN propagation in intermediate tensors.

Data Pipeline Corruption

Inspect input voxel or mesh representations in trellis2/datasets/ and trellis2/utils/mesh_utils.py for holes or non-manifold edges. Run data_toolkit/voxelize_pbr.py on problematic assets and visualize the voxel grid using vis_utils.plot_voxels. Corrupted input representations propagate directly to the final output.

Renderer and Post-Processing Issues

Ensure the renderer receives the correct data type (Mesh, Voxel, or MeshWithPbrMaterial). After sampling, recompute vertex normals using mesh_utils.compute_normals to prevent shiny patches or missing surfaces in the final visualization.

Systematic Debugging Workflow

Follow this structured approach to isolate sampling failures:

  1. Enable verbose output – Set verbose=True in the sampler constructor to monitor the progress bar and confirm the full step range executes.
  2. Capture intermediate states – Extract pred_x_t and pred_x_0 from the result edict. Save tensors at intervals (e.g., every 20 steps) to identify when geometry degradation begins.
  3. Visualize progressively – Use render_utils.render_frames or vis_utils.plot_voxels to render intermediate tensors as voxel grids or mesh frames.
  4. Tune hyperparameters – For under-refined geometry, increase steps or lower sigma_min. For over-smoothed outputs, decrease steps or raise guidance_strength.
  5. Validate tensor shapes – Print the shapes of cond and neg_cond immediately before calling sampler.sample() to catch dimension mismatches.
  6. Inspect raw data – Visualize a single training sample before sampling to ensure the dataset pipeline produces valid inputs.

Debug Script for Inspecting Sampling Artifacts

Use this minimal implementation to log intermediate tensors and validate your configuration:

import torch
from trellis2.pipelines.samplers.flow_euler import FlowEulerSampler
from trellis2.pipelines.samplers.classifier_free_guidance_mixin import ClassifierFreeGuidanceSamplerMixin
from trellis2.renderers.mesh_renderer import MeshRenderer
from trellis2.utils.vis_utils import plot_voxels
from trellis2.utils.render_utils import render_frames

# Load model with proper device mapping

model = torch.load("checkpoints/flow_matcher.pt", map_location="cpu")
model.eval()

# Prepare noise tensor: [B, C, D, H, W]

noise = torch.randn(1, 4, 64, 64, 64)
cond = torch.randn(1, 512)  # Example text embedding

neg_cond = torch.zeros_like(cond)

# Instantiate sampler with diagnostic-friendly settings

sampler = FlowEulerSampler(sigma_min=0.01, verbose=True)

# Execute sampling with increased steps for quality

result = sampler.sample(
    model=model,
    x_t=noise,
    cond=cond,
    neg_cond=neg_cond,
    steps=80,
    guidance_strength=0.8,
)

# Debug: Visualize intermediate predictions every 20 steps

for i, (x_t, x_0) in enumerate(zip(result.pred_x_t, result.pred_x_0)):
    if i % 20 == 0:
        plot_voxels(
            x_t.squeeze().cpu().numpy(), 
            title=f"Step {i} (Noisy)"
        )

# Render final geometry

renderer = MeshRenderer()
mesh = renderer.render(result.samples.squeeze())
renderer.show(mesh)  # Launches interactive viewer

Key Source Files for Debugging

These modules contain the critical logic for diagnosing sampling issues:

Summary

  • Validate configuration: Keep sigma_min between 0 and 1, steps above 50 for detail, and guidance parameters within [0, 1].
  • Check conditioning: Verify cond and neg_cond tensor shapes match model expectations to prevent silent broadcasting errors.
  • Inspect intermediate states: Extract pred_x_t and pred_x_0 from the sampler's edict output to identify when artifacts first appear.
  • Verify data integrity: Run voxelize_pbr.py and visualize inputs with plot_voxels to ensure the dataset pipeline produces valid geometry.
  • Recompute normals: Call mesh_utils.compute_normals after sampling to fix rendering artifacts in the final mesh.

Frequently Asked Questions

Why is my TRELLIS.2 output empty or containing NaN values?

Empty outputs typically indicate a device mismatch or corrupted checkpoint loading. Use torch.load(..., map_location='cpu') when loading models on CPU-only machines, and verify that the checkpoint architecture matches the FlowEulerSampler expectations. Check that sigma_min is strictly greater than 0 to avoid numerical instability in the noise schedule.

How do I fix coarse or low-detail geometry in sampled outputs?

Increase the steps parameter in FlowEulerSampler.sample() (e.g., from 50 to 100) to allow more refinement iterations. Additionally, lower sigma_min to retain more detail in the late stages of denoising. Inspect intermediate pred_x_0 tensors to confirm detail is present before the final rendering stage.

What causes color bleeding or semantic mismatches in generated textures?

Color bleeding arises from mismatched dimensions in the conditional inputs. Print the shapes of cond and neg_cond tensors before sampling—they must match the model's expected embedding dimensions exactly. Ensure your dataset pipeline correctly pre-processes text or image embeddings according to the specifications in trellis2/datasets/.

How can I visualize intermediate steps during the sampling process?

The sample() method returns an edict containing pred_x_t (noisy intermediate states) and pred_x_0 (predicted clean states) for each timestep. Iterate through these lists and pass tensors to vis_utils.plot_voxels for voxel visualization or render_utils.render_frames for mesh rendering. This reveals whether artifacts originate during early noise reduction or final denoising.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →