Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
532625e
Make gradient checkpointing and offloading per-component; centralize …
May 25, 2026
5a41835
Merge branch 'master' into split-offload
dxqb May 26, 2026
2f0620b
Revert "Revert "Upgrade transformers to 5.9 and huggingface-hub to 1.…
dxqb Jun 5, 2026
0b4ddc4
Merge branch 'upstream' into split-offload
dxqb Jun 6, 2026
d12ddd8
Merge commit '2f0620be0' into ideogram-base
dxqb Jun 10, 2026
efd85f7
Add shared pipeline-dtype-copy helper to DtypeModelSaverMixin
dxqb Jun 13, 2026
e0f4a72
Generalize _copy_pipeline_to_dtype and adopt it in all model savers
dxqb Jun 13, 2026
15f40a8
Merge branch 'upstream' into split-offload
dxqb Jun 13, 2026
cb79456
Centralize checkpointing/offloading gate inside enable_checkpointing
dxqb Jun 13, 2026
74ba5e3
Merge branch 'split-offload' into ideogram-base
dxqb Jun 14, 2026
0c23f3a
Merge branch 'save-pipeline-dtype-util' into ideogram-base
dxqb Jun 14, 2026
a4e3111
Add Ideogram 4 model support (LoRA, Fine Tune)
dxqb Jun 14, 2026
67e5a42
Pin mgds to dxqb/mgds PR #57 (ideogram branch)
dxqb Jun 14, 2026
f2ac77a
Fix Wuerstchen v2 prior checkpointing gate: only check checkpointing,…
dxqb Jun 17, 2026
618cc68
Merge remote-tracking branch 'Nerogar/master' into ideogram-base
dxqb Jun 17, 2026
aa7225e
Merge branch 'ideogram-base' into ideogram
dxqb Jun 17, 2026
71b8067
Use decorator form for factory.register() in Ideogram model files
dxqb Jun 17, 2026
4f35755
Merge branch 'master' into ideogram
dxqb Jun 19, 2026
2a891b7
Merge remote-tracking branch 'Nerogar/master' into split-offload
dxqb Jun 19, 2026
b67dd10
Merge remote-tracking branch 'Nerogar/master' into ideogram-base
dxqb Jun 19, 2026
96f2f4f
Merge branch 'ideogram-base' into ideogram
dxqb Jun 19, 2026
c0e1d73
Merge remote-tracking branch 'origin/ideogram' into ideogram
dxqb Jun 19, 2026
414ca28
Centralize model composition and training methods in ModelType
dxqb Jun 20, 2026
f4b7d50
Add per-component offloading/checkpointing from PR #1476
dxqb Jun 20, 2026
4a04e31
LoRA output formats: convert()-native saver/loader rework
dxqb Jun 29, 2026
c2952d2
Merge branch 'master' into lora-output-formats
dxqb Jun 29, 2026
b288e1c
ModelType: match lora-output-formats _MODEL_PARTS ordering
dxqb Jun 30, 2026
91f1f46
Merge branch 'centralize-model-type' into split-offload
dxqb Jun 30, 2026
ad1b49e
Merge branch 'split-offload' into ideogram-base
dxqb Jun 30, 2026
b764802
Merge branch 'ideogram-base' into ideogram
dxqb Jun 30, 2026
c42f660
Merge lora-output-formats into ideogram
dxqb Jun 30, 2026
ab712f7
Ideogram: adopt the per-format LoRA conversion API
dxqb Jun 30, 2026
c1c8ae8
Simplify _copy_pipeline_to_dtype API: pass tokenizer objects directly
dxqb Jul 1, 2026
624cddc
Merge branch 'save-pipeline-dtype-util' into ideogram-base
dxqb Jul 1, 2026
d598a02
Merge branch 'ideogram-base' into ideogram
dxqb Jul 1, 2026
29a0e07
Fix IdeogramModelSaver call to _copy_pipeline_to_dtype after API change
dxqb Jul 1, 2026
cc43b19
Merge branch 'merge' into lora-output-formats
dxqb Jul 1, 2026
54a8c2c
Merge branch 'lora-output-formats' of origin into lora-output-formats
dxqb Jul 1, 2026
d680a19
Centralize model composition and training methods in ModelType
dxqb Jul 1, 2026
a562693
Merge branch 'centralize-model-type' into split-offload
dxqb Jul 1, 2026
47e20b3
Merge branch 'split-offload' into ideogram-base
dxqb Jul 1, 2026
9f101d8
Merge branch 'ideogram-base' into ideogram
dxqb Jul 1, 2026
a45edda
Bump diffusers pin to latest upstream commit
dxqb Jul 1, 2026
fcd9b0d
Fix Ideogram4 LoRA output formats: fuse qkv for ORIGINAL/COMFY/KOHYA
dxqb Jul 1, 2026
7a5b53c
Commit stray preset revert left over from the split-offload merge
dxqb Jul 1, 2026
85ed2e4
Merge remote-tracking branch 'Nerogar/merge' into ideogram-base
dxqb Jul 1, 2026
6b82c06
Merge branch 'ideogram-base' into ideogram
dxqb Jul 1, 2026
3a59057
Avoid N^2 base recompute in fused qkv LoRA/LoHa adapters
dxqb Jul 2, 2026
3fced71
Avoid N^2 base recompute in fused qkv LoRA/LoHa adapters
dxqb Jul 2, 2026
85e6e93
Merge branch 'merge' into ideogram
dxqb Jul 2, 2026
09ee0e3
Address self-review comments on lora-output-formats
dxqb Jul 2, 2026
6a13051
LoRA loader: default LEGACY conversion to None instead of a generic g…
dxqb Jul 3, 2026
a226803
Merge branch 'lora-output-formats' into ideogram
dxqb Jul 3, 2026
76eeec7
Merge branch 'ideogram' of origin into ideogram
dxqb Jul 3, 2026
0807164
Ideogram sampler: fall back to empty-prompt CFG when unconditional tr…
dxqb Jul 3, 2026
0a9f279
Merge remote-tracking branch 'Nerogar/merge' into ideogram-base
dxqb Jul 4, 2026
c9c88e7
Centralize model composition and training methods in ModelType
dxqb Jul 4, 2026
338bc65
Merge origin/centralize-model-type into split-offload
dxqb Jul 4, 2026
baab41c
Fix Anima/Krea2 checkpointing calls to match part-based conductor API
dxqb Jul 4, 2026
b5c61ce
Merge remote-tracking branch 'Nerogar/merge' into split-offload
dxqb Jul 4, 2026
6908a6a
Address PR #1476 review comments
dxqb Jul 4, 2026
a30f033
Address further PR #1476 review: decouple checkpointing/offloading fr…
dxqb Jul 4, 2026
877978b
Merge remote-tracking branch 'Nerogar/merge' into ideogram-base
dxqb Jul 4, 2026
39ce7fe
Merge remote-tracking branch 'origin/split-offload' into ideogram-base
dxqb Jul 4, 2026
faf9fbb
Merge remote-tracking branch 'private/ideogram-base' into ideogram-base
dxqb Jul 4, 2026
221092c
Merge branch 'ideogram-base' into ideogram
dxqb Jul 4, 2026
5371e3c
Ideogram: PR review fixes, offloading/checkpointing refinements, pres…
dxqb Jul 5, 2026
4d504e0
presets: enable transformer offloading in Ideogram LoRA 16GB preset
dxqb Jul 5, 2026
e62fb30
Merge remote-tracking branch 'private/merge' into ideogram-base
dxqb Jul 5, 2026
dc5ca31
Merge branch 'ideogram-base' into ideogram
dxqb Jul 5, 2026
abc18db
Wire up text encoder checkpointing/offloading for Ideogram
dxqb Jul 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions modules/dataLoader/IdeogramBaseDataLoader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import os

from modules.dataLoader.BaseDataLoader import BaseDataLoader
from modules.dataLoader.mixin.DataLoaderText2ImageMixin import DataLoaderText2ImageMixin
from modules.model.IdeogramModel import PROMPT_MAX_LENGTH, IdeogramModel
from modules.modelSetup.BaseIdeogramSetup import BaseIdeogramSetup
from modules.util import factory
from modules.util.config.TrainConfig import TrainConfig
from modules.util.enum.ModelType import ModelType
from modules.util.TrainProgress import TrainProgress

from mgds.pipelineModules.DecodeTokens import DecodeTokens
from mgds.pipelineModules.DecodeVAE import DecodeVAE
from mgds.pipelineModules.EncodeIdeogramText import EncodeIdeogramText
from mgds.pipelineModules.EncodeVAE import EncodeVAE
from mgds.pipelineModules.PadMaskedTokens import PadMaskedTokens
from mgds.pipelineModules.PruneMaskedTokens import PruneMaskedTokens
from mgds.pipelineModules.RescaleImageChannels import RescaleImageChannels
from mgds.pipelineModules.SampleVAEDistribution import SampleVAEDistribution
from mgds.pipelineModules.SaveImage import SaveImage
from mgds.pipelineModules.SaveText import SaveText
from mgds.pipelineModules.ScaleImage import ScaleImage
from mgds.pipelineModules.Tokenize import Tokenize


@factory.register(BaseDataLoader, ModelType.IDEOGRAM_4)
class IdeogramBaseDataLoader(
BaseDataLoader,
DataLoaderText2ImageMixin,
):
def _preparation_modules(self, config: TrainConfig, model: IdeogramModel):
rescale_image = RescaleImageChannels(image_in_name='image', image_out_name='image', in_range_min=0, in_range_max=1, out_range_min=-1, out_range_max=1)
encode_image = EncodeVAE(in_name='image', out_name='latent_image_distribution', vae=model.vae, autocast_contexts=[model.autocast_context], dtype=model.train_dtype.torch_dtype())
image_sample = SampleVAEDistribution(in_name='latent_image_distribution', out_name='latent_image', mode='mean')
downscale_mask = ScaleImage(in_name='mask', out_name='latent_mask', factor=0.125)

# Ideogram wraps each prompt in the Qwen chat template (mirrors Ideogram4Pipeline.encode_prompt / encode_text).
# EncodeIdeogramText uses a plain arange for RoPE positions, and encode_text left-aligns by reading [:, :n],
# both of which require the real tokens to come first — relies on the tokenizer's default right-padding.
tokenize_prompt = Tokenize(
in_name='prompt', tokens_out_name='tokens', mask_out_name='tokens_mask',
tokenizer=model.tokenizer, max_token_length=PROMPT_MAX_LENGTH,
apply_chat_template=lambda prompt: [{"role": "user", "content": [{"type": "text", "text": prompt}]}],
apply_chat_template_kwargs={'add_generation_prompt': True},
)
encode_prompt = EncodeIdeogramText(
tokens_name='tokens', tokens_attention_mask_in_name='tokens_mask',
hidden_state_out_name='text_encoder_hidden_state', tokens_attention_mask_out_name='tokens_mask',
text_encoder=model.text_encoder, autocast_contexts=[model.autocast_context], dtype=model.train_dtype.torch_dtype(),
)
prune_masked_tokens = PruneMaskedTokens(tokens_name='tokens', tokens_mask_name='tokens_mask', hidden_state_name='text_encoder_hidden_state')

modules = [rescale_image, encode_image, image_sample]
if config.masked_training or config.model_type.has_mask_input():
modules.append(downscale_mask)
modules += [tokenize_prompt, encode_prompt]

if config.latent_caching:
modules.append(prune_masked_tokens)

return modules

def _cache_modules(self, config: TrainConfig, model: IdeogramModel, model_setup: BaseIdeogramSetup):
image_split_names = ['latent_image', 'original_resolution', 'crop_offset']

if config.masked_training or config.model_type.has_mask_input():
image_split_names.append('latent_mask')

image_aggregate_names = ['crop_resolution', 'image_path']

text_split_names = []

sort_names = image_aggregate_names + image_split_names + [
'prompt', 'tokens', 'tokens_mask', 'text_encoder_hidden_state',
'concept'
]

text_split_names += ['tokens', 'tokens_mask', 'text_encoder_hidden_state']

return self._cache_modules_from_names(
model, model_setup,
image_split_names=image_split_names,
image_aggregate_names=image_aggregate_names,
text_split_names=text_split_names,
sort_names=sort_names,
config=config,
text_caching=True,
)

def _output_modules(self, config: TrainConfig, model: IdeogramModel, model_setup: BaseIdeogramSetup):
pad_masked_tokens = PadMaskedTokens(tokens_name='tokens', tokens_mask_name='tokens_mask', hidden_state_name='text_encoder_hidden_state', max_length=PROMPT_MAX_LENGTH)

output_names = [
'image_path', 'latent_image',
'prompt',
'tokens',
'tokens_mask',
'original_resolution', 'crop_resolution', 'crop_offset',
]

if config.masked_training or config.model_type.has_mask_input():
output_names.append('latent_mask')

output_names.append('text_encoder_hidden_state')

output_module_list = self._output_modules_from_out_names(
model, model_setup,
output_names=output_names,
config=config,
use_conditioning_image=False,
vae=model.vae,
autocast_context=[model.autocast_context],
train_dtype=model.train_dtype,
)

if config.latent_caching:
output_module_list = [pad_masked_tokens] + output_module_list

return output_module_list

def _debug_modules(self, config: TrainConfig, model: IdeogramModel):
debug_dir = os.path.join(config.debug_dir, "dataloader")

def before_save_fun():
model.vae_to(self.train_device)

decode_image = DecodeVAE(in_name='latent_image', out_name='decoded_image', vae=model.vae, autocast_contexts=[model.autocast_context], dtype=model.train_dtype.torch_dtype())
upscale_mask = ScaleImage(in_name='latent_mask', out_name='decoded_mask', factor=8)
decode_prompt = DecodeTokens(in_name='tokens', out_name='decoded_prompt', tokenizer=model.tokenizer)
save_image = SaveImage(image_in_name='decoded_image', original_path_in_name='image_path', path=debug_dir, in_range_min=-1, in_range_max=1, before_save_fun=before_save_fun)
save_mask = SaveImage(image_in_name='decoded_mask', original_path_in_name='image_path', path=debug_dir, in_range_min=0, in_range_max=1, before_save_fun=before_save_fun)
save_prompt = SaveText(text_in_name='decoded_prompt', original_path_in_name='image_path', path=debug_dir, before_save_fun=before_save_fun)

modules = []

modules.append(decode_image)
modules.append(save_image)

if config.masked_training or config.model_type.has_mask_input():
modules.append(upscale_mask)
modules.append(save_mask)

modules.append(decode_prompt)
modules.append(save_prompt)

return modules

def _create_dataset(
self,
config: TrainConfig,
model: IdeogramModel,
model_setup: BaseIdeogramSetup,
train_progress: TrainProgress,
is_validation: bool = False,
):
return DataLoaderText2ImageMixin._create_dataset(self,
config, model, model_setup, train_progress, is_validation,
aspect_bucketing_quantization=64,
)
Loading