Skip to content

Commit e1cf5ab

Browse files
[bugfix]: pin the CPU platform in the FP8 tests and stop writing MASTER_PORT
Fixes three problems in the tests added by the previous commit. The block-wiring fixture swapped in a hand-written platform stub that defined only is_mps and get_attn_backend_cls. Constructing the block reaches set_weight_attrs, which calls current_platform.is_tpu on every linear, so the test raised AttributeError inside the attention to_q before the feed-forward was built and before either FP8 assertion ran. It now pins the real CpuPlatform, which answers the whole current Platform interface rather than the two methods that happened to be needed. The two-rank test wrote MASTER_ADDR and MASTER_PORT into the environment. test_gpu_tests_preserve_a_launcher_assigned_rendezvous_port scans every file under fastvideo/tests and fails on a written MASTER_PORT, because that clobbers the port the CI runner leased to the lane. The rendezvous now goes through init_method, and the os import is gone with it. The loader guard test passed device=cpu, which does not change the global platform. maybe_load_fsdp_model turns FSDP off on MPS, so on a Mac the guard sat inside a branch that never ran and the test failed later for an unrelated reason. It pins CpuPlatform too, so every host takes the same path.
1 parent 62d986d commit e1cf5ab

2 files changed

Lines changed: 28 additions & 30 deletions

File tree

fastvideo/tests/ops/quantization/test_fp8_ffn_suffix_wiring.py

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
1212
These are CPU-only contracts. Attaching ``quant_method`` needs neither a GPU
1313
nor real weights. The one test that builds a real H3 block takes
14-
``cpu_attention_platform``, because constructing the block resolves an
15-
attention backend and that is the only GPU-shaped dependency in this file.
14+
``cpu_attention_platform``, which pins the CPU platform so the block resolves
15+
the same attention backend on every host.
1616
"""
1717
from __future__ import annotations
1818

@@ -62,33 +62,21 @@ def test_minimax_h3_feed_forward_linears_get_fp8_method() -> None:
6262

6363
@pytest.fixture
6464
def cpu_attention_platform(monkeypatch):
65-
"""Resolve attention to SDPA so an H3 block can be built without a GPU.
66-
67-
``MiniMaxH3Attention.__init__`` and ``DistributedAttention.__init__`` both
68-
call ``get_attn_backend``, which asks the platform for a backend qualname
69-
and raises ``Invalid attention backend for ...`` on an empty string
70-
(``selector.py``). A CPU-only host has no platform that answers, so the
71-
block raises during construction and the FP8 assertions below never run.
72-
73-
Only the name is resolved here. ``SDPAImpl.__init__`` stores scalars and
74-
touches no device, and nothing in this test runs attention.
65+
"""Build the H3 block against the real CPU platform, on any host.
66+
67+
Constructing the block reaches ``set_weight_attrs``, which calls
68+
``current_platform.is_tpu()``, and then ``get_attn_backend``, which asks the
69+
platform for a backend qualname. Pinning ``CpuPlatform`` rather than a stub
70+
means no future platform call can be missed, and the test takes the same
71+
path on a CUDA host, a Mac and a CPU-only runner. ``CpuPlatform`` answers
72+
``TORCH_SDPA``; ``SDPAImpl.__init__`` stores scalars and touches no device,
73+
and nothing here runs attention.
7574
"""
7675
from fastvideo import platforms
7776
from fastvideo.attention import selector
77+
from fastvideo.platforms.cpu import CpuPlatform
7878

79-
class _SDPAOnlyPlatform:
80-
device_name = "cpu-test"
81-
82-
@classmethod
83-
def is_mps(cls) -> bool:
84-
return False
85-
86-
@classmethod
87-
def get_attn_backend_cls(cls, selected_backend, head_size, dtype) -> str:
88-
del selected_backend, head_size, dtype
89-
return "fastvideo.attention.backends.sdpa.SDPABackend"
90-
91-
monkeypatch.setattr(platforms, "_current_platform", _SDPAOnlyPlatform())
79+
monkeypatch.setattr(platforms, "_current_platform", CpuPlatform())
9280
# The resolution is memoized on inputs that do not include the platform,
9381
# so a real entry from another test would survive the swap.
9482
selector._cached_get_attn_backend.cache_clear()

fastvideo/tests/ops/quantization/test_fp8_fsdp_shard_guard.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from __future__ import annotations
1616

1717
import contextlib
18-
import os
1918
import socket
2019

2120
import pytest
@@ -75,14 +74,23 @@ def test_helper_reports_only_layers_the_converter_would_touch() -> None:
7574
assert _has_fp8_convertible_layers(plain) is False
7675

7776

78-
def test_loader_refuses_fp8_when_the_shard_dim_is_greater_than_one() -> None:
77+
def test_loader_refuses_fp8_when_the_shard_dim_is_greater_than_one(monkeypatch) -> None:
7978
"""The guard must fire before the loader builds a device mesh.
8079
8180
``maybe_load_fsdp_model`` hard-codes a CUDA mesh for every non-NPU
8281
platform, so a guard placed after mesh creation could not be reached on a
8382
CPU host at all, and on a GPU host would fire only after sharding had
8483
already started.
84+
85+
The platform is pinned because the loader turns FSDP off entirely on MPS.
86+
Left alone, this would skip the guard on a Mac and fail later for an
87+
unrelated reason, so the test would only really run on Linux.
8588
"""
89+
from fastvideo import platforms
90+
from fastvideo.platforms.cpu import CpuPlatform
91+
92+
monkeypatch.setattr(platforms, "_current_platform", CpuPlatform())
93+
8694
with pytest.raises(NotImplementedError) as excinfo:
8795
maybe_load_fsdp_model(
8896
model_cls=_FP8Linear,
@@ -105,9 +113,11 @@ def test_loader_refuses_fp8_when_the_shard_dim_is_greater_than_one() -> None:
105113
def _sharded_conversion_worker(rank: int, world_size: int, port: int) -> None:
106114
from torch.distributed.tensor import Shard, distribute_tensor, init_device_mesh
107115

108-
os.environ["MASTER_ADDR"] = "127.0.0.1"
109-
os.environ["MASTER_PORT"] = str(port)
110-
dist.init_process_group("gloo", rank=rank, world_size=world_size)
116+
# The rendezvous goes through init_method, not the environment.
117+
# ``test_gpu_tests_preserve_a_launcher_assigned_rendezvous_port`` scans
118+
# every file under fastvideo/tests and fails on a written MASTER_PORT,
119+
# because that would clobber the port the CI runner leased to the lane.
120+
dist.init_process_group("gloo", init_method=f"tcp://127.0.0.1:{port}", rank=rank, world_size=world_size)
111121
try:
112122
mesh = init_device_mesh("cpu", (world_size, ))
113123
model = _FP8Linear()

0 commit comments

Comments
 (0)