|
29 | 29 | ) |
30 | 30 | from megatron.bridge.data.collators.registry import resolve_model_collate |
31 | 31 | from megatron.bridge.models.nemotron_omni.data.collate_fn import nemotron_omni_expanded_collate_fn |
| 32 | +from megatron.bridge.peft.lora_layers import LoRALinear |
32 | 33 | from megatron.bridge.training.config import ConfigContainer |
33 | 34 | from megatron.bridge.training.mixed_precision import get_mixed_precision_config |
34 | 35 | from megatron.bridge.training.optim import _get_scheduler |
@@ -526,7 +527,7 @@ def test_super_vl_sft_recipe_reuses_omni_data_and_super_training_stack(fake_proc |
526 | 527 |
|
527 | 528 | assert isinstance(cfg, ConfigContainer) |
528 | 529 | assert _FakeAutoBridge.hf_path == _TEST_SUPER_VL_HF_ID |
529 | | - assert _FakeAutoBridge.kwargs == {"trust_remote_code": True} |
| 530 | + assert _FakeAutoBridge.kwargs == {"revision": _SUPER_VL_HF_REVISION, "trust_remote_code": True} |
530 | 531 | assert _FakeAutoBridge.load_weights is False |
531 | 532 |
|
532 | 533 | assert isinstance(cfg.dataset, EnergonDatasetConfig) |
@@ -593,12 +594,12 @@ def test_super_vl_peft_recipe_uses_native_lora_targets_and_frozen_vision(fake_pr |
593 | 594 | assert cfg.dataset.pad_to_max_length is True |
594 | 595 | assert cfg.dataset.do_validation is False |
595 | 596 | assert cfg.peft.target_modules == [ |
596 | | - "linear_qkv", |
597 | | - "linear_proj", |
598 | | - "in_proj", |
599 | | - "out_proj", |
600 | | - "linear_fc1", |
601 | | - "linear_fc2", |
| 597 | + "*language_model.*.linear_qkv", |
| 598 | + "*language_model.*.linear_proj", |
| 599 | + "*language_model.*.in_proj", |
| 600 | + "*language_model.*.out_proj", |
| 601 | + "*language_model.*.linear_fc1", |
| 602 | + "*language_model.*.linear_fc2", |
602 | 603 | ] |
603 | 604 | assert cfg.peft.dim == 32 |
604 | 605 | assert cfg.peft.alpha == 32 |
@@ -648,6 +649,46 @@ def test_super_vl_peft_recipe_uses_native_lora_targets_and_frozen_vision(fake_pr |
648 | 649 | assert cfg.ddp.grad_reduce_in_fp32 is True |
649 | 650 |
|
650 | 651 |
|
| 652 | +@pytest.mark.unit |
| 653 | +@pytest.mark.parametrize( |
| 654 | + "recipe_func", |
| 655 | + [ |
| 656 | + _super_vl_h100_recipe_module.nemotron_35_super_vl_peft_16gpu_h100_bf16_config, |
| 657 | + _super_vl_gb200_recipe_module.nemotron_35_super_vl_peft_16gpu_gb200_bf16_config, |
| 658 | + ], |
| 659 | + ids=["h100", "gb200"], |
| 660 | +) |
| 661 | +@pytest.mark.parametrize("wrapped", [False, True], ids=["bare", "wrapped"]) |
| 662 | +def test_super_vl_peft_adapters_only_modify_language_modules(recipe_func, wrapped, fake_processor): |
| 663 | + cfg = _build_config(recipe_func, fake_processor) |
| 664 | + target_names = ("linear_qkv", "linear_proj", "in_proj", "out_proj", "linear_fc1", "linear_fc2") |
| 665 | + |
| 666 | + def linear_stack(): |
| 667 | + return torch.nn.ModuleDict({name: torch.nn.Linear(4, 4) for name in target_names}) |
| 668 | + |
| 669 | + # Identical leaf names expose accidental unqualified matches in both media |
| 670 | + # components, while the language MTP path must still receive adapters. |
| 671 | + model = torch.nn.Module() |
| 672 | + model.language_model = torch.nn.ModuleDict({"decoder": linear_stack(), "mtp": linear_stack()}) |
| 673 | + model.vision_model = torch.nn.ModuleDict({"decoder": linear_stack()}) |
| 674 | + model.vision_projection = torch.nn.ModuleDict({"encoder": linear_stack()}) |
| 675 | + if wrapped: |
| 676 | + wrapper = torch.nn.Module() |
| 677 | + wrapper.module = model |
| 678 | + model = wrapper |
| 679 | + base_parameters = list(model.parameters()) |
| 680 | + model = cfg.peft(model) |
| 681 | + |
| 682 | + prefix = "module." if wrapped else "" |
| 683 | + expected = {f"{prefix}language_model.{stack}.{name}" for stack in ("decoder", "mtp") for name in target_names} |
| 684 | + adapted = {name for name, module in model.named_modules() if isinstance(module, LoRALinear)} |
| 685 | + assert adapted == expected |
| 686 | + assert all(not parameter.requires_grad for parameter in base_parameters) |
| 687 | + trainable = {name for name, parameter in model.named_parameters() if parameter.requires_grad} |
| 688 | + assert trainable |
| 689 | + assert all(name.startswith(f"{prefix}language_model.") and ".adapter." in name for name in trainable) |
| 690 | + |
| 691 | + |
651 | 692 | def test_super_vl_pretrain_recipe_uses_tuned_h100_training_policy(fake_processor): |
652 | 693 | cfg = _build_config( |
653 | 694 | _super_vl_h100_recipe_module.nemotron_35_super_vl_pretrain_64gpu_h100_bf16_config, |
@@ -682,7 +723,6 @@ def test_super_vl_pretrain_recipe_uses_tuned_h100_training_policy(fake_processor |
682 | 723 | assert cfg.model.moe_expert_capacity_factor is None |
683 | 724 | assert cfg.model.moe_pad_expert_input_to_capacity is False |
684 | 725 | assert cfg.model.moe_hybridep_pad_uneven_dispatch_inputs is False |
685 | | - assert cfg.model.moe_hybridep_assume_equal_dispatch_inputs is True |
686 | 726 | assert cfg.model.moe_flex_dispatcher_num_sms == 32 |
687 | 727 | assert cfg.model.moe_hybridep_num_sms is None |
688 | 728 | assert cfg.model.moe_hybridep_num_sms_preprocessing == 108 |
@@ -774,7 +814,6 @@ def test_super_vl_pretrain_recipe_uses_gb200_nvl72_policy(fake_processor): |
774 | 814 | assert cfg.model.moe_expert_capacity_factor is None |
775 | 815 | assert cfg.model.moe_pad_expert_input_to_capacity is False |
776 | 816 | assert cfg.model.moe_hybridep_pad_uneven_dispatch_inputs is False |
777 | | - assert cfg.model.moe_hybridep_assume_equal_dispatch_inputs is True |
778 | 817 | assert cfg.model.moe_flex_dispatcher_num_sms == 32 |
779 | 818 | assert cfg.model.moe_hybridep_num_sms == 32 |
780 | 819 | assert cfg.model.moe_permute_fusion_into_hybridep is False |
@@ -926,12 +965,12 @@ def test_super_vl_peft_recipe_uses_gb200_support_topology(fake_processor): |
926 | 965 | assert isinstance(cfg.dataset, EnergonDatasetConfig) |
927 | 966 | assert cfg.dataset.task_encoder.hf_processor_path == _TEST_SUPER_VL_HF_ID |
928 | 967 | assert cfg.peft.target_modules == [ |
929 | | - "linear_qkv", |
930 | | - "linear_proj", |
931 | | - "in_proj", |
932 | | - "out_proj", |
933 | | - "linear_fc1", |
934 | | - "linear_fc2", |
| 968 | + "*language_model.*.linear_qkv", |
| 969 | + "*language_model.*.linear_proj", |
| 970 | + "*language_model.*.in_proj", |
| 971 | + "*language_model.*.out_proj", |
| 972 | + "*language_model.*.linear_fc1", |
| 973 | + "*language_model.*.linear_fc2", |
935 | 974 | ] |
936 | 975 | assert cfg.peft.dim == 32 |
937 | 976 | assert cfg.peft.alpha == 32 |
|
0 commit comments