Skip to content
Open
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
1 change: 1 addition & 0 deletions src/maxtext/common/common_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class AttentionType(enum.Enum):
MLA = "mla"
COMPRESSED = "compressed"
FULL = "full"
BLOCK_DIFFUSION = "block_diffusion"


class ShardMode(enum.Enum):
Expand Down
14 changes: 13 additions & 1 deletion src/maxtext/configs/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,13 @@ param_scan_axis: 1
# The attention parameter dictates the specific algorithm/methodology used to compute the attention scores
# The attention_type parameter determines the variants of attention, e.g. global or local_sliding
attention: 'autoselected' # Supported attention: autoselected, dot_product, flash, cudnn_flash_te
attention_type: 'global' # Supported attention_type: global, local_sliding, chunk, mla
attention_type: 'global' # Supported attention_type: global, local_sliding, chunk, mla, full, compressed, block_diffusion
share_kv_projections: false # Note: Not compatible with attention_type='mla'
attention_bias: false # If true, adds a learnable bias to the query, key, and value projections
attention_sink: false
sliding_window_size: 0
chunk_attn_window_size: 0
block_diffusion_block_size: 32 # Size of each bidirectional block when attention_type='block_diffusion'
attn_logits_soft_cap: 0.0
final_logits_soft_cap: 0.0
z_loss_multiplier: 0.0
Expand Down Expand Up @@ -790,6 +791,11 @@ olmo_apply_ngram_filter: true # mask instances with repetitive n-grams (OLMo-cor
# Training loop
steps: 150_001 # If set to -1 then will inherit value from learning_rate_schedule_steps
log_period: 100 # The frequency of Tensorboard flush, gcs metrics writing, and managed profiler metrics updating.
training_objective: 'causal_lm' # Supported objectives: causal_lm, block_diffusion
block_diffusion_mask_id: -1 # Tokenizer mask-token id; required for training_objective='block_diffusion'
block_diffusion_min_noise: 0.001 # Minimum per-block corruption probability for block-diffusion training
block_diffusion_logit_alignment: 'same_position' # Supported alignments: same_position, shifted
block_diffusion_canvas_policy: 'all_masked' # Supported canvases: all_masked, seed_and_mask

jax_distributed_initialization_timeout: 300 # This is the default timeout in https://github.com/jax-ml/jax/blob/main/jax/_src/distributed.py
# Note there are two separate initializations - the jax coordination service (aka jax.distributed.initialize) and the backend (e.g. PjRT), the timeout above refers
Expand Down Expand Up @@ -1315,6 +1321,12 @@ engram_kernel_size: 4
engram_seed: 0

##### Distillation parameters
distill_data_source: "dataset" # dataset or student_rollout for diffusion on-policy distillation
distill_rollout_algorithm: "low_confidence"
distill_rollout_confidence_threshold: 0.9
distill_rollout_temperature: 1.0
distill_rollout_max_denoise_steps: -1 # -1 uses block_diffusion_block_size
distill_rollout_stop_token_ids: [] # Empty uses the tokenizer EOS; set model-specific EOT IDs explicitly
distill_alpha: 0.5
distill_temperature: 1.0
# distill_beta is used for cosine similarity loss between intermediate activataitions of out_proj in teacher/student models.
Expand Down
95 changes: 94 additions & 1 deletion src/maxtext/configs/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ class Attention(BaseModel):
"autoselected",
description="The attention algorithm to use (dot_product, flash, cudnn_flash_te, vllm_rpa, vllm_batched_rpa, etc).",
)
attention_type: Literal["global", "local_sliding", "chunk", "mla", "full", "compressed"] = Field(
attention_type: Literal["global", "local_sliding", "chunk", "mla", "full", "compressed", "block_diffusion"] = Field(
"global", description="The variant of attention to use."
)
share_kv_projections: bool = Field(
Expand Down Expand Up @@ -619,6 +619,10 @@ class Attention(BaseModel):
)
sliding_window_size: NonNegativeInt = Field(0, description="The size of the sliding window for local attention.")
chunk_attn_window_size: NonNegativeInt = Field(0, description="The window size for chunked attention.")
block_diffusion_block_size: PositiveInt = Field(
32,
description="The size of each bidirectional block when attention_type is 'block_diffusion'.",
)
attn_logits_soft_cap: None | NonNegativeFloat = Field(
None, description="Soft-cap value for attention logits. None means no cap."
)
Expand Down Expand Up @@ -1507,6 +1511,35 @@ class Distillation(BaseModel):
description="GCS or local path to the pre-generated ArrayRecord teacher data.",
)

distill_data_source: Literal["dataset", "student_rollout"] = Field(
"dataset",
description="Whether distillation consumes dataset targets or fresh rollouts from the current student.",
)
distill_rollout_algorithm: Literal["low_confidence"] = Field(
"low_confidence",
description="Block-diffusion rollout algorithm used for on-policy distillation.",
)
distill_rollout_confidence_threshold: float = Field(
0.9,
ge=0.0,
le=1.0,
description="Confidence threshold for parallel token commits during diffusion rollout.",
)
distill_rollout_temperature: float = Field(
1.0,
gt=0.0,
description="Temperature used to compute rollout token confidence.",
)
distill_rollout_max_denoise_steps: int = Field(
-1,
ge=-1,
description="Maximum denoising iterations per block; -1 uses block_diffusion_block_size.",
)
distill_rollout_stop_token_ids: list[int] = Field(
default_factory=list,
description="Generated token IDs that terminate the OPD completion; empty uses the tokenizer EOS ID.",
)

# --- Loss Params ---
distill_alpha: float = Field(0.5, description="Weight for the distillation loss component.")
distill_temperature: float = Field(1.0, description="Temperature for distillation softening.")
Expand Down Expand Up @@ -1579,6 +1612,28 @@ class Distillation(BaseModel):
class TrainingLoop(BaseModel):
"""Configuration for the main training loop, evaluation, and reproducibility."""

training_objective: Literal["causal_lm", "block_diffusion"] = Field(
"causal_lm",
description="The token-prediction objective used to prepare targets and compute loss.",
)
block_diffusion_mask_id: int = Field(
-1,
description="The tokenizer mask-token id required by the block-diffusion training objective.",
)
block_diffusion_min_noise: float = Field(
1.0e-3,
gt=0.0,
le=1.0,
description="The minimum corruption probability sampled independently for each block.",
)
block_diffusion_logit_alignment: Literal["same_position", "shifted"] = Field(
"same_position",
description="How model logits align to clean target-token positions.",
)
block_diffusion_canvas_policy: Literal["all_masked", "seed_and_mask"] = Field(
"all_masked",
description="Whether every block is fully maskable or begins with a clean anchor token.",
)
steps: int = Field(
150_001,
ge=-1,
Expand Down Expand Up @@ -3283,6 +3338,44 @@ def calculate_global_batch_sizes(per_device_batch_size, expansion_factor, num_de
not isinstance(self.sliding_window_size, int) or self.sliding_window_size <= 0
):
raise ValueError("`sliding_window_size` must be an integer > 0 for 'local_sliding' attention.")
if self.attention_type == AttentionType.BLOCK_DIFFUSION.value:
if self.attention not in ("autoselected", "dot_product", "flash"):
raise ValueError("Block-diffusion attention is supported only by dot_product attention and TPU Splash attention.")
if self.attention in ("autoselected", "flash") and self.hardware != "tpu":
raise ValueError(
"Block-diffusion attention with attention='autoselected' or attention='flash' requires hardware='tpu'; "
"use attention='dot_product' on other hardware."
)
if self.training_objective == "block_diffusion":
if self.attention_type != AttentionType.BLOCK_DIFFUSION.value:
raise ValueError("`training_objective='block_diffusion'` requires `attention_type='block_diffusion'`.")
if self.block_diffusion_mask_id < 0 or self.block_diffusion_mask_id >= self.vocab_size:
raise ValueError(
f"`block_diffusion_mask_id` ({self.block_diffusion_mask_id}) must satisfy "
f"0 <= block_diffusion_mask_id < vocab_size ({self.vocab_size})."
)
if self.packing:
raise ValueError("`training_objective='block_diffusion'` requires `packing=False`.")
if self.mtp_num_layers > 0:
raise ValueError("`training_objective='block_diffusion'` is not compatible with MTP.")
if self.num_vocab_tiling > 1:
raise ValueError("`training_objective='block_diffusion'` is not compatible with vocabulary tiling.")
if self.dataset_type != "hf":
raise ValueError("`training_objective='block_diffusion'` currently requires `dataset_type='hf'`.")
if self.use_dpo:
raise ValueError("`training_objective='block_diffusion'` is not compatible with DPO.")
if self.use_multimodal or self.use_audio:
raise ValueError("`training_objective='block_diffusion'` currently supports text-only training.")
valid_model_contracts = {
("same_position", "all_masked"),
("shifted", "seed_and_mask"),
}
model_contract = (self.block_diffusion_logit_alignment, self.block_diffusion_canvas_policy)
if model_contract not in valid_model_contracts:
raise ValueError(
"Block-diffusion training supports only `same_position/all_masked` or `shifted/seed_and_mask`; "
f"received `{model_contract[0]}/{model_contract[1]}`."
)
if self.quantize_kvcache and not self.kv_quant_axis:
raise ValueError("`kv_quant_axis` cannot be empty when quantize_kvcache is True.")
if (
Expand Down
15 changes: 15 additions & 0 deletions src/maxtext/diffusion/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Shared block-diffusion model semantics."""
Loading
Loading