acdir-llada-math500 / lmdeploy /tests /pytorch /nn /test_embedding.py
NYCU-MLLab's picture
Upload folder using huggingface_hub
4a28d4d verified
Raw
History Blame Contribute Delete
4.18 kB
import os
import time
import pytest
import torch
import torch.distributed as dist
import torch.multiprocessing as mp
from torch import nn
from lmdeploy.pytorch.distributed import DefaultContext
from lmdeploy.pytorch.nn import ParallelEmbedding
def parallel_emb(rank: int, world_size: int, vocab_size: int, feat_size: int, padding_idx: int, dtype: torch.dtype,
x: torch.Tensor, weight: torch.Tensor, result_queue: mp.Queue):
dist.init_process_group('nccl', rank=rank, world_size=world_size)
gpu_group = dist.new_group(ranks=list(range(world_size)), backend='nccl')
DefaultContext.attn_tp_group.rank = rank
DefaultContext.dist_config.attn_tp = world_size
DefaultContext.attn_tp_group.gpu_group = gpu_group
model = ParallelEmbedding(vocab_size=vocab_size,
hidden_size=feat_size,
padding_idx=padding_idx,
dtype=dtype,
is_tp=True,
device=torch.device(type='cuda', index=rank))
weight = weight.to(torch.device(type='cuda', index=rank))
model.weight_loader(model.weight, weight)
input = x.to(torch.device(type='cuda', index=rank))
with torch.inference_mode():
out = model(input)
if rank == 0:
result_queue.put(mp.reductions.reduce_tensor(out))
if dist.is_initialized():
dist.destroy_process_group()
class TestEmbedding:
@pytest.fixture
def vocab_size(self, request):
yield request.param
@pytest.fixture
def feat_size(self, request):
yield request.param
@pytest.fixture
def padding_idx(self, request):
yield request.param
@pytest.fixture
def dtype(self, request):
yield request.param
@pytest.fixture
def tp(self, request):
yield request.param
@pytest.fixture
def seqlen(self, request):
yield request.param
@pytest.fixture
def weight(self, vocab_size, feat_size, dtype):
yield torch.rand(vocab_size, feat_size, dtype=dtype)
@pytest.fixture
def x(self, seqlen, vocab_size):
yield torch.randint(low=0, high=vocab_size, size=(seqlen, ), dtype=torch.int32)
@pytest.fixture
def gt(self, x, vocab_size, feat_size, padding_idx, dtype, weight):
token_emb = nn.Embedding(vocab_size,
feat_size,
padding_idx=padding_idx,
dtype=dtype,
device=torch.device(type='cuda', index=0))
token_emb.weight.data.copy_(weight)
token_emb._fill_padding_idx_with_zero()
input = x.to(torch.device(type='cuda', index=0))
yield token_emb(input)
@pytest.mark.parametrize('vocab_size', [65576, 65533, 3333], indirect=True)
@pytest.mark.parametrize('feat_size', [4096, 768], indirect=True)
@pytest.mark.parametrize('padding_idx', [None], indirect=True)
@pytest.mark.parametrize('seqlen', [1024, 1011, 128], indirect=True)
@pytest.mark.parametrize('tp', [2], indirect=True)
@pytest.mark.parametrize('dtype', [torch.bfloat16], indirect=True)
def test_embedding(self, vocab_size, feat_size, padding_idx, seqlen, tp, dtype, x, weight, gt):
os.environ['MASTER_ADDR'] = 'localhost'
os.environ['MASTER_PORT'] = '29500'
os.environ['NCCL_SOCKET_IFNAME'] = 'lo'
world_size = tp
processes = []
mp.set_start_method('spawn', force=True)
result_queue = mp.Queue()
for rank in range(world_size):
p = mp.Process(target=parallel_emb,
args=(rank, world_size, vocab_size, feat_size, padding_idx, dtype, x, weight, result_queue))
processes.append(p)
p.start()
time.sleep(0.5)
func, args = result_queue.get()
out = func(*args)
for p in processes:
p.join(timeout=10)
if p.is_alive():
p.terminate()
p.join(timeout=5)
if p.is_alive():
p.kill()
torch.testing.assert_close(out, gt)