chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:18:33 +08:00
commit 4ececc111a
2017 changed files with 331736 additions and 0 deletions
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
@@ -0,0 +1,120 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
from typing import List
import pytest
import torch
from deepspeed.accelerator import get_accelerator
from deepspeed.inference.v2.model_implementations.flat_model_helpers import (
flatten_inference_model,
restore_inference_model,
)
from deepspeed.inference.v2.model_implementations.layer_container_base import LayerContainer
from .utils import SimpleParam, DummyInferenceModel
class TransformerLayerContainer(LayerContainer):
"""
Stub layer container
"""
PARAM_MAPPING = {
"param_1": "param_1.param",
"param_2": "param_2.param",
}
param_1: SimpleParam
param_2: SimpleParam
class NonTransformerContainer(LayerContainer):
"""
Stub layer container
"""
PARAM_MAPPING = {
"param_1": "param_1.param",
"param_2": "param_2.param",
"param_3": "param_3.param",
}
param_1: SimpleParam
param_2: SimpleParam
param_3: SimpleParam
@pytest.mark.inference_v2
def test_contiguify_roundtrip():
"""
Validate that contiguify round trips and reconstructions are correct.
"""
model = DummyInferenceModel()
n_layers = 2
transformer_params = []
transformer_containers = []
# Create parameters and populate them into the containers
for i in range(n_layers):
transformer_containers.append(TransformerLayerContainer(model))
layer_params = []
for j in range(2):
layer_params.append(torch.rand(16, 16))
transformer_containers[i].set_dependency(f"param_{j+1}", layer_params[j])
layer_params = [p.to(get_accelerator().current_device()) for p in layer_params]
transformer_params.append(layer_params)
assert transformer_containers[i].is_populated == True
non_transformer_params = []
non_transformer_container = NonTransformerContainer(model)
for i in range(3):
non_transformer_params.append(torch.rand(16, 16).permute(1, 0))
non_transformer_container.set_dependency(f"param_{i+1}", non_transformer_params[i])
non_transformer_params = [p.to(get_accelerator().current_device()) for p in non_transformer_params]
def validate_containers(t_containers: List[LayerContainer], n_t_containers: LayerContainer,
t_params: List[List[torch.Tensor]], n_t_params: List[torch.Tensor]):
"""
Validate params match what is on the containers.
"""
for i in range(n_layers):
l_c = t_containers[i]
assert l_c.is_initialized == True
assert torch.equal(l_c.param_1, t_params[i][0])
assert torch.equal(l_c.param_2, t_params[i][1])
assert n_t_containers.is_initialized == True
assert torch.equal(n_t_containers.param_1, n_t_params[0])
assert torch.equal(n_t_containers.param_2, n_t_params[1])
assert torch.equal(n_t_containers.param_3, n_t_params[2])
assert not n_t_containers.param_1.is_contiguous()
assert not n_t_containers.param_2.is_contiguous()
assert not n_t_containers.param_3.is_contiguous()
buffer, metadata = flatten_inference_model(transformer_containers, non_transformer_container, "NoOpPolicy")
# Validate containers before contiguify
validate_containers(transformer_containers, non_transformer_container, transformer_params, non_transformer_params)
# Validate restore pass
transformer_containers_r = []
for i in range(n_layers):
transformer_containers_r.append(TransformerLayerContainer(model))
non_transformer_container_r = NonTransformerContainer(model)
restore_inference_model(buffer, metadata, transformer_containers_r, non_transformer_container_r)
validate_containers(transformer_containers_r, non_transformer_container_r, transformer_params,
non_transformer_params)
@@ -0,0 +1,48 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import pytest
import torch
from deepspeed.inference.v2.inference_parameter import InferenceParameter
from deepspeed.inference.v2.model_implementations.layer_container_base import LayerContainer
from .utils import SimpleParam, DummyInferenceModel
class ParentLayer(LayerContainer):
"""
A layer that has a dependency on a simple parameter.
"""
param_1: SimpleParam
class ChildLayer(ParentLayer):
"""
A layer that inherits from another layer.
"""
param_2: SimpleParam
@pytest.mark.inference_v2
def test_layer_inheritance():
inference_model = DummyInferenceModel()
multi_param_layer = ChildLayer(inference_model)
assert multi_param_layer.n_params == 2
assert multi_param_layer.is_initialized is False
multi_param_layer.param_1.param = torch.ones(16, 16)
assert multi_param_layer.is_initialized is False
multi_param_layer.param_2.param = torch.full((16, 16), 2.0)
assert multi_param_layer.is_populated is True
assert isinstance(multi_param_layer.param_1, InferenceParameter)
assert isinstance(multi_param_layer.param_2, InferenceParameter)
@@ -0,0 +1,168 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import pytest
import torch
from deepspeed.inference.v2.allocator import on_device
from deepspeed.inference.v2.inference_parameter import InferenceParameter
from deepspeed.inference.v2.model_implementations.parameter_base import ParameterBase, ParamList
from deepspeed.inference.v2.model_implementations.layer_container_base import LayerContainer
class MultiDependencyContainer(ParameterBase):
dependency_1: torch.Tensor
dependency_2: torch.Tensor
@on_device
def finalize(self) -> torch.Tensor:
param = torch.cat([self.dependency_1, self.dependency_2])
return InferenceParameter.initialize(param)
class ListDependencyContainer(ParameterBase):
dependencies: ParamList("list_items") # noqa: F821
@on_device
def finalize(self) -> torch.Tensor:
param = torch.cat(tuple(self.dependencies))
return InferenceParameter.initialize(param)
class MappingLayer(LayerContainer):
PARAM_MAPPING = {
"model.val.item.d_1": "multi_depend.dependency_1",
"model.val.item.d_2": "multi_depend.dependency_2",
"model.list_vals.*.d": "list_depend.dependencies"
}
multi_depend: MultiDependencyContainer
list_depend: ListDependencyContainer
class SubMappingLayer(MappingLayer):
PARAM_MAPPING = {
"model.val.item2.d_1": "multi_depend2.dependency_1",
"model.val.item2.d_2": "multi_depend2.dependency_2",
}
multi_depend2: MultiDependencyContainer
class DoubleMappingLayer(LayerContainer):
PARAM_MAPPING = {
"model.val.item.d_1": ["multi_depend.dependency_1", "multi_depend.dependency_2"],
}
multi_depend: MultiDependencyContainer
class InferenceModel:
@property
def list_items(self) -> int:
return 16
@pytest.mark.inference_v2
def test_mapping_syntax():
model = InferenceModel()
mapping_layer = MappingLayer(model)
mapping_layer.set_dependency("model.val.item.d_1", torch.ones(1))
mapping_layer.set_dependency("model.val.item.d_2", torch.ones(1) * 2)
assert isinstance(mapping_layer.multi_depend, torch.Tensor)
for i in range(16):
mapping_layer.set_dependency(f"model.list_vals.{i}.d", torch.ones(1) * i)
if i != 16 - 1:
assert mapping_layer.is_populated == False
assert isinstance(mapping_layer.list_depend, InferenceParameter)
assert mapping_layer.is_populated == True
@pytest.mark.inference_v2
def test_sub_mapping_syntax():
model = InferenceModel()
mapping_layer = SubMappingLayer(model)
mapping_layer.set_dependency("model.val.item.d_1", torch.ones(1))
mapping_layer.set_dependency("model.val.item.d_2", torch.ones(1) * 2)
assert isinstance(mapping_layer.multi_depend, InferenceParameter)
mapping_layer.set_dependency("model.val.item2.d_1", torch.ones(1))
mapping_layer.set_dependency("model.val.item2.d_2", torch.ones(1) * 2)
assert isinstance(mapping_layer.multi_depend2, InferenceParameter)
# We want to check into double digits to make sure that this isn't specific
# to single difit indexing.
for i in range(16):
mapping_layer.set_dependency(f"model.list_vals.{i}.d", torch.ones(1) * i)
if i != 16 - 1:
assert mapping_layer.is_populated == False
assert isinstance(mapping_layer.list_depend, InferenceParameter)
assert mapping_layer.is_populated == True
@pytest.mark.inference_v2
def test_double_mapping_syntax():
model = InferenceModel()
mapping_layer = DoubleMappingLayer(model)
mapping_layer.set_dependency("model.val.item.d_1", torch.ones(1))
# The single parameter setting should immediately make the parameter finalized
# and the whole layer initialized.
assert isinstance(mapping_layer.multi_depend, InferenceParameter)
assert mapping_layer.is_populated == True
@pytest.mark.inference_v2
def test_insufficient_mapping_syntax():
"""
In the above example, we don't have a mapping for `multi_depend2.dependency_2`.
"""
with pytest.raises(ValueError):
class InsuffienctMappingLayer(LayerContainer):
PARAM_MAPPING = {
"model.val.item.d_1": "multi_depend1.dependency_1",
"model.val.item.d_2": "multi_depend1.dependency_2",
"model.val.item2.d_1": "multi_depend2.dependency_1",
}
multi_depend1: MultiDependencyContainer
multi_depend2: MultiDependencyContainer
@pytest.mark.inference_v2
def test_unknown_target_mapping_syntax():
"""
In the above example, `multi_depend_unknown` does not exist
"""
with pytest.raises(ValueError):
class UnknownTargetMappingLayer(LayerContainer):
PARAM_MAPPING = {
"model.val.item.d_1": "multi_depend1.dependency_1",
"model.val.item.d_2": "multi_depend1.dependency_2",
"model.val.item2.d_1": "multi_depend_unknown.dependency_1",
}
multi_depend: MultiDependencyContainer
@@ -0,0 +1,79 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import pytest
import torch
from deepspeed.inference.v2.inference_parameter import InferenceParameter
from deepspeed.inference.v2.model_implementations.layer_container_base import LayerContainer
from .utils import validate_device, SimpleParam, ListParam, DummyInferenceModel
class MultiParameterLayer(LayerContainer):
"""
Two dependencies, both of which are simple parameters.
"""
param_1: SimpleParam
param_2: SimpleParam
class MixedMultiParameterLayer(LayerContainer):
"""
Two dependencies, one of which is a simple parameter, the other is a list parameter.
"""
param_1: SimpleParam
param_2: ListParam
@pytest.mark.inference_v2
def test_multi_parameter_layer():
inference_model = DummyInferenceModel()
multi_param_layer = MultiParameterLayer(inference_model)
assert multi_param_layer.n_params == 2
assert multi_param_layer.is_populated is False
multi_param_layer.param_1.param = torch.ones(16, 16)
assert multi_param_layer.is_populated is False
multi_param_layer.param_2.param = torch.full((16, 16), 2.0)
assert multi_param_layer.is_populated is True
assert isinstance(multi_param_layer.param_1, InferenceParameter)
assert isinstance(multi_param_layer.param_2, InferenceParameter)
@pytest.mark.inference_v2
def test_mixed_multi_parameter_layer():
inference_model = DummyInferenceModel()
mixed_multi_param_layer = MixedMultiParameterLayer(inference_model)
assert mixed_multi_param_layer.n_params == 2
assert mixed_multi_param_layer.is_populated is False
mixed_multi_param_layer.param_2.params[1] = torch.full((16, 16), 2.0)
assert mixed_multi_param_layer.is_populated is False
assert not isinstance(mixed_multi_param_layer.param_2, InferenceParameter)
mixed_multi_param_layer.param_1.param = torch.ones(16, 16)
assert mixed_multi_param_layer.is_populated is False
assert isinstance(mixed_multi_param_layer.param_1, InferenceParameter)
validate_device(mixed_multi_param_layer.param_1)
mixed_multi_param_layer.param_2.params[0] = torch.full((16, 16), 2.0)
assert mixed_multi_param_layer.is_populated is True
assert isinstance(mixed_multi_param_layer.param_2, InferenceParameter)
validate_device(mixed_multi_param_layer.param_2)
@@ -0,0 +1,105 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import pytest
import torch
from deepspeed.inference.v2.allocator import on_device
from deepspeed.inference.v2.inference_parameter import InferenceParameter
from deepspeed.inference.v2.model_implementations.parameter_base import ParameterBase, ParamList
from deepspeed.inference.v2.model_implementations.layer_container_base import LayerContainer
from deepspeed.inference.v2.model_implementations.common_parameters import *
from .utils import validate_device
class SimpleMoELayer(LayerContainer):
moe_mlp_1: UnfusedMoEMLP1Parameter
class DummyInferenceModel:
def __init__(self, experts_per_rank: int) -> None:
self._num_experts = experts_per_rank
@property
def n_experts(self) -> int:
return self._num_experts
@on_device
def transform_moe_mlp_1_param(self, param: torch.Tensor) -> torch.Tensor:
return InferenceParameter.initialize(param)
@pytest.mark.inference_v2
def test_simple_moe_layer():
inference_model = DummyInferenceModel(experts_per_rank=2)
simple_moe_layer = SimpleMoELayer(inference_model)
assert simple_moe_layer.moe_mlp_1.experts[0] is None
assert simple_moe_layer.moe_mlp_1.experts[1] is None
# Set the first expert
simple_moe_layer.moe_mlp_1.experts[0] = torch.zeros(16, 16)
assert simple_moe_layer.moe_mlp_1.experts[0] is not None
assert simple_moe_layer.moe_mlp_1.experts[1] is None
assert not simple_moe_layer.is_initialized
# Set the second expert
simple_moe_layer.moe_mlp_1.experts[1] = torch.ones(16, 16)
# We have all the experts, so the layer should be initialized
assert simple_moe_layer.is_initialized
assert isinstance(simple_moe_layer.moe_mlp_1, torch.Tensor)
validate_device(simple_moe_layer.moe_mlp_1)
"""
Check that we can mix the number of elements in lists in the same context and have that
be tracked correctly.
"""
class CustomListParam1(ParameterBase):
deps: ParamList("attr_1")
class CustomListParam2(ParameterBase):
deps: ParamList("attr_2")
class MixedLayer(LayerContainer):
list_1: CustomListParam1
list_2: CustomListParam2
class MixedInferenceModel:
@property
def attr_1(self) -> int:
return 1
@property
def attr_2(self) -> int:
return 2
@pytest.mark.inference_v2
def test_mixed_param_lists():
model = MixedInferenceModel()
layer = MixedLayer(model)
assert layer.list_1.deps.n_params == 1
assert layer.list_2.deps.n_params == 2
@@ -0,0 +1,60 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import torch
from deepspeed.accelerator import get_accelerator
from deepspeed.inference.v2.allocator import on_device
from deepspeed.inference.v2.inference_parameter import InferenceParameter
from deepspeed.inference.v2.model_implementations.parameter_base import ParameterBase, ParametrizedList
class SimpleParam(ParameterBase):
"""
Parameter with single dependency.
"""
param: torch.Tensor
@on_device
def finalize(self) -> torch.Tensor:
return self.inference_model.transform(self.param)
class SimpleParametrizedList(ParametrizedList):
"""
Parameter list based on `num_dependencies` attribute.
"""
count_attr: str = "num_dependencies"
class ListParam(ParameterBase):
"""
Parameter with list dependency.
NOTE: This uses the tuple workaround for the `ParametrizedList` class
as described in the docstring of `ParametrizedList`.
"""
params: SimpleParametrizedList
@on_device
def finalize(self) -> torch.Tensor:
return self.inference_model.transform(torch.cat(tuple(self.params)))
class DummyInferenceModel:
@property
def num_dependencies(self) -> int:
return 2
def transform(self, param: torch.Tensor) -> torch.Tensor:
return InferenceParameter.initialize(param)
def validate_device(tensor: torch.Tensor):
assert tensor.device == torch.device(get_accelerator().current_device())