From 7c398ccdfd31f70ea640f3c6fe147bc6af8050bc Mon Sep 17 00:00:00 2001 From: Alpamys Date: Tue, 28 Jul 2026 15:32:56 +0500 Subject: [PATCH] test(stream): skip the two NF4 training-step tests when MPS is the accelerator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI was red on macOS only (3/11 jobs); ubuntu and windows were green across 3.10/3.11/3.12, as were lint and type-check. Cause is not bitsandbytes availability but device disagreement: on an Apple-Silicon runner with no CUDA, TrainingArguments picks `mps`, while this suite builds the streamed model on `cpu`. The batch is then moved to MPS and the step raises "Placeholder storage has not been allocated on MPS device!". Only the two tests that actually call trainer.train() were affected; test_setup_builds_a_real_trl_trainer_under_nf4 passed, because building the trainer never touches a device. v0.72.0 hit exactly this and guards test_one_training_step_actually_runs the same way; this mirrors that helper rather than inventing a second one. NF4 streaming is measured on CUDA and CPU only, and bitsandbytes' 4-bit kernels have no MPS support, so skipping is the honest outcome — not a claim that it works there. Verified on the CUDA dev box: 88 passed, zero skipped, i.e. the guard does not over-skip where the tests are meaningful. --- tests/test_v07202.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/test_v07202.py b/tests/test_v07202.py index 982547e..63fdd1a 100644 --- a/tests/test_v07202.py +++ b/tests/test_v07202.py @@ -40,6 +40,34 @@ def _cuda() -> bool: requires_cuda = pytest.mark.skipif(not _cuda(), reason="needs a CUDA device") +def _mps_is_the_accelerator() -> bool: + """True on an Apple-Silicon runner with no CUDA. + + ``TrainingArguments`` picks ``mps`` as its device there, while this suite + builds the streamed model on ``cpu``; a real training step then moves the + batch to MPS and hits "Placeholder storage has not been allocated on MPS + device". NF4 streaming is measured on CUDA and CPU only — bitsandbytes' + 4-bit kernels are not supported on MPS at all — so the step is skipped + rather than making an unverified claim about it. Mirrors the identical + guard in tests/test_v07200.py. + """ + try: + import torch + + if torch.cuda.is_available(): + return False + backend = getattr(torch.backends, "mps", None) + return bool(backend is not None and backend.is_available()) + except Exception: + return False + + +skip_on_mps = pytest.mark.skipif( + _mps_is_the_accelerator(), + reason="MPS is untested for NF4 streaming (measured on CUDA + CPU only)", +) + + # ========================================================================== # fixtures # ========================================================================== @@ -1628,6 +1656,7 @@ class TestNF4EndToEndSetup: assert wrapper.trainer is not None assert wrapper.model.is_loaded_in_4bit is True + @skip_on_mps def test_one_nf4_training_step_actually_runs(self, tmp_path, monkeypatch): wrapper, dataset = self._wrapper(tmp_path, monkeypatch) wrapper.setup(dataset) @@ -1635,6 +1664,7 @@ class TestNF4EndToEndSetup: wrapper.trainer.train() assert wrapper._stream_runtime.pool.loads > 0, "no layer was ever streamed" + @skip_on_mps def test_the_saved_adapter_is_canonical(self, tmp_path, monkeypatch): """v0.72.1's fix has to survive NF4 all the way through TRL's save.""" from safetensors.torch import load_file