Skip to content

Commit 103d28b

Browse files
authored
[quantization] swap modules in one pass through a per-quantizer quantized_module (#50343)
* [quantization] swap modules in one pass through a per-quantizer quantized_module * [quantization] build_fp8_linear / build_fp8_experts
1 parent 749a263 commit 103d28b

28 files changed

Lines changed: 296 additions & 543 deletions

‎src/transformers/integrations/__init__.py‎

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818

1919
_import_structure = {
20-
"aqlm": ["replace_with_aqlm_linear"],
2120
"awq": [
2221
"post_init_awq_exllama_modules",
2322
"replace_quantization_scales",
@@ -26,7 +25,6 @@
2625
"bitnet": [
2726
"BitLinear",
2827
"pack_weights",
29-
"replace_with_bitnet_linear",
3028
"unpack_weights",
3129
],
3230
"bitsandbytes": [
@@ -48,9 +46,9 @@
4846
"set_hf_deepspeed_config",
4947
"unset_hf_deepspeed_config",
5048
],
51-
"eetq": ["replace_with_eetq_linear"],
49+
"eetq": ["load_eetq_kernels"],
5250
"fbgemm_fp8": ["FbgemmFp8Linear", "FbgemmFp8Llama4TextExperts", "replace_with_fbgemm_fp8_linear"],
53-
"finegrained_fp8": ["FP8Embedding", "FP8Linear", "replace_with_fp8_embedding", "replace_with_fp8_linear"],
51+
"finegrained_fp8": ["FP8Embedding", "FP8Linear"],
5452
"fsdp": ["is_fsdp_enabled", "is_fsdp_managed_module"],
5553
"gemma_quant": [
5654
"QuantizedEmbedding",
@@ -67,7 +65,6 @@
6765
"HiggsLinear",
6866
"dequantize_higgs",
6967
"quantize_with_higgs",
70-
"replace_with_higgs_linear",
7168
],
7269
"hqq": ["prepare_for_hqq_linear"],
7370
"hub_kernels": [
@@ -127,7 +124,6 @@
127124
"liger": ["apply_liger_kernel"],
128125
"metal_quantization": [
129126
"MetalLinear",
130-
"replace_with_metal_linear",
131127
],
132128
"moe": [
133129
"batched_mm_experts_forward",
@@ -146,7 +142,7 @@
146142
"deactivate_neftune",
147143
"neftune_post_forward_hook",
148144
],
149-
"nvfp4": ["NVFP4Linear", "NVFP4Quantize", "replace_with_nvfp4_linear"],
145+
"nvfp4": ["NVFP4Linear", "NVFP4Quantize"],
150146
"peft": ["PeftAdapterMixin"],
151147
"quanto": ["replace_with_quanto_layers"],
152148
"sinq": ["SinqDeserialize", "SinqQuantize"],
@@ -174,7 +170,6 @@
174170
]
175171

176172
if TYPE_CHECKING:
177-
from .aqlm import replace_with_aqlm_linear
178173
from .awq import (
179174
post_init_awq_exllama_modules,
180175
replace_quantization_scales,
@@ -183,7 +178,6 @@
183178
from .bitnet import (
184179
BitLinear,
185180
pack_weights,
186-
replace_with_bitnet_linear,
187181
unpack_weights,
188182
)
189183
from .bitsandbytes import (
@@ -205,9 +199,9 @@
205199
set_hf_deepspeed_config,
206200
unset_hf_deepspeed_config,
207201
)
208-
from .eetq import replace_with_eetq_linear
202+
from .eetq import load_eetq_kernels
209203
from .fbgemm_fp8 import FbgemmFp8Linear, FbgemmFp8Llama4TextExperts, replace_with_fbgemm_fp8_linear
210-
from .finegrained_fp8 import FP8Embedding, FP8Linear, replace_with_fp8_embedding, replace_with_fp8_linear
204+
from .finegrained_fp8 import FP8Embedding, FP8Linear
211205
from .fsdp import is_fsdp_enabled, is_fsdp_managed_module
212206
from .gemma_quant import (
213207
QuantizedEmbedding,
@@ -220,7 +214,7 @@
220214
GGUF_CONFIG_MAPPING,
221215
_gguf_parse_value,
222216
)
223-
from .higgs import HiggsLinear, dequantize_higgs, quantize_with_higgs, replace_with_higgs_linear
217+
from .higgs import HiggsLinear, dequantize_higgs, quantize_with_higgs
224218
from .hqq import prepare_for_hqq_linear
225219
from .hub_kernels import (
226220
LayerRepository,
@@ -279,7 +273,6 @@
279273
from .liger import apply_liger_kernel
280274
from .metal_quantization import (
281275
MetalLinear,
282-
replace_with_metal_linear,
283276
)
284277
from .moe import (
285278
batched_mm_experts_forward,
@@ -293,7 +286,7 @@
293286
swizzle_mxfp4,
294287
)
295288
from .neftune import activate_neftune, deactivate_neftune, neftune_post_forward_hook
296-
from .nvfp4 import NVFP4Linear, NVFP4Quantize, replace_with_nvfp4_linear
289+
from .nvfp4 import NVFP4Linear, NVFP4Quantize
297290
from .peft import PeftAdapterMixin
298291
from .quanto import replace_with_quanto_layers
299292
from .sinq import SinqDeserialize, SinqQuantize

‎src/transformers/integrations/aqlm.py‎

Lines changed: 0 additions & 70 deletions
This file was deleted.

‎src/transformers/integrations/bitnet.py‎

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from ..core_model_loading import ConversionOps
2-
from ..quantizers.quantizers_utils import get_module_from_name, should_convert_module
2+
from ..quantizers.quantizers_utils import get_module_from_name
33
from ..utils import is_torch_available, logging
44

55

@@ -282,64 +282,6 @@ def forward(self, input):
282282
return output
283283

284284

285-
def replace_with_bitnet_linear(model, modules_to_not_convert: list[str] | None = None, quantization_config=None):
286-
"""
287-
Public method that replaces the linear layers of the given model with bitnet quantized layers.
288-
289-
Args:
290-
model (`torch.nn.Module`):
291-
The model to convert, can be any `torch.nn.Module` instance.
292-
modules_to_not_convert (`list[str]`, *optional*, defaults to `None`):
293-
A list of nn.Linear weights to not convert. If a parameter path is in the list (e.g. `lm_head.weight`), the corresponding module will not be
294-
converted.
295-
quantization_config (`BitNetConfig`):
296-
The quantization config object that contains the quantization parameters.
297-
"""
298-
299-
has_been_replaced = False
300-
# we need this to correctly materialize the weights during quantization
301-
for module_name, module in model.named_modules():
302-
if not should_convert_module(module_name, modules_to_not_convert):
303-
continue
304-
with torch.device("meta"):
305-
if isinstance(module, nn.Linear):
306-
if quantization_config and quantization_config.linear_class == "autobitlinear":
307-
new_module = AutoBitLinear(
308-
in_features=module.in_features,
309-
out_features=module.out_features,
310-
bias=module.bias is not None,
311-
device=module.weight.device,
312-
dtype=module.weight.dtype,
313-
online_quant=(quantization_config.quantization_mode == "online"),
314-
use_rms_norm=quantization_config.use_rms_norm,
315-
rms_norm_eps=quantization_config.rms_norm_eps,
316-
)
317-
if quantization_config.quantization_mode == "offline":
318-
new_module.requires_grad_(False)
319-
else:
320-
new_module = BitLinear(
321-
in_features=module.in_features,
322-
out_features=module.out_features,
323-
bias=module.bias is not None,
324-
device=module.weight.device,
325-
dtype=module.weight.dtype,
326-
use_rms_norm=quantization_config.use_rms_norm if quantization_config else False,
327-
rms_norm_eps=quantization_config.rms_norm_eps if quantization_config else 1e-6,
328-
)
329-
new_module.requires_grad_(False)
330-
model.set_submodule(module_name, new_module)
331-
has_been_replaced = True
332-
333-
if not has_been_replaced:
334-
logger.warning(
335-
"You are loading your model using bitnet but no linear modules were found in your model."
336-
" Please double check your model architecture, or submit an issue on github if you think this is"
337-
" a bug."
338-
)
339-
340-
return model
341-
342-
343285
class BitNetDeserialize(ConversionOps):
344286
def __init__(self, hf_quantizer):
345287
self.hf_quantizer = hf_quantizer

‎src/transformers/integrations/eetq.py‎

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
from ..core_model_loading import ConversionOps
15-
from ..quantizers.quantizers_utils import should_convert_module
1615
from ..utils import is_torch_available, logging
1716

1817

@@ -83,41 +82,9 @@ def forward(self, input):
8382
return output
8483

8584

86-
def replace_with_eetq_linear(model, modules_to_not_convert: list[str] | None = None, pre_quantized=False):
87-
"""
88-
A helper function to replace all `torch.nn.Linear` modules by `EetqLinear` modules.
89-
90-
Parameters:
91-
model (`torch.nn.Module`):
92-
Input model or `torch.nn.Module` as the function is run recursively.
93-
modules_to_not_convert (`list[`str`]`, *optional*, defaults to `None`):
94-
Names of the modules to not convert in `EetqLinear`. In practice we keep the `lm_head` in full precision
95-
for numerical stability reasons.
96-
"""
85+
def load_eetq_kernels():
86+
"""Loads the EETQ hub kernels used by `EetqLinear` and `EetqQuantize`."""
9787
from .hub_kernels import get_kernel
9888

9989
global eetq_kernels_hub
10090
eetq_kernels_hub = get_kernel("kernels-community/quantization-eetq", version=1)
101-
102-
has_been_replaced = False
103-
# we need this to correctly materialize the weights during quantization
104-
module_kwargs = {} if pre_quantized else {"dtype": None}
105-
for module_name, module in model.named_modules():
106-
if not should_convert_module(module_name, modules_to_not_convert):
107-
continue
108-
with torch.device("meta"):
109-
if isinstance(module, nn.Linear):
110-
new_module = EetqLinear(
111-
module.in_features, module.out_features, bias=module.bias is not None, **module_kwargs
112-
)
113-
model.set_submodule(module_name, new_module)
114-
has_been_replaced = True
115-
116-
if not has_been_replaced:
117-
logger.warning(
118-
"You are loading your model using eetq but no linear modules were found in your model."
119-
" Please double check your model architecture, or submit an issue on github if you think this is"
120-
" a bug."
121-
)
122-
123-
return model

0 commit comments

Comments
 (0)