Skip to content

Commit c5b135a

Browse files
Add experimental attention quantization flags.
This will add two experimental flags to the splash attention config, to quantize Q and K respectively. Attention quantization is currently a research project so these should be turned off by default. In the future we will support more quantization options for the backwards pass, RoPE vs. no-RoPE, more dtypes, etc. PiperOrigin-RevId: 949075090
1 parent e932496 commit c5b135a

3 files changed

Lines changed: 33 additions & 0 deletions

File tree

src/maxtext/configs/base.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,8 @@ local_sa_v_layout: None # inherits from sa_v_layout if None
11201120
local_use_splash_scheduler: None # inherits from use_splash_scheduler if None
11211121
local_sa_fuse_reciprocal: None # inherits from sa_fuse_reciprocal if None
11221122
local_sa_use_base2_exp: None # inherits from sa_use_base2_exp if None
1123+
experimental_sa_quant_q_fp8: False # Experimental flag: If enabled, the Q tensor in splash attention is quantized to jnp.float8_e4m3fn, without scaling factors.
1124+
experimental_sa_quant_k_fp8: False # Experimental flag: If enabled, the K tensor in splash attention is quantized to jnp.float8_e4m3fn, without scaling factors.
11231125
use_max_logit_estimate: -1 # -1 means no estimate, any > 0 value will be used as max logit estimate
11241126
cost_estimate_flops_fwd: -1 # -1 means using splash default cost estmiation, any >= 0 value will be used as cost estmiation for splash to overlap for communication (forward)
11251127
cost_estimate_flops_bwd: -1 # -1 means using splash default cost estmiation, any >= 0 value will be used as cost estmiation for splash to overlap for communication (backward)

src/maxtext/configs/types.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,20 @@ class SplashAttention(BaseModel):
740740
local_use_splash_scheduler: bool | None = Field(None, description="Use experimental local splash attention scheduler.")
741741
local_sa_fuse_reciprocal: bool | None = Field(None, description="Maps to local fuse_reciprocal in SplashConfig.")
742742
local_sa_use_base2_exp: bool | None = Field(None, description="Maps to local use_base2_exp in SplashConfig.")
743+
experimental_sa_quant_q_fp8: bool | None = Field(
744+
None,
745+
description=(
746+
"Experimental flag: If enabled, the Q tensor in splash attention is"
747+
" quantized to jnp.float8_e4m3fn, without scaling factors."
748+
),
749+
)
750+
experimental_sa_quant_k_fp8: bool | None = Field(
751+
None,
752+
description=(
753+
"Experimental flag: If enabled, the K tensor in splash attention is"
754+
" quantized to jnp.float8_e4m3fn, without scaling factors."
755+
),
756+
)
743757
use_max_logit_estimate: int = Field(
744758
-1,
745759
description="-1 means no estimate, any > 0 value will be used as max logit estimate",
@@ -3456,6 +3470,16 @@ def calculate_global_batch_sizes(per_device_batch_size, expansion_factor, num_de
34563470
"Please disable attn_logits_soft_cap when using use_qk_clip."
34573471
)
34583472

3473+
if self.experimental_sa_quant_q_fp8 and self.attention_type != "mla":
3474+
raise ValueError(
3475+
"Q quantization is currently only supported with"
3476+
f" attention_type='mla'. Found attention_type='{self.attention_type}'"
3477+
)
3478+
if self.experimental_sa_quant_k_fp8 and self.attention_type != "mla":
3479+
raise ValueError(
3480+
"K quantization is currently only supported with"
3481+
f" attention_type='mla'. Found attention_type='{self.attention_type}'"
3482+
)
34593483
if self.share_kv_projections and self.fused_qkv:
34603484
raise ValueError("`share_kv_projections` is not compatible with `fused_qkv`.")
34613485
if self.share_kv_projections and self.attention_type == "mla":

src/maxtext/layers/attention_mla.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,10 @@ def mla_query_projection(
876876
# Query projection is scaled by self.softmax_scale to be consistent MaxText implementation.
877877
# DeepSeek v3 was doing it in attention score computation.
878878
query = jnp.concatenate([q_nope, q_pe], axis=-1) * self.softmax_scale
879+
880+
if self.config.experimental_sa_quant_q_fp8:
881+
query = query.astype(jnp.float8_e4m3fn)
882+
879883
query = self._maybe_shard_with_logical(query, query_logical_name)
880884
return query, low_rank_q
881885

@@ -899,6 +903,9 @@ def mla_get_key_value(self, low_rank_main, key_rope, model_mode):
899903

900904
key = jnp.concatenate([key_nope, key_rope], axis=-1)
901905

906+
if self.config.experimental_sa_quant_k_fp8:
907+
key = key.astype(jnp.float8_e4m3fn)
908+
902909
key = self._maybe_shard_with_logical(key, key_logical_name)
903910
value = self._maybe_shard_with_logical(value, value_logical_name)
904911
return key, value

0 commit comments

Comments
 (0)