Skip to content

Commit 6dac3ef

Browse files
authored
Fix sm-train unit tests + use single logger in base trainer (#6030)
* cleanup: use a single logger in base_trainer * fix: update recipe resolver unit tests
1 parent 1e1cbcf commit 6dac3ef

2 files changed

Lines changed: 60 additions & 5 deletions

File tree

‎sagemaker-train/src/sagemaker/train/base_trainer.py‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
from sagemaker.train.defaults import TrainDefaults
3535
from sagemaker.train.utils import _get_unique_name
3636

37+
logger = logging.getLogger(__name__)
38+
39+
3740
class BaseTrainer(ABC):
3841
"""Abstract base class for all SageMaker training workflows.
3942
@@ -156,7 +159,6 @@ def _fetch_full_recipe_template(self) -> Optional[Dict[str, Any]]:
156159
157160
Returns None if the template can't be fetched (fallback to synthetic template).
158161
"""
159-
logger = logging.getLogger(__name__)
160162
frt = getattr(self.hyperparameters, '_full_recipe_template', None) if hasattr(self, 'hyperparameters') else None
161163
if isinstance(frt, dict):
162164
return frt
@@ -392,8 +394,6 @@ def _train_serverful_smtj(self, training_dataset=None, validation_dataset=None,
392394
)
393395
from sagemaker.train.defaults import TrainDefaults
394396

395-
logger = logging.getLogger(__name__)
396-
397397
sagemaker_session = TrainDefaults.get_sagemaker_session(
398398
sagemaker_session=self.sagemaker_session
399399
)
@@ -848,8 +848,6 @@ def _train_hyperpod(self, training_dataset=None, validation_dataset=None,
848848
(SFT, DPO, RLVR).
849849
"""
850850

851-
logger = logging.getLogger(__name__)
852-
853851
sagemaker_session = TrainDefaults.get_sagemaker_session(
854852
sagemaker_session=self.sagemaker_session
855853
)

‎sagemaker-train/tests/unit/train/test_trainer_recipe_integration.py‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,9 @@ def test_non_spec_keys_flow_into_train_hyperparameters(
611611
overrides={"training_config": {"sequence_length": 8192}},
612612
)
613613

614+
# For serverless (ie compute=None): Non-spec keys that aren't overridden don't flow to hyperparams
615+
trainer.compute = MagicMock()
616+
614617
with patch("sagemaker.train.sft_trainer.TrainingJob") as mock_tj, \
615618
patch("sagemaker.train.sft_trainer.TrainDefaults") as mock_defaults, \
616619
patch("sagemaker.train.sft_trainer._create_input_data_config") as mock_input, \
@@ -640,6 +643,54 @@ def test_non_spec_keys_flow_into_train_hyperparameters(
640643
assert "warmup_ratio" in final_hp
641644
assert final_hp["warmup_ratio"] == "0.1"
642645

646+
@patch("sagemaker.train.sft_trainer._validate_eula_for_gated_model", return_value=False)
647+
@patch("sagemaker.train.sft_trainer._get_fine_tuning_options_and_model_arn")
648+
@patch("sagemaker.train.sft_trainer._validate_and_resolve_model_package_group", return_value="my-group")
649+
@patch("sagemaker.train.sft_trainer._resolve_model_and_name", return_value=("model_obj", "nova-lite-v2"))
650+
def test_serverless_non_spec_keys_dont_flow_into_train_hyperparameters(
651+
self, mock_resolve, mock_validate_group, mock_get_options, mock_eula,
652+
mock_hyperparams_with_full_template
653+
):
654+
"""Non-spec keys from full template are included in final training hyperparameters."""
655+
mock_get_options.return_value = (mock_hyperparams_with_full_template, "model-arn", False)
656+
657+
from sagemaker.train.sft_trainer import SFTTrainer
658+
659+
trainer = SFTTrainer(
660+
model="nova-lite-v2",
661+
model_package_group="my-group",
662+
training_dataset="s3://bucket/train.jsonl",
663+
overrides={"training_config": {"sequence_length": 8191}},
664+
)
665+
666+
with patch("sagemaker.train.sft_trainer.TrainingJob") as mock_tj, \
667+
patch("sagemaker.train.sft_trainer.TrainDefaults") as mock_defaults, \
668+
patch("sagemaker.train.sft_trainer._create_input_data_config") as mock_input, \
669+
patch("sagemaker.train.sft_trainer._convert_input_data_to_channels", return_value=[]), \
670+
patch("sagemaker.train.sft_trainer._create_output_config", return_value=MagicMock()), \
671+
patch("sagemaker.train.sft_trainer._create_serverless_config", return_value=MagicMock()), \
672+
patch("sagemaker.train.sft_trainer._create_mlflow_config", return_value=None), \
673+
patch("sagemaker.train.sft_trainer._create_model_package_config", return_value=None), \
674+
patch("sagemaker.train.sft_trainer._validate_hyperparameter_values"), \
675+
patch("sagemaker.train.sft_trainer._get_jumpstart_tags", return_value=[]):
676+
677+
mock_session = MagicMock()
678+
mock_session.boto_session.region_name = "us-west-2"
679+
mock_defaults.get_sagemaker_session.return_value = mock_session
680+
mock_defaults.get_role.return_value = "arn:aws:iam::123:role/Role"
681+
mock_tj.create.return_value = MagicMock()
682+
683+
trainer.train(wait=False)
684+
685+
call_kwargs = mock_tj.create.call_args[1]
686+
final_hp = call_kwargs["hyper_parameters"]
687+
688+
# Non-spec key is now in final hyperparameters
689+
assert "sequence_length" in final_hp
690+
assert final_hp["sequence_length"] == "8191"
691+
# Other full template keys also present
692+
assert "warmup_ratio" not in final_hp
693+
643694
@patch("sagemaker.train.sft_trainer._validate_eula_for_gated_model", return_value=False)
644695
@patch("sagemaker.train.sft_trainer._get_fine_tuning_options_and_model_arn")
645696
@patch("sagemaker.train.sft_trainer._validate_and_resolve_model_package_group", return_value="my-group")
@@ -660,6 +711,9 @@ def test_nested_keys_flow_into_train_hyperparameters(
660711
overrides={"training_config": {"lr_scheduler": {"warmup_steps": 30}}},
661712
)
662713

714+
# For serverless (ie compute=None): Non-spec keys that aren't overridden don't flow to hyperparams
715+
trainer.compute = MagicMock()
716+
663717
with patch("sagemaker.train.sft_trainer.TrainingJob") as mock_tj, \
664718
patch("sagemaker.train.sft_trainer.TrainDefaults") as mock_defaults, \
665719
patch("sagemaker.train.sft_trainer._create_input_data_config") as mock_input, \
@@ -725,6 +779,9 @@ def test_deeply_nested_peft_keys_flow_into_hyperparameters(
725779
overrides={"training_config": {"peft": {"lora_tuning": {"alpha": 128}}}},
726780
)
727781

782+
# For serverless (ie compute=None): Non-spec keys that aren't overridden don't flow to hyperparams
783+
trainer.compute = MagicMock()
784+
728785
with patch("sagemaker.train.sft_trainer.TrainingJob") as mock_tj, \
729786
patch("sagemaker.train.sft_trainer.TrainDefaults") as mock_defaults, \
730787
patch("sagemaker.train.sft_trainer._create_input_data_config"), \

0 commit comments

Comments
 (0)