Skip to content

Commit 949b114

Browse files
authored
Feat: Add MaxText GRPO training DAG for RL pipeline validation (GoogleCloudPlatform#999)
This pull request introduces a new GRPO (Group Relative Policy Optimization) training DAG for the MaxText reinforcement learning pipeline, specifically targeting the Llama3.1 70B model. It also updates workflow triggers and adds support for a new nightly GRPO Docker image.
1 parent a4df6ea commit 949b114

8 files changed

Lines changed: 263 additions & 0 deletions

File tree

dags/common/vm_resource.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,3 +397,7 @@ class DockerImage(enum.Enum):
397397
MAXTEXT_JAX_052_RECIPES_012 = (
398398
"gcr.io/tpu-prod-env-multipod/maxtext_tpu_recipes:jax0.5.2-recipes0.1.2"
399399
)
400+
MAXTEXT_POST_TRAINING_RL = (
401+
"gcr.io/cloud-tpu-multipod-dev/maxtext-post-training:"
402+
f"{datetime.datetime.today().strftime('%Y-%m-%d')}"
403+
)

dags/gcs_bucket.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
# Multi-tier checkpointing need special permission for GCS Bucket
2828
# For further question reach out to Multi-tier Checkpointing Owners.
2929
ORBAX_AUTOMATION_BUCKET_EUROPE_WEST4 = "gs://orbax-automation-europe-west4"
30+
RL_AUTOMATION_BUCKET = "gs://rl-automation"

dags/orbax/util/test_config_util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
DockerImage.MAXTEXT_TPU_JAX_ORBAX_HEAD,
2727
)]
2828

29+
2930
# Valid models and sizes for current Maxtext Repository.
3031
MODELS = {
3132
"deepseek2",

dags/post_training/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""DAGs and utilities for MaxText post training."""

dags/post_training/maxtext_rl.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
"""
2+
GRPO (Group Relative Policy Optimization) training DAG for Llama3.1 70B
3+
model.
4+
5+
This DAG runs GRPO training validation to test the MaxText reinforcement
6+
learning pipeline. The workflow deploys training jobs to GKE clusters
7+
using Pathways, executes the GRPO algorithm, and validates successful
8+
completion through comprehensive log monitoring of training signals.
9+
"""
10+
11+
import datetime
12+
13+
from airflow import models
14+
15+
from dags import composer_env
16+
from dags.common import test_owner
17+
from dags.common.vm_resource import XpkClusters
18+
from dags.multipod.configs import gke_config
19+
from dags.post_training.util import validation_util, test_config_util
20+
from xlml.utils.xpk import MAIN_BRANCH
21+
from xlml.utils.gke import zone_to_region
22+
23+
SCHEDULE = "0 20 * * *" if composer_env.is_prod_env() else None
24+
DAG_TEST_NAME = "maxtext_rl"
25+
26+
with models.DAG(
27+
dag_id=DAG_TEST_NAME,
28+
start_date=datetime.datetime(2025, 9, 21),
29+
schedule_interval=SCHEDULE,
30+
catchup=False,
31+
tags=[
32+
"maxtext",
33+
"post-training",
34+
"rl",
35+
"grpo",
36+
"TPU",
37+
"v5p-128",
38+
"nightly",
39+
],
40+
description="GRPO training for MaxText RL pipeline validation.",
41+
doc_md="""
42+
# GRPO MaxText RL Training
43+
44+
### Overview
45+
This DAG runs GRPO (Group Relative Policy Optimization) training
46+
to validate the MaxText reinforcement learning pipeline. The workflow
47+
tests the complete RL training stack including infrastructure setup,
48+
model initialization, training execution, and result validation.
49+
50+
### Execution Flow
51+
1. **Job Launch:** Deploy GRPO training job to GKE cluster using Pathways infrastructure
52+
2. **Model Loading:** Initialize Llama3.1 70B model with HuggingFace authentication
53+
3. **Training Run:** Execute train_rl with JAX proxy/CPU platforms
54+
4. **Log Validation:** Monitor and check for "Post GRPO Training" completion signal
55+
5. **Success/Failure:** Report final status based on log validation and job completion
56+
57+
### Success Criteria
58+
The test passes when:
59+
1. Training job completes successfully without errors
60+
2. "Post GRPO Training" log message appears in jax-tpu container logs
61+
3. No infrastructure failures or container launch issues occur
62+
4. All training steps execute within expected parameters
63+
""",
64+
concurrency=1,
65+
) as dag:
66+
training_config = test_config_util.RLTestConfig(
67+
cluster=XpkClusters.TPU_V5P_128_CLUSTER,
68+
accelerator="v5p-128",
69+
slices=[1], # Single slice for RL training
70+
model_name="llama3.1-70b",
71+
short_id="max-rl",
72+
base_dir=(
73+
f"{test_config_util.DEFAULT_BUCKET}/llama3.1-70b-Instruct/outputs"
74+
),
75+
tokenizer_path="meta-llama/Llama-3.1-70B-Instruct",
76+
load_parameters_path=(
77+
f"{test_config_util.DEFAULT_BUCKET}/llama3.1-70b-Instruct/"
78+
"scanned-pathways/0/items/"
79+
),
80+
rl_config_path="src/MaxText/configs/rl.yml",
81+
)
82+
# HF token retrieved from Airflow Variables for secure credential management
83+
HF_TOKEN_LLAMA3_1 = models.Variable.get("HF_TOKEN_LLAMA3_1", None)
84+
85+
for mode, image in test_config_util.DOCKER_IMAGES_RL:
86+
for slice_num in training_config.slices:
87+
run_name = validation_util.generate_run_name(
88+
short_id=training_config.short_id,
89+
checkpointing_type="rl",
90+
slice_number=slice_num,
91+
accelerator=training_config.accelerator,
92+
)
93+
94+
rl_training_command = (
95+
f"export HF_TOKEN={HF_TOKEN_LLAMA3_1} && "
96+
"export TPU_MIN_LOG_LEVEL=0 && "
97+
"export TF_CPP_MIN_LOG_LEVEL=0 && "
98+
"export TPU_STDERR_LOG_LEVEL=0 && "
99+
"export JAX_PLATFORMS=proxy,cpu && "
100+
"export JAX_BACKEND_TARGET=grpc://127.0.0.1:29000 && "
101+
"export ENABLE_PATHWAYS_PERSISTENCE='1' && "
102+
f"python -m src.MaxText.rl.train_rl "
103+
f"{training_config.rl_config_path} run_name={run_name} "
104+
f"model_name={training_config.model_name} "
105+
f"tokenizer_path={training_config.tokenizer_path} "
106+
f"load_parameters_path={training_config.load_parameters_path} "
107+
f"base_output_directory={training_config.base_dir}",
108+
)
109+
110+
start_time = validation_util.generate_timestamp()
111+
112+
grpo_training_task = gke_config.get_gke_config(
113+
num_slices=slice_num,
114+
cluster=training_config.cluster,
115+
time_out_in_min=30,
116+
test_name=f"{training_config.short_id}",
117+
run_model_cmds=rl_training_command,
118+
docker_image=image.value,
119+
test_owner=test_owner.JACKY_F,
120+
).run(
121+
use_pathways=True,
122+
xpk_branch=MAIN_BRANCH,
123+
skip_post_process=True,
124+
)
125+
126+
end_time = validation_util.generate_timestamp()
127+
128+
validate_grpo_training = validation_util.validate_log_exist(
129+
project_id=training_config.cluster.project,
130+
location=zone_to_region(training_config.cluster.zone),
131+
cluster_name=training_config.cluster.name,
132+
text_filter="Post RL Training",
133+
namespace="default",
134+
container_name="jax-tpu",
135+
pod_pattern=f"{training_config.short_id}.*",
136+
start_time=start_time,
137+
end_time=end_time,
138+
)
139+
140+
(
141+
run_name
142+
>> start_time
143+
>> grpo_training_task
144+
>> end_time
145+
>> validate_grpo_training
146+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Utility modules for post training configurations and validation."""
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"""Test Configuration Class utility for post training testcases."""
2+
3+
from dataclasses import dataclass
4+
5+
from dags import gcs_bucket
6+
from dags.common.vm_resource import XpkClusters, DockerImage
7+
from dags.multipod.configs.common import SetupMode
8+
9+
10+
DEFAULT_BUCKET = gcs_bucket.RL_AUTOMATION_BUCKET
11+
12+
# Docker images for GRPO/RL training
13+
DOCKER_IMAGES_RL = [(
14+
SetupMode.NIGHTLY,
15+
DockerImage.MAXTEXT_POST_TRAINING_RL,
16+
)]
17+
18+
19+
@dataclass
20+
class RLTestConfig:
21+
"""Configuration for RL (GRPO) training tests.
22+
23+
This class holds the configuration parameters specific to reinforcement
24+
learning training jobs, including model parameters, infrastructure
25+
settings, and RL-specific training configurations.
26+
27+
Attributes:
28+
cluster: The GKE cluster to use for training.
29+
accelerator: The type of accelerator (e.g., v5p-128).
30+
slices: List of slice numbers to test with.
31+
model_name: The name of the model being trained
32+
(e.g., llama3.1-70b).
33+
short_id: A short identifier for the test run.
34+
base_dir: Base GCS directory for outputs.
35+
tokenizer_path: Path to the tokenizer (HuggingFace model
36+
path or local path).
37+
load_parameters_path: GCS path to load model parameters
38+
from.
39+
rl_config_path: Path to the RL configuration YAML file
40+
(relative to MaxText root).
41+
"""
42+
43+
cluster: XpkClusters
44+
accelerator: str
45+
slices: list[int]
46+
model_name: str
47+
short_id: str
48+
base_dir: str
49+
tokenizer_path: str
50+
load_parameters_path: str
51+
rl_config_path: str = "src/MaxText/configs/rl.yml"
52+
53+
def __init__(
54+
self,
55+
cluster: XpkClusters,
56+
accelerator: str,
57+
slices: list[int],
58+
model_name: str,
59+
short_id: str,
60+
base_dir: str,
61+
tokenizer_path: str,
62+
load_parameters_path: str,
63+
rl_config_path: str = "src/MaxText/configs/rl.yml",
64+
):
65+
"""Initializes the RL test configurations.
66+
67+
Args:
68+
cluster: The specified cluster to be used for the test.
69+
accelerator: The type of accelerator (e.g., v5p-128,
70+
v6e-256) to use.
71+
slices: The number of slices to be used.
72+
model_name: The name of the base model being tested
73+
(e.g., llama3.1-70b).
74+
short_id: A short identifier for the test run.
75+
base_dir: The base GCS directory for storing outputs.
76+
tokenizer_path: Path to the tokenizer (HuggingFace
77+
model path).
78+
load_parameters_path: GCS path to load pretrained model
79+
parameters from.
80+
rl_config_path: Path to the RL configuration YAML file
81+
(default: src/MaxText/configs/rl.yml).
82+
"""
83+
self.cluster = cluster
84+
self.accelerator = accelerator
85+
self.slices = slices
86+
self.model_name = model_name
87+
self.short_id = short_id
88+
self.base_dir = base_dir
89+
self.tokenizer_path = tokenizer_path
90+
self.load_parameters_path = load_parameters_path
91+
self.rl_config_path = rl_config_path
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Validation utilities for post training DAGs.
2+
3+
This module provides validation functions specific to post training
4+
workflows, reusing generic utilities from the orbax module where applicable.
5+
"""
6+
7+
# Re-export commonly used validation functions from orbax
8+
from dags.orbax.util.validation_util import (
9+
generate_run_name,
10+
generate_timestamp,
11+
validate_log_exist,
12+
)
13+
14+
__all__ = [
15+
"generate_run_name",
16+
"generate_timestamp",
17+
"validate_log_exist",
18+
]

0 commit comments

Comments
 (0)