DIAMONDConfig
GenerativeModelConfigDIAMONDConfig(sample_size: int | tuple[int, int] = 64, in_channels: int = 3, out_channels: int = 3, act_fn: GenerativeActivation = 'silu', num_actions: int = 18, conditioning_frames: int = 4, unet_channels: tuple[int, ...] = (64, 64, 64, 64), unet_layers: tuple[int, ...] = (2, 2, 2, 2), cond_dim: int = 256, attn_depths: tuple[int, ...] | None = None, with_agent: bool = True, noise_previous_obs: bool = False, upsampler_channels: tuple[int, ...] | None = None, upsampler_layers: tuple[int, ...] | None = None, upsampler_attn_depths: tuple[int, ...] | None = None, upsampling_factor: int = 1, sigma_data: float = 0.5, p_mean: float = -0.4, p_std: float = 1.2, sigma_offset_noise: float = 0.3, attention_head_dim: int = 8, denoise_steps: int = 3, reward_channels: tuple[int, ...] = (32, 32, 32, 32), reward_layers: tuple[int, ...] = (2, 2, 2, 2), reward_cond_dim: int = 128, reward_frames: int = 2, reward_lstm_dim: int = 512, actor_channels: tuple[int, ...] = (32, 32, 64, 64), actor_layers: tuple[int, ...] = (1, 1, 1, 1), actor_lstm_dim: int = 512, horizon: int = 15, gamma: float = 0.985, lambda_: float = 0.95, entropy_weight: float = 0.001, burn_in: int = 4)Frozen configuration for the DIAMOND family.
Parameters
sample_sizeint or tuple of int= 6464x64 before anything else touches them.in_channelsint= 3out_channelsint= 3in_channels.num_actionsint= 18conditioning_framesint= 4unet_channelstuple of int= (64, 64, 64, 64)unet_layerstuple of int= (2, 2, 2, 2)cond_dimint= 256attn_depthstuple of int or None= NoneNone means none of
them do, which is Atari's setting and the common case; it is
expanded to match unet_channels rather than written out, so
a narrower model does not have to restate it. All zero for Atari, where
only the middle blocks do; the CS:GO world model turns it on at
its two deepest resolutions, which is where a 3D scene needs to
relate parts of the frame that convolutions cannot reach.with_agentbool= Truenull: that experiment trains a world model on static data
with no reinforcement learning at all, so an agent would be
parameters nothing ever updates.noise_previous_obsbool= Falseupsampler_channelstuple of int or None= Noneupsampler_layerstuple of int or None= Noneupsampler_attn_depthstuple of int or None= Noneupsampling_factorint= 1sigma_datafloat= 0.5p_meanfloat= -0.4p_stdfloat= 1.2sigma_offset_noisefloat= 0.3config/agent/default.yaml. Offset noise
lets the model shift a frame's overall level, which plain
isotropic noise cannot express at any single .attention_head_dimint= 8denoise_stepsint= 3reward_channelstuple of int= (32, 32, 32, 32)reward_layerstuple of int= (2, 2, 2, 2)reward_cond_dimint= 128reward_framesint= 2reward_lstm_dimint= 512actor_channelstuple of int= (32, 32, 64, 64)actor_layerstuple of int= (1, 1, 1, 1)actor_lstm_dimint= 512horizonint= 15gammafloat= 0.985lambda_float= 0.95entropy_weightfloat= 0.001burn_inint= 4Notes
Reference: Alonso et al., "Diffusion for World Modeling: Visual Details Matter in Atari", NeurIPS, 2024 (arXiv:2405.12399). Architecture values are Table 2, training values Table 3, and the preconditioner constants Appendix C.
The base is GenerativeModelConfig rather than
WorldModelConfig, even though this is a world model. That
base describes a latent one — stoch_size, deter_size,
free_nats, kl_weight — and DIAMOND has no posterior and no
KL to free-bit. Inheriting them would put six fields on the
documentation page that nothing in this family reads.
Examples
>>> from lucid.models.generative.diamond import DIAMONDConfig
>>> config = DIAMONDConfig()
>>> config.conditioning_frames, config.denoise_steps
(4, 3)
The denoiser's first convolution has to take the noised frame *and*
the stack of past frames, which is what makes frame stacking cheap:
>>> config.denoiser_in_channels
15
Three fields here have no counterpart in the paper — they come from
the released configuration, which is more specific than the text:
>>> config.sigma_offset_noise, config.reward_frames
(0.3, 2)Used by 3
Constructors
1__init__
→None__init__(sample_size: int | tuple[int, int] = 64, in_channels: int = 3, out_channels: int = 3, act_fn: GenerativeActivation = 'silu', num_actions: int = 18, conditioning_frames: int = 4, unet_channels: tuple[int, ...] = (64, 64, 64, 64), unet_layers: tuple[int, ...] = (2, 2, 2, 2), cond_dim: int = 256, attn_depths: tuple[int, ...] | None = None, with_agent: bool = True, noise_previous_obs: bool = False, upsampler_channels: tuple[int, ...] | None = None, upsampler_layers: tuple[int, ...] | None = None, upsampler_attn_depths: tuple[int, ...] | None = None, upsampling_factor: int = 1, sigma_data: float = 0.5, p_mean: float = -0.4, p_std: float = 1.2, sigma_offset_noise: float = 0.3, attention_head_dim: int = 8, denoise_steps: int = 3, reward_channels: tuple[int, ...] = (32, 32, 32, 32), reward_layers: tuple[int, ...] = (2, 2, 2, 2), reward_cond_dim: int = 128, reward_frames: int = 2, reward_lstm_dim: int = 512, actor_channels: tuple[int, ...] = (32, 32, 64, 64), actor_layers: tuple[int, ...] = (1, 1, 1, 1), actor_lstm_dim: int = 512, horizon: int = 15, gamma: float = 0.985, lambda_: float = 0.95, entropy_weight: float = 0.001, burn_in: int = 4)Initialise the layer.
Parameters
channelsintProperties
2Channels the denoiser's first convolution reads.
The noised next frame plus clean past frames, stacked.
Frame height and width, whichever way sample_size was written.
Atari's frames are square and CS:GO's are not — 150 by 280 — so nothing downstream may assume one number.