Classifier‑Free Guidance Implementation in TRELLIS 2 Samplers: A Deep Dive into the Mixin Pattern
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 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.
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):
- Convert predictions to estimated start latents via
_pred_to_xstart(x_t, t, pred) - Rescale the standard deviation of these
x_0estimates - 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):
| 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:
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) adds per‑interval guidance scaling, allowing CFG strength to vary across diffusion timesteps.
Practical Code Examples
Instantiating a CFG‑Enabled Sampler
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
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 |
Core CFG implementation with dual‑pass logic and rescaling |
trellis2/pipelines/samplers/base.py |
Base sampler with _pred_to_xstart and _xstart_to_pred helpers |
trellis2/pipelines/samplers/guidance_interval_mixin.py |
Per‑timestep guidance scaling |
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_xstartand_xstart_to_predmethods. - The mixin performs dual forward passes through
_inference_model, then linearly interpolates results based onguidance_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
FlowEulerSamplerin 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.
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 →