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

89 lines
3.0 KiB
Python

# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
from typing import Optional, Tuple
import pytest
import torch
from deepspeed.accelerator import get_accelerator
from deepspeed.inference.v2.modules import ConfigBundle
from deepspeed.inference.v2.modules.configs import DSNormConfig
from deepspeed.inference.v2.modules.interfaces import DSPreNormRegistry
from ...v2.inference_test_utils import get_dtypes, allclose
def reference_implementation(residual: torch.Tensor, hidden_states: Optional[torch.Tensor], gamma: torch.Tensor,
epsilon: float) -> Tuple[torch.Tensor, torch.Tensor]:
dtype = residual.dtype
if hidden_states is not None:
hidden_states = hidden_states
residual = residual + hidden_states
rms_vals = residual.to(torch.float32)
variance = rms_vals.pow(2).mean(-1, keepdim=True)
rms_vals = rms_vals * torch.rsqrt(variance + epsilon)
if gamma.dtype in [torch.float16, torch.bfloat16]:
rms_vals = rms_vals.to(gamma.dtype)
hidden_states = gamma * rms_vals
return residual.to(dtype), hidden_states.to(dtype)
def _pre_rms_test_helper(n_tokens: int, n_channels: int, dtype: torch.dtype, res_add: bool = False):
config = DSNormConfig(max_tokens=2048,
type="rms_norm",
channels=n_channels,
residual_dtype=dtype,
input_dtype=dtype,
output_dtype=dtype,
eps=1e-5)
bundle = ConfigBundle(name='cuda_pre_rms', config=config)
# Input vals
if res_add:
hidden_states = torch.randn((n_tokens, n_channels),
dtype=dtype,
device=get_accelerator().current_device_name())
else:
hidden_states = None
residual = torch.randn((n_tokens, n_channels), dtype=dtype, device=get_accelerator().current_device_name())
gamma = torch.randn((n_channels), dtype=torch.float32, device=get_accelerator().current_device_name())
epsilon = 1e-5
# Reference output
ref_residual, ref_output = reference_implementation(residual, hidden_states, gamma, epsilon)
# New output
pre_ln_module = DSPreNormRegistry.instantiate_config(bundle)
gamma = pre_ln_module.transform_param(gamma)
ds_residual, ds_output = pre_ln_module(residual, hidden_states, gamma)
# Check
assert allclose(ds_residual, ref_residual)
assert allclose(ds_output, ref_output)
@pytest.mark.inference_v2_ops
@pytest.mark.parametrize("tokens, channels", [(1, 2048), (37, 8192), (1280, 768), (2048, 5120)])
def test_token_channels(tokens: int, channels: int) -> None:
_pre_rms_test_helper(tokens, channels, torch.float16)
@pytest.mark.inference_v2_ops
@pytest.mark.parametrize("dtype", get_dtypes(include_float=False))
def test_dtype(dtype: torch.dtype) -> None:
_pre_rms_test_helper(733, 2560, dtype)
@pytest.mark.inference_v2_ops
def test_no_res_add():
_pre_rms_test_helper(733, 2560, torch.float16, res_add=False)