fix: RoFormer on DirectML — CPU state-dict load + complex-op CPU hops (#292) (#295)
* fix: load Roformer state dicts on CPU for DirectML devices (#292)
torch-directml's torch.load deserialization hook expects integer device
ids and raises TypeError ("'>=' not supported between instances of
'torch.device' and 'int'") when map_location targets a privateuseone
device. This made the new Roformer implementation fail on every DirectML
load and silently fall back to the legacy path (whose CPU map_location
got further, then died on ComplexFloat at inference — separate fix).
Load the state dict on CPU and move the model to the device afterwards,
gated on DML so cuda/mps/cpu keep byte-identical behavior.
Part 3 of the RoFormer-on-Windows plan (see #294 for the plan doc).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: route Roformer complex ops to CPU on DirectML devices (#292)
torch-directml has no complex tensor support — torch.stft with
return_complex, view_as_complex, complex multiplies and torch.istft all
fail with 'Invalid or unsupported data type ComplexFloat'. Hop exactly
those ops to CPU when the input lives on a privateuseone device, keeping
the transformer stack (the heavy compute) on the DML device. This is the
same pattern the MDX arch already uses in uvr_lib_v5/stft.py (which is
why MDX works on DirectML today) and mirrors the existing MPS istft hop.
All hops are gated on _is_dml_device(); cuda/mps/cpu behavior is
unchanged — the MPS branches are untouched. The helper is module-level
so tests can force the DML branches on CPU tensors: new equivalence
tests assert the hopped path produces identical output to the normal
path for both BSRoformer and MelBandRoformer.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com> A
Andrew Beveridge ☄️ committed
675e5ff5644488c9f6a6680c4a0e389fa57b73e2
Parent: 20f9021
Committed by GitHub <noreply@github.com>
on 7/20/2026, 6:08:59 PM