Skip to content

Commit f83928c

Browse files
committed
[JAX] CI fixes: dynamic FSDP_SIZE + accept exit 5 for pre-Blackwell skip
Two failures from the same PR run: * CI B200 (8 GPUs) -- the test hard-coded EP_SIZE=2, FSDP_SIZE=2 -> 4-device mesh, while jax.device_count()==8. mesh_utils.create_device_mesh rejected with 'Number of devices 8 must equal the product of mesh_shape (2, 2)'. FSDP_SIZE now derives from jax.device_count() // EP_SIZE, so the test scales to whatever the launcher gives us (4 GPUs -> FSDP=2, 8 GPUs -> FSDP=4). BATCH formula already depends on EP_SIZE*FSDP_SIZE so it scales automatically and stays MXFP8-aligned. * CI H100 (4 GPUs) -- the file emits pytest.skip(allow_module_level=True) when get_device_compute_capability(0) < 100 (Blackwell-only). pytest reports 'no tests collected' with exit code 5, which the multiprocess launcher was treating as a failure. Accept 5 alongside 0; anything else is still a failure. Signed-off-by: tdophung <tdophung@nvidia.com>
1 parent 2313ff3 commit f83928c

2 files changed

Lines changed: 13 additions & 5 deletions

File tree

tests/jax/run_multiprocess_moe_vjp.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,12 @@ done
105105
# Final pass/fail. Any non-zero in any process fails the suite, but
106106
# we tolerate non-zero on the non-zero processes only if proc 0
107107
# reports PASS (this matches the encoder launcher's logic). Simplest
108-
# strict rule: any non-zero is a failure.
108+
# Treat exit 0 (pass) and exit 5 (pytest "no tests collected", which
109+
# the file emits via ``pytest.skip(allow_module_level=True)`` on
110+
# pre-Blackwell GPUs) as success. Anything else is a failure.
109111
FAILED=0
110112
for e in "${EXITS[@]}"; do
111-
if [ "$e" != "0" ]; then
113+
if [ "$e" != "0" ] && [ "$e" != "5" ]; then
112114
FAILED=1
113115
break
114116
fi

tests/jax/test_multiprocess_moe_vjp.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,17 @@ def _read_mp_options():
129129
]
130130

131131

132-
NUM_DEVICES_REQUIRED = 4
133132
EP_AXIS = "ep"
134133
FSDP_AXIS = "fsdp"
135134
EP_SIZE = 2
136-
FSDP_SIZE = 2
135+
# FSDP_SIZE adapts to whatever the launcher gave us: dlcluster GB200
136+
# gives 4 GPUs (FSDP=2), CI B200 gives 8 GPUs (FSDP=4). Both stay
137+
# 128-aligned for MXFP8 and divide num_experts/topk cleanly.
138+
assert (
139+
jax.device_count() % EP_SIZE == 0
140+
), f"device_count {jax.device_count()} must be divisible by EP_SIZE={EP_SIZE}"
141+
FSDP_SIZE = jax.device_count() // EP_SIZE
142+
NUM_DEVICES_REQUIRED = EP_SIZE * FSDP_SIZE
137143

138144
LOGICAL_AXIS_RULES = (
139145
("exp", EP_AXIS),
@@ -280,7 +286,7 @@ def _local_shard(x):
280286
# 4-way data-parallel shard of a Mixtral-8 block).
281287
# -----------------------------------------------------------------------------
282288

283-
BATCH = EP_SIZE * FSDP_SIZE * 4 # 16
289+
BATCH = EP_SIZE * FSDP_SIZE * 4 # 16 on 4-GPU, 32 on 8-GPU
284290
SEQ = 2048
285291
HIDDEN = 1024
286292
INTER = 4096

0 commit comments

Comments
 (0)