-
Notifications
You must be signed in to change notification settings - Fork 5k
[AutoTP] Add support for vocab-parallel LM head and related configurations #8309
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: master
Are you sure you want to change the base?
Changes from all commits
8cf638a
bf8b7e2
8f03c27
97078ce
a3b4405
a47d7ab
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 |
|---|---|---|
|
|
@@ -846,6 +846,22 @@ def _apply_autotp_partitioning(self, model, tp_config): | |
| from deepspeed.runtime.tensor_parallel.config import _get_hf_tp_plan | ||
| hf_tp_plan = _get_hf_tp_plan(model) | ||
|
|
||
| def finalize_autotp(autotp=None, attach_uc_metadata=False): | ||
| if autotp is not None: | ||
| autotp.register_replicated_grad_hooks(model) | ||
|
|
||
| from deepspeed.module_inject.layers import VocabParallelLinear | ||
| vocab_parallel_heads = [module for module in model.modules() if isinstance(module, VocabParallelLinear)] | ||
| if len(vocab_parallel_heads) > 1: | ||
| raise ValueError("Unable to choose a loss for multiple no-gather vocab-parallel LM heads") | ||
| if vocab_parallel_heads: | ||
| from deepspeed.sequence.cross_entropy import configure_vocab_parallel_loss | ||
| configure_vocab_parallel_loss(model, vocab_parallel_heads[0]) | ||
|
|
||
| if attach_uc_metadata: | ||
| setattr(model, UNIVERSAL_CHECKPOINT_INFO, collect_autotp_universal_checkpoint_info(model)) | ||
| setattr(model, "ds_autotp_parsed", True) | ||
|
|
||
| if partition_config is not None: | ||
| autotp = AutoTP(module=model, | ||
| all_reduce_linears=(), | ||
|
|
@@ -855,15 +871,14 @@ def _apply_autotp_partitioning(self, model, tp_config): | |
| orig_layer_impl=None, | ||
| keep_module_on_host=tp_config.keep_module_on_host, | ||
| partition_config=partition_config, | ||
| vocab_parallel_lm_head=tp_config.vocab_parallel_lm_head, | ||
| model_config=model_config, | ||
| tp_grain_size=tp_config.tensor_parallel.tp_grain_size, | ||
| training_mode=True) | ||
| autotp.set_tensor_parallel_config(tp_size, tp_config.tensor_parallel.tp_group) | ||
| autotp.update_linear_policies() | ||
| autotp._replace_module(model) | ||
| autotp.register_replicated_grad_hooks(model) | ||
| setattr(model, UNIVERSAL_CHECKPOINT_INFO, collect_autotp_universal_checkpoint_info(model)) | ||
| setattr(model, "ds_autotp_parsed", True) | ||
| finalize_autotp(autotp, attach_uc_metadata=True) | ||
| return | ||
|
|
||
| if tp_size <= 1: | ||
|
|
@@ -896,16 +911,15 @@ def _apply_autotp_partitioning(self, model, tp_config): | |
| orig_layer_impl=None, | ||
| keep_module_on_host=tp_config.keep_module_on_host, | ||
| partition_config=tp_plan_config, | ||
| vocab_parallel_lm_head=tp_config.vocab_parallel_lm_head, | ||
| model_config=model_config, | ||
| tp_grain_size=tp_config.tensor_parallel.tp_grain_size, | ||
| training_mode=True, | ||
| ) | ||
| autotp.set_tensor_parallel_config(tp_size, tp_config.tensor_parallel.tp_group) | ||
| autotp.update_linear_policies() | ||
| autotp._replace_module(model) | ||
| autotp.register_replicated_grad_hooks(model) | ||
| setattr(model, UNIVERSAL_CHECKPOINT_INFO, collect_autotp_universal_checkpoint_info(model)) | ||
| setattr(model, "ds_autotp_parsed", True) | ||
| finalize_autotp(autotp, attach_uc_metadata=True) | ||
| return | ||
| log_dist( | ||
| f"AutoTP: effective HuggingFace tp_plan could not be converted; falling back to heuristic AutoTP. " | ||
|
|
@@ -916,13 +930,30 @@ def _apply_autotp_partitioning(self, model, tp_config): | |
| log_dist("AutoTP: no effective HuggingFace tp_plan was found; falling back to heuristic AutoTP.", | ||
| ranks=[0]) | ||
|
|
||
| vocab_head_autotp = None | ||
| if tp_config.vocab_parallel_lm_head: | ||
| vocab_head_autotp = AutoTP(module=model, | ||
| all_reduce_linears=(), | ||
| prefix="", | ||
| state_dict=None, | ||
| linear_layer_setting=(torch.nn.Linear, torch.nn.Embedding), | ||
| orig_layer_impl=None, | ||
| keep_module_on_host=tp_config.keep_module_on_host, | ||
| vocab_parallel_lm_head=True, | ||
| model_config=model_config, | ||
| tp_grain_size=tp_config.tensor_parallel.tp_grain_size, | ||
| training_mode=True) | ||
| vocab_head_autotp.set_tensor_parallel_config(tp_size, tp_config.tensor_parallel.tp_group) | ||
| vocab_head_autotp._resolve_vocab_parallel_lm_head() | ||
|
|
||
| parser_dict = AutoTP.tp_parser(model) | ||
| for client_module, injection_policy in parser_dict: | ||
| tp_config.injection_policy_tuple = injection_policy | ||
| replace_transformer_layer(client_module, model, None, tp_config, model_config, training_mode=True) | ||
|
|
||
| setattr(model, UNIVERSAL_CHECKPOINT_INFO, collect_autotp_universal_checkpoint_info(model)) | ||
| setattr(model, "ds_autotp_parsed", True) | ||
| if vocab_head_autotp is not None: | ||
| vocab_head_autotp._replace_vocab_parallel_lm_head() | ||
| finalize_autotp(attach_uc_metadata=True) | ||
|
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.
When neither a partition config nor a convertible HuggingFace TP plan exists, this branch only invokes AGENTS.md reference: AGENTS.md:L35-L36 Useful? React with 👍 / 👎.
Contributor
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. Fixed in a3b440523 . The heuristic AutoTP path now creates a dedicated AutoTP instance for the output head and explicitly replaces the single supported |
||
|
|
||
| def __del__(self): | ||
| try: | ||
|
|
||
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.
For the usual module order where a tied embedding precedes
lm_head, an HF/custom plan can replace the embedding first;_slice_embeddingcreates a newParameter, so this later identity scan no longer sees that the original head and embedding were tied. The configuration is then incorrectly accepted and silently breaks weight sharing instead of raising the documented error. Capture and validate candidate ties before traversal mutates either module; integration coverage using an actual tied model and embedding plan is also required.AGENTS.md reference: AGENTS.md:L35-L36
Useful? React with 👍 / 👎.
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.
Fixed in a3b440523 . AutoTP now records the identities of vocab-head modules tied to embeddings when it is constructed, before traversal can replace an embedding parameter.
_validate_untied_vocab_head()checks this original tie information as well as the current parameter identity. A regression test covers anembedding_rowwiseplan followed by acolwisetiedlm_headand verifies that the configuration is rejected before weight sharing can be broken.