[Bugfix] Align MiniMax-H3 inference steps with denoiser evaluations (#7219)

Signed-off-by: zhuhh97 <zhuhonghan@huawei.com>
Co-authored-by: Gao Han <hgaoaf@connect.ust.hk>
This commit is contained in:
Honghan ZhuandGao Han authored and GitHub committed 2026-09-24 03:56:38 +00:00
1 parent 6daf5b30f0
commit 67aa30c966
10 files changed
+90 -40

No files matched your search

@@ -781,17 +781,16 @@ class MiniMaxH3Pipeline(
def _validate_turbo_sampling(self, sampling: Any, spec: TurboSpec) -> None:
"""Hold a request to the contract of the artifact that is loaded.
Sigma-point count and both flow shifts vary across the Turbo family, so
Denoiser count and both flow shifts vary across the Turbo family, so
each is checked against the adapter's own spec rather than a single
published configuration.
"""
extra = sampling.extra_args or {}
sigma_points = sampling.num_inference_steps
if sigma_points != spec.sigma_points:
if sampling.num_inference_steps != spec.denoise_steps:
raise OmniClientError(
f"{spec.filename} is a {spec.denoise_steps}-step artifact and requires "
f"num_inference_steps={spec.sigma_points} "
f"num_inference_steps={spec.denoise_steps} "
f"({spec.sigma_points} sigma points produce {spec.denoise_steps} denoiser evaluations)"
)
try:
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
from __future__ import annotations
from collections.abc import Sequence
@@ -41,7 +42,7 @@ def _time_shift_sigmas(
shift_scale: float = 6.0,
base_schedule: Sequence[float] | None = None,
) -> list[float]:
"""Build a shifted sigma schedule.
"""Build N + 1 sigma boundaries for N denoiser evaluations.
``base_schedule`` supplies the rectified-flow positions explicitly and takes
precedence over ``num_steps``. Distilled checkpoints need it because their
@@ -59,21 +60,16 @@ def _time_shift_sigmas(
if num_steps <= 0:
raise ValueError("MiniMax H3 num_steps must be > 0")
# The rectified-flow sigma range is fixed at [1.0, 0.0].
# Requests count denoiser evaluations, not sigma points. Include both
# endpoints so even a one-step request traverses the full [1.0, 0.0] range.
base = torch.linspace(
1.0,
0.0,
int(num_steps),
int(num_steps) + 1,
device="cpu",
dtype=torch.float32,
)
shifted = float(shift_scale) * base / (1 + (float(shift_scale) - 1) * base)
shifted, _ = torch.unique_consecutive(shifted, return_counts=True)
# A one-point request is still exactly one point. Normal serving uses
# multiple points, but preserving the requested cardinality keeps
# ``num_inference_steps`` the sole schedule-size control.
if num_steps > 1 and shifted[-1].item() > 0.0:
shifted = torch.cat([shifted, torch.tensor([0.0], dtype=shifted.dtype)])
return [float(value) for value in shifted.tolist()]