28
28
import torch
29
29
import torch .nn as nn
30
30
from transformers import PretrainedConfig
31
+ from transformers .utils import is_flash_attn_2_available
31
32
32
33
from vllm .model_executor .custom_op import CustomOp
33
34
from vllm .platforms import current_platform
34
35
36
+ if is_flash_attn_2_available ():
37
+ from flash_attn .layers .rotary import apply_rotary_emb
38
+
35
39
36
40
def _rotate_neox (x : torch .Tensor ) -> torch .Tensor :
37
41
x1 = x [..., :x .shape [- 1 ] // 2 ]
@@ -46,20 +50,12 @@ def _rotate_gptj(x: torch.Tensor) -> torch.Tensor:
46
50
return x .flatten (- 2 )
47
51
48
52
49
- def _apply_rotary_emb (
53
+ def _apply_rotary_emb_torch (
50
54
x : torch .Tensor ,
51
55
cos : torch .Tensor ,
52
56
sin : torch .Tensor ,
53
57
is_neox_style : bool ,
54
58
) -> torch .Tensor :
55
- """
56
- Args:
57
- x: [num_tokens, num_heads, head_size]
58
- cos: [num_tokens, head_size // 2]
59
- sin: [num_tokens, head_size // 2]
60
- is_neox_style: Whether to use the Neox-style or GPT-J-style rotary
61
- positional embeddings.
62
- """
63
59
cos = cos .unsqueeze (- 2 ).to (x .dtype )
64
60
sin = sin .unsqueeze (- 2 ).to (x .dtype )
65
61
if is_neox_style :
@@ -75,6 +71,27 @@ def _apply_rotary_emb(
75
71
return torch .stack ((o1 , o2 ), dim = - 1 ).flatten (- 2 )
76
72
77
73
74
+ def _apply_rotary_emb (x : torch .Tensor ,
75
+ cos : torch .Tensor ,
76
+ sin : torch .Tensor ,
77
+ is_neox_style : bool ,
78
+ use_flash_attn = False ) -> torch .Tensor :
79
+ """
80
+ Args:
81
+ x: [num_tokens, num_heads, head_size]
82
+ cos: [num_tokens, head_size // 2]
83
+ sin: [num_tokens, head_size // 2]
84
+ is_neox_style: Whether to use the Neox-style or GPT-J-style rotary
85
+ positional embeddings.
86
+ use_flash_attn: Whether to enable Flash Attention optimizations.
87
+ """
88
+ if use_flash_attn :
89
+ return apply_rotary_emb (x .unsqueeze (0 ), cos , sin ,
90
+ not is_neox_style ).squeeze (0 )
91
+ else :
92
+ return _apply_rotary_emb_torch (x , cos , sin , is_neox_style )
93
+
94
+
78
95
@CustomOp .register ("rotary_embedding" )
79
96
class RotaryEmbedding (CustomOp ):
80
97
"""Original rotary positional embedding."""
@@ -100,6 +117,10 @@ def __init__(
100
117
cache = cache .to (dtype )
101
118
self .cos_sin_cache : torch .Tensor
102
119
self .register_buffer ("cos_sin_cache" , cache , persistent = False )
120
+ if is_flash_attn_2_available ():
121
+ self ._use_flash_attn = True
122
+ else :
123
+ self ._use_flash_attn = False
103
124
104
125
def _compute_inv_freq (self , base : Union [int , float ]) -> torch .Tensor :
105
126
"""Compute the inverse frequency."""
@@ -141,14 +162,16 @@ def forward_native(
141
162
query = query .view (num_tokens , - 1 , self .head_size )
142
163
query_rot = query [..., :self .rotary_dim ]
143
164
query_pass = query [..., self .rotary_dim :]
144
- query_rot = _apply_rotary_emb (query_rot , cos , sin , self .is_neox_style )
165
+ query_rot = _apply_rotary_emb (query_rot , cos , sin , self .is_neox_style ,
166
+ self ._use_flash_attn )
145
167
query = torch .cat ((query_rot , query_pass ), dim = - 1 ).reshape (query_shape )
146
168
147
169
key_shape = key .shape
148
170
key = key .view (num_tokens , - 1 , self .head_size )
149
171
key_rot = key [..., :self .rotary_dim ]
150
172
key_pass = key [..., self .rotary_dim :]
151
- key_rot = _apply_rotary_emb (key_rot , cos , sin , self .is_neox_style )
173
+ key_rot = _apply_rotary_emb (key_rot , cos , sin , self .is_neox_style ,
174
+ self ._use_flash_attn )
152
175
key = torch .cat ((key_rot , key_pass ), dim = - 1 ).reshape (key_shape )
153
176
return query , key
154
177
@@ -309,9 +332,11 @@ def _apply_rotary_emb_neuron(
309
332
key = key .view (num_tokens , - 1 , self .head_size )
310
333
311
334
if self .rotary_dim == self .head_size :
312
- query = _apply_rotary_emb (query , cos , sin , self .is_neox_style )
335
+ query = _apply_rotary_emb (query , cos , sin , self .is_neox_style ,
336
+ self ._use_flash_attn )
313
337
query = query .reshape (query_shape )
314
- key = _apply_rotary_emb (key , cos , sin , self .is_neox_style )
338
+ key = _apply_rotary_emb (key , cos , sin , self .is_neox_style ,
339
+ self ._use_flash_attn )
315
340
key = key .reshape (key_shape )
316
341
else :
317
342
head_size = query .shape [- 1 ]
@@ -938,6 +963,10 @@ def __init__(
938
963
self .mrope_section = mrope_section
939
964
if self .mrope_section :
940
965
assert sum (self .mrope_section ) == rotary_dim // 2
966
+ if is_flash_attn_2_available ():
967
+ self ._use_flash_attn = True
968
+ else :
969
+ self ._use_flash_attn = False
941
970
942
971
def forward (
943
972
self ,
@@ -977,14 +1006,16 @@ def forward(
977
1006
query = query .view (num_tokens , - 1 , self .head_size )
978
1007
query_rot = query [..., :self .rotary_dim ]
979
1008
query_pass = query [..., self .rotary_dim :]
980
- query_rot = _apply_rotary_emb (query_rot , cos , sin , self .is_neox_style )
1009
+ query_rot = _apply_rotary_emb (query_rot , cos , sin , self .is_neox_style ,
1010
+ self ._use_flash_attn )
981
1011
query = torch .cat ((query_rot , query_pass ), dim = - 1 ).reshape (query_shape )
982
1012
983
1013
key_shape = key .shape
984
1014
key = key .view (num_tokens , - 1 , self .head_size )
985
1015
key_rot = key [..., :self .rotary_dim ]
986
1016
key_pass = key [..., self .rotary_dim :]
987
- key_rot = _apply_rotary_emb (key_rot , cos , sin , self .is_neox_style )
1017
+ key_rot = _apply_rotary_emb (key_rot , cos , sin , self .is_neox_style ,
1018
+ self ._use_flash_attn )
988
1019
key = torch .cat ((key_rot , key_pass ), dim = - 1 ).reshape (key_shape )
989
1020
return query , key
990
1021
0 commit comments