Spaces:
Running on Zero
Running on Zero
File size: 6,439 Bytes
28404e6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | # Copyright 2025 Tencent Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import gc
import re
from typing import List, Optional, Union
import torch
__all__ = [
"replace_module",
"cleanup_memory",
"should_quantize_layer",
"_compile_pattern",
"_ensure_deep_gemm",
"_ensure_sgl_kernel",
"QuantType",
]
class QuantType:
FP8_PER_TENSOR = "fp8-per-tensor"
FP8_PER_TOKEN = "fp8-per-token"
FP8_PER_BLOCK = "fp8-per-block"
FP8_PER_CHANNEL_VLLM = "fp8-per-channel-vllm"
FP8_PER_TENSOR_WEIGHT_ONLY = "fp8-per-tensor-weight-only"
FP8_PER_TOKEN_SGL = "fp8-per-token-sgl"
INT8 = "int8"
INT8_TORCHAO = "int8-torchao"
INT8_VLLM = "int8-vllm"
INT8_TRITON = "int8-triton"
INT8_SGL = "int8-sgl"
INT8_Q8F = "int8-q8f"
NVFP4 = "nvfp4"
MXFP4 = "mxfp4"
MXFP6 = "mxfp6"
MXFP8 = "mxfp8"
VALID_TYPES = [
FP8_PER_TENSOR,
FP8_PER_TOKEN,
FP8_PER_BLOCK,
FP8_PER_CHANNEL_VLLM,
FP8_PER_TENSOR_WEIGHT_ONLY,
FP8_PER_TOKEN_SGL,
INT8,
INT8_TORCHAO,
INT8_VLLM,
INT8_TRITON,
INT8_SGL,
INT8_Q8F,
NVFP4,
MXFP4,
MXFP6,
MXFP8,
]
@classmethod
def validate(cls, quant_type: str):
if quant_type not in cls.VALID_TYPES:
raise ValueError(f"Invalid quant_type: {quant_type}. Valid types: {cls.VALID_TYPES}")
def replace_module(model: torch.nn.Module, name: str, new_module: torch.nn.Module):
"""
Replace a submodule in the model with a new module by name.
"""
if "." in name:
parent_name = name.rsplit(".", 1)[0]
child_name = name[len(parent_name) + 1 :]
parent = model.get_submodule(parent_name)
else:
parent_name = ""
parent = model
child_name = name
setattr(parent, child_name, new_module)
def cleanup_memory():
"""
Run garbage collection and clear CUDA memory cache.
"""
gc.collect()
torch.cuda.empty_cache()
def _compile_pattern(pattern: Union[str, re.Pattern], case_sensitive: bool = False) -> re.Pattern:
"""
Compile a pattern (string or pre-compiled pattern) into a regex pattern object.
Args:
pattern: String pattern or already-compiled regex pattern.
case_sensitive: Whether the match is case sensitive.
Returns:
Compiled regex pattern object.
"""
if isinstance(pattern, str):
# If the string contains special regex characters, treat as regex.
if any(char in pattern for char in ".*+?^${}[]|()\\"):
flags = 0 if case_sensitive else re.IGNORECASE
return re.compile(pattern, flags)
else:
# Escape regular string so it matches literally.
escaped = re.escape(pattern)
flags = 0 if case_sensitive else re.IGNORECASE
return re.compile(escaped, flags)
else:
# Already a compiled pattern.
return pattern
def should_quantize_layer(
layer_name: str,
include_patterns: Optional[List[Union[str, re.Pattern]]] = None,
exclude_patterns: Optional[List[Union[str, re.Pattern]]] = None,
case_sensitive: bool = False,
) -> bool:
"""
Decide whether a layer should be quantized based on inclusion/exclusion patterns.
Args:
layer_name: Name of the layer.
include_patterns: List of patterns (str or regex) to include.
exclude_patterns: List of patterns (str or regex) to exclude.
case_sensitive: Whether patterns are matched case sensitively.
Returns:
bool: Whether this layer should be quantized.
Note:
String patterns are auto-detected as regex if they include special chars:
- If contains any . * + ? ^ $ { } [ ] | ( ) \\ -> treated as regex
- Otherwise, escaped and matched literally
"""
if include_patterns is None:
include_patterns = []
if exclude_patterns is None:
exclude_patterns = []
# Check exclusion patterns
for pattern in exclude_patterns:
compiled_pattern = _compile_pattern(pattern, case_sensitive)
if compiled_pattern.search(layer_name):
return False
# If no include patterns, default is to include all layers
if not include_patterns:
return True
# Check inclusion patterns
for pattern in include_patterns:
compiled_pattern = _compile_pattern(pattern, case_sensitive)
if compiled_pattern.search(layer_name):
return True
return False
_deep_gemm_cached = None
def _ensure_deep_gemm():
"""
Lazy, safe import of deep_gemm with process-level caching. Returns the module
if available, otherwise raises a clear error.
"""
global _deep_gemm_cached
if _deep_gemm_cached is not None:
return _deep_gemm_cached
try:
import deep_gemm
_deep_gemm_cached = deep_gemm
return _deep_gemm_cached
except ImportError as e:
raise ImportError(
(
"deep_gemm is required for 'fp8-per-block' quantization with "
"native_fp8_support, but was not found. Please install deep_gemm first."
)
) from e
_sgl_kernel_cached = None
def _ensure_sgl_kernel():
"""
Lazy, safe import of sgl_kernel with process-level caching. Returns the module
if available, otherwise raises a clear error.
"""
global _sgl_kernel_cached
if _sgl_kernel_cached is not None:
return _sgl_kernel_cached
try:
import sgl_kernel
_sgl_kernel_cached = sgl_kernel
return _sgl_kernel_cached
except ImportError as e:
raise ImportError(
(
"sgl_kernel is required for 'fp8-per-token-sgl' quantization with "
"native_fp8_support, but was not found. Please install sgl_kernel first"
)
) from e
|