A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 5, 14:45 UTC
[Bugfix] Fix AWQ models batch invariance issues (#38670)
Signed-off-by: yusuf <yusuf@deeplearningmachine.mynet> Signed-off-by: <> Co-authored-by: yusuf <yusuf@deeplearningmachine.mynet>
Yusuf Mohammad committed
Apr 3, 2026 at 15:54 UTC
46f02e00f2d99944ecd24000bcc8be2a9504eafe
4 files changed
+27
-10
tests/v1/determinism/test_batch_invariance.py
+5
-5
@@ -187,7 +187,7 @@ def test_logprobs_bitwise_batch_invariance_bs1_vs_bsN(
187
tensor_parallel_size=tp_size,
188
max_num_seqs=128,
189
max_model_len=8192,
190
- dtype="bfloat16", # not everything is supported
190
+ dtype="auto", # not everything is supported
191
gpu_memory_utilization=0.9,
192
enforce_eager=IS_DEVICE_CAPABILITY_BELOW_90,
193
attention_config={"backend": backend},
@@ -400,7 +400,7 @@ def test_simple_generation(backend):
400
tensor_parallel_size=int(os.getenv("VLLM_TP_SIZE", "1")),
401
gpu_memory_utilization=0.9,
402
max_model_len=2048,
403
- dtype="bfloat16",
403
+ dtype="auto",
404
enable_prefix_caching=False,
405
enforce_eager=IS_DEVICE_CAPABILITY_BELOW_90,
406
attention_config={"backend": backend},
@@ -466,7 +466,7 @@ def test_logprobs_without_batch_invariance_should_fail(
466
tensor_parallel_size=tp_size,
467
max_num_seqs=32,
468
max_model_len=8192,
469
- dtype="bfloat16",
469
+ dtype="auto",
470
enforce_eager=IS_DEVICE_CAPABILITY_BELOW_90,
471
attention_config={"backend": backend},
472
)
@@ -686,7 +686,7 @@ def test_decode_logprobs_match_prefill_logprobs(
686
tensor_parallel_size=tp_size,
687
max_num_seqs=32,
688
max_model_len=8192,
689
- dtype="bfloat16",
689
+ dtype="auto",
690
enforce_eager=IS_DEVICE_CAPABILITY_BELOW_90,
691
attention_config={"backend": backend},
692
)
@@ -931,7 +931,7 @@ def LLM_with_max_seqs(
931
max_num_seqs=max_num_seqs,
932
gpu_memory_utilization=gpu_memory_utilization,
933
max_model_len=max_model_len,
934
- dtype="bfloat16",
934
+ dtype="auto",
935
tensor_parallel_size=int(os.getenv("VLLM_TP_SIZE", "1")),
936
enable_prefix_caching=False,
937
enforce_eager=IS_DEVICE_CAPABILITY_BELOW_90,
vllm/model_executor/layers/batch_invariant.py
+12
-3
@@ -10,6 +10,7 @@ import vllm.envs as envs
10
from vllm.logger import init_logger
11
from vllm.platforms import current_platform
12
from vllm.triton_utils import tl, triton
13
+from vllm.utils.mem_utils import get_max_shared_memory_bytes
14
from vllm.utils.platform_utils import num_compute_units
15
from vllm.utils.torch_utils import is_torch_equal_or_newer
16
from vllm.v1.attention.backends.registry import AttentionBackendEnum
@@ -177,7 +178,7 @@ def matmul_persistent(
178
},
179
torch.float16: {
180
"BLOCK_SIZE_M": 128,
180
- "BLOCK_SIZE_N": 256,
181
+ "BLOCK_SIZE_N": _fp16_block_size_n,
182
"BLOCK_SIZE_K": 64,
183
"GROUP_SIZE_M": 8,
184
"num_stages": 3,
@@ -700,7 +701,7 @@ def bmm_batch_invariant(a, b, *, out=None):
701
},
702
torch.float16: {
703
"BLOCK_SIZE_M": 128,
703
- "BLOCK_SIZE_N": 256,
704
+ "BLOCK_SIZE_N": _fp16_block_size_n,
705
"BLOCK_SIZE_K": 64,
706
"num_stages": 3,
707
"num_warps": 8,
@@ -752,7 +753,8 @@ def addmm_batch_invariant(bias, a, b):
753
754
755
def _log_softmax_batch_invariant(input, dim, _half_to_float):
755
- assert not _half_to_float, "not implemented"
756
+ if _half_to_float:
757
+ return log_softmax(input.float(), dim=dim)
758
return log_softmax(input, dim=dim)
759
760
@@ -923,12 +925,15 @@ _original_fp16_reduction_precision = None
925
_original_bf16_reduction_precision = None
926
_original_cublas_workspace_cfg = None
927
_original_cublaslt_workspace_size = None
928
+_fp16_block_size_n = 256
929
930
931
def enable_batch_invariant_mode():
932
global _batch_invariant_MODE, _batch_invariant_LIB, _original_torch_bmm
933
global _original_fp16_reduction_precision, _original_bf16_reduction_precision
934
global _original_cublas_workspace_cfg, _original_cublaslt_workspace_size
935
+ global _fp16_block_size_n
936
+
937
if _batch_invariant_MODE:
938
return
939
@@ -944,6 +949,10 @@ def enable_batch_invariant_mode():
949
_batch_invariant_LIB.impl("aten::addmm", addmm_batch_invariant, "CUDA")
950
_batch_invariant_LIB.impl("aten::matmul", matmul_batch_invariant, "CUDA")
951
_batch_invariant_LIB.impl("aten::linear", linear_batch_invariant, "CUDA")
952
+
953
+ # Query the shared memory size and set block size
954
+ # accordingly to avoid triton OutOfResources
955
+ _fp16_block_size_n = 256 if get_max_shared_memory_bytes() > 106496 else 128
956
else:
957
# Only source of batch invariance for Hopper is split-k, can disable through
958
# cuBLAS workspace config
vllm/model_executor/layers/quantization/awq.py
+4
-2
@@ -8,6 +8,7 @@ from safetensors.torch import _TYPES as _SAFETENSORS_TO_TORCH_DTYPE
8
from transformers import PretrainedConfig
9
10
from vllm import _custom_ops as ops
11
+from vllm import envs
12
from vllm.logger import init_logger
13
from vllm.model_executor.layers.fused_moe.layer import FusedMoE
14
from vllm.model_executor.layers.linear import (
@@ -273,8 +274,9 @@ class AWQLinearMethod(LinearMethodBase):
274
275
# num_tokens >= threshold
276
FP16_MATMUL_HEURISTIC_CONDITION = x.shape[:-1].numel() >= 256
276
-
277
- if FP16_MATMUL_HEURISTIC_CONDITION:
277
+ # Batch invariant mode requires torch.matmul path
278
+ # for Triton override
279
+ if FP16_MATMUL_HEURISTIC_CONDITION or envs.VLLM_BATCH_INVARIANT:
280
out = ops.awq_dequantize(qweight, scales, qzeros, 0, 0, 0)
281
out = torch.matmul(reshaped_x, out)
282
else:
vllm/model_executor/layers/quantization/awq_marlin.py
+6
@@ -10,6 +10,7 @@ from transformers import PretrainedConfig
10
11
import vllm.model_executor.layers.fused_moe # noqa
12
from vllm import _custom_ops as ops
13
+from vllm import envs
14
from vllm.logger import init_logger
15
from vllm.model_executor.kernels.linear import (
16
MPLinearLayerConfig,
@@ -233,6 +234,11 @@ class AWQMarlinConfig(QuantizationConfig):
234
def override_quantization_method(
235
cls, hf_quant_cfg, user_quant
236
) -> "QuantizationMethods | None":
237
+ # Skip override to marlin kernels, as they are not
238
+ # batch invariant
239
+ if envs.VLLM_BATCH_INVARIANT:
240
+ return None
241
+
242
can_convert = cls.is_awq_marlin_compatible(hf_quant_cfg)
243
is_valid_user_quant = (
244
user_quant is None or user_quant == "marlin" or user_quant == "awq_marlin"