Skip to content

Commit 3bc5597

Browse files
authored
Merge pull request #3151 from bghira/feature/musubi-h2d-hybrid
Stream checkpointed Musubi blocks through a packed H2D ring
2 parents 793b54e + 2320af2 commit 3bc5597

33 files changed

Lines changed: 845 additions & 154 deletions

simpletuner/helpers/models/auraflow/transformer.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -806,8 +806,6 @@ def _to_pos(idx):
806806

807807
# MMDiT blocks.
808808
for index_block, block in enumerate(self.joint_transformer_blocks):
809-
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
810-
musubi_manager.stream_in(block, hidden_states.device)
811809
# TREAD: START a route?
812810
if use_routing and route_ptr < len(routes) and global_idx == routes[route_ptr]["start_layer_idx"]:
813811
mask_ratio = routes[route_ptr]["selection_ratio"]
@@ -827,7 +825,7 @@ def _to_pos(idx):
827825
hidden_states = hidden_states + block_controlnet_hidden_states[index_block // interval_control]
828826
continue
829827

830-
if (
828+
checkpoint_this_block = (
831829
self.training
832830
and torch.is_grad_enabled()
833831
and should_checkpoint_block(
@@ -836,7 +834,11 @@ def _to_pos(idx):
836834
self.gradient_checkpointing_interval,
837835
self.gradient_checkpointing_segment_stride,
838836
)
839-
):
837+
)
838+
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
839+
musubi_manager.stream_in(block, hidden_states.device, checkpointed=checkpoint_this_block)
840+
841+
if checkpoint_this_block:
840842

841843
if self.gradient_checkpointing_backend.startswith("unsloth"):
842844
from simpletuner.helpers.training.offloaded_gradient_checkpointer import offloaded_checkpoint
@@ -916,9 +918,6 @@ def custom_forward(hidden_states, encoder_hidden_states, temb, context_temb, che
916918
for index_block, block in enumerate(self.single_transformer_blocks):
917919
actual_index = len(self.joint_transformer_blocks) + index_block
918920

919-
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
920-
musubi_manager.stream_in(block, combined_hidden_states.device)
921-
922921
# TREAD: START a route?
923922
if use_routing and route_ptr < len(routes) and global_idx == routes[route_ptr]["start_layer_idx"]:
924923
mask_ratio = routes[route_ptr]["selection_ratio"]
@@ -959,7 +958,7 @@ def custom_forward(hidden_states, encoder_hidden_states, temb, context_temb, che
959958
)
960959
continue
961960

962-
if (
961+
checkpoint_this_block = (
963962
self.training
964963
and torch.is_grad_enabled()
965964
and should_checkpoint_block(
@@ -968,7 +967,15 @@ def custom_forward(hidden_states, encoder_hidden_states, temb, context_temb, che
968967
self.gradient_checkpointing_interval,
969968
self.gradient_checkpointing_segment_stride,
970969
)
971-
):
970+
)
971+
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
972+
musubi_manager.stream_in(
973+
block,
974+
combined_hidden_states.device,
975+
checkpointed=checkpoint_this_block,
976+
)
977+
978+
if checkpoint_this_block:
972979

973980
if self.gradient_checkpointing_backend.startswith("unsloth"):
974981
from simpletuner.helpers.training.offloaded_gradient_checkpointer import offloaded_checkpoint

simpletuner/helpers/models/chroma/transformer.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -964,8 +964,6 @@ def _to_pos(idx):
964964
grounding_objs = self.position_net(**grounding_kwargs)
965965

966966
for index_block, block in enumerate(self.transformer_blocks):
967-
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
968-
musubi_manager.stream_in(block, hidden_states.device)
969967
actual_index = global_idx
970968
img_offset = 3 * len(self.single_transformer_blocks)
971969
txt_offset = img_offset + 6 * len(self.transformer_blocks)
@@ -1035,6 +1033,13 @@ def _to_pos(idx):
10351033
)
10361034
)
10371035

1036+
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
1037+
musubi_manager.stream_in(
1038+
block,
1039+
hidden_states.device,
1040+
checkpointed=use_checkpoint and not self.gradient_checkpointing_backend.endswith("-ffn"),
1041+
)
1042+
10381043
if use_checkpoint:
10391044
if self.gradient_checkpointing_backend.startswith("unsloth"):
10401045
from simpletuner.helpers.training.offloaded_gradient_checkpointer import offloaded_checkpoint
@@ -1130,8 +1135,6 @@ def run_checkpointed_block(
11301135
txt_len = encoder_hidden_states.shape[1]
11311136

11321137
for index_block, block in enumerate(self.single_transformer_blocks):
1133-
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
1134-
musubi_manager.stream_in(block, hidden_states.device)
11351138
actual_index = global_idx
11361139
start_idx = 3 * index_block
11371140
if pooled_temb.ndim == 4:
@@ -1237,6 +1240,13 @@ def run_checkpointed_block(
12371240
)
12381241
)
12391242

1243+
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
1244+
musubi_manager.stream_in(
1245+
block,
1246+
hidden_states.device,
1247+
checkpointed=use_checkpoint and not self.gradient_checkpointing_backend.endswith("-ffn"),
1248+
)
1249+
12401250
if use_checkpoint:
12411251
if self.gradient_checkpointing_backend.startswith("unsloth"):
12421252
from simpletuner.helpers.training.offloaded_gradient_checkpointer import offloaded_checkpoint

simpletuner/helpers/models/cosmos/transformer.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -895,9 +895,7 @@ def forward(
895895
)
896896
hidden_states = router.start_route(hidden_states, mask_info)
897897
break
898-
if musubi_offload_active and musubi_manager.is_managed_block(bid):
899-
musubi_manager.stream_in(block, hidden_states.device)
900-
if (
898+
checkpoint_this_block = (
901899
grad_enabled
902900
and self.gradient_checkpointing
903901
and should_checkpoint_block(
@@ -906,7 +904,10 @@ def forward(
906904
self.gradient_checkpointing_interval,
907905
self.gradient_checkpointing_segment_stride,
908906
)
909-
):
907+
)
908+
if musubi_offload_active and musubi_manager.is_managed_block(bid):
909+
musubi_manager.stream_in(block, hidden_states.device, checkpointed=checkpoint_this_block)
910+
if checkpoint_this_block:
910911
hidden_states = self._gradient_checkpointing_func(
911912
block,
912913
hidden_states,

simpletuner/helpers/models/cosmos3/transformer.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ def _should_gradient_checkpoint_layer(self, layer_idx: int) -> bool:
707707
@staticmethod
708708
def _stream_in_for_checkpoint_recompute(musubi_manager, layer_idx: int, layer: nn.Module, device: torch.device) -> None:
709709
if musubi_manager is not None and musubi_manager.is_managed_block(layer_idx):
710-
musubi_manager.stream_in(layer, device)
710+
musubi_manager.stream_in(layer, device, checkpointed=True)
711711

712712
# -------------------------------------------------------------------------
713713
# Pure-tensor packing/unpacking helpers (no layer state).
@@ -1057,9 +1057,14 @@ def forward(
10571057
gen_seq = hidden_states
10581058
rotary_gen = (cos[und_len:], sin[und_len:])
10591059
for layer_idx, decoder_layer in enumerate(self.layers):
1060+
checkpoint_this_block = self._should_gradient_checkpoint_layer(layer_idx)
10601061
if musubi_offload_active and musubi_manager.is_managed_block(layer_idx):
1061-
musubi_manager.stream_in(decoder_layer, gen_seq.device)
1062-
if self._should_gradient_checkpoint_layer(layer_idx):
1062+
musubi_manager.stream_in(
1063+
decoder_layer,
1064+
gen_seq.device,
1065+
checkpointed=checkpoint_this_block,
1066+
)
1067+
if checkpoint_this_block:
10631068

10641069
def checkpointed_gen_only(
10651070
x,
@@ -1088,9 +1093,14 @@ def checkpointed_gen_only(
10881093
rotary_emb = (cos[:und_len], sin[:und_len], cos[und_len:], sin[und_len:])
10891094
vision_gen_indexes = vision_mse_loss_indexes - und_len
10901095
for layer_idx, decoder_layer in enumerate(self.layers):
1096+
checkpoint_this_block = self._should_gradient_checkpoint_layer(layer_idx)
10911097
if musubi_offload_active and musubi_manager.is_managed_block(layer_idx):
1092-
musubi_manager.stream_in(decoder_layer, gen_seq.device)
1093-
if self._should_gradient_checkpoint_layer(layer_idx):
1098+
musubi_manager.stream_in(
1099+
decoder_layer,
1100+
gen_seq.device,
1101+
checkpointed=checkpoint_this_block,
1102+
)
1103+
if checkpoint_this_block:
10941104

10951105
def checkpointed_layer(
10961106
und,

simpletuner/helpers/models/ernie/transformer.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,19 @@ def apply_layer(layer_idx, layer, batch_first_hidden_states, rotary_emb, attn_ma
260260
musubi_offload_active = musubi_manager.activate(combined_blocks, hidden_states.device, grad_enabled)
261261

262262
for layer_idx, layer in enumerate(self.layers):
263+
checkpoint_this_block = (
264+
layer_idx not in skip_set
265+
and grad_enabled
266+
and self.gradient_checkpointing
267+
and should_checkpoint_block(
268+
layer_idx,
269+
True,
270+
self.gradient_checkpointing_interval,
271+
getattr(self, "gradient_checkpointing_segment_stride", None),
272+
)
273+
)
263274
if musubi_offload_active and musubi_manager.is_managed_block(layer_idx):
264-
musubi_manager.stream_in(layer, hidden_states.device)
275+
musubi_manager.stream_in(layer, hidden_states.device, checkpointed=checkpoint_this_block)
265276
if use_routing and route_ptr < len(routes) and layer_idx == routes[route_ptr]["start_layer_idx"]:
266277
keep_mask = torch.zeros(
267278
(batch_size, hidden_states.shape[1]),

simpletuner/helpers/models/flux/transformer.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,8 +1208,18 @@ def run_double_block(
12081208
capture_idx += len(segment_blocks)
12091209
continue
12101210

1211+
checkpoint_this_block = (
1212+
self.training
1213+
and self.gradient_checkpointing
1214+
and not run_gap_eagerly
1215+
and (self.gradient_checkpointing_interval is None or index_block % self.gradient_checkpointing_interval == 0)
1216+
)
12111217
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
1212-
musubi_manager.stream_in(block, hidden_states.device)
1218+
musubi_manager.stream_in(
1219+
block,
1220+
hidden_states.device,
1221+
checkpointed=checkpoint_this_block and not self.gradient_checkpointing_backend.endswith("-ffn"),
1222+
)
12131223
# TREAD: START a route?
12141224
if use_routing and route_ptr < len(routes) and global_idx == routes[route_ptr]["start_layer_idx"]:
12151225
mask_ratio = routes[route_ptr]["selection_ratio"]
@@ -1237,12 +1247,7 @@ def run_double_block(
12371247

12381248
# concatenate text + image rope
12391249
current_rope = tuple(torch.cat([tr, ir], dim=1) for tr, ir in zip(text_rope_b, img_rope_r))
1240-
if (
1241-
self.training
1242-
and self.gradient_checkpointing
1243-
and not run_gap_eagerly
1244-
and (self.gradient_checkpointing_interval is None or index_block % self.gradient_checkpointing_interval == 0)
1245-
):
1250+
if checkpoint_this_block:
12461251
checkpoint_ffn = self.gradient_checkpointing_backend.endswith("-ffn")
12471252

12481253
def create_custom_forward(module):
@@ -1365,8 +1370,18 @@ def run_single_block(_relative_index, segment_block, segment_hidden_states):
13651370
capture_idx += len(segment_blocks)
13661371
continue
13671372

1373+
checkpoint_this_block = (
1374+
self.training
1375+
and self.gradient_checkpointing
1376+
and not run_gap_eagerly
1377+
and (self.gradient_checkpointing_interval is None or index_block % self.gradient_checkpointing_interval == 0)
1378+
)
13681379
if musubi_offload_active and musubi_manager.is_managed_block(global_idx):
1369-
musubi_manager.stream_in(block, hidden_states.device)
1380+
musubi_manager.stream_in(
1381+
block,
1382+
hidden_states.device,
1383+
checkpointed=checkpoint_this_block and not self.gradient_checkpointing_backend.endswith("-ffn"),
1384+
)
13701385
# TREAD: START? (operate on *image* tokens only)
13711386
if use_routing and route_ptr < len(routes) and global_idx == routes[route_ptr]["start_layer_idx"]:
13721387
mask_ratio = routes[route_ptr]["selection_ratio"]
@@ -1402,12 +1417,7 @@ def run_single_block(_relative_index, segment_block, segment_hidden_states):
14021417
)
14031418
current_rope = tuple(torch.cat([tr, ir], dim=1) for tr, ir in zip(text_rope_b, img_rope_r))
14041419

1405-
if (
1406-
self.training
1407-
and self.gradient_checkpointing
1408-
and not run_gap_eagerly
1409-
and (self.gradient_checkpointing_interval is None or index_block % self.gradient_checkpointing_interval == 0)
1410-
):
1420+
if checkpoint_this_block:
14111421
checkpoint_ffn = self.gradient_checkpointing_backend.endswith("-ffn")
14121422

14131423
def create_custom_forward(module):

simpletuner/helpers/models/flux2/transformer.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,9 +1315,14 @@ def run_double_block(_idx, block, encoder_hidden_states, hidden_states):
13151315
break
13161316

13171317
global_layer_idx = index_block
1318+
checkpoint_this_block = grad_enabled and self.gradient_checkpointing
13181319

13191320
if musubi_offload_active and musubi_manager.is_managed_block(global_layer_idx):
1320-
musubi_manager.stream_in(block, hidden_states.device)
1321+
musubi_manager.stream_in(
1322+
block,
1323+
hidden_states.device,
1324+
checkpointed=checkpoint_this_block,
1325+
)
13211326

13221327
# Check for TREAD routing
13231328
if self._tread_router is not None and self.training:
@@ -1356,7 +1361,7 @@ def run_double_block(_idx, block, encoder_hidden_states, hidden_states):
13561361
torch.cat([current_pe_txt[1], current_pe_img[1]], dim=0),
13571362
)
13581363

1359-
if torch.is_grad_enabled() and self.gradient_checkpointing:
1364+
if checkpoint_this_block:
13601365

13611366
def create_custom_forward(module):
13621367
def custom_forward(*inputs):
@@ -1442,9 +1447,14 @@ def run_single_block(_idx, block, hidden_states):
14421447
break
14431448

14441449
global_layer_idx = num_double + index_block
1450+
checkpoint_this_block = grad_enabled and self.gradient_checkpointing
14451451

14461452
if musubi_offload_active and musubi_manager.is_managed_block(global_layer_idx):
1447-
musubi_manager.stream_in(block, hidden_states.device)
1453+
musubi_manager.stream_in(
1454+
block,
1455+
hidden_states.device,
1456+
checkpointed=checkpoint_this_block,
1457+
)
14481458

14491459
# Check for TREAD routing
14501460
if self._tread_router is not None and self.training:
@@ -1490,7 +1500,7 @@ def run_single_block(_idx, block, hidden_states):
14901500
tread_routing_info = None
14911501
current_concat_pe = concat_rotary_emb
14921502

1493-
if torch.is_grad_enabled() and self.gradient_checkpointing:
1503+
if checkpoint_this_block:
14941504

14951505
def create_custom_forward(module):
14961506
def custom_forward(*inputs):

simpletuner/helpers/models/hidream/transformer.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,8 +1666,18 @@ def custom_forward(pe_embedder):
16661666
# Process through double stream blocks
16671667
capture_idx = 0
16681668
for bid, block in enumerate(self.double_stream_blocks):
1669+
checkpoint_this_block = self.training and should_checkpoint_block(
1670+
bid,
1671+
self.gradient_checkpointing,
1672+
self.gradient_checkpointing_interval,
1673+
self.gradient_checkpointing_segment_stride,
1674+
)
16691675
if musubi_offload_active and musubi_manager.is_managed_block(block_id):
1670-
musubi_manager.stream_in(block, hidden_states.device)
1676+
musubi_manager.stream_in(
1677+
block,
1678+
hidden_states.device,
1679+
checkpointed=checkpoint_this_block,
1680+
)
16711681
# TREAD routing for this layer
16721682
if use_routing:
16731683
# Check if this layer should use routing
@@ -1698,12 +1708,7 @@ def custom_forward(pe_embedder):
16981708
)
16991709

17001710
# Process through the block with optional gradient checkpointing
1701-
if self.training and should_checkpoint_block(
1702-
bid,
1703-
self.gradient_checkpointing,
1704-
self.gradient_checkpointing_interval,
1705-
self.gradient_checkpointing_segment_stride,
1706-
):
1711+
if checkpoint_this_block:
17071712

17081713
def create_custom_forward(module, return_dict=None):
17091714
def custom_forward(*inputs):
@@ -1797,8 +1802,18 @@ def custom_forward(*inputs):
17971802

17981803
# 7. Process through single stream blocks
17991804
for bid, block in enumerate(self.single_stream_blocks):
1805+
checkpoint_this_block = self.training and should_checkpoint_block(
1806+
len(self.double_stream_blocks) + bid,
1807+
self.gradient_checkpointing,
1808+
self.gradient_checkpointing_interval,
1809+
self.gradient_checkpointing_segment_stride,
1810+
)
18001811
if musubi_offload_active and musubi_manager.is_managed_block(block_id):
1801-
musubi_manager.stream_in(block, hidden_states.device)
1812+
musubi_manager.stream_in(
1813+
block,
1814+
hidden_states.device,
1815+
checkpointed=checkpoint_this_block,
1816+
)
18021817
# TREAD routing for single stream layers
18031818
if use_routing:
18041819
# Check if this layer should use routing
@@ -1835,12 +1850,7 @@ def custom_forward(*inputs):
18351850
hidden_states = torch.cat([hidden_states, cur_llama_embedding], dim=1)
18361851

18371852
# Process through the block with optional gradient checkpointing
1838-
if self.training and should_checkpoint_block(
1839-
len(self.double_stream_blocks) + bid,
1840-
self.gradient_checkpointing,
1841-
self.gradient_checkpointing_interval,
1842-
self.gradient_checkpointing_segment_stride,
1843-
):
1853+
if checkpoint_this_block:
18441854

18451855
def create_custom_forward(module, return_dict=None):
18461856
def custom_forward(*inputs):

0 commit comments

Comments
 (0)