Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 11 additions & 2 deletions src/maxdiffusion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@

__version__ = "0.22.0.dev0"

# Monkeypatch jax.numpy.clip to support legacy a_min and a_max arguments (fixed for newer JAX 0.4.31+)
import jax.numpy as jnp
orig_clip = jnp.clip
def patched_clip(a, a_min=None, a_max=None, *args, **kwargs):
c_min = kwargs.pop("min", a_min)
c_max = kwargs.pop("max", a_max)
return orig_clip(a, min=c_min, max=c_max, *args, **kwargs)
jnp.clip = patched_clip

from typing import TYPE_CHECKING

from .utils import (
Expand Down Expand Up @@ -367,7 +376,7 @@
_import_structure["models.controlnet_flax"] = ["FlaxControlNetModel"]
_import_structure["models.modeling_flax_utils"] = ["FlaxModelMixin"]
_import_structure["models.unet_2d_condition_flax"] = ["FlaxUNet2DConditionModel"]
_import_structure["models.flux.transformers.transformer_flux_flax"] = ["FluxTransformer2DModel"]
_import_structure["models.flux.transformers.transformer_flux"] = ["FluxTransformer2DModel"]
_import_structure["models.vae_flax"] = ["FlaxAutoencoderKL"]
_import_structure["models.ltx_video.transformers.transformer3d"] = ["Transformer3DModel"]
_import_structure["pipelines"].extend(["FlaxDiffusionPipeline"])
Expand Down Expand Up @@ -444,7 +453,7 @@
from .models.controlnet_flax import FlaxControlNetModel
from .models.modeling_flax_utils import FlaxModelMixin
from .models.unet_2d_condition_flax import FlaxUNet2DConditionModel
from .models.flux.transformers.transformer_flux_flax import FluxTransformer2DModel
from .models.flux.transformers.transformer_flux import FluxTransformer2DModel
from .models.ltx_video.transformers.transformer3d import Transformer3DModel
from .models.vae_flax import FlaxAutoencoderKL
from .pipelines import FlaxDiffusionPipeline
Expand Down
2 changes: 1 addition & 1 deletion src/maxdiffusion/checkpointing/flux_checkpointer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
FlaxAutoencoderKL,
max_logging,
)
from maxdiffusion.models.flux.transformers.transformer_flux_flax import FluxTransformer2DModel
from maxdiffusion.models.flux.transformers.transformer_flux import FluxTransformer2DModel
from ..pipelines.flux.flux_pipeline import FluxPipeline

from transformers import (CLIPTokenizer, FlaxCLIPTextModel, FlaxT5EncoderModel, AutoTokenizer)
Expand Down
25 changes: 19 additions & 6 deletions src/maxdiffusion/configs/base_flux2klein.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ flux_name: "flux2klein"
scale_shift_order: "scale_shift"
use_latents: False
latents_path: ""
max_sequence_length: 512
max_sequence_length: 256
time_shift: True
base_shift: 0.5
max_shift: 1.15
Expand All @@ -63,18 +63,31 @@ jit_initializers: True
# Set true to load weights from pytorch
from_pt: True
split_head_dim: True
attention: 'flash' # Supported attention: dot_product, flash, cudnn_flash_te
attention: 'ulysses_custom' # Supported attention: dot_product, flash, cudnn_flash_te, ulysses_custom
use_base2_exp: True
use_experimental_scheduler: True
# If mask_padding_tokens is True, we pass in segment ids to splash attention to avoid attending to padding tokens.
# Else we do not pass in segment ids and on vpu bound hardware like trillium this is faster.
# However, when padding tokens are significant, this will lead to worse quality and should be set to True.
mask_padding_tokens: True
mask_padding_tokens: False
# Maxdiffusion has 2 types of attention sharding strategies:
# 1. attention_sharding_uniform = True : same sequence sharding rules applied for q in both (self and cross attention)
# 2. attention_sharding_uniform = False : Heads are sharded uniformly across devices for self attention while sequence is sharded
# in cross attention q.
attention_sharding_uniform: True

flash_block_sizes: {}
flash_block_sizes: {
"block_q" : 4352,
"block_kv_compute" : 1024,
"block_kv" : 1024,
"block_kv_compute_in" : 1024,
"heads_per_tile" : 3,
"block_q_dkv" : 4352,
"block_kv_dkv" : 1024,
"block_kv_dkv_compute" : 1024,
"block_q_dq" : 4352,
"block_kv_dq" : 1024
}
# GroupNorm groups
norm_num_groups: 32

Expand Down Expand Up @@ -148,7 +161,7 @@ logical_axis_rules: [
['out_channels', 'tensor'],
['conv_out', 'fsdp'],
]
data_sharding: [['data', 'fsdp', 'context', 'tensor']]
data_sharding: [['data', 'fsdp']]

# One axis for each parallelism type may hold a placeholder (-1)
# value to auto-shard based on available slices and devices.
Expand Down Expand Up @@ -203,7 +216,7 @@ num_train_epochs: 1
seed: 0
output_dir: 'output/'
output_name: "flux2klein_generated_image.png"
per_device_batch_size: 1
per_device_batch_size: 1.0

warmup_steps_fraction: 0.1
learning_rate_schedule_steps: -1 # By default the length of the schedule is set to the number of steps.
Expand Down
23 changes: 18 additions & 5 deletions src/maxdiffusion/configs/base_flux2klein_9B.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,31 @@ jit_initializers: True
# Set true to load weights from pytorch
from_pt: True
split_head_dim: True
attention: 'flash' # Supported attention: dot_product, flash, cudnn_flash_te
attention: 'ulysses_custom' # Supported attention: dot_product, flash, cudnn_flash_te, ulysses_custom
use_base2_exp: True
use_experimental_scheduler: True
# If mask_padding_tokens is True, we pass in segment ids to splash attention to avoid attending to padding tokens.
# Else we do not pass in segment ids and on vpu bound hardware like trillium this is faster.
# However, when padding tokens are significant, this will lead to worse quality and should be set to True.
mask_padding_tokens: True
mask_padding_tokens: False
# Maxdiffusion has 2 types of attention sharding strategies:
# 1. attention_sharding_uniform = True : same sequence sharding rules applied for q in both (self and cross attention)
# 2. attention_sharding_uniform = False : Heads are sharded uniformly across devices for self attention while sequence is sharded
# in cross attention q.
attention_sharding_uniform: True

flash_block_sizes: {}
flash_block_sizes: {
"block_q" : 4864,
"block_kv_compute" : 1024,
"block_kv" : 1024,
"block_kv_compute_in" : 1024,
"heads_per_tile" : 3,
"block_q_dkv" : 4864,
"block_kv_dkv" : 1024,
"block_kv_dkv_compute" : 1024,
"block_q_dq" : 4864,
"block_kv_dq" : 1024
}
# GroupNorm groups
norm_num_groups: 32

Expand Down Expand Up @@ -148,7 +161,7 @@ logical_axis_rules: [
['out_channels', 'tensor'],
['conv_out', 'fsdp'],
]
data_sharding: [['data', 'fsdp', 'context', 'tensor']]
data_sharding: [['data', 'fsdp']]

# One axis for each parallelism type may hold a placeholder (-1)
# value to auto-shard based on available slices and devices.
Expand Down Expand Up @@ -203,7 +216,7 @@ num_train_epochs: 1
seed: 0
output_dir: 'output/'
output_name: "flux2klein_generated_image.png"
per_device_batch_size: 1
per_device_batch_size: 1.0

warmup_steps_fraction: 0.1
learning_rate_schedule_steps: -1 # By default the length of the schedule is set to the number of steps.
Expand Down
33 changes: 17 additions & 16 deletions src/maxdiffusion/configs/base_flux_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ t5xxl_model_name_or_path: 'ariG23498/t5-v1-1-xxl-flax'

# Flux params
flux_name: "flux-dev"
max_sequence_length: 512
max_sequence_length: 256
time_shift: True
base_shift: 0.5
max_shift: 1.15
Expand Down Expand Up @@ -62,30 +62,31 @@ jit_initializers: True
# Set true to load weights from pytorch
from_pt: True
split_head_dim: True
attention: 'flash' # Supported attention: dot_product, flash, cudnn_flash_te
use_base2_exp: False
use_experimental_scheduler: False
attention: 'ulysses_custom' # Supported attention: dot_product, flash, cudnn_flash_te, ulysses_custom
use_base2_exp: True
use_experimental_scheduler: True
# If mask_padding_tokens is True, we pass in segment ids to splash attention to avoid attending to padding tokens.
# Else we do not pass in segment ids and on vpu bound hardware like trillium this is faster.
# However, when padding tokens are significant, this will lead to worse quality and should be set to True.
mask_padding_tokens: True
mask_padding_tokens: False
# Maxdiffusion has 2 types of attention sharding strategies:
# 1. attention_sharding_uniform = True : same sequence sharding rules applied for q in both (self and cross attention)
# 2. attention_sharding_uniform = False : Heads are sharded uniformly across devices for self attention while sequence is sharded
# in cross attention q.
attention_sharding_uniform: True

#flash_block_sizes: {}
# Use the following flash_block_sizes on v6e (Trillium) due to larger vmem.
flash_block_sizes: {
"block_q" : 1536,
"block_kv_compute" : 1536,
"block_kv" : 1536,
"block_q_dkv" : 1536,
"block_kv_dkv" : 1536,
"block_kv_dkv_compute" : 1536,
"block_q_dq" : 1536,
"block_kv_dq" : 1536
"block_q" : 4864,
"block_kv_compute" : 1024,
"block_kv" : 1024,
"block_kv_compute_in" : 1024,
"heads_per_tile" : 3,
"block_q_dkv" : 4864,
"block_kv_dkv" : 1024,
"block_kv_dkv_compute" : 1024,
"block_q_dq" : 4864,
"block_kv_dq" : 1024
}
# GroupNorm groups
norm_num_groups: 32
Expand Down Expand Up @@ -162,7 +163,7 @@ logical_axis_rules: [
['out_channels', 'tensor'],
['conv_out', 'fsdp'],
]
data_sharding: [['data', 'fsdp', 'context', 'tensor']]
data_sharding: [['data', 'fsdp']]

# One axis for each parallelism type may hold a placeholder (-1)
# value to auto-shard based on available slices and devices.
Expand Down Expand Up @@ -251,7 +252,7 @@ max_train_steps: 1500
num_train_epochs: 1
seed: 0
output_dir: 'sdxl-model-finetuned'
per_device_batch_size: 1
per_device_batch_size: 1.0

warmup_steps_fraction: 0.1
learning_rate_schedule_steps: -1 # By default the length of the schedule is set to the number of steps.
Expand Down
41 changes: 17 additions & 24 deletions src/maxdiffusion/configs/base_flux_schnell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,38 +61,31 @@ jit_initializers: True
# Set true to load weights from pytorch
from_pt: True
split_head_dim: True
attention: 'flash' # Supported attention: dot_product, flash, cudnn_flash_te
attention: 'ulysses_custom' # Supported attention: dot_product, flash, cudnn_flash_te, ulysses_custom
use_base2_exp: True
use_experimental_scheduler: True
# If mask_padding_tokens is True, we pass in segment ids to splash attention to avoid attending to padding tokens.
# Else we do not pass in segment ids and on vpu bound hardware like trillium this is faster.
# However, when padding tokens are significant, this will lead to worse quality and should be set to True.
mask_padding_tokens: True
mask_padding_tokens: False
# Maxdiffusion has 2 types of attention sharding strategies:
# 1. attention_sharding_uniform = True : same sequence sharding rules applied for q in both (self and cross attention)
# 2. attention_sharding_uniform = False : Heads are sharded uniformly across devices for self attention while sequence is sharded
# in cross attention q.
attention_sharding_uniform: True
# Use the following flash_block_sizes on v6e (Trillium) due to larger vmem.
flash_block_sizes: {
"block_q" : 256,
"block_kv_compute" : 256,
"block_kv" : 256,
"block_q_dkv" : 256,
"block_kv_dkv" : 256,
"block_kv_dkv_compute" : 256,
"block_q_dq" : 256,
"block_kv_dq" : 256
"block_q" : 4864,
"block_kv_compute" : 1024,
"block_kv" : 1024,
"block_kv_compute_in" : 1024,
"heads_per_tile" : 3,
"block_q_dkv" : 4864,
"block_kv_dkv" : 1024,
"block_kv_dkv_compute" : 1024,
"block_q_dq" : 4864,
"block_kv_dq" : 1024
}

# Use the following flash_block_sizes on v6e (Trillium).
# flash_block_sizes: {
# "block_q" : 2176,
# "block_kv_compute" : 2176,
# "block_kv" : 2176,
# "block_q_dkv" : 2176,
# "block_kv_dkv" : 2176,
# "block_kv_dkv_compute" : 2176,
# "block_q_dq" : 2176,
# "block_kv_dq" : 2176
# }
# GroupNorm groups
norm_num_groups: 32

Expand Down Expand Up @@ -166,7 +159,7 @@ logical_axis_rules: [
['out_channels', 'tensor'],
['conv_out', 'fsdp'],
]
data_sharding: [['data', 'fsdp', 'context', 'tensor']]
data_sharding: [['data', 'fsdp']]

# One axis for each parallelism type may hold a placeholder (-1)
# value to auto-shard based on available slices and devices.
Expand Down Expand Up @@ -227,7 +220,7 @@ max_train_steps: 200
num_train_epochs: 1
seed: 0
output_dir: 'sdxl-model-finetuned'
per_device_batch_size: 1
per_device_batch_size: 1.0

warmup_steps_fraction: 0.0
learning_rate_schedule_steps: -1 # By default the length of the schedule is set to the number of steps.
Expand Down
9 changes: 5 additions & 4 deletions src/maxdiffusion/generate_flux.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from transformers import (CLIPTokenizer, FlaxCLIPTextModel, T5EncoderModel, FlaxT5EncoderModel, AutoTokenizer)

from maxdiffusion import FlaxAutoencoderKL, pyconfig, max_logging, max_utils
from maxdiffusion.models.flux.transformers.transformer_flux_flax import FluxTransformer2DModel
from maxdiffusion.models.flux.transformers.transformer_flux import FluxTransformer2DModel
from maxdiffusion.train_utils import transformer_engine_context
from maxdiffusion.max_utils import (
device_put_replicated,
Expand Down Expand Up @@ -78,7 +78,7 @@ def unpack(x: Array, height: int, width: int) -> Array:


def vae_decode(latents, vae, state, config):
img = unpack(x=latents.astype(jnp.float32), height=config.resolution, width=config.resolution)
img = unpack(x=latents.astype(jnp.bfloat16), height=config.resolution, width=config.resolution)
img = img / vae.config.scaling_factor + vae.config.shift_factor
img = vae.apply({"params": state.params}, img, deterministic=True, method=vae.decode).sample
return img
Expand Down Expand Up @@ -281,7 +281,7 @@ def run(config):
devices_array = create_device_mesh(config)
mesh = Mesh(devices_array, config.mesh_axes)

global_batch_size = config.per_device_batch_size * jax.local_device_count()
global_batch_size = int(round(config.per_device_batch_size * jax.local_device_count()))

# LOAD VAE
with mesh:
Expand Down Expand Up @@ -482,8 +482,9 @@ def validate_inputs(latents, latent_image_ids, prompt_embeds, text_ids, timestep
max_logging.log(f"Inference time: {t1 - t0:.1f}s.")
imgs = np.array(imgs)
imgs = (imgs * 0.5 + 0.5).clip(0, 1)
imgs = np.nan_to_num(imgs, nan=0.0)
imgs = np.transpose(imgs, (0, 2, 3, 1))
imgs = np.uint8(imgs * 255)
imgs = np.uint8(np.clip(imgs * 255, 0, 255))
for i, image in enumerate(imgs):
Image.fromarray(image).save(f"flux_{i}.png")

Expand Down
Loading
Loading