-
Notifications
You must be signed in to change notification settings - Fork 577
Support quantization for tokamax gmm v2 #4451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 8 commits
f814413
2cec661
b135e8e
f9f37b8
22bd5bc
159ea30
0db4e43
5073aef
f201c4a
a251753
f4553b6
fc5ac54
fced014
2ae50ca
61e72b2
16ac8aa
7b84920
51376c1
ded3f1b
5334a53
4d8578b
6225e47
201a8fc
38bd713
608305d
1ad5e94
87b2c8e
a5aac8c
9b67772
a911746
86d3272
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -39,7 +39,8 @@ | |||||||
| from maxtext.utils import max_logging | ||||||||
|
|
||||||||
| logger = logging.getLogger(__name__) | ||||||||
| logger.setLevel(os.environ.get("LOGLEVEL", "INFO")) | ||||||||
| # TODO: revert before merge | ||||||||
| # logger.setLevel(os.environ.get("LOGLEVEL", "INFO")) | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🟡 The logger level restriction was commented out during development with a "revert before merge" TODO. Leaving this in the codebase can lead to verbosity issues or inconsistent logger behavior in production. Please restore the logger level setup and remove the TODO.
Suggested change
|
||||||||
|
|
||||||||
| _BASE_CONFIG_ATTR = "base_config" | ||||||||
| _MAX_PREFIX = "M_" | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -352,6 +352,7 @@ class Checkpointing(BaseModel): | |
| source_checkpoint_layout: Literal["orbax", "safetensors", "safetensors_dynamic"] = Field( | ||
| "orbax", description="The layout of the source checkpoint to load." | ||
| ) | ||
| save_checkpoint_on_start: bool = Field(True, description="If True, saves an initial checkpoint upon training start.") | ||
| save_checkpoint_on_completion: bool = Field( | ||
| True, description="If True, saves a final checkpoint upon training completion." | ||
| ) | ||
|
|
@@ -444,7 +445,7 @@ class Quantization(BaseModel): | |
| use_qwix_quantization: bool = Field(False, description="Whether to use qwix for quantization.") | ||
| use_manual_quantization: bool = Field( | ||
| False, | ||
| description="Whether to use manual quantization for batch split. Only used if use_batch_split_schedule is True.", | ||
| description="Whether to use manual quantization for batch split. Only used if `use_batch_split_schedule=True`.", | ||
| ) | ||
| weight_quantization_calibration_method: str = Field( | ||
| "absmax", | ||
|
|
@@ -616,20 +617,6 @@ class Attention(BaseModel): | |
| use_post_attn_norm: bool = Field(False, description="Apply LayerNorm after the attention block.") | ||
| use_post_ffw_norm: bool = Field(False, description="Apply LayerNorm after the feed-forward block.") | ||
| use_ragged_attention: bool = Field(False, description="Whether to use ragged attention kernels.") | ||
| use_tokamax_gmm: bool = Field( | ||
| False, | ||
| description="Whether to use the Tokamax library for GMM kernel implementation.", | ||
| ) | ||
| use_gmm_v2: bool = Field( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we still have this config that sets all fwd, dlhs and drhs to true in types.py when true?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have refactored the flag. Instead of three flags, we now use the original single flag
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keep |
||
| False, | ||
| description=( | ||
| "Whether to use GMM v2 (with bf16 activations and weights) for MoE." | ||
| " Requires use_tokamax_gmm: true. Currently incompatible with quantization." | ||
| ), | ||
| ) | ||
| num_moe_emb_chunks: int = Field( | ||
| 0, description="Number of chunks for overlapping token all-gather and GMM computation along embedding dimension." | ||
| ) | ||
| ragged_block_size: int = Field(256, description="Block size for ragged attention.") | ||
| enable_padding_causal_mask: bool = Field(True, description="Temporary flag for Transformer Engine padding.") | ||
| use_tokamax_splash: bool = Field(False, description="Whether to use tokamax splash attention.") | ||
|
|
@@ -969,6 +956,27 @@ class MoEKernels(BaseModel): | |
|
|
||
| merge_gating_gmm: bool = Field(False, description="whether to merge the two gating gmm kernels into one.") | ||
|
|
||
| # tokamax gmm | ||
| use_tokamax_gmm: bool = Field( | ||
| False, | ||
| description="Whether to use the Tokamax library for GMM kernel implementation.", | ||
| ) | ||
| use_gmm_v2_fwd: bool = Field( | ||
| False, | ||
| description="Whether to use GMM v2 for MoE forward pass. (Requires use_tokamax_gmm: true)", | ||
| ) | ||
| use_gmm_v2_dlhs: bool = Field( | ||
| False, | ||
| description="Whether to use GMM v2 for MoE backward pass (dlhs). (Requires use_tokamax_gmm: true)", | ||
| ) | ||
| use_gmm_v2_drhs: bool = Field( | ||
| False, | ||
| description="Whether to use GMM v2 for MoE backward pass (drhs). (Requires use_tokamax_gmm: true)", | ||
| ) | ||
| num_moe_emb_chunks: int = Field( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rebase?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously, these are under AttentionConfig, here. I am moving them to MoEConfig. |
||
| 0, description="Number of chunks for overlapping token all-gather and GMM computation along embedding dimension." | ||
| ) | ||
|
|
||
|
|
||
| class DeepSeekMoE(BaseModel): | ||
| """Configuration specific to DeepSeek-style MoE layers.""" | ||
|
|
@@ -2691,6 +2699,7 @@ def validate_num_moe_emb_chunks(self): | |
| Validates that num_moe_emb_chunks is used with supported settings. | ||
| """ | ||
| if self.num_moe_emb_chunks > 0: | ||
| # TODO: update self.use_gmm_v2 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Does this need to be removed prior to merging?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have updated the validation check for |
||
| if not self.use_gmm_v2 or not self.use_ring_of_experts: | ||
| raise ValueError( | ||
| f"num_moe_emb_chunks > 0 requires use_gmm_v2=True and use_ring_of_experts=True. " | ||
|
|
@@ -2946,6 +2955,10 @@ def get_num_target_devices(): | |
| "Please migrate to Qwix by setting use_qwix_quantization=True." | ||
| ) | ||
|
|
||
| # Check quant config is non-empty for Qwix quantization | ||
| if self.use_qwix_quantization and not self.quantization: | ||
| raise ValueError("Qwix quantization is enabled but quantization is not set.") | ||
|
|
||
| # Default quantization sharding count to number of local devices if not set. | ||
| if self.quantization_local_shard_count == -1: | ||
| try: | ||
|
|
@@ -3573,11 +3586,36 @@ def calculate_global_batch_sizes(per_device_batch_size, expansion_factor, num_de | |
| if self.share_kv_projections and self.attention_type == "mla": | ||
| raise ValueError("`share_kv_projections` is not compatible with `attention_type='mla'`.") | ||
|
|
||
| if self.use_gmm_v2 and (self.quantization or self.use_qwix_quantization): | ||
| raise ValueError("Quantization with GMM v2 is not supported yet.") | ||
| if self.use_gmm_v2 and not self.use_tokamax_gmm: | ||
| if self.use_manual_quantization and not self.use_batch_split_schedule: | ||
| raise ValueError("manual quantization is only used when `use_batch_split_schedule=True`.") | ||
|
|
||
| if (self.use_gmm_v2_fwd or self.use_gmm_v2_dlhs or self.use_gmm_v2_drhs) and not self.use_tokamax_gmm: | ||
| raise ValueError("GMM v2 requires `use_tokamax_gmm=true`.") | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shall we also add a check to disable the use of use_gmm_v2* and use_manual_quantization together?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have added check to ensure
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added another check to reflect that gmm v2 is not supported for batch-split. |
||
| # Ensure GMM v2 flags (fwd, dlhs, drhs) are set to a valid combination: | ||
| # - v1+v1+v1 (False, False, False) | ||
| # - v2+v2+v2 (True, True, True) | ||
| # - v2+v1+v2 (True, False, True) | ||
| gmm_v2_combo = ( | ||
| self.use_gmm_v2_fwd, | ||
| self.use_gmm_v2_dlhs, | ||
| self.use_gmm_v2_drhs, | ||
| ) | ||
| valid_combos = { | ||
| (False, False, False), # 111 (v1+v1+v1) | ||
| (True, True, True), # 222 (v2+v2+v2) | ||
| (True, False, True), # 212 (v2+v1+v2) | ||
|
CaptainO5 marked this conversation as resolved.
Outdated
|
||
| } | ||
| if gmm_v2_combo not in valid_combos: | ||
| raise ValueError( | ||
| "Invalid GMM v2 configuration combination (fwd, dlhs, drhs). " | ||
| "Allowed combinations are:\n" | ||
| " - v1+v1+v1 (False, False, False)\n" | ||
| " - v2+v2+v2 (True, True, True)\n" | ||
| " - v2+v1+v2 (True, False, True)\n" | ||
| f"But got: {gmm_v2_combo}" | ||
| ) | ||
|
|
||
| for val in self.compress_ratios: | ||
| if val != 0 and val < 4: | ||
| raise ValueError(f"compress_ratio must be 0 (disabled) or >= 4, got {val}") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if we should simplify back to
use_gmm_v2config for users? What's the gain for using different combination?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, could you help update this file when applies?
maxtext/docs/reference/core_concepts/moe_configuration.md
Line 4 in fe5032a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the advice! I have added
use_gmm_v2tomoe_configure.md.