-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Add mock SFT dataset and varlen dataset family #6685
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
Changes from all commits
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 |
|---|---|---|
|
|
@@ -1246,13 +1246,6 @@ def validate_args(args, defaults={}): | |
| if args.rl_use_sequence_packing: | ||
| args.consumed_train_bins = 0 | ||
|
|
||
| # Support for variable sequence lengths across batches/microbatches. | ||
| # set it if the dataloader supports generation of variable sequence lengths | ||
| # across batches/microbatches. Due to additional communication overhead | ||
| # during pipeline parallelism, it should not be set if sequence length | ||
| # is constant during training. | ||
| args.variable_seq_lengths = False | ||
|
|
||
| # Iteration-based training. | ||
| # Skip these checks when skip_train is set: LR config is irrelevant. | ||
| if args.train_iters and not args.skip_train: | ||
|
|
@@ -1430,6 +1423,23 @@ def validate_args(args, defaults={}): | |
| assert args.dataloader_type == 'single', 'Hybrid context parallelism only supported with single dataloader type' | ||
| assert args.calculate_per_token_loss, 'Hybrid context parallelism must be used with --calculate-per-token-loss' | ||
|
|
||
| # Support for variable sequence lengths across batches/microbatches. | ||
| # set it if the dataloader supports generation of variable sequence lengths | ||
| # across batches/microbatches. Due to additional communication overhead | ||
| # during pipeline parallelism, it should not be set if sequence length | ||
| # is constant during training. | ||
| args.variable_seq_lengths = False | ||
| if args.mock_data and args.sft and args.sft_mock_dataset_config_json is None: | ||
| args.sft_mock_dataset_config_json = json.dumps( | ||
| { | ||
| "mode": "distribution", | ||
| "type": "lognormal", | ||
| "min_seq_len": args.seq_length // 2, | ||
| "max_seq_len": args.seq_length, | ||
| "mean_seq_len": args.seq_length // 4 * 3, | ||
| "lognormal_sigma": 1.1, | ||
| } | ||
| ) | ||
| # disable async_tensor_model_parallel_allreduce when | ||
| # model parallel memory optimization is enabled | ||
| if (args.tensor_model_parallel_size > 1 or args.context_parallel_size > 1) \ | ||
|
|
@@ -1642,6 +1652,19 @@ def validate_args(args, defaults={}): | |
| if args.ckpt_format == "fsdp_dtensor": | ||
| assert args.use_megatron_fsdp, "--ckpt-format fsdp_dtensor is only tested with Megatron FSDP." | ||
|
|
||
| # Packed-sequence buffer-size check. Placed after varlen scheduler | ||
| # auto-select so it validates the final resolved scheduler. | ||
| if args.sequence_packing_scheduler is not None: | ||
|
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. Can these checks be in the config dataclass post_init? |
||
| args.variable_seq_lengths = True | ||
| assert args.max_seqlen_per_dp_cp_rank is not None, ( | ||
| "--max-seqlen-per-dp-cp-rank must be set when using sequence packing" | ||
| ) | ||
| total_cp_ranks = args.context_parallel_size | ||
| assert total_cp_ranks * args.max_seqlen_per_dp_cp_rank >= args.seq_length, ( | ||
| f'Packed sequence buffer size ({total_cp_ranks * args.max_seqlen_per_dp_cp_rank}) ' | ||
| f'must be >= single sequence max length ({args.seq_length})' | ||
| ) | ||
|
|
||
| # Data blend checks | ||
| assert args.mock_data + \ | ||
| bool(args.data_path) + \ | ||
|
|
@@ -2336,6 +2359,9 @@ def _add_network_size_args(parser): | |
| "gtp_weight_remat_size", | ||
| # internal/derived: controlled only via --expert-tensor-parallel-num-weight-shards | ||
| "expert_gtp_weight_remat_size", | ||
| "max_seqlen_per_dp_cp_rank", | ||
| "hybrid_context_parallel", | ||
| "sequence_packing_scheduler", | ||
| ] | ||
| transformer_factory = ArgumentGroupFactory(TransformerConfig, exclude=exclude) | ||
| transformer_group = transformer_factory.build_group(parser, "transformer configuration") | ||
|
|
@@ -3172,6 +3198,14 @@ def _add_distributed_args(parser): | |
| 'all layers will share the same communication type. Users can also ' | ||
| 'specify separated types for each layer like ' | ||
| '--cp-comm-type p2p p2p a2a a2a a2a+p2p a2a+p2p') | ||
| group.add_argument('--max-seqlen-per-dp-cp-rank', type=int, default=None, | ||
| help='Maximum sequence length per CP rank. This is used to calculate the ' | ||
| 'number of sub-samples assigned to each CP rank when using heterogeneous context parallel.') | ||
| group.add_argument('--hybrid-context-parallel', action='store_true', default=False, | ||
| help='Enables hybrid context parallel. This is used to balance the workload ' | ||
| 'of each CP rank when we use packed samples with variable sequence lengths. ' | ||
| 'Requires --max-seqlen-per-dp-cp-rank to be set.') | ||
| group.add_argument('--sequence-packing-scheduler', type=str, default=None, choices=['dp_balanced']) | ||
| group.add_argument('--fake-process-group', action='store_true', default=False, | ||
| help='If set, initialize with fake distributed process group and all distributed communication operations will be skipped. \ | ||
| This is quite useful for profiling memory usage of distributed training with just one GPU. \ | ||
|
|
@@ -3719,8 +3753,28 @@ def _add_kitchen_quantization_arguments(parser: argparse.ArgumentParser): | |
| def _add_sft_args(parser): | ||
| group = parser.add_argument_group(title='sft') | ||
| group.add_argument('--sft', action="store_true", help='Megatron SFT training') | ||
| group.add_argument('--sft-tokenizer-prompt-format', type=str, default="nemotron-h-aligned", | ||
| help='SFT prompt format.') | ||
| group.add_argument( | ||
|
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. Why change the formatting here? |
||
| '--sft-tokenizer-prompt-format', | ||
| type=str, | ||
| default="nemotron-h-aligned", | ||
| help='SFT prompt format.', | ||
| ) | ||
| group.add_argument( | ||
|
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. Can you match the formatting of other arguments? |
||
| '--sft-mock-dataset-config-json', | ||
| type=str, | ||
| default=None, | ||
| help='This config provides the necessary information for the mock dataset. ' | ||
| 'Accepts either an inline JSON literal or a path to a JSON file containing ' | ||
| 'the same schema. You can either specify a CSV file that contains sequence lengths, ' | ||
| 'where each line stores the length of a sequence, for example: ' | ||
| '{"mode":"file","path":"/path/to/file"}. Alternatively, you can specify a distribution ' | ||
| '(currently only supporting lognormal distribution) along with the required parameters, ' | ||
| 'for example, {"mode":"distribution","type":"lognormal","min_seq_len":1024,' | ||
| '"max_seq_len":2048,"mean_seq_len":1536,"lognormal_sigma":1.1}, where sigma controls ' | ||
| 'the variability of the lognormal distribution. ' | ||
| 'If not specified and --mock-data is set, defaults to a lognormal distribution with ' | ||
| 'min_seq_len=seq_length//2, max_seq_len=seq_length, mean_seq_len=seq_length*3//4, lognormal_sigma=1.1.', | ||
| ) | ||
| return parser | ||
|
|
||
| def _add_logits_distillation_args(parser): | ||
|
|
||
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.
Shouldn't some/most of these checks be in model_parallel_config if that's where sequence_packing_scheduler is?