main
py 164 lines 4.84 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from itertools import product
5
6 import torch
7
8 import vllm.ir.ops
9 from vllm.config import VllmConfig
10
11 from ..vllm_inductor_pass import (
12 VllmFusionPatternMatcherPass,
13 VllmPatternReplacement,
14 )
15
16
17 class AddRMSNormPattern(VllmPatternReplacement):
18 def __init__(self, epsilon: float, residual_first: bool) -> None:
19 self.epsilon = epsilon
20 self.residual_first = residual_first
21
22 @property
23 def pattern(self):
24 def _pattern(
25 branch: torch.Tensor,
26 residual: torch.Tensor,
27 weight: torch.Tensor,
28 ) -> tuple[torch.Tensor, torch.Tensor]:
29 residual_out = (
30 residual + branch if self.residual_first else branch + residual
31 )
32 rms = vllm.ir.ops.rms_norm(residual_out, weight, self.epsilon)
33 return rms, residual_out
34
35 return _pattern
36
37 @property
38 def replacement(self):
39 def _replacement(
40 branch: torch.Tensor,
41 residual: torch.Tensor,
42 weight: torch.Tensor,
43 ) -> tuple[torch.Tensor, torch.Tensor]:
44 return vllm.ir.ops.fused_add_rms_norm(
45 branch, residual, weight, self.epsilon
46 )
47
48 return _replacement
49
50 def get_inputs(self) -> list[torch.Tensor]:
51 return [
52 self.empty_bf16(5, 16), # branch
53 self.empty_bf16(5, 16), # residual
54 self.empty_bf16(16), # weight
55 ]
56
57
58 class RMSNormReshapePattern(VllmPatternReplacement):
59 """Move a prefix-flatten before RMSNorm."""
60
61 def __init__(self, epsilon: float) -> None:
62 self.epsilon = epsilon
63
64 @property
65 def pattern(self):
66 def _pattern(
67 input: torch.Tensor,
68 weight: torch.Tensor,
69 ) -> torch.Tensor:
70 rms = vllm.ir.ops.rms_norm(input, weight, self.epsilon)
71 return rms.reshape(-1, rms.shape[-1])
72
73 return _pattern
74
75 @property
76 def replacement(self):
77 def _replacement(
78 input: torch.Tensor,
79 weight: torch.Tensor,
80 ) -> torch.Tensor:
81 input = input.reshape(-1, input.shape[-1])
82 return vllm.ir.ops.rms_norm(input, weight, self.epsilon)
83
84 return _replacement
85
86 def get_inputs(self) -> list[torch.Tensor]:
87 return [
88 self.empty_bf16(1, 5, 16), # input
89 self.empty_bf16(16), # weight
90 ]
91
92
93 class FusedAddRMSNormReshapePattern(VllmPatternReplacement):
94 """Move a prefix-flatten before fused add RMSNorm."""
95
96 def __init__(self, epsilon: float) -> None:
97 self.epsilon = epsilon
98
99 @property
100 def pattern(self):
101 def _pattern(
102 input: torch.Tensor,
103 residual: torch.Tensor,
104 weight: torch.Tensor,
105 ) -> tuple[torch.Tensor, torch.Tensor]:
106 rms, residual_out = vllm.ir.ops.fused_add_rms_norm(
107 input, residual, weight, self.epsilon
108 )
109 return rms.reshape(-1, rms.shape[-1]), residual_out
110
111 return _pattern
112
113 @property
114 def replacement(self):
115 def _replacement(
116 input: torch.Tensor,
117 residual: torch.Tensor,
118 weight: torch.Tensor,
119 ) -> tuple[torch.Tensor, torch.Tensor]:
120 original_shape = input.shape
121 hidden_size = input.shape[-1]
122 rms, residual_out = vllm.ir.ops.fused_add_rms_norm(
123 input.reshape(-1, hidden_size),
124 residual.reshape(-1, hidden_size),
125 weight,
126 self.epsilon,
127 )
128 return rms, residual_out.reshape(original_shape)
129
130 return _replacement
131
132 def get_inputs(self) -> list[torch.Tensor]:
133 return [
134 self.empty_bf16(1, 5, 16), # input
135 self.empty_bf16(1, 5, 16), # residual
136 self.empty_bf16(16), # weight
137 ]
138
139
140 class AddRMSNormFusionPass(VllmFusionPatternMatcherPass):
141 """Fuse residual Add and RMSNorm emitted separately by the Transformers backend."""
142
143 def __init__(self, config: VllmConfig) -> None:
144 super().__init__(config, "add_rmsnorm_fusion_pass")
145
146 for epsilon, residual_first in product([1e-5, 1e-6], [True, False]):
147 self.register(AddRMSNormPattern(epsilon, residual_first))
148
149 self.dump_patterns(config, self.pm_pass)
150
151
152 class RMSNormReshapeFusionPass(VllmFusionPatternMatcherPass):
153 """Move the Transformers backend's post-RMSNorm flatten before the norm
154 for downstream 2D fusions.
155 """
156
157 def __init__(self, config: VllmConfig) -> None:
158 super().__init__(config, "rmsnorm_reshape_fusion_pass")
159
160 for epsilon in [1e-5, 1e-6]:
161 self.register(FusedAddRMSNormReshapePattern(epsilon))
162 self.register(RMSNormReshapePattern(epsilon))
163
164 self.dump_patterns(config, self.pm_pass)