Skip to content

Commit e97057a

Browse files
committed
Update FLUX model configuration and recipes to use 12B variant
Signed-off-by: Ao Tang <aot@nvidia.com>
1 parent b68a88c commit e97057a

10 files changed

Lines changed: 43 additions & 103 deletions

File tree

‎examples/diffusion/recipes/flux/README.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,23 @@ uv run python examples/diffusion/recipes/flux/inference_flux.py \
9292

9393
Run FLUX pretraining with the generic **run_recipe** script (same entry point as for LLM training).
9494

95-
**Recipe:** [megatron.bridge.diffusion.recipes.flux.flux.pretrain_config](https://github.com/NVIDIA-NeMo/Megatron-Bridge/blob/main/src/megatron/bridge/diffusion/recipes/flux/flux.py)
95+
**Recipe:** [megatron.bridge.diffusion.recipes.flux.flux.flux_12b_pretrain_config](https://github.com/NVIDIA-NeMo/Megatron-Bridge/blob/main/src/megatron/bridge/diffusion/recipes/flux/flux.py)
9696

9797
From the **Megatron-Bridge repository root**:
9898

9999
**Mock data (no dataset path):**
100100

101101
```bash
102102
uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
103-
--recipe flux_14b_pretrain_config \
103+
--recipe flux_12b_pretrain_config \
104104
--step_func flux_step
105105
```
106106

107107
**Real data (WebDataset path):** Set `dataset.path` so the recipe uses real data instead of mock:
108108

109109
```bash
110110
uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
111-
--recipe flux_14b_pretrain_config \
111+
--recipe flux_12b_pretrain_config \
112112
--step_func flux_step \
113113
dataset.path=${WORKSPACE}/data/my_flux_wds/
114114
```
@@ -117,7 +117,7 @@ uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
117117

118118
```bash
119119
uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
120-
--recipe flux_14b_pretrain_config \
120+
--recipe flux_12b_pretrain_config \
121121
--step_func flux_step \
122122
dataset.path=${WORKSPACE}/data/my_flux_wds/ \
123123
train.train_iters=10000 \
@@ -139,7 +139,7 @@ Run FLUX fine-tuning with the generic **run_recipe** script. Set the pretrained
139139

140140
```bash
141141
uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
142-
--recipe flux_finetune_config \
142+
--recipe flux_12b_finetune_config \
143143
--step_func flux_step \
144144
checkpoint.pretrained_checkpoint=${WORKSPACE}/checkpoints/flux/flux.1-dev/iter_0000000
145145
```
@@ -148,7 +148,7 @@ uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
148148

149149
```bash
150150
uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
151-
--recipe flux_finetune_config \
151+
--recipe flux_12b_finetune_config \
152152
--step_func flux_step \
153153
checkpoint.pretrained_checkpoint=${WORKSPACE}/checkpoints/flux/flux.1-dev/iter_0000000 \
154154
dataset.path=${WORKSPACE}/data/my_flux_wds/ \
@@ -169,9 +169,9 @@ uv run torchrun --nproc_per_node=8 scripts/training/run_recipe.py \
169169
Run [inference_flux.py](inference_flux.py) with `--flux_ckpt` (Megatron `iter_*` path), `--vae_ckpt`, and `--prompts`.
170170

171171
3. **Pretraining**
172-
Run `scripts/training/run_recipe.py --recipe flux_14b_pretrain_config --step_func flux_step` (optionally with `dataset.path=...` for real data and CLI overrides).
172+
Run `scripts/training/run_recipe.py --recipe flux_12b_pretrain_config --step_func flux_step` (optionally with `dataset.path=...` for real data and CLI overrides).
173173

174174
4. **Fine-Tuning**
175-
Run `scripts/training/run_recipe.py --recipe flux_finetune_config --step_func flux_step checkpoint.pretrained_checkpoint=<path>` (optionally with `dataset.path=...` and overrides).
175+
Run `scripts/training/run_recipe.py --recipe flux_12b_finetune_config --step_func flux_step checkpoint.pretrained_checkpoint=<path>` (optionally with `dataset.path=...` and overrides).
176176

177177
For more details, see the recipe in `src/megatron/bridge/diffusion/recipes/flux/flux.py` and `scripts/training/run_recipe.py`.

‎scripts/training/run_recipe.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
3232
Diffusion (FLUX) pretrain:
3333
torchrun --nproc_per_node=8 run_recipe.py \
34-
--recipe flux_14b_pretrain_config \
34+
--recipe flux_12b_pretrain_config \
3535
--step_func flux_step
3636
3737
With CLI overrides:

‎src/megatron/bridge/diffusion/data/flux/flux_energon_datamodule.py‎

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import logging
1818
from dataclasses import dataclass
19-
from typing import Optional, Union
19+
from typing import Optional
2020

2121
from megatron.bridge.data.utils import DatasetBuildContext, DatasetProvider
2222
from megatron.bridge.diffusion.data.common.diffusion_energon_datamodule import (
@@ -29,17 +29,6 @@
2929
logger = logging.getLogger(__name__)
3030

3131

32-
def _is_empty_path(path: Optional[Union[str, list]]) -> bool:
33-
"""Return True if path should be treated as empty (use mock data)."""
34-
if path is None:
35-
return True
36-
if isinstance(path, str):
37-
return not path.strip()
38-
if isinstance(path, list):
39-
return len(path) == 0
40-
return True
41-
42-
4332
@dataclass(kw_only=True)
4433
class FluxDatasetConfig(DatasetProvider):
4534
"""
@@ -50,7 +39,7 @@ class FluxDatasetConfig(DatasetProvider):
5039
to load real data; no separate --data_paths or mock flag needed.
5140
"""
5241

53-
path: Optional[Union[str, list]] = None
42+
path: Optional[str] = None
5443
seq_length: int = 1024
5544
packing_buffer_size: Optional[int] = None
5645
micro_batch_size: int = 1
@@ -70,7 +59,7 @@ def __post_init__(self):
7059
self.sequence_length = self.seq_length
7160

7261
def build_datasets(self, context: DatasetBuildContext):
73-
if _is_empty_path(self.path):
62+
if not (self.path or "").strip():
7463
logger.info(
7564
"FLUX dataset: path is None or empty; using mock/synthetic data. "
7665
"Set dataset.path=/path/to/wds to use real data."
@@ -97,7 +86,6 @@ def build_datasets(self, context: DatasetBuildContext):
9786
)
9887
return mock_cfg.build_datasets(context)
9988

100-
# Real data: path is set (string or list)
10189
real_cfg = FluxDataModuleConfig(
10290
path=self.path,
10391
seq_length=self.seq_length,

‎src/megatron/bridge/diffusion/models/flux/__init__.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
get_flux_single_transformer_engine_spec,
5454
)
5555
from megatron.bridge.diffusion.models.flux.flux_model import Flux
56-
from megatron.bridge.diffusion.models.flux.flux_provider import FluxModelProvider14B, FluxProvider
56+
from megatron.bridge.diffusion.models.flux.flux_provider import FluxModelProvider12B, FluxProvider
5757
from megatron.bridge.diffusion.models.flux.layers import (
5858
EmbedND,
5959
MLPEmbedder,
@@ -66,7 +66,7 @@
6666
__all__ = [
6767
# Main model
6868
"Flux",
69-
"FluxModelProvider14B",
69+
"FluxModelProvider12B",
7070
"FluxProvider",
7171
# Transformer layers
7272
"MMDiTLayer",

‎src/megatron/bridge/diffusion/models/flux/flux_provider.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ def provide(self, pre_process=None, post_process=None, vp_stage=None) -> Flux:
135135

136136

137137
@dataclass
138-
class FluxModelProvider14B(FluxProvider):
139-
"""FLUX 14B model configuration.
138+
class FluxModelProvider12B(FluxProvider):
139+
"""FLUX 12B model configuration.
140140
141141
Architecture: 19 joint + 38 single transformer blocks, hidden_size=3072,
142142
24 attention heads, context_dim=4096. Default seq_length=1024.

‎src/megatron/bridge/diffusion/recipes/flux/__init__.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
# limitations under the License.
1414

1515
from megatron.bridge.diffusion.recipes.flux.flux import (
16-
flux_14b_finetune_config,
17-
flux_14b_pretrain_config,
16+
flux_12b_finetune_config,
17+
flux_12b_pretrain_config,
1818
)
1919

2020

21-
__all__ = ["flux_14b_finetune_config", "flux_14b_pretrain_config"]
21+
__all__ = ["flux_12b_finetune_config", "flux_12b_pretrain_config"]

‎src/megatron/bridge/diffusion/recipes/flux/flux.py‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from megatron.core.distributed import DistributedDataParallelConfig
1919

2020
from megatron.bridge.diffusion.data.flux.flux_energon_datamodule import FluxDatasetConfig
21-
from megatron.bridge.diffusion.models.flux.flux_provider import FluxModelProvider14B
21+
from megatron.bridge.diffusion.models.flux.flux_provider import FluxModelProvider12B
2222
from megatron.bridge.training.config import (
2323
CheckpointConfig,
2424
ConfigContainer,
@@ -30,9 +30,9 @@
3030
from megatron.bridge.training.mixed_precision import get_mixed_precision_config
3131

3232

33-
def flux_14b_pretrain_config() -> ConfigContainer:
33+
def flux_12b_pretrain_config() -> ConfigContainer:
3434
"""
35-
Return a pre-training configuration for FLUX model.
35+
Return a pre-training configuration for FLUX 12B model.
3636
3737
Default parallelism: TP=2, PP=1. Uses mock/synthetic data when data_paths is None.
3838
To customize (e.g. data paths, checkpoint dir), edit this recipe or add a new recipe
@@ -49,8 +49,8 @@ def flux_14b_pretrain_config() -> ConfigContainer:
4949
checkpoint_dir = os.path.join(run_output_dir, "checkpoints")
5050
tensorboard_dir = os.path.join(run_output_dir, "tb_logs")
5151

52-
# Model configuration - use FluxModelProvider14B (19 joint + 38 single layers)
53-
model_cfg = FluxModelProvider14B()
52+
# Model configuration - use FluxModelProvider12B (19 joint + 38 single layers)
53+
model_cfg = FluxModelProvider12B()
5454
model_cfg.tensor_model_parallel_size = 2
5555
model_cfg.pipeline_model_parallel_size = 1
5656
model_cfg.pipeline_dtype = torch.bfloat16
@@ -145,14 +145,14 @@ def flux_14b_pretrain_config() -> ConfigContainer:
145145
return cfg
146146

147147

148-
def flux_14b_finetune_config(pretrained_checkpoint: str | None = None) -> ConfigContainer:
148+
def flux_12b_finetune_config(pretrained_checkpoint: str | None = None) -> ConfigContainer:
149149
"""
150-
Return a fine-tuning configuration for FLUX model.
150+
Return a fine-tuning configuration for FLUX 12B model.
151151
152-
Uses the same defaults as flux_14b_pretrain_config() and overrides checkpoint to load from
152+
Uses the same defaults as flux_12b_pretrain_config() and overrides checkpoint to load from
153153
pretrained_checkpoint when provided.
154154
"""
155-
cfg = flux_14b_pretrain_config()
155+
cfg = flux_12b_pretrain_config()
156156
base_output_dir = os.path.join(os.getcwd(), "nemo_experiments")
157157
run_output_dir = os.path.join(base_output_dir, "default")
158158
checkpoint_dir = os.path.join(run_output_dir, "checkpoints")

‎tests/functional_tests/diffusion/flux/test_flux_pretrain.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
"""Functional smoke tests for Mcore FLUX pretrain mock runs.
1616
17-
Uses the generic run_recipe.py entry point with flux_14b_pretrain_config and flux_step.
17+
Uses the generic run_recipe.py entry point with flux_12b_pretrain_config and flux_step.
1818
Mock/synthetic data is used when dataset.path is not set (no --mock flag).
1919
"""
2020

@@ -57,7 +57,7 @@ def test_flux_pretrain_mock(self, tmp_path):
5757
"--parallel-mode",
5858
"scripts/training/run_recipe.py",
5959
"--recipe",
60-
"flux_14b_pretrain_config",
60+
"flux_12b_pretrain_config",
6161
"--step_func",
6262
"flux_step",
6363
"model.tensor_model_parallel_size=1",

‎tests/unit_tests/diffusion/data/flux/test_flux_energon_datamodule.py‎

Lines changed: 3 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,35 +24,6 @@
2424
pytestmark = [pytest.mark.unit]
2525

2626

27-
# -----------------------------------------------------------------------------
28-
# _is_empty_path
29-
# -----------------------------------------------------------------------------
30-
31-
32-
class TestIsEmptyPath:
33-
"""Tests for _is_empty_path helper."""
34-
35-
def test_none_is_empty(self):
36-
assert flux_dm_mod._is_empty_path(None) is True
37-
38-
def test_empty_string_is_empty(self):
39-
assert flux_dm_mod._is_empty_path("") is True
40-
41-
def test_whitespace_only_string_is_empty(self):
42-
assert flux_dm_mod._is_empty_path(" ") is True
43-
44-
def test_non_empty_string_is_not_empty(self):
45-
assert flux_dm_mod._is_empty_path("/path/to/data") is False
46-
assert flux_dm_mod._is_empty_path("x") is False
47-
48-
def test_empty_list_is_empty(self):
49-
assert flux_dm_mod._is_empty_path([]) is True
50-
51-
def test_non_empty_list_is_not_empty(self):
52-
assert flux_dm_mod._is_empty_path(["/a"]) is False
53-
assert flux_dm_mod._is_empty_path(["/a", "/b"]) is False
54-
55-
5627
# -----------------------------------------------------------------------------
5728
# FluxDatasetConfig (unified config: mock vs real at runtime)
5829
# -----------------------------------------------------------------------------
@@ -98,6 +69,9 @@ def test_build_datasets_empty_string_path_uses_mock_branch(self):
9869
fake_train, fake_val, fake_test = iter(["a"]), iter(["b"]), iter(["c"])
9970

10071
class FakeMockConfig:
72+
def __init__(self, **kwargs):
73+
pass
74+
10175
def build_datasets(self, context):
10276
return (fake_train, fake_val, fake_test)
10377

@@ -130,28 +104,6 @@ def test_build_datasets_string_path_uses_real_branch(self, monkeypatch):
130104
# Verify real config was built with the string path (via _FakeDiffusionDataModule)
131105
assert cfg.path == "/path/to/wds"
132106

133-
def test_build_datasets_list_path_uses_first_element(self, monkeypatch):
134-
"""When path is a list, build_datasets uses path[0] as path_str for FluxDataModuleConfig."""
135-
received_paths = []
136-
137-
class CapturePathFake(_FakeDiffusionDataModule):
138-
def __init__(self, *, path, **kwargs):
139-
received_paths.append(path)
140-
super().__init__(path=path, **kwargs)
141-
142-
monkeypatch.setattr(flux_dm_mod, "DiffusionDataModule", CapturePathFake)
143-
cfg = flux_dm_mod.FluxDatasetConfig(
144-
path=["/first/shard", "/second/shard"],
145-
seq_length=1024,
146-
packing_buffer_size=4,
147-
micro_batch_size=2,
148-
global_batch_size=8,
149-
num_workers=0,
150-
)
151-
train, val, test = cfg.build_datasets(context=None)
152-
assert list(train) == list("train")
153-
assert received_paths == ["/first/shard"]
154-
155107

156108
# -----------------------------------------------------------------------------
157109
# FluxDataModuleConfig (real data only)

‎tests/unit_tests/diffusion/recipes/flux/test_flux_recipe.py‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from megatron.bridge.diffusion.data.flux.flux_energon_datamodule import FluxDatasetConfig
1818
from megatron.bridge.diffusion.models.flux.flux_provider import FluxProvider
19-
from megatron.bridge.diffusion.recipes.flux.flux import flux_14b_pretrain_config
19+
from megatron.bridge.diffusion.recipes.flux.flux import flux_12b_pretrain_config
2020
from megatron.bridge.training.config import ConfigContainer
2121

2222

@@ -28,7 +28,7 @@ class TestPretrainConfig:
2828

2929
def test_pretrain_config_returns_complete_config(self):
3030
"""Test that pretrain_config returns a ConfigContainer with all required components."""
31-
config = flux_14b_pretrain_config()
31+
config = flux_12b_pretrain_config()
3232

3333
assert isinstance(config, ConfigContainer)
3434
assert isinstance(config.model, FluxProvider)
@@ -44,23 +44,23 @@ def test_pretrain_config_returns_complete_config(self):
4444

4545
def test_pretrain_config_directory_structure(self):
4646
"""Test that pretrain_config uses default directory structure."""
47-
config = flux_14b_pretrain_config()
47+
config = flux_12b_pretrain_config()
4848

4949
assert "default" in config.checkpoint.save
5050
assert "default" in config.logger.tensorboard_dir
5151
assert config.checkpoint.save.endswith("checkpoints")
5252

5353
def test_pretrain_config_default_training_parameters(self):
5454
"""Test pretrain_config default training parameters."""
55-
config = flux_14b_pretrain_config()
55+
config = flux_12b_pretrain_config()
5656

5757
assert config.train.train_iters == 10000
5858
assert config.train.global_batch_size == 16
5959
assert config.train.micro_batch_size == 1
6060

6161
def test_pretrain_config_default_model_parameters(self):
6262
"""Test that default model parameters are set correctly."""
63-
config = flux_14b_pretrain_config()
63+
config = flux_12b_pretrain_config()
6464

6565
assert config.model.num_joint_layers == 19
6666
assert config.model.hidden_size == 3072
@@ -69,17 +69,17 @@ def test_pretrain_config_default_model_parameters(self):
6969

7070
def test_pretrain_config_default_dataset_configuration(self):
7171
"""Test pretrain_config default dataset parameters."""
72-
config = flux_14b_pretrain_config()
72+
config = flux_12b_pretrain_config()
7373

7474
assert config.dataset.image_H == 1024
7575
assert config.dataset.image_W == 1024
7676
assert config.dataset.latent_channels == 16
7777

7878
def test_pretrain_config_dataset_accepts_path_list(self):
7979
"""Test that dataset config can be overridden to use real data paths."""
80-
config = flux_14b_pretrain_config()
80+
config = flux_12b_pretrain_config()
8181
assert config.dataset.path is None
8282

83-
# FluxDatasetConfig accepts path as list; recipe default is None
84-
config.dataset.path = ["/some/data/path"]
85-
assert config.dataset.path == ["/some/data/path"]
83+
# FluxDatasetConfig accepts path as str; recipe default is None
84+
config.dataset.path = "/some/data/path"
85+
assert config.dataset.path == "/some/data/path"

0 commit comments

Comments
 (0)