# Euler Ancestral vs Plain Euler vs Res2s Sampler in LTX-2: When to Use Each

> Discover when to use Euler Ancestral for stochastic diversity, plain Euler for fast deterministic sampling, and Res2s for high accuracy with fewer steps in LTX-2.

- Repository: [Lightricks/LTX-2](https://github.com/Lightricks/LTX-2)
- Tags: deep-dive
- Published: 2026-08-18

---

**Use the Euler Ancestral sampler when you need stochastic diversity with classifier-free guidance, plain Euler for fast deterministic sampling with many steps, and Res2s when you need higher accuracy with fewer inference steps.**

LTX-2 provides three diffusion samplers built on different numerical integration strategies and noise policies. Choosing the right sampler depends on your trade-offs between speed, stochasticity, and per-step accuracy in video and audio generation pipelines.

## Plain Euler Sampler: Fast and Deterministic

The **plain Euler sampler** (`EulerDiffusionStep`) implements a first-order explicit Euler integration with no additional noise injection. It follows the deterministic ODE trajectory defined by the rectified-flow model.

In [`packages/ltx-core/src/ltx_core/components/diffusion_steps.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-core/src/ltx_core/components/diffusion_steps.py), the `step()` method performs a simple velocity update:

```python
sigma, sigma_next = sigmas[step_idx], sigmas[step_idx + 1]
dt = sigma_next - sigma
velocity = to_velocity(sample, sigma, denoised_sample)
next = sample + velocity * dt

```

**When to use it:**
- Maximum speed with minimal memory overhead
- Large number of diffusion steps is available
- Stochastic diversity is not required (e.g., reproducible generations)
- Simple ODE solve suffices for your quality requirements

## Euler Ancestral Sampler: Controlled Stochasticity

The **Euler Ancestral sampler** (`EulerAncestralDiffusionStep`) extends the first-order Euler method with a rectified-flow "ancestral" SDE step. It adds stochastic noise controlled by the `eta` parameter (and optional `s_noise`) to preserve variance across timesteps.

The implementation (lines 43-56 in [`diffusion_steps.py`](https://github.com/Lightricks/LTX-2/blob/main/diffusion_steps.py)) computes a down-step ratio that interpolates between current and target sigma based on `eta`. The deterministic component moves toward the denoised prediction, then SDE noise reintroduces stochasticity back to the target sigma level. Notably, setting `eta=0` collapses this to the plain Euler step (lines 85-87).

```python
from ltx_core.components.diffusion_steps import EulerAncestralDiffusionStep
from ltx_pipelines.utils.samplers import euler_ancestral_denoising_loop

stepper = EulerAncestralDiffusionStep(eta=0.7, s_noise=1.0)

video_state, audio_state = euler_ancestral_denoising_loop(
    sigmas=my_sigmas,
    video_state=init_video,
    audio_state=init_audio,
    stepper=stepper,
    transformer=my_model,
    denoiser=my_denoiser,
    noise_seed=42,
)

```

**When to use it:**
- Classifier-free guidance (CFG) scenarios where stochasticity improves sample diversity
- Avoiding mode collapse in generation
- Need variance-preserving transitions between timesteps
- Experimenting with intermediate behavior via small `eta` values (e.g., 0.2)

## Res2s Second-Order Sampler: Accuracy with Fewer Steps

The **Res2s sampler** (`Res2sDiffusionStep`) implements a second-order Runge-Kutta (midpoint) method in log-sigma space. It uses coefficients `a21`, `b1`, `b2` derived from analytic φ-functions that solve the linear ODE part, as defined in [`packages/ltx-pipelines/src/ltx_pipelines/utils/res2s.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-pipelines/src/ltx_pipelines/utils/res2s.py) (lines 25-62).

The algorithm proceeds in four stages:

1. **Stage 1**: Evaluate the denoiser at the current point
2. **Stage 2**: Compute midpoint `x_mid` using coefficient `a21`, with optional SDE noise injection
3. **Stage 2 evaluation**: Denoise the midpoint
4. **Combine**: Weight both ε-estimates with `b1` and `b2` to produce the next latent

```python
from ltx_core.components.diffusion_steps import Res2sDiffusionStep
from ltx_pipelines.utils.samplers import res2s_audio_video_denoising_loop

stepper = Res2sDiffusionStep()

video_state, audio_state = res2s_audio_video_denoising_loop(
    sigmas=my_sigmas,
    video_state=init_video,
    audio_state=init_audio,
    stepper=stepper,
    transformer=my_model,
    denoiser=my_denoiser,
    eta=0.5,  # typical default for Res2s

    noise_seed=123,
)

```

**When to use it:**
- Limited inference budget where fewer steps must maintain quality
- Higher per-step accuracy justifies extra compute
- GPU/TPU hardware where the additional midpoint evaluation is cheap
- Need stability benefits of second-order integration

## Quick Decision Guide

| Situation | Recommended Sampler | Key Configuration |
|-----------|---------------------|-------------------|
| Speed-first, many steps available | Plain Euler | Default `EulerDiffusionStep` |
| CFG with diversity needs | Euler Ancestral | `eta > 0` (try 0.5-0.7) |
| Fewer steps, higher fidelity | Res2s | `eta ≈ 0.5` default |
| Reproducible generations | Plain Euler or Euler Ancestral with `eta=0` | Set `noise_seed` for consistency |
| Mild stochasticity test | Euler Ancestral | `eta=0.2` |

## Implementation Details by Source File

| Component | File Path |
|-----------|-----------|
| Euler family step classes | [`packages/ltx-core/src/ltx_core/components/diffusion_steps.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-core/src/ltx_core/components/diffusion_steps.py) |
| Res2s coefficient calculation | [`packages/ltx-pipelines/src/ltx_pipelines/utils/res2s.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-pipelines/src/ltx_pipelines/utils/res2s.py) |
| High-level sampling loops | [`packages/ltx-pipelines/src/ltx_pipelines/utils/samplers.py`](https://github.com/Lightricks/LTX-2/blob/main/packages/ltx-pipelines/src/ltx_pipelines/utils/samplers.py) |

## Summary

- **Plain Euler** (`EulerDiffusionStep`): First-order, deterministic, minimal overhead—best when steps are plentiful and speed matters most.
- **Euler Ancestral** (`EulerAncestralDiffusionStep`): First-order with `eta`-controlled noise—optimal for CFG scenarios needing diversity; `eta=0` recovers plain Euler.
- **Res2s** (`Res2sDiffusionStep`): Second-order Runge-Kutta with midpoint evaluation—superior when fewer steps must deliver higher fidelity, assuming hardware can absorb the extra denoiser call.

## Frequently Asked Questions

### What happens when I set `eta=0` in Euler Ancestral?

The sampler collapses to deterministic plain Euler behavior. The down-step ratio equals `sigma_next`, eliminating the stochastic noise injection and following the same ODE trajectory as `EulerDiffusionStep`.

### Does Res2s always add noise, or can it run deterministically?

Res2s supports both modes. While it defaults to `eta ≈ 0.5` for stochastic SDE injection at the sub-step, you can pass `eta=0` to run deterministically using only the second-order Runge-Kutta integration without midpoint renoising.

### Which sampler gives the best quality per inference step?

Res2s typically delivers higher quality per step due to its second-order accuracy, allowing coarser sigma schedules. However, the actual best choice depends on your compute budget: if you can afford many steps, plain Euler may suffice; if steps are limited, Res2s' extra compute per step often pays off.

### How does the `s_noise` parameter interact with `eta` in Euler Ancestral?

`s_noise` scales the magnitude of injected stochastic noise independently of `eta`, which controls the variance-preserving schedule interpolation. Higher `s_noise` increases raw noise strength while `eta` determines how much the denoising trajectory deviates from the deterministic path.