UniPCMultistepScheduler fails in torch.linalg.solve under a float64 default dtype: the unit entry of rks takes the default dtype
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- machine-learning, testing-qa
Research direction
Start in src/diffusers/schedulers/scheduling_unipc_multistep.py at the rks construction in multistep_uni_p_bh_update and multistep_uni_c_bh_update, then read tests/schedulers/test_scheduler_unipc.py and run the default-dtype coverage. Done means the scheduler runs with torch.float64 as the default dtype without a linalg.solve dtype error, while existing behavior and tests remain unchanged.
Written by the indexing model from the issue text.
Description
Describe the bug
multistep_uni_p_bh_update and multistep_uni_c_bh_update build rks from the sigmas, which are float32, and append torch.ones((), device=device), which takes the default dtype. Under torch.set_default_dtype(torch.float64) the torch.stack(rks) promotes R to float64 while b stays float32, and the first torch.linalg.solve(R, b) (the order-2 corrector on the second step with the default config) raises
RuntimeError: linalg.solve: Expected A and B to have the same dtype, but found A of type Double and B of type Float instead
whatever the dtype of the sample (float16, float32 and float64 all fail). DPMSolverMultistepScheduler, DEISMultistepScheduler and SASolverScheduler run under a float64 default dtype.
Fix, patch below: torch.ones_like(h) in both places, so the unit entry has the dtype and device of the other rks entries. Under the float32 default this is the same tensor as before: 540 configurations (solver_order 1 to 3, bh1/bh2, the three prediction_types, Karras sigmas or not, predict_x0, thresholding, 1/2/3/10/25 steps) are bit-identical to main. test_default_dtype_float64 fails on main with the error above and passes with the patch, the file's 64 tests pass, ruff is clean. I can open the PR if this looks right to you.
Reproduction
import torch
from diffusers import UniPCMultistepScheduler
torch.set_default_dtype(torch.float64)
scheduler = UniPCMultistepScheduler()
scheduler.set_timesteps(10)
sample = torch.rand(1, 3, 8, 8, generator=torch.Generator().manual_seed(0), dtype=torch.float32)
for t in scheduler.timesteps:
sample = scheduler.step(sample * t / (t + 1), t, sample).prev_sample
print(sample.dtype, sample.abs().mean())
Logs
Traceback (most recent call last):
File "repro.py", line 11, in <module>
sample = scheduler.step(sample * t / (t + 1), t, sample).prev_sample
File ".../diffusers/schedulers/scheduling_unipc_multistep.py", line 1191, in step
sample = self.multistep_uni_c_bh_update(
File ".../diffusers/schedulers/scheduling_unipc_multistep.py", line 1078, in multistep_uni_c_bh_update
rhos_c = torch.linalg.solve(R, b).to(device).to(x.dtype)
RuntimeError: linalg.solve: Expected A and B to have the same dtype, but found A of type Double and B of type Float instead
With the patch: torch.float32 tensor(0.2337, dtype=torch.float32), the same value as under the float32 default dtype.
System Info
- diffusers 0.40.0 (PyPI) and main at e0abab8
- torch 2.14.0+cpu, numpy 2.2.6
- Python 3.13, Linux
AI disclosure: I used an AI coding agent to help find this, to write the reproduction, the patch, the test and this report. I have read and checked the report, the patch and the test myself and I will answer questions personally.
Patch
git diff against main (2 files, +15 -2)
diff --git a/src/diffusers/schedulers/scheduling_unipc_multistep.py b/src/diffusers/schedulers/scheduling_unipc_multistep.py
index 5c2cbcc..e8f5af1 100644
--- a/src/diffusers/schedulers/scheduling_unipc_multistep.py
+++ b/src/diffusers/schedulers/scheduling_unipc_multistep.py
@@ -903,7 +903,7 @@ class UniPCMultistepScheduler(SchedulerMixin, ConfigMixin):
rks.append(rk)
D1s.append((mi - m0) / rk)
- rks.append(torch.ones((), device=device))
+ rks.append(torch.ones_like(h))
rks = torch.stack(rks)
R = []
@@ -1038,7 +1038,7 @@ class UniPCMultistepScheduler(SchedulerMixin, ConfigMixin):
rks.append(rk)
D1s.append((mi - m0) / rk)
- rks.append(torch.ones((), device=device))
+ rks.append(torch.ones_like(h))
rks = torch.stack(rks)
R = []
diff --git a/tests/schedulers/test_scheduler_unipc.py b/tests/schedulers/test_scheduler_unipc.py
index ac7e1d3..92ff4e7 100644
--- a/tests/schedulers/test_scheduler_unipc.py
+++ b/tests/schedulers/test_scheduler_unipc.py
@@ -257,6 +257,19 @@ class UniPCMultistepSchedulerTest(SchedulerCommonTest):
assert sample.dtype == torch.float16
+ def test_default_dtype_float64(self):
+ # the unit entry of `rks` took the default dtype, the other entries the dtype of the sigmas
+ default_dtype = torch.get_default_dtype()
+ torch.set_default_dtype(torch.float64)
+ try:
+ sample = self.full_loop(solver_order=3)
+ finally:
+ torch.set_default_dtype(default_dtype)
+ result_mean = torch.mean(torch.abs(sample))
+
+ assert sample.dtype == torch.float64
+ assert abs(result_mean.item() - torch.mean(torch.abs(self.full_loop(solver_order=3))).item()) < 1e-3
+
def test_full_loop_with_noise(self):
scheduler_class = self.scheduler_classes[0]
scheduler_config = self.get_scheduler_config()
- Dominant language
- Python
- Stars
- 34.6k
- Forks
- 7.4k
- Avg merge
- 4d 8h
- Merged PRs (30d)
- 50
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from huggingface/diffusers
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
huggingface/diffusers#14881 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
huggingface/diffusers#14864 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
huggingface/diffusers#14837 ·
Maintainers usually reply within 1 day
-
bug needs-env-info pipelines
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
huggingface/diffusers#14794 ·
Maintainers usually reply within 1 day
-
bug needs-code-example needs-env-info pipelines
Difficulty 1/5 Under an hour Newbie friendliness 86/100
huggingface/diffusers#14780 · 1 comment ·
Maintainers usually reply within 1 day
All issues in huggingface/diffusers
Similar issues
-
[Bug] @deck.gl/arcgis dist import resolves to unpublished @deck.gl/core source path (9.3.11, 9.4.0)Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
workflow: a tick's dispatch counts as 'only this step', and no review self-grants a round unattendedOpenworkflow
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
kristofdegrave/homeassistant-smart-charging#1505 ·
Maintainers usually reply within 1 day
-
metadata submission
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
canonical/content-cache-operator#163 · 1 comment ·
Maintainers usually reply within 1 day
-
[submission]Opensubmission
Difficulty 1/5 Under an hour Newbie friendliness 65/100
leanprover/lean-eval-submissions#1852 ·
Maintainers usually reply within 1 day