# Classifier‑Free Guidance Implementation in TRELLIS 2 Samplers: A Deep Dive into the Mixin Pattern

> Explore how Classifier-Free Guidance is implemented in TRELLIS.2 samplers using the ClassifierFreeGuidanceSamplerMixin. Learn about weighted predictions for enhanced results.

- Repository: [Microsoft/TRELLIS.2](https://github.com/microsoft/TRELLIS.2)
- Tags: deep-dive
- Published: 2026-08-04

---

**Classifier‑Free Guidance (CFG) in TRELLIS 2 is implemented through the `ClassifierFreeGuidanceSamplerMixin` class, which overrides the `_inference_model` method to compute a weighted combination of conditioned and unconditioned predictions.**

TRELLIS 2's diffusion pipelines support **classifier‑free guidance** via a clean mixin architecture. The implementation lives in [`trellis2/pipelines/samplers/classifier_free_guidance_mixin.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/classifier_free_guidance_mixin.py) and allows any compatible sampler to gain CFG capabilities through simple inheritance—no code duplication required.

## How the ClassifierFreeGuidanceSamplerMixin Works

The mixin intercepts the core inference step and applies CFG through four distinct operations.

### Guidance Strength Short‑Circuits

When `guidance_strength` equals **1**, the mixin bypasses CFG entirely and returns the standard conditioned prediction. When it equals **0**, it returns the purely unconditioned prediction. These checks appear at lines 10‑14 of [`classifier_free_guidance_mixin.py`](https://github.com/microsoft/TRELLIS.2/blob/main/classifier_free_guidance_mixin.py).

### Dual Forward Passes

For intermediate strengths, the mixin invokes `super()._inference_model` **twice** (lines 15‑16):

- Once with the **positive condition** (`cond`)
- Once with the **negative condition** (`neg_cond`)

This yields `pred_pos` and `pred_neg`, the model's outputs under each conditioning scenario.

### Linear Interpolation

The final prediction combines these outputs linearly (line 17):

```

guidance_strength * pred_pos + (1 - guidance_strength) * pred_neg

```

Higher guidance strengths push the result closer to the conditioned prediction, amplifying the influence of the prompt.

### Optional CFG Rescaling

When `guidance_rescale > 0`, the mixin mitigates excessive variance through a three‑step process (lines 20‑27):

1. Convert predictions to estimated start latents via `_pred_to_xstart(x_t, t, pred)`
2. Rescale the standard deviation of these `x_0` estimates
3. Re‑encode with `_xstart_to_pred(x_t, t, x_0)` for the final sampling update

This rescaling prevents over‑saturation artifacts common with aggressive CFG values.

## Required Helper Methods

The mixin delegates latent space conversions to methods defined in `BaseSampler` ([`trellis2/pipelines/samplers/base.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/base.py)):

| Method | Purpose |
|--------|---------|
| `_pred_to_xstart(x_t, t, pred)` | Maps model output back to estimated denoised latent |
| `_xstart_to_pred(x_t, t, x_0)` | Converts denoised latent back to model‑space prediction |

Any sampler inheriting from `BaseSampler` automatically receives these helpers, making CFG adoption frictionless.

## Integrating CFG into TRELLIS 2 Samplers

TRELLIS 2 samplers typically inherit from multiple mixins. The **Euler sampler** demonstrates this pattern in [`trellis2/pipelines/samplers/flow_euler.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/flow_euler.py):

```python
class FlowEulerSampler(
    ClassifierFreeGuidanceSamplerMixin,
    GuidanceIntervalMixin,
    BaseSampler,
):
    ...

```

**Inheritance order matters.** Placing `ClassifierFreeGuidanceSamplerMixin` first ensures its `_inference_model` implementation takes precedence. Internally, it calls `super()` to reach the base sampler's original prediction routine.

The `GuidanceIntervalMixin` (from [`trellis2/pipelines/samplers/guidance_interval_mixin.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/guidance_interval_mixin.py)) adds per‑interval guidance scaling, allowing CFG strength to vary across diffusion timesteps.

## Practical Code Examples

### Instantiating a CFG‑Enabled Sampler

```python
from trellis2.pipelines.samplers.flow_euler import FlowEulerSampler

sampler = FlowEulerSampler(
    guidance_strength=0.7,   # 0.0 = unconditional, 1.0 = fully conditional

    guidance_rescale=0.5,    # Optional variance rescaling

)

samples = sampler.sample(prompt="A futuristic cityscape")

```

The mixin automatically handles dual forward passes and interpolation—no manual intervention required.

### Creating a Custom CFG Sampler

```python
from trellis2.pipelines.samplers.base import BaseSampler
from trellis2.pipelines.samplers.classifier_free_guidance_mixin import ClassifierFreeGuidanceSamplerMixin

class MyCFGSampler(ClassifierFreeGuidanceSamplerMixin, BaseSampler):
    pass

cfg_sampler = MyCFGSampler(guidance_strength=0.9, guidance_rescale=0.2)

latent = cfg_sampler._inference_model(
    model=my_diffusion_model,
    x_t=noisy_latent,
    t=current_step,
    cond=conditioned_embedding,
    neg_cond=unconditioned_embedding,
    guidance_strength=0.9,
    guidance_rescale=0.2,
)

```

Supply `cond` (your prompt embedding) and `neg_cond` (typically unconditioned embeddings). The sampler manages the rest.

## Key Source Files

| File | Role |
|------|------|
| [`trellis2/pipelines/samplers/classifier_free_guidance_mixin.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/classifier_free_guidance_mixin.py) | Core CFG implementation with dual‑pass logic and rescaling |
| [`trellis2/pipelines/samplers/base.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/base.py) | Base sampler with `_pred_to_xstart` and `_xstart_to_pred` helpers |
| [`trellis2/pipelines/samplers/guidance_interval_mixin.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/guidance_interval_mixin.py) | Per‑timestep guidance scaling |
| [`trellis2/pipelines/samplers/flow_euler.py`](https://github.com/microsoft/TRELLIS.2/blob/main/trellis2/pipelines/samplers/flow_euler.py) | Example sampler using CFG mixin |

## Summary

- **Classifier‑free guidance in TRELLIS 2** is implemented via `ClassifierFreeGuidanceSamplerMixin`, a reusable wrapper around any sampler with `_pred_to_xstart` and `_xstart_to_pred` methods.
- The mixin performs **dual forward passes** through `_inference_model`, then **linearly interpolates** results based on `guidance_strength`.
- **Optional rescaling** prevents variance explosion when guidance is strong.
- **Inheritance‑based design** lets samplers adopt CFG by adding one mixin to their class hierarchy—exemplified by `FlowEulerSampler` in the official codebase.

## Frequently Asked Questions

### How do I enable classifier‑free guidance in a custom TRELLIS 2 sampler?

Inherit from `ClassifierFreeGuidanceSamplerMixin` before `BaseSampler` (or your base class). Ensure your sampler implements `_pred_to_xstart` and `_xstart_to_pred`. Pass `guidance_strength` and optional `guidance_rescale` during instantiation.

### What values should I use for guidance_strength and guidance_rescale?

`guidance_strength` typically ranges from **1.0 to 7.5** for CFG effects, though TRELLIS 2 accepts 0.0–1.0 direct scaling. `guidance_rescale` (0.0–1.0) applies when variance artifacts appear—start with **0.5** and adjust.

### Does classifier‑free guidance double inference time?

Yes. The mixin calls `_inference_model` twice per step: once conditioned, once unconditioned. This is the standard CFG trade‑off for improved prompt adherence.

### Can I use classifier‑free guidance with time‑varying strength?

Yes. Combine `ClassifierFreeGuidanceSamplerMixin` with `GuidanceIntervalMixin` to apply different `guidance_strength` values across diffusion timesteps.