Files
2026-07-13 13:18:33 +08:00

93 lines
3.4 KiB
Python

# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import torch
import deepspeed
import pytest
from unit.common import DistributedTest
from deepspeed.utils.torch import required_torch_version
from deepspeed.moe.layer import MoE
class MPU():
def __init__(self, tp_world_size):
self.rank = deepspeed.comm.get_rank()
self.world_size = deepspeed.comm.get_world_size()
self.tp_world_size = tp_world_size
for i in range(0, self.world_size, tp_world_size):
ranks = range(i, i + tp_world_size)
group = deepspeed.comm.new_group(ranks)
if self.rank in ranks:
self.tp_group = group
for i in range(0, tp_world_size):
ranks = range(i, self.world_size, tp_world_size)
group = deepspeed.comm.new_group(ranks)
if self.rank in ranks:
self.dp_group = group
def get_model_parallel_rank(self):
return self.rank % self.tp_world_size
def get_model_parallel_world_size(self):
return self.tp_world_size
def get_data_parallel_rank(self):
return self.rank // self.tp_world_size
def get_data_parallel_world_size(self):
return self.world_size // self.tp_world_size
def get_data_parallel_group(self):
return self.dp_group
def get_model_parallel_group(self):
return self.tp_group
@pytest.mark.parametrize("ep_size, tp_size", [(1, 2), (1, 4), (2, 2)])
@pytest.mark.parametrize("enable_expert_tp", [True, False])
@pytest.mark.parametrize("use_residual", [True, False])
class TestMOETensorParallel(DistributedTest):
world_size = 4
def test(self, ep_size, tp_size, enable_expert_tp, use_residual):
# TODO: replace this with a true parallel mlp in the future
# and run convergence tests
if not required_torch_version(min_version=1.8):
pytest.skip("DeepSpeed MoE tests need torch 1.8 or higher to run correctly")
config_dict = {"train_batch_size": 8, "steps_per_print": 1, "fp16": {"enabled": True}}
hidden_dim = 16
tensor_parallel_expert = torch.nn.Sequential(torch.nn.Linear(hidden_dim, 4 * hidden_dim // tp_size),
torch.nn.ReLU(),
torch.nn.Linear(4 * hidden_dim // tp_size, hidden_dim))
# set num experts to world size
world_size = deepspeed.comm.get_world_size()
model = MoE(
hidden_size=hidden_dim,
expert=tensor_parallel_expert,
num_experts=world_size,
ep_size=ep_size,
use_residual=use_residual,
enable_expert_tensor_parallelism=enable_expert_tp,
)
optimizer = torch.optim.AdamW(params=model.parameters())
model, _, _, _ = deepspeed.initialize(config=config_dict,
model=model,
optimizer=optimizer,
dist_init_required=False,
mpu=MPU(tp_size))
assert model.num_local_experts == world_size // ep_size
if enable_expert_tp:
assert deepspeed.utils.groups._get_expert_model_parallel_world_size() == tp_size
else:
assert deepspeed.utils.groups._get_expert_model_parallel_world_size() == 1