Skip to content

Commit c78f2c5

Browse files
committed
Add: Working Replica Resize with fuji-test-v2.
Some changes to fuji-test-v2 hidden_dim=8 --> hidden_dim=32 fixed mesh shape error. Change poll time pathways elastic manager 10 --> 30s
1 parent ab20f71 commit c78f2c5

5 files changed

Lines changed: 40 additions & 11 deletions

File tree

axlearn/common/elastic_input.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
from axlearn.common.config import REQUIRED, Required, config_class, maybe_set_config
5050
from axlearn.common.input_dispatch import BaseInputDispatcher, _validate_logical_feed_shapes
5151
from axlearn.common.module import Module
52-
from axlearn.common.utils import Nested, Tensor, live_devices
52+
from axlearn.common.utils import Nested, Tensor, live_devices, live_slice_indices
53+
5354

5455

5556
class ElasticSpmdInputDispatcher(BaseInputDispatcher):
@@ -79,6 +80,10 @@ def is_in_elastic_mode(self) -> bool:
7980
if cfg.num_max_slices is None:
8081
return False
8182
else:
83+
print(
84+
f"Live_slice_count by lkolluru: {live_slice_indices()}, slices_cnt: {len(live_slice_indices())}",
85+
live_slice_indices(),len(live_slice_indices())
86+
)
8287
if slice_count() < cfg.num_max_slices:
8388
return True
8489
elif slice_count() >= cfg.num_max_slices:
@@ -95,6 +100,7 @@ def __init__(self, cfg: Config, *, parent: Optional[Module]):
95100
cfg: ElasticSpmdInputDispatcher.Config = self.config
96101

97102
mesh = thread_resources.env.physical_mesh
103+
print("physical mesh by lkolluru: ", mesh)
98104
if mesh.empty:
99105
raise ValueError("Expected to be initialized within the context of a mesh.")
100106

@@ -120,6 +126,7 @@ def __init__(self, cfg: Config, *, parent: Optional[Module]):
120126
)
121127
if self.is_in_elastic_mode:
122128
num_partitions = num_partitions // slice_count() * cfg.num_max_slices
129+
print(f"num_partitions by lkolluru: {num_partitions} and live_devices: {slice_count()} ")
123130

124131
if cfg.global_logical_batch_size % num_partitions != 0:
125132
raise ValueError(
@@ -128,6 +135,7 @@ def __init__(self, cfg: Config, *, parent: Optional[Module]):
128135
)
129136

130137
self._device_physical_batch_size = cfg.global_logical_batch_size // num_partitions
138+
print("device_physical_batch_size on init by lkolluru: ", self._device_physical_batch_size)
131139

132140
# Infer the physical feeds and feed index along dim=0.
133141
_, _, pid2fid = get_process_index_and_count_and_mapping(
@@ -178,6 +186,7 @@ def fid2pids(feed_id):
178186

179187
if self.is_in_elastic_mode:
180188
print(" In elastic mode lkolluru")
189+
# I think this should be len(live_slice_indices())....
181190
adjusted_device_physical_batch_size = math.ceil(
182191
self._device_physical_batch_size * (cfg.num_max_slices / slice_count())
183192
)

axlearn/common/launch_trainer.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,15 @@ def get_trainer_config(
149149
select_mesh_config(trainer_config, mesh_selector=flag_values.mesh_selector)
150150
trainer_config.mesh_axis_names = trainer_config.mesh_axis_names or ("data", "model")
151151
# trainer_config.mesh_shape = trainer_config.mesh_shape or (len(jax.devices()), 1)
152-
trainer_config.mesh_shape = trainer_config.mesh_shape or (len(live_devices()), 1)
152+
153+
print("Live devices ", live_devices())
154+
if len(live_devices()) == 32:
155+
trainer_config.mesh_shape = trainer_config.mesh_shape or (len(live_devices()), 1)
156+
if len(live_devices()) == 16:
157+
trainer_config.mesh_shape = (1, 1, 1, len(live_devices()), 1, 1)
158+
159+
print("trainer_config.mesh_shape by camilo: ", trainer_config.mesh_shape)
160+
153161
if isinstance(trainer_config.mesh_shape, MeshShape):
154162
trainer_config.mesh_shape = infer_mesh_shape(trainer_config.mesh_shape)
155163
trainer_config.start_trace_steps = [int(el) for el in flag_values.trace_at_steps]

axlearn/common/launch_trainer_main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def pre_callback():
6767

6868
train = utils.elastic_manager.replica_resize(
6969
max_resizes=10, # Handle up to 10 slice up or slice down transitions
70-
poll_interval=10, # Monitor thread checks inactive slice health every 10 seconds
70+
poll_interval=30, # Monitor thread checks inactive slice health every 30 seconds
7171
pre_callback=pre_callback,
7272
)(train)
7373

axlearn/common/utils.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ def live_devices():
9898
device_list = jax.devices()
9999

100100
if pathwaysutils.is_pathways_backend_used() and elastic_manager is not None:
101+
# print(f"Live devices: {device_list}, active slices: {elastic_manager.active_slice_indices}")
102+
# return_cnt = [d for d in device_list if d.slice_index in elastic_manager.active_slice_indices]
103+
# print(f"Live Devices by camilo return value : {return_cnt}")
101104
return [d for d in device_list if d.slice_index in elastic_manager.active_slice_indices]
102105
else:
103106
return device_list
@@ -1820,11 +1823,14 @@ def create_device_mesh(
18201823
# Check if the devices are part of a multi-granule configuration.
18211824
# <https://github.com/google/jax/blob/b81b79c1b0d2ec/jax/experimental/mesh_utils.py#L313>
18221825
device_platform = devices[0].platform
1826+
1827+
print(f"Devices before granule calculation: {devices}")
18231828
device_attr = "process_index" if device_platform != "tpu" else "slice_index"
18241829
is_multi_granule_env = hasattr(devices[0], device_attr)
18251830
if not all(el.platform == device_platform for el in devices):
18261831
raise NotImplementedError(f"Not all devices had platform: {device_platform}.")
1827-
1832+
print("IS MULTI GRANULE by camilo: {is_multi_granule_env}")
1833+
print(f"Granule devices: {(getattr(el, device_attr) for el in devices.flatten())} + 1, by camilo")
18281834
num_granules = (
18291835
max(getattr(el, device_attr) for el in devices.flatten()) + 1 if is_multi_granule_env else 1
18301836
)
@@ -1833,6 +1839,9 @@ def create_device_mesh(
18331839
num_devices % num_granules == 0
18341840
), "Number of devices must be divisible by number of granules."
18351841
num_devices_per_granule = num_devices // num_granules
1842+
print(f"Num Granules by camilo: {num_granules}")
1843+
print(f"Num Devices by camilo: {num_devices}")
1844+
print(f"Num Devices per Granule by camilo: {num_devices_per_granule}")
18361845

18371846
# Fallback to a standard mesh if on GPU with incompatible multi-granule mesh.
18381847
if (
@@ -1898,6 +1907,8 @@ def create_device_mesh(
18981907
if num_granules == 1:
18991908
return build_standard_mesh(mesh_shape.ici_mesh_shape, devices=devices)
19001909

1910+
print(f"Mesh shape CREATE DEVICE MESH by camilo: {devices}")
1911+
19011912
return create_hybrid_device_mesh(
19021913
mesh_shape,
19031914
devices=devices,

axlearn/experiments/text/gpt/fuji.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,12 @@ def get_trainer_kwargs(
295295

296296
# dict() is more readable here.
297297
# pylint: disable=use-dict-literal
298+
# Camilo: Changes made to fuji-test to make replica resize work.
298299
if model_size == "test":
299300
trainer_kwargs = dict(
300301
model_kwargs=dict(
301302
num_layers=4,
302-
hidden_dim=8,
303+
hidden_dim=32,
303304
ffn_dim=scaled_hidden_dim(scale=8 / 3, round_up_to_multiples_of=16),
304305
num_heads=4,
305306
num_kv_heads=2,
@@ -310,12 +311,12 @@ def get_trainer_kwargs(
310311
),
311312
learner_kwargs=dict(peak_lr=6e-4, weight_decay=0.01),
312313
max_sequence_length=64,
313-
train_batch_size=32,
314-
eval_batch_size=32,
315-
max_step=3000,
316-
eval_every_n_steps=1500,
317-
save_every_n_steps=500,
318-
mesh_shape=mesh_shape_from_axes(data=-1),
314+
train_batch_size=train_batch_size,
315+
eval_batch_size=train_batch_size,
316+
max_step=10000,
317+
eval_every_n_steps=50000,
318+
save_every_n_steps=1000,
319+
mesh_shape=mesh_shape_from_axes(data=-1, fsdp=8),
319320
)
320321
elif model_size == "1B":
321322
trainer_kwargs = dict(

0 commit comments

Comments
 (0)