@@ -138,14 +138,11 @@ def flash_attention_kernel(
138138 mask_function : MaskFunctionType | None ,
139139 dropout_rate : float ,
140140):
141+ del head_dim
141142 float32 = jnp .float32
142143 # pylint: disable=invalid-name
143144 HEAD_DIM_MINOR = QKVLayout .HEAD_DIM_MINOR
144145
145- head_dim_repeats , rem = divmod (head_dim , NUM_LANES )
146- if rem != 0 :
147- raise NotImplementedError (f"{ head_dim = } should be a multiple of { NUM_LANES } " )
148-
149146 h , i , j = pl .program_id (0 ), pl .program_id (1 ), pl .program_id (2 )
150147
151148 @pl .when (j == 0 )
@@ -171,8 +168,8 @@ def init():
171168 def body (kv_compute_index , _ ):
172169 slice_k = pl .ds (kv_compute_index * bkv_compute , bkv_compute )
173170 m_prev , l_prev = m_scratch_ref [...], l_scratch_ref [...]
174- assert m_prev .shape == (bq , NUM_LANES )
175- assert l_prev .shape == (bq , NUM_LANES )
171+ assert m_prev .shape == (bq , 1 )
172+ assert l_prev .shape == (bq , 1 )
176173
177174 q = q_ref [...] if q_layout == HEAD_DIM_MINOR else q_ref [...].T
178175 qk_dims = NT_DIM_NUMBERS if k_layout == HEAD_DIM_MINOR else NN_DIM_NUMBERS
@@ -217,17 +214,13 @@ def body(kv_compute_index, _):
217214 m_curr = qk .max (axis = - 1 )[:, None ]
218215 assert m_curr .shape == (bq , 1 )
219216 m_next = jnp .maximum (m_prev , m_curr )
220- assert m_next .shape == (bq , NUM_LANES )
221-
222- bkv_repeats , rem = divmod (bkv_compute , NUM_LANES )
223- if rem != 0 :
224- raise NotImplementedError (f"{ bkv_compute = } should be a multiple of { NUM_LANES } " )
217+ assert m_next .shape == (bq , 1 )
225218
226- s_curr = jnp .exp (qk - pltpu . repeat ( m_next , bkv_repeats , axis = 1 ) )
219+ s_curr = jnp .exp (qk - m_next )
227220 assert s_curr .shape == (bq , bkv_compute )
228221
229222 l_curr = jax .lax .broadcast_in_dim (s_curr .sum (axis = - 1 ), l_prev .shape , (0 ,))
230- assert l_curr .shape == (bq , NUM_LANES )
223+ assert l_curr .shape == (bq , 1 )
231224
232225 alpha = jnp .exp (m_prev - m_next )
233226 l_next = l_curr + alpha * l_prev
@@ -254,7 +247,7 @@ def body(kv_compute_index, _):
254247 s_curr = jnp .where (dropout_mask , 0.0 , s_curr ) / (1.0 - dropout_rate )
255248 o_curr = lax .dot_general (s_curr , v , sv_dims )
256249
257- alpha_o = pltpu . repeat ( alpha , head_dim_repeats , axis = 1 )
250+ alpha_o = alpha
258251 o_scratch_ref [:] = alpha_o * o_scratch_ref [:] + o_curr
259252
260253 @pl .when (should_run )
@@ -269,10 +262,10 @@ def end():
269262 if logit_sink_ref is not None :
270263 sink_value = logit_sink_ref [h ].astype (jnp .float32 )
271264 l = l + jnp .exp (sink_value - m_scratch_ref [...])
272- l_inv = pltpu . repeat ( 1.0 / l , head_dim_repeats , axis = 1 )
265+ l_inv = 1.0 / l # TODO(dhwang2): dividing directly by `l` is a more stable operation.
273266 o_ref [...] = (o_scratch_ref [...] * l_inv ).astype (o_ref .dtype )
274267 if logsumexp_ref is not None :
275- assert logsumexp_ref .shape == (bq , NUM_LANES )
268+ assert logsumexp_ref .shape == (bq , 1 )
276269 logsumexp_ref [...] = (jnp .log (l ) + m_scratch_ref [...]).astype (logsumexp_ref .dtype )
277270
278271 m_scratch_ref [...] = jnp .zeros_like (m_scratch_ref )
@@ -546,28 +539,28 @@ def kv_segment_ids_index_map(
546539 num_scalar_prefetch = 4
547540
548541 out_shapes = [
549- jax .ShapeDtypeStruct ((bq , NUM_LANES ), jnp .float32 ), # m_scratch
550- jax .ShapeDtypeStruct ((bq , NUM_LANES ), jnp .float32 ), # l_scratch
542+ jax .ShapeDtypeStruct ((bq , 1 ), jnp .float32 ), # m_scratch
543+ jax .ShapeDtypeStruct ((bq , 1 ), jnp .float32 ), # l_scratch
551544 jax .ShapeDtypeStruct ((bq , head_dim ), jnp .float32 ), # o_scratch
552545 jax .ShapeDtypeStruct ((num_q_heads , q_seq_len , head_dim ), q .dtype ),
553546 ]
554547 out_specs = [
555548 # TODO(sharadmv): convert m/l to be scratch
556- pl .BlockSpec ((bq , NUM_LANES ), lambda h , i , j , * _ : (0 , 0 )),
557- pl .BlockSpec ((bq , NUM_LANES ), lambda h , i , j , * _ : (0 , 0 )),
549+ pl .BlockSpec ((bq , 1 ), lambda h , i , j , * _ : (0 , 0 )),
550+ pl .BlockSpec ((bq , 1 ), lambda h , i , j , * _ : (0 , 0 )),
558551 pl .BlockSpec ((bq , head_dim ), lambda h , i , j , * _ : (0 , 0 )),
559552 pl .BlockSpec ((None , bq , head_dim ), out_index_map ),
560553 ]
561554 if save_residuals :
562555 out_shapes += [
563- jax .ShapeDtypeStruct ((num_q_heads , q_seq_len , NUM_LANES ), jnp .float32 ), # logsumexp
556+ jax .ShapeDtypeStruct ((num_q_heads , q_seq_len , 1 ), jnp .float32 ), # logsumexp
564557 ]
565558
566559 def logsumexp_index_map (h , i , * _ ):
567560 return h , i , 0
568561
569562 out_specs += [
570- pl .BlockSpec ((None , bq , NUM_LANES ), logsumexp_index_map ),
563+ pl .BlockSpec ((None , bq , 1 ), logsumexp_index_map ),
571564 ]
572565 else :
573566 out_shapes += [None ]
0 commit comments