Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / components / quantization / modules / replacement.py: 100%
30 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-11-15 07:18 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-11-15 07:18 +0800
1# Copyright 2026 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15"""Legacy policy-based replacement factories shared across models.
17New configurations can select fixed strategies through Module Family rules.
18These factories retain the original low-precision module layout and policy API.
19"""
21from collections.abc import Mapping
22from typing import Any
24from torch import nn # pylint: disable=forbidden-backend-import
26from hyper_parallel.components.quantization.functional import build_low_precision_strategy
27from hyper_parallel.components.quantization.functional.linear_strategy_factory import (
28 build_linear_strategy,
29)
30from hyper_parallel.components.quantization.modules.grouped_experts import (
31 GroupedExperts,
32)
33from hyper_parallel.components.quantization.modules.linear import LowPrecisionLinear
34from hyper_parallel.models.replacement import module_replacement
37def _check_ep1_only(context: Mapping[str, Any], factory_name: str) -> None:
38 """Reject any active model-parallel axis (EP=1 packed experts only)."""
39 active_model_parallel_axes = [
40 axis.upper()
41 for axis in ("tp", "cp", "ep", "pp")
42 if context.get(axis)
43 ]
44 if active_model_parallel_axes:
45 raise NotImplementedError(
46 f"{factory_name} currently require TP=CP=EP=PP=1; "
47 f"active axes: {active_model_parallel_axes}."
48 )
51@module_replacement
52def replace_linear(
53 *,
54 module: nn.Module,
55 module_fqn: str,
56 context: Mapping[str, Any],
57) -> LowPrecisionLinear:
58 """Replace one exact Dense Linear using its resolved low-precision policy."""
60 if type(module) is not nn.Linear: # pylint: disable=unidiomatic-typecheck
61 raise TypeError(
62 f"{module_fqn!r} must be exact nn.Linear, got {type(module).__name__}"
63 )
64 if context.get("pp"):
65 raise NotImplementedError(
66 "Low-precision Linear training is not yet supported with pipeline parallelism."
67 )
68 try:
69 strategy = build_linear_strategy(
70 context.get("low_precision"),
71 in_features=module.in_features,
72 out_features=module.out_features,
73 )
74 except ValueError as error:
75 raise ValueError(
76 f"Low-precision Linear target {module_fqn!r} is invalid: {error}"
77 ) from error
78 return LowPrecisionLinear.from_linear(module, strategy=strategy)
81@module_replacement
82def replace_grouped_experts(
83 *,
84 module: nn.Module,
85 module_fqn: str,
86 context: Mapping[str, Any],
87) -> GroupedExperts:
88 """Replace packed experts with the policy-selected grouped-linear strategy."""
90 _check_ep1_only(context, "Low-precision grouped experts")
91 parameters = tuple(module.parameters(recurse=False))
92 strategy = build_low_precision_strategy(
93 context.get("low_precision"),
94 tile_shapes=tuple(tuple(parameter.shape) for parameter in parameters),
95 )
96 return GroupedExperts.from_module(
97 module,
98 fqn=module_fqn,
99 grouped_linear=strategy,
100 )
103__all__ = ["replace_linear", "replace_grouped_experts"]