1717import sys
1818
1919import pytest
20- import torch
20+
21+ try :
22+ import mindspeed .megatron_adaptor # noqa: F401 isort: skip # must precede mbridge on NPU
23+ except ImportError :
24+ pass
2125
2226from areal .api .alloc_mode import ModelAllocation
27+ from areal .infra .platforms import current_platform
2328from areal .utils .network import find_free_ports
2429from areal .utils .testing_utils import DENSE_MODEL_PATHS , MOE_MODEL_PATHS
2530
2934 / "run_megatron_engine_vlm_distributed.py"
3035).resolve ()
3136
32- CUDA_AVAILABLE = torch .cuda .is_available ()
37+ # Detect any accelerator (CUDA or NPU)
38+ ACCELERATOR_AVAILABLE = current_platform .device_type in ("cuda" , "npu" )
3339
3440
3541def _run_vlm_test (
@@ -122,7 +128,7 @@ def _run_vlm_test(
122128 {"VLM_MODEL_PATH" : MOE_MODEL_PATHS ["qwen3_vl_moe" ]},
123129 id = "qwen3_vl_moe" ,
124130 marks = pytest .mark .skipif (
125- torch . cuda .device_count () < 8 ,
131+ current_platform .device_count () < 8 ,
126132 reason = "Qwen3-VL-MoE-30B-A3B requires at least 8 GPUs" ,
127133 ),
128134 ),
@@ -131,7 +137,7 @@ def _run_vlm_test(
131137
132138@pytest .mark .gpu
133139@pytest .mark .slow
134- @pytest .mark .skipif (not CUDA_AVAILABLE , reason = "CUDA not available" )
140+ @pytest .mark .skipif (not ACCELERATOR_AVAILABLE , reason = "No accelerator available" )
135141@pytest .mark .parametrize ("model_env" , _VLM_MODELS )
136142def test_engine_initializes (model_env , tmp_path_factory ):
137143 """Verify VLM engine detects vision model and loads processor."""
@@ -141,7 +147,7 @@ def test_engine_initializes(model_env, tmp_path_factory):
141147
142148@pytest .mark .gpu
143149@pytest .mark .slow
144- @pytest .mark .skipif (not CUDA_AVAILABLE , reason = "CUDA not available" )
150+ @pytest .mark .skipif (not ACCELERATOR_AVAILABLE , reason = "No accelerator available" )
145151@pytest .mark .parametrize ("model_env" , _VLM_MODELS )
146152def test_simple_forward (model_env , tmp_path_factory ):
147153 """Verify forward pass with VLM inputs completes."""
@@ -151,7 +157,7 @@ def test_simple_forward(model_env, tmp_path_factory):
151157
152158@pytest .mark .gpu
153159@pytest .mark .slow
154- @pytest .mark .skipif (not CUDA_AVAILABLE , reason = "CUDA not available" )
160+ @pytest .mark .skipif (not ACCELERATOR_AVAILABLE , reason = "No accelerator available" )
155161@pytest .mark .parametrize ("model_env" , _VLM_MODELS )
156162def test_hf_save_load_weights (model_env , tmp_path_factory ):
157163 """Verify save/load preserves VLM weights and saves processor."""
@@ -168,11 +174,11 @@ def test_hf_save_load_weights(model_env, tmp_path_factory):
168174@pytest .mark .gpu
169175@pytest .mark .multi_gpu
170176@pytest .mark .slow
171- @pytest .mark .skipif (not CUDA_AVAILABLE , reason = "CUDA not available" )
177+ @pytest .mark .skipif (not ACCELERATOR_AVAILABLE , reason = "No accelerator available" )
172178@pytest .mark .parametrize ("model_env" , _VLM_MODELS )
173179def test_train_tensor_parallel (model_env , tmp_path_factory ):
174180 """VLM training with TP=2 to avoid single-device OOM."""
175- if torch . cuda .device_count () < 2 :
181+ if current_platform .device_count () < 2 :
176182 pytest .skip ("VLM TP training requires at least 2 GPUs" )
177183 output = str (tmp_path_factory .mktemp ("vlm_test" ) / "train_tp2.out" )
178184 _run_vlm_test (
@@ -191,7 +197,7 @@ def test_train_tensor_parallel(model_env, tmp_path_factory):
191197
192198@pytest .mark .multi_gpu
193199@pytest .mark .slow
194- @pytest .mark .skipif (not CUDA_AVAILABLE , reason = "CUDA not available" )
200+ @pytest .mark .skipif (not ACCELERATOR_AVAILABLE , reason = "No accelerator available" )
195201def test_qwen3vl_moe_expert_parallel (tmp_path_factory ):
196202 """Forward smoke test for Qwen3-VL-MoE under ``(attn:d2t4|ffn:d2e4)``.
197203
@@ -200,7 +206,7 @@ def test_qwen3vl_moe_expert_parallel(tmp_path_factory):
200206 ``InvalidAllocationModeError`` (attn=4 vs ffn=8). Validates the hybrid
201207 attn/ffn parser, EP-aware weight init, and VLM forward path.
202208 """
203- if torch . cuda .device_count () < 8 :
209+ if current_platform .device_count () < 8 :
204210 pytest .skip ("Qwen3-VL-MoE expert parallel requires 8 GPUs to run" )
205211 output = str (
206212 tmp_path_factory .mktemp ("test_output" ) / "qwen3vl_moe_expert_parallel.out"
@@ -215,15 +221,15 @@ def test_qwen3vl_moe_expert_parallel(tmp_path_factory):
215221
216222@pytest .mark .multi_gpu
217223@pytest .mark .slow
218- @pytest .mark .skipif (not CUDA_AVAILABLE , reason = "CUDA not available" )
224+ @pytest .mark .skipif (not ACCELERATOR_AVAILABLE , reason = "No accelerator available" )
219225def test_qwen3vl_moe_dcp_save_load (tmp_path_factory ):
220226 """DCP save/load round-trip for Qwen3-VL-MoE under ``(attn:d2p1t4|ffn:d1p1t2e4)``.
221227
222228 Allocation: attn DP=2 PP=1 TP=4 (8 GPUs); ffn DP=1 PP=1 TP=2 EP=4 (8 GPUs).
223229 Drops the ``cp=2`` segment from the dense Qwen3-MoE analog because VLM
224230 forbids CP>1 (megatron_engine.py:347).
225231 """
226- if torch . cuda .device_count () < 8 :
232+ if current_platform .device_count () < 8 :
227233 pytest .skip ("Qwen3-VL-MoE DCP save load requires 8 GPUs to run" )
228234 output = str (tmp_path_factory .mktemp ("test_output" ) / "qwen3vl_moe_save_load.out" )
229235 _run_vlm_test (
0 commit comments