sampling ¶
On-device (MLX) DMD sampling for the FastWan runtime.
The hybrid proof-of-concept ran the FastWan DiT in MLX but bounced every denoising step back through torch/NumPy to run the DMD scheduler math (MLX -> np.array -> torch (CPU) -> np.array -> MLX). That host round-trip forces a full device sync per step and defeats MLX's lazy graph execution.
This module mirrors the exact DMD arithmetic from fastvideo/models/utils.py::pred_noise_to_pred_video and FlowMatchEulerDiscreteScheduler.add_noise while keeping every large tensor on the MLX device. The schedule lookup (argmin over the ~1000-entry training schedule) is done once on the host in NumPy: it is tiny, it is the same value torch would compute, and it sidesteps the reduction-index quirk that affects argmin on the Metal/MPS backends (see the CPU fallbacks in fastvideo/models/utils.py and scheduling_flow_match_euler_discrete.py).
Because the DMD loop applies a single scalar timestep per step, sigma is a scalar and the update is a plain elementwise affine combination — no permute/flatten reshaping is required.
Classes¶
fastvideo.mlx_runtime.sampling.MLXDMDSchedule dataclass ¶
Host-side copy of a flow-match scheduler's (sigmas, timesteps).
Holds the full training schedule so a DMD timestep (e.g. one of 1000, 757, 522) can be mapped to its flow-match sigma with the same nearest-timestep lookup the torch path uses.
Methods:¶
fastvideo.mlx_runtime.sampling.MLXDMDSchedule.from_torch_scheduler classmethod ¶
from_torch_scheduler(scheduler: Any) -> MLXDMDSchedule
Snapshot scheduler.sigmas / scheduler.timesteps to NumPy.
Matches pred_noise_to_pred_video / add_noise, which index the scheduler's full training schedule (not the per-inference subset).
Source code in fastvideo/mlx_runtime/sampling.py
fastvideo.mlx_runtime.sampling.MLXDMDSchedule.sigma_for ¶
Find the sigma associated with the scheduled timestep nearest to the given timestep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timestep | float | Timestep for which to find the nearest scheduled sigma. | required |
Returns:
| Name | Type | Description |
|---|---|---|
float | float | Sigma associated with the nearest scheduled timestep. |
Source code in fastvideo/mlx_runtime/sampling.py
Functions:¶
fastvideo.mlx_runtime.sampling.add_noise ¶
add_noise(clean_latent: array, noise: array, sigma: float) -> array
Flow-match forward noising, mirroring the scheduler's add_noise.
sample = (1 - sigma) * clean_latent + sigma * noise.
Source code in fastvideo/mlx_runtime/sampling.py
fastvideo.mlx_runtime.sampling.dmd_step ¶
dmd_step(*, latents: array, noise_input_latent: array, pred_noise: array, schedule: MLXDMDSchedule, timestep: float, next_timestep: float | None, noise: array | None = None) -> array
Compute one DMD sampling update, optionally re-noising the clean latent prediction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
latents | array | Retained for call-site compatibility and not used in the update. | required |
noise_input_latent | array | Noisy latent used to compute the clean prediction. | required |
pred_noise | array | Predicted noise or velocity. | required |
schedule | MLXDMDSchedule | Flow-matching schedule used to map timesteps to sigmas. | required |
timestep | float | Current sampling timestep. | required |
next_timestep | float | None | Timestep for the next update, or | required |
noise | array | None | Fresh noise used for re-noising intermediate steps. | None |
Returns:
| Type | Description |
|---|---|
array | The re-noised latent for the next step or the clean latent prediction on |
array | the final step. |
Raises:
| Type | Description |
|---|---|
ValueError | If |
Source code in fastvideo/mlx_runtime/sampling.py
fastvideo.mlx_runtime.sampling.pred_noise_to_pred_video ¶
pred_noise_to_pred_video(pred_noise: array, noise_input_latent: array, sigma: float) -> array
Compute the clean latent prediction from a flow-matching noise prediction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pred_noise | array | Predicted noise. | required |
noise_input_latent | array | Noised latent input. | required |
sigma | float | Noise level used for the prediction. | required |
Returns:
| Type | Description |
|---|---|
array | mx.array: Predicted clean latent. |