Skip to content

Commit 839a63d

Browse files
committed
Fix: Change cluster test to "ml-auto-solutions-orbax".
Fix: Refactor cpc dict into a CheckpointConfiguration class, that holds relevant info about cpc metadata. Fix: Change name of DAG to be mtc and emc. mainly because both of these test are being tested. Fix: Fix some try and catch exceptions that seems to be unnecessary. Fix: Refactor whole Cpc delete task into two task initiate_cpc and wait_to_delete. wait_to_delete task is a sensor task that will check every 10 s if the delition already happened. Fix: Two Dags testing mtc and emc (with replicator=true and replicator=false) Fix: Change loggin.py library to logging_mtc.py names conflict. Fix: Use abhinav-mtc xpk branch instead of main branch since xpk version > 0.4.1 crash airflow pod. b/437817546 Fix: Correct name of DAG to emtc (Emergency multitier Checkpointer). Fix: Change name_id of the test to be related to Orbax. Create new tag with Orbax. Remove --restart-on-user-code-failure flag since is already outdated in both main and develop branch Fix: Backup interval to longer. Only testing local saves. GCS testing is in DAG002 mend
1 parent f9dfcaf commit 839a63d

4 files changed

Lines changed: 82 additions & 130 deletions

File tree

dags/common/test_owner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class Team(enum.Enum):
6565
# Multi-tier Checkpointing
6666
ABHINAV_S = "abhinavclemson"
6767
XUEFENG_G = "xuefgu"
68-
CAMILO = "CAMILO P."
68+
CAMILO_Q = "camiloCienet"
6969

7070
# MLCompass
7171
ORTI_B = "ortibazar"

dags/common/vm_resource.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ class XpkClusters:
260260
zone=Zone.EUROPE_WEST4_B.value,
261261
)
262262
TPU_V5P_128_CLUSTER_ORBAX = XpkClusterConfig(
263-
name="orbax-ml-auto-solutions",
263+
name="ml-auto-solutions-orbax",
264264
device_version=TpuVersion.V5P,
265265
core_count=128,
266266
project=Project.CLOUD_TPU_MULTIPOD_DEV.value,

dags/orbax/maxtext_multi_tier_chechpoint_save_local.py renamed to dags/orbax/maxtext_mtc_emergency_save_local.py

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,53 +23,57 @@
2323
from xlml.utils.xpk import BRANCH_ABHINAV_MTC
2424
from xlml.utils.gke import zone_to_region
2525

26-
# Global variables across test configurations.
2726
SCHEDULE = "0 10 * * *" if composer_env.is_prod_env() else None
2827
DAG_TEST_NAME = "maxtext_emc_and_mtc_orbax_save_local"
2928
BASE_OUTPUT_DIRECTORY = gcs_bucket.MTC_AUTOMATION_BUCKET
3029

31-
# The variable DOCKER_IMAGES will hold multiple configurations e.g nightly , stable.
30+
# For this DAG, only one version of the Docker image is supported at the moment.
31+
# Other versions (e.g., "stable") may be introduced later.
3232
DOCKER_IMAGES = [(
3333
SetupMode.NIGHTLY,
3434
DockerImage.MAXTEXT_TPU_JAX_NIGHTLY,
3535
)]
3636
RAM_DISK = "/local"
3737

38+
3839
@dataclass
3940
class Testcase:
40-
"""Holds a single test case configuration for multi-tier checkpointing.
41+
"""
42+
Represents the information of a checkpointing mechanism.
4143
42-
This class is used to define the properties of a specific test run,
43-
including the name of the checkpoint and whether to use a replicator.
44+
Attributes:
45+
name: A unique name for the checkpointing configuration.
46+
use_replicator: Indicates whether a replicator is enabled for this test case.
4447
"""
45-
checkpointing_name: str
48+
49+
name: str
4650
use_replicator: bool
4751

52+
4853
@dataclass
4954
class Testconfig:
50-
"""Holds the general configuration for a multi-tier checkpointing test.
51-
52-
This class defines the environment and parameters for a single test run,
53-
including cluster details, model settings, and checkpointing intervals.
54-
55-
cluster (XpkClusters): The cluster to be used for the test.
56-
machine_type (str): The type of machine to run the test on.
57-
accelerator (str): The type of accelerator (e.g., GPU, TPU) to use.
58-
slices (list[int]): The number of slices to be used.
59-
model_name (str): The name of the model being tested.
60-
name_prefix (str): A prefix to be used for naming the test run.
61-
replicator_min (int): The minimum number of replicators required.
62-
step (int): The current step of the training process.
63-
local_checkpoint_step (int): The step interval for local checkpoints.
64-
checkpoint_step (int): The step interval for global checkpoints.
65-
ram_disk_mi (str): Information about the RAM disk.
55+
"""Holds the general configuration for a checkpointing test.
56+
57+
Attributes:
58+
cluster: The specified cluster to be used for the test.
59+
machine_type: The type of machine (e.g., GPU, TPU).
60+
accelerator: The type of accelerator (e.g., GPU, TPU) to use.
61+
slices: The number of slices to be used.
62+
model_name: The name of the model being tested.
63+
short_id (str): A short id to be used for naming the test run.
64+
replicator_min: The time the replicator takes to backup checkpoints to bucket.
65+
step: The current step of the training process.
66+
local_checkpoint_step: The step interval for local checkpoints.
67+
checkpoint_step: The step interval for the checkpoints store in the bucket.
68+
ram_disk_mi: The size about the RAM disk in the CSI driver, in Mi.
6669
"""
70+
6771
cluster: XpkClusters
6872
machine_type: str
6973
accelerator: str
7074
slices: list[int]
7175
model_name: str
72-
name_prefix: str
76+
short_id: str
7377
replicator_min: int
7478
step: int
7579
local_checkpoint_step: int
@@ -102,7 +106,7 @@ class Testconfig:
102106
accelerator="v5p-128",
103107
slices=[2],
104108
model_name="llama2-7b",
105-
name_prefix="max-sv",
109+
short_id="max-sv",
106110
replicator_min=30,
107111
step=100,
108112
local_checkpoint_step=20,
@@ -113,26 +117,23 @@ class Testconfig:
113117
tests_to_run_seq = []
114118
# Individual test cases for Multi-tier Checkpointing and Emergency Checkpointing
115119
for tc in [
116-
Testcase(checkpointing_name="mtc", use_replicator=True),
117-
Testcase(checkpointing_name="emc", use_replicator=False),
120+
Testcase(name="mtc", use_replicator=True),
121+
Testcase(name="emc", use_replicator=False),
118122
]:
119-
folder = f"maxtext_{tc.checkpointing_name}_orbax_save_local"
120-
BASE_OUTPUT_DIRECTORY = posixpath.join(BASE_OUTPUT_DIRECTORY, folder)
121-
with TaskGroup(
122-
group_id=f"maxtext_{tc.checkpointing_name}_orbax_save_local"
123-
) as task:
123+
folder = f"maxtext_{tc.name}_orbax_save_local"
124+
run_dir_out = posixpath.join(BASE_OUTPUT_DIRECTORY, folder)
125+
with TaskGroup(group_id=f"maxtext_{tc.name}_orbax_save_local") as task:
124126
for mode, image in DOCKER_IMAGES:
125127
for test_config in test_configs:
126128
cpc_conf = mtc.CheckpointConfiguration(
127129
project_id=test_config.cluster.project,
128130
region=zone_to_region(test_config.cluster.zone),
129131
cluster_name=test_config.cluster.name,
130132
gcs_bucket=gcs_bucket.MTC_AUTOMATION_BUCKET.removeprefix("gs://"),
131-
ramdisk_memory=test_config.ram_disk_mi,
133+
ram_disk_memory_in_mi=test_config.ram_disk_mi,
132134
machine_type=test_config.machine_type,
133135
)
134136
for slice_num in test_config.slices:
135-
136137
# We conditionally set the trigger_rule on the first task.
137138
# If first task group failed the next one can execute.
138139
init_delete_cpc = mtc.initiate_cpc_deletion(cpc_conf)
@@ -141,12 +142,12 @@ class Testconfig:
141142
)(cpc_conf)
142143
apply_cpc = mtc.apply_cpc(cpc_conf)
143144
run_time = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")
144-
run_name = f"{test_config.name_prefix}-{tc.checkpointing_name}-{slice_num}x-{test_config.accelerator}-{run_time}"
145+
run_name = f"{test_config.short_id}-{tc.name}-{slice_num}x-{test_config.accelerator}-{run_time}"
145146
workload_command = (
146147
"export TPU_PREMAPPED_BUFFER_SIZE=52428800000 && "
147148
"export TPU_PREMAPPED_BUFFER_TRANSFER_THRESHOLD_BYTES=52428800000 && "
148149
"python3 -m MaxText.train MaxText/configs/base.yml remat_policy=full "
149-
f"global_parameter_scale=1 base_output_directory={BASE_OUTPUT_DIRECTORY} "
150+
f"global_parameter_scale=1 base_output_directory={run_dir_out} "
150151
f"dataset_type=synthetic steps={test_config.step} per_device_batch_size=1 "
151152
f"max_target_length=256 model_name={test_config.model_name} per_device_batch_size=2 "
152153
"reuse_example_batch=1 enable_emergency_checkpoint=true "
@@ -160,7 +161,7 @@ class Testconfig:
160161
num_slices=slice_num,
161162
cluster=test_config.cluster,
162163
time_out_in_min=60,
163-
test_name=f"{test_config.name_prefix}-{tc.checkpointing_name}",
164+
test_name=f"{test_config.short_id}-{tc.name}",
164165
run_model_cmds=workload_command,
165166
docker_image=image.value,
166167
test_owner=test_owner.CAMILO_Q,
@@ -176,7 +177,7 @@ class Testconfig:
176177
num_slices=slice_num,
177178
cluster=test_config.cluster,
178179
time_out_in_min=60,
179-
test_name=f"{test_config.name_prefix}-cl",
180+
test_name=f"{test_config.short_id}-cl",
180181
run_model_cmds=cleanup_command,
181182
docker_image=image.value,
182183
test_owner=test_owner.CAMILO_Q,
@@ -190,7 +191,8 @@ class Testconfig:
190191
end_time = log.generate_timestamp()
191192
vali_step = test_config.step - 1
192193
vali_step_list = [
193-
i for i in range(0, vali_step, test_config.local_checkpoint_step)
194+
i
195+
for i in range(0, vali_step, test_config.local_checkpoint_step)
194196
]
195197
vali_step_list.append(vali_step)
196198

dags/orbax/util/multi_tier_checkpoint_util.py

Lines changed: 40 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,24 @@
2121
class CheckpointConfiguration:
2222
"""A dataclass to hold attributes of a Cloud Public Compute (CPC) instance."""
2323

24-
def __init__(self,
25-
project_id: str,
26-
region: str,
27-
cluster_name: str,
28-
gcs_bucket: str,
29-
machine_type: str,
30-
ramdisk_memory: str,
31-
toleration_key: str = "google.com/tpu",
24+
project_id: str
25+
region: str
26+
cluster_name: str
27+
gcs_bucket: str
28+
machine_type: str
29+
ramdisk_memory_in_mi: str
30+
toleration_key: str
31+
cpc_yaml_template: str
32+
33+
def __init__(
34+
self,
35+
project_id: str,
36+
region: str,
37+
cluster_name: str,
38+
gcs_bucket: str,
39+
machine_type: str,
40+
ram_disk_memory_in_mi: str,
41+
toleration_key: str = "google.com/tpu",
3242
):
3343
"""
3444
Initializes the CheckpointConfiguration.
@@ -40,7 +50,8 @@ def __init__(self,
4050
gcs_bucket (str): The name of the GCS bucket for checkpoints.
4151
machine_type (str): The machine type for the instance.
4252
ramdisk_memory_in_mi (str): The size of the RAM disk in mebibytes (Mi).
43-
Defaults to "2G".
53+
The unit is in mebibytes (Mi) but the value should be passed as a string
54+
with the unit, e.g., "2G" or "2048M". Defaults to "100G"".
4455
toleration_key (str): The toleration key for the Kubernetes pod.
4556
Defaults to "google.com/tpu".
4657
"""
@@ -49,80 +60,38 @@ def __init__(self,
4960
self.cluster_name = cluster_name
5061
self.gcs_bucket = gcs_bucket
5162
self.machine_type = machine_type
52-
self.ramdisk_memory = ramdisk_memory
63+
self.ramdisk_memory = ram_disk_memory_in_mi
5364
self.toleration_key = toleration_key
54-
55-
def _get_custom_objects_api_client(
56-
self, project_id: str, region: str, cluster_name: str
57-
) -> k8s_client.CustomObjectsApi:
58-
"""Create a CustomObjectsApi client for the given cluster."""
59-
return k8s_client.CustomObjectsApi(
60-
gke.get_authenticated_client(
61-
self.project_id,
62-
self.region,
63-
self.cluster_name
64-
)
65-
)
66-
67-
# memory_size: This should be Mi
68-
def _create_cpc_content(
69-
self,
70-
gcs_bucket: str,
71-
machine_type: str,
72-
toleration_key: str,
73-
memory_size_in_mi: str,
74-
) -> str:
75-
"""Creates the CheckpointConfiguration YAML content as a string.
76-
77-
This method generates a templated YAML string for a GKE CheckpointConfiguration
78-
resource, including parameters for the GCS bucket, machine type, toleration,
79-
and RAM disk size.
80-
81-
Args:
82-
gcs_bucket (str): The name of the GCS bucket for storing checkpoints.
83-
machine_type (str): The instance type of the node.
84-
toleration_key (str): The toleration key to allow scheduling on specific nodes.
85-
memory_size_in_mi (str): The desired size of the in-memory volume.
86-
The unit is in mebibytes (Mi) but the value should be passed as a string
87-
with the unit, e.g., "2G" or "1024M".
88-
89-
Returns:
90-
str: The templated YAML content as a string.
91-
"""
92-
cpc_yaml_template = f"""
65+
self.cpc_yaml_template = f"""
9366
apiVersion: checkpointing.gke.io/v1
9467
kind: CheckpointConfiguration
9568
metadata:
9669
name: my-checkpointconfiguration # This name will be used for deletion
9770
spec:
98-
cloudStorageBucketName: {gcs_bucket}
71+
cloudStorageBucketName: {self.gcs_bucket}
9972
nodeSelector:
100-
node.kubernetes.io/instance-type: {machine_type}
73+
node.kubernetes.io/instance-type: {self.machine_type}
10174
tolerations:
102-
- key: {toleration_key}
75+
- key: {self.toleration_key}
10376
operator: Exists
10477
effect: NoSchedule
105-
inMemoryVolumeSize: {memory_size_in_mi}
78+
inMemoryVolumeSize: {self.ramdisk_memory}
10679
"""
107-
logging.info(f"Generated CPC YAML content: \n{cpc_yaml_template}")
108-
return cpc_yaml_template
80+
81+
def create_custom_objects_api_client(self) -> k8s_client.CustomObjectsApi:
82+
"""Create a CustomObjectsApi client for the given cluster."""
83+
return k8s_client.CustomObjectsApi(
84+
gke.get_authenticated_client(
85+
self.project_id, self.region, self.cluster_name
86+
)
87+
)
10988

11089

11190
@task
11291
def apply_cpc(cpc: CheckpointConfiguration) -> None:
11392
"""Applies the CheckpointConfiguration to the cluster (create or replace)."""
114-
custom_api = cpc._get_custom_objects_api_client(
115-
cpc.project_id, cpc.region, cpc.cluster_name
116-
)
117-
118-
cpc_yaml_string = cpc._create_cpc_content(
119-
cpc.gcs_bucket,
120-
cpc.machine_type,
121-
cpc.toleration_key,
122-
cpc.ramdisk_memory,
123-
)
124-
cpc_body = yaml.safe_load(cpc_yaml_string)
125-
93+
custom_api = cpc.create_custom_objects_api_client()
94+
cpc_body = yaml.safe_load(cpc.cpc_yaml_template)
12695
api_version = cpc_body.get("apiVersion")
12796
kind = cpc_body.get("kind")
12897
name = cpc_body.get("metadata", {}).get("name")
@@ -139,7 +108,6 @@ def apply_cpc(cpc: CheckpointConfiguration) -> None:
139108
logging.info(f"CheckpointConfiguration '{name}' created successfully.")
140109

141110
except ApiException as api_error:
142-
143111
# If it already exists (409 Conflict), then try to replace it
144112
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409
145113
if api_error.status == 409:
@@ -174,17 +142,8 @@ def initiate_cpc_deletion(cpc: CheckpointConfiguration) -> None:
174142
"""
175143
Sends the delete request for the CheckpointConfiguration.
176144
"""
177-
custom_api = cpc._get_custom_objects_api_client(
178-
cpc.project_id, cpc.region, cpc.cluster_name
179-
)
180-
cpc_body = yaml.safe_load(
181-
cpc._create_cpc_content(
182-
cpc.gcs_bucket,
183-
cpc.machine_type,
184-
cpc.toleration_key,
185-
cpc.ramdisk_memory,
186-
)
187-
)
145+
custom_api = cpc.create_custom_objects_api_client()
146+
cpc_body = yaml.safe_load(cpc.cpc_yaml_template)
188147
name_to_delete = cpc_body.get("metadata", {}).get("name")
189148

190149
if not name_to_delete:
@@ -234,17 +193,8 @@ def wait_for_cpc_deletion(cpc: CheckpointConfiguration) -> bool:
234193
"""
235194
A sensor that waits for the CheckpointConfiguration to be completely deleted.
236195
"""
237-
custom_api = cpc._get_custom_objects_api_client(
238-
cpc.project_id, cpc.region, cpc.cluster_name
239-
)
240-
cpc_body = yaml.safe_load(
241-
cpc._create_cpc_content(
242-
cpc.gcs_bucket,
243-
cpc.machine_type,
244-
cpc.toleration_key,
245-
cpc.ramdisk_memory,
246-
)
247-
)
196+
custom_api = cpc.create_custom_objects_api_client()
197+
cpc_body = yaml.safe_load(cpc.cpc_yaml_template)
248198
name_to_delete = cpc_body.get("metadata", {}).get("name")
249199

250200
if not name_to_delete:

0 commit comments

Comments
 (0)