1010import datetime
1111from dataclasses import dataclass
1212import posixpath
13+ from typing import Optional
1314
1415from airflow import models
1516from airflow .utils .task_group import TaskGroup
1920from dags .common .vm_resource import DockerImage , XpkClusters
2021from dags .multipod .configs import gke_config
2122from dags .multipod .configs .common import SetupMode
22- from dags .orbax .util import logging_mtc as log
23- from dags .orbax .util import multi_tier_checkpoint_util as mtc
23+ from dags .orbax .util import validation_util
24+ from dags .orbax .util import checkpoint_util
2425from xlml .utils .xpk import BRANCH_ABHINAV_MTC
2526from xlml .utils .gke import zone_to_region
2627
2728SCHEDULE = "0 10 * * *" if composer_env .is_prod_env () else None
2829DAG_TEST_NAME = "maxtext_emc_and_mtc_orbax_save_local"
29- BASE_OUTPUT_DIRECTORY = gcs_bucket .MTC_AUTOMATION_BUCKET
30+ BASE_OUTPUT_DIR = gcs_bucket .MTC_AUTOMATION_BUCKET
3031
31- # For this DAG, only one version of the Docker image is supported at the moment.
32+ # Only one version of the Docker image is supported at the moment.
3233# Other versions (e.g., "stable") may be introduced later.
3334DOCKER_IMAGES = [(
3435 SetupMode .NIGHTLY ,
@@ -66,7 +67,7 @@ class TestConfig:
6667 local_checkpoint_step : int
6768 checkpoint_step : int
6869 ram_disk_size : str
69- cpc_config : mtc .CheckpointConfiguration
70+ cpc_config : checkpoint_util .CheckpointConfiguration
7071
7172 def __init__ (
7273 self ,
@@ -79,8 +80,8 @@ def __init__(
7980 replicator_backup_time : int ,
8081 step : int ,
8182 local_checkpoint_step : int ,
82- checkpoint_step : int ,
8383 ram_disk_size_in_mi : str ,
84+ checkpoint_step : Optional [int ] = None ,
8485 ):
8586 """
8687 Initializes the test configurations.
@@ -114,7 +115,7 @@ def __init__(
114115 self .local_checkpoint_step = local_checkpoint_step
115116 self .checkpoint_step = checkpoint_step
116117 self .ram_disk_size = ram_disk_size_in_mi
117- self .cpc_config = mtc .CheckpointConfiguration (
118+ self .cpc_config = checkpoint_util .CheckpointConfiguration (
118119 project_id = self .cluster .project ,
119120 region = zone_to_region (self .cluster .zone ),
120121 cluster_name = self .cluster .name ,
@@ -127,7 +128,7 @@ def generate_workload_command(
127128 self ,
128129 cp : Checkpointing ,
129130 checkpoint_dir : str ,
130- out_dir : str ,
131+ out_folder : str ,
131132 slice_number : int ,
132133 ) -> str :
133134 run_time = datetime .datetime .now ().strftime ("%Y-%m-%d-%H-%M" )
@@ -138,7 +139,7 @@ def generate_workload_command(
138139 "python3 -m MaxText.train MaxText/configs/base.yml "
139140 "remat_policy=full "
140141 "global_parameter_scale=1 "
141- f"base_output_directory={ out_dir } "
142+ f"base_output_directory={ posixpath . join ( BASE_OUTPUT_DIR , out_folder ) } "
142143 "dataset_type=synthetic "
143144 f"steps={ self .step } "
144145 "per_device_batch_size=1 "
@@ -169,21 +170,49 @@ def generate_workload_command(
169170 "orbax" ,
170171 ],
171172 description = "A DAG to run MaxText multi-tier checkpointing tests." ,
172- doc_md = "" ,
173+ doc_md = """
174+ # Emergency Checkpoint Manager and Multi-tier Checkpoint Validation DAG
175+
176+ ### Description
177+ This DAG (Directed Acyclic Graph) automates the process of validating
178+ checkpoint saving when using both **Emergency Checkpoint Manager**
179+ and **Multi-tier Checkpoint** features. The flag that controls the
180+ behaviour of using MTC or EMC is **user_replicatior**.
181+ Also the steps flag controls how many steps the job will run.
182+
183+ ### Prerequisites
184+ To run this test, you need an existing cluster with the Multi-tier
185+ Checkpointing configuration enabled, as well as a bucket with HNS
186+ (Hierarchical Namespace) enabled.
187+
188+ ### Procedures
189+ 1. **Apply Configuration:** A Checkpoint Configuration YAML file is
190+ applied to the cluster, enabling Multi-tier Checkpoint (MTC) features.
191+ 2. **Run Maxtext Jobsets:** The DAG runs a Maxtext jobset twice.
192+ One run has `replicator_enabled` set to `True` (for MTC), and the
193+ other has it set to `False` (for Emergency Checkpoint Manager).
194+ 3. **Validate Checkpoints:** The DAG validates that **local checkpoints**
195+ are being saved correctly in the `local/` directory for both job runs.
196+
197+ 4. The validation logic is the same for both the MTC and Emergency
198+ Checkpoint Manager job runs because their local checkpoint saving
199+ behavior is similar. This is why a single validation task is used for both.
200+ """ ,
173201 concurrency = 2 ,
174202) as dag :
203+ # Only one set of test configurations (e.g., v5p-128) is supported at the moment.
204+ # Other configurations (e.g., v5e and/or v6e) may be introduced later.
175205 test_configs = [
176206 TestConfig (
177207 cluster = XpkClusters .TPU_V5P_128_CLUSTER_ORBAX ,
178208 machine_type = "ct5p-hightpu-4t" ,
179209 accelerator = "v5p-128" ,
180210 slices = [2 ],
181211 model_name = "llama2-7b" ,
182- short_id = "max-sv" ,
212+ short_id = "max-sv-loc " ,
183213 replicator_backup_time = 30 ,
184214 step = 100 ,
185215 local_checkpoint_step = 20 ,
186- checkpoint_step = 25 ,
187216 ram_disk_size_in_mi = "800000Mi" ,
188217 ),
189218 ]
@@ -200,9 +229,6 @@ def generate_workload_command(
200229 use_replicator = False ,
201230 ),
202231 ]:
203- folder = f"maxtext_{ checkpointing .name } _orbax_save_local"
204- output_dir = posixpath .join (BASE_OUTPUT_DIRECTORY , folder )
205-
206232 with TaskGroup (
207233 group_id = f"maxtext_{ checkpointing .name } _orbax_save_local" ,
208234 ) as group :
@@ -211,19 +237,18 @@ def generate_workload_command(
211237 for slice_num in test_config .slices :
212238 # We conditionally set the trigger_rule on the first task.
213239 # If first task group failed the next one can execute.
214- init_delete_cpc = mtc .initiate_cpc_deletion (test_config .cpc_config )
215- wait_delete_cpc = mtc .wait_for_cpc_deletion .override (
240+ wait_delete_cpc = checkpoint_util .wait_for_cpc_deletion .override (
216241 trigger_rule = "all_done"
217242 )(test_config .cpc_config )
218- apply_cpc = mtc .apply_cpc (test_config .cpc_config )
243+ apply_cpc = checkpoint_util .apply_cpc (test_config .cpc_config )
219244 workload_command = test_config .generate_workload_command (
220245 cp = checkpointing ,
221246 checkpoint_dir = RAM_DISK ,
222- out_dir = output_dir ,
247+ out_folder = group . group_id ,
223248 slice_number = slice_num ,
224249 )
225250
226- start_time = log .generate_timestamp ()
251+ start_time = validation_util .generate_timestamp ()
227252 maxtext_chkpt_run_test = gke_config .get_gke_config (
228253 num_slices = slice_num ,
229254 cluster = test_config .cluster ,
@@ -255,20 +280,15 @@ def generate_workload_command(
255280 skip_post_process = True ,
256281 )
257282
258- end_time = log .generate_timestamp ()
283+ end_time = validation_util .generate_timestamp ()
259284 vali_step = test_config .step - 1
260285 vali_step_list = [
261286 i
262287 for i in range (0 , vali_step , test_config .local_checkpoint_step )
263288 ]
264289 vali_step_list .append (vali_step )
265290
266- # Here we are looking for the string '(blocking + background)'.
267- # We will compare expected steps with the ones we found when query
268- # this regex. Should be the same. If for some reason the restore
269- # start from 0 this task will fail
270- # because len(valid_step_list) != len(founded_steps)
271- validate_log = log .validate_log_with_step (
291+ validate_log = validation_util .validate_log_with_step (
272292 project_id = test_config .cluster .project ,
273293 location = zone_to_region (test_config .cluster .zone ),
274294 cluster_name = test_config .cluster .name ,
@@ -279,8 +299,7 @@ def generate_workload_command(
279299 )
280300
281301 (
282- init_delete_cpc
283- >> wait_delete_cpc
302+ wait_delete_cpc
284303 >> apply_cpc
285304 >> start_time
286305 >> maxtext_chkpt_run_test
0 commit comments