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:
- Should “faithful” inference for the distilled student follow the same TrigFlow iteration as training (
x -> x0 -> cos/sin re-noise)?
- 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?
- 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!
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 themtau):self.denoise(x, t_cur, ..., net_type="student").x0to getx0Inside
denoise(), the network time input isc_noise = sin(tau)/(cos(tau)+sin(tau)) * 1000viaRectifiedFlow_TrigFlowWrapper, and the input is scaled byc_in = 1/(cos+sin).2) Inference script sampler —
infer_*.pyIn the inference script, the code starts from the same angle-like timesteps but then converts them to a RectifiedFlow-style time:
Then each step uses an RF update formula:
So inference:
s = sin(tau)/(cos+sin)xasnoise * s0(cos+sin)^{-1}input scaling thatdenoise()applies during training samplingcos/sinre-noising stepMy 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:
x -> x0 -> cos/sin re-noise)?c_in/c_skip/c_out) into an RF-style sampler so the two match more closely?x = noise * t0(RF boundary scaling) while training sampling initializes withx = noise?Any clarification (and/or recommended sampler to use for reporting metrics) would be greatly appreciated. Thanks again for the excellent work!