From b9dd863a2cee96cabac475dc3cd6d41516a0005c Mon Sep 17 00:00:00 2001 From: Sammy Tourani Date: Mon, 14 Sep 2026 02:29:14 -0400 Subject: [PATCH] downcast MiniMax-H3 position_ids at the device transfer on fp64-less backends Both layout steps build position_ids in float64 on CPU and then move it to the execution device with a plain .to(device), which raises on MPS. Pass the dtype through maybe_adjust_dtype_for_device so the transfer lands as float32 on mps/npu/neuron and is unchanged everywhere else. The fp64 construction is untouched, and MiniMaxH3RotaryPosEmbed.forward already casts position_ids to float32, so no device sees different rotary angles. --- .../modular_pipelines/minimax_h3/before_denoise.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/diffusers/modular_pipelines/minimax_h3/before_denoise.py b/src/diffusers/modular_pipelines/minimax_h3/before_denoise.py index c670467a9307..247b9e88d761 100644 --- a/src/diffusers/modular_pipelines/minimax_h3/before_denoise.py +++ b/src/diffusers/modular_pipelines/minimax_h3/before_denoise.py @@ -17,7 +17,7 @@ from ...schedulers import MiniMaxH3Scheduler from ...utils import logging -from ...utils.torch_utils import randn_tensor +from ...utils.torch_utils import maybe_adjust_dtype_for_device, randn_tensor from ..modular_pipeline import ModularPipelineBlocks, PipelineState from ..modular_pipeline_utils import ComponentSpec, ConfigSpec, InputParam, OutputParam from .modular_pipeline import ( @@ -441,7 +441,10 @@ def __call__(self, components: MiniMaxH3ModularPipeline, state: PipelineState) - components.video_tag, block_state.keyframe_anchors, ) - block_state.position_ids = position_ids.to(device) + # The grid is built in fp64 to reproduce the released coordinates exactly, but MPS, NPU and Neuron have no + # fp64; the transformer's rope casts to fp32 anyway, so downcasting here is all the transfer needs. + position_ids_dtype = maybe_adjust_dtype_for_device(position_ids.dtype, device) + block_state.position_ids = position_ids.to(device, position_ids_dtype) block_state.token_tags = token_tags.to(device) block_state.video_indices = video_indices.to(device) block_state.audio_indices = audio_indices.to(device) @@ -765,7 +768,10 @@ def __call__(self, components: MiniMaxH3ModularPipeline, state: PipelineState) - components.audio_tag, components.video_tag, ) - block_state.position_ids = position_ids.to(device) + # The grid is built in fp64 to reproduce the released coordinates exactly, but MPS, NPU and Neuron have no + # fp64; the transformer's rope casts to fp32 anyway, so downcasting here is all the transfer needs. + position_ids_dtype = maybe_adjust_dtype_for_device(position_ids.dtype, device) + block_state.position_ids = position_ids.to(device, position_ids_dtype) block_state.token_tags = token_tags.to(device) block_state.video_indices = video_indices.to(device) block_state.audio_indices = audio_indices.to(device)