Skip to content

Clarification: training sampler (generate_samples_from_batch) vs inference sampler mismatch (TrigFlow vs RF) — is this intended? #27

Description

@LeslieZhoa

Hi, thank you for open-sourcing the code and the great paper. I’m trying to better understand the sampling formulation and align my own evaluation pipeline with the training setup.

While reading the repo, I noticed that the sampling logic used in training (student visualization / rollout) appears different from the sampling logic in the provided inference script. Both work well in practice, but I’m not sure whether the difference is intentional (e.g., an equivalent re-parameterization) or just an implementation choice.

What I observed

1) Training sampler (student) — generate_samples_from_batch()

In T2VDistillModel_rCM.generate_samples_from_batch() the student sampling uses TrigFlow angle timesteps (call them tau):

  • timesteps (TrigFlow angle):
    t_steps = [atan(sigma_max)] + mid_t + [0]
  • at each step:
    • call self.denoise(x, t_cur, ..., net_type="student").x0 to get x0
    • update state using a TrigFlow-style “re-noising” step:
      x = cos(t_next) * x0 + sin(t_next) * randn()

Inside denoise(), the network time input is c_noise = sin(tau)/(cos(tau)+sin(tau)) * 1000 via RectifiedFlow_TrigFlowWrapper, and the input is scaled by c_in = 1/(cos+sin).

2) Inference script sampler — infer_*.py

In the inference script, the code starts from the same angle-like timesteps but then converts them to a RectifiedFlow-style time:

t_steps = [atan(sigma_max), *mid_t, 0]
t_steps = sin(t_steps) / (cos(t_steps) + sin(t_steps))   # RF time, call it s(tau)
x = init_noise * t_steps[0]

Then each step uses an RF update formula:

v_pred = net(x, timesteps=t_cur*1000)
x = (1 - t_next) * (x - t_cur * v_pred) + t_next * randn()

So inference:

  • advances in RF time s = sin(tau)/(cos+sin)
  • initializes x as noise * s0
  • does not apply the same (cos+sin)^{-1} input scaling that denoise() applies during training sampling
  • uses a different state update equation than the training TrigFlow-style cos/sin re-noising step

My question

Is this discrepancy intended / mathematically equivalent under a certain change of variables, or is inference using a different (but empirically good) heuristic sampler?

More specifically:

  1. Should “faithful” inference for the distilled student follow the same TrigFlow iteration as training (x -> x0 -> cos/sin re-noise)?
  2. If the RF sampler is intended, is there a recommended way to map the training formulation (with c_in/c_skip/c_out) into an RF-style sampler so the two match more closely?
  3. Is there a reason inference initializes with x = noise * t0 (RF boundary scaling) while training sampling initializes with x = noise?

Any clarification (and/or recommended sampler to use for reporting metrics) would be greatly appreciated. Thanks again for the excellent work!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions