99from torch ._inductor .pattern_matcher import PatternMatcherPass
1010from torch ._ops import OpOverload
1111
12+ import vllm .envs as envs
1213from vllm .config import VllmConfig
1314from vllm .logger import init_logger
1415from vllm .model_executor .layers .quantization .utils .quant_utils import (
@@ -76,6 +77,22 @@ def __str__(self):
7677 torch .ops ._C .rms_norm_dynamic_per_token_quant .default , # noqa: E501
7778}
7879
80+ if current_platform .is_rocm () and envs .VLLM_ROCM_USE_AITER :
81+ AITER_RMS_GROUP_QUANT_OP = \
82+ torch .ops .vllm .rocm_aiter_rmsnorm_fp8_group_quant .default
83+ AITER_RMS_ADD_GROUP_QUANT_OP = \
84+ torch .ops .vllm .rocm_aiter_rmsnorm_with_add_fp8_group_quant .default
85+
86+ BLOCK_LINEAR_OP = torch .ops .vllm .apply_w8a8_block_fp8_linear .default
87+ AITER_BLOCK_LINEAR_OP = \
88+ torch .ops .vllm .rocm_aiter_gemm_w8a8_blockscale .default
89+
90+ AITER_RMS_OP = torch .ops .vllm .rocm_aiter_rms_norm .default
91+ AITER_RMS_ADD_OP = torch .ops .vllm .rocm_aiter_rmsnorm2d_fwd_with_add .default
92+
93+ import aiter as rocm_aiter
94+ rocm_aiter_fp8_dtype = rocm_aiter .dtypes .fp8
95+ rocm_aiter_fp8_quant_group_size = 128
7996
8097class RMSNormQuantPattern :
8198
@@ -336,6 +353,129 @@ def replacement(result: torch.Tensor, input: torch.Tensor,
336353 pm .fwd_only ,
337354 pm_pass ,
338355 )
356+
357+
358+ class AiterRMSGroupQuantFP8Pattern ():
359+
360+ def __init__ (self ,
361+ epsilon : float ,
362+ quant_dtype : torch .dtype ):
363+ self .epsilon = epsilon
364+ self .quant_dtype = quant_dtype
365+
366+ def register (self , pm_pass : PatternMatcherPass ):
367+
368+ def pattern (input : torch .Tensor , weight : torch .Tensor , #result_rms: torch.Tensor,
369+ linear_weight : torch .Tensor ,
370+ linear_weight_scale : torch .Tensor ):
371+ at1 = AITER_RMS_OP (x = input ,
372+ weight = weight ,
373+ variance_epsilon = self .epsilon )
374+
375+ at2 = BLOCK_LINEAR_OP (input = at1 ,
376+ weight = linear_weight ,
377+ block_size = [128 , 128 ],
378+ weight_scale = linear_weight_scale ,
379+ input_scale = None ,
380+ bias = None ,
381+ cutlass_block_fp8_supported = False ,
382+ use_aiter_and_is_supported = True )
383+
384+ return at2
385+
386+ def replacement (input : torch .Tensor , weight : torch .Tensor ,
387+ linear_weight : torch .Tensor ,
388+ linear_weight_scale : torch .Tensor ):
389+ at1 = AITER_RMS_GROUP_QUANT_OP (x = input ,
390+ residual = None ,
391+ weight = weight ,
392+ variance_epsilon = self .epsilon )
393+
394+ at2 = AITER_BLOCK_LINEAR_OP (A = at1 [0 ],
395+ B = linear_weight ,
396+ As = at1 [1 ],
397+ Bs = linear_weight_scale ,
398+ block_size = [128 , 128 ],
399+ output_dtype = input .dtype )
400+
401+ return at2
402+
403+ inputs = [
404+ empty_bf16 (5 , 4 ), # input
405+ empty_bf16 (1 , 5 ), # weight
406+ torch .empty ((2 , 5 ), device = "cuda" , dtype = FP8_DTYPE ), # linear_weight
407+ empty_fp32 (1 , 1 ), # linear_weight_scale
408+ ]
409+
410+ pm .register_replacement (
411+ pattern ,
412+ replacement ,
413+ inputs ,
414+ pm .fwd_only ,
415+ pm_pass )
416+
417+
418+ class AiterFusedAddRMSGroupQuantPattern ():
419+
420+ def __init__ (self ,
421+ epsilon : float ,
422+ quant_dtype : torch .dtype ):
423+ self .epsilon = epsilon
424+ self .quant_dtype = quant_dtype
425+
426+ def register (self , pm_pass : PatternMatcherPass ):
427+
428+ def pattern (input : torch .Tensor , residual : torch .Tensor , weight : torch .Tensor ,
429+ linear_weight : torch .Tensor ,
430+ linear_weight_scale : torch .Tensor ):
431+ at1 = AITER_RMS_ADD_OP (x = input ,
432+ residual = residual ,
433+ weight = weight ,
434+ variance_epsilon = self .epsilon )
435+
436+ at2 = BLOCK_LINEAR_OP (input = at1 [0 ],
437+ weight = linear_weight ,
438+ block_size = [128 , 128 ],
439+ weight_scale = linear_weight_scale ,
440+ input_scale = None ,
441+ bias = None ,
442+ cutlass_block_fp8_supported = False ,
443+ use_aiter_and_is_supported = True )
444+ # result, residual
445+ return at2 , at1 [1 ]
446+
447+ def replacement (input : torch .Tensor , residual : torch .Tensor , weight : torch .Tensor ,
448+ linear_weight : torch .Tensor ,
449+ linear_weight_scale : torch .Tensor ):
450+
451+ at1 = AITER_RMS_ADD_GROUP_QUANT_OP (x = input ,
452+ residual = residual ,
453+ weight = weight ,
454+ variance_epsilon = self .epsilon )
455+
456+ at2 = AITER_BLOCK_LINEAR_OP (A = at1 [0 ],
457+ B = linear_weight ,
458+ As = at1 [1 ],
459+ Bs = linear_weight_scale ,
460+ block_size = [128 , 128 ],
461+ output_dtype = input .dtype )
462+ # result, residual
463+ return at2 , at1 [2 ]
464+
465+ inputs = [
466+ empty_bf16 (5 , 4 ), # input
467+ empty_bf16 (5 , 4 ), # residual
468+ empty_bf16 (1 , 5 ), # weight
469+ torch .empty ((2 , 5 ), device = "cuda" , dtype = FP8_DTYPE ), # linear_weight
470+ empty_fp32 (1 , 1 ), # linear_weight_scale
471+ ]
472+
473+ pm .register_replacement (
474+ pattern ,
475+ replacement ,
476+ inputs ,
477+ pm .fwd_only ,
478+ pm_pass )
339479
340480
341481class RMSNormQuantFusionPass (VllmPatternMatcherPass ):
@@ -367,6 +507,14 @@ def __init__(self, config: VllmConfig):
367507 # Fuse fused_add_rms_norm + dynamic per-token fp8 quant
368508 FusedAddRMSNormDynamicQuantPattern (epsilon , FP8_DTYPE ).register (
369509 self .patterns )
510+
511+ if envs .VLLM_ROCM_USE_AITER :
512+ # Fuse rms_norm + dynamic group fp8 quant
513+ AiterRMSGroupQuantFP8Pattern (epsilon , FP8_DTYPE ).register (
514+ self .patterns )
515+
516+ AiterFusedAddRMSGroupQuantPattern (epsilon , FP8_DTYPE ).register (
517+ self .patterns )
370518
371519 self .dump_patterns (config , self .patterns )
372520
@@ -380,4 +528,6 @@ def uuid(self) -> Any:
380528 RMSNormStaticQuantPattern ,
381529 RMSNormDynamicQuantPattern ,
382530 FusedAddRMSNormStaticQuantPattern ,
383- FusedAddRMSNormDynamicQuantPattern )
531+ FusedAddRMSNormDynamicQuantPattern ,
532+ AiterRMSGroupQuantFP8Pattern ,
533+ AiterFusedAddRMSGroupQuantPattern )
0 commit comments