Improving Transformers World Model for RL

repository·main·Indexed 41 days ago

https://github.com/lucidrains/improving-transformers-world-model-for-rl

A library implementing a Transformer-based World Model for Reinforcement Learning (RL) version 0.0.59. It features a NearestNeighborTokenizer for discretizing observations and a BlockCausalTransformer for modeling environment dynamics, including action conditioning and reward prediction. The package provides an Agent API with Impala, Actor, and Critic components, supporting PPO-style updates via a learn() method and trajectory generation through a WorldModel.sample() interface.

Tokens
4K
Snippets
13
Records
17
Agent score
98%

What's inside Improving Transformers World Model

  1. How BlockCausalTransformer works with residual streams

    main

    The BlockCausalTransformer is designed for efficient temporal modeling using several advanced techniques:

    1. Hyper Connections: Uses get_init_and_expand_reduce_stream_functions to manage multiple residual streams, allowing for complex information flow.
    2. Block Causal Attention: Implements attention that is causal at a block level (defined by block_size), which can be optimized using PyTorch's flex_attention if available.
    3. Value Residual Learning: In non-first layers, the attention mechanism can incorporate a value_residual to improve training stability and information retention.
    4. Rotary Embeddings: Uses RotaryEmbedding for relative positional encoding.
    5. SwiGLU FeedForward: Uses the SwiGLU activation variant for the feedforward layers.
  2. How Impala, Actor, and Critic work together

    main

    The agent follows a hierarchical architecture:

    1. Impala: Acts as the visual encoder and temporal memory. It processes images through a CNN and a GRU to produce a latent state representation.
    2. Actor: Takes the latent state from Impala and maps it to action logits. If dim_world_model_embed was provided during initialization, it uses a FiLM (Feature-wise Linear Modulation) layer to condition the policy on world model embeddings.
    3. Critic: Takes the latent state from Impala and predicts the state value. It uses an HLGaussLayer for value estimation, which supports both regression and histogram-based loss.
  3. Calculate Generalized Advantage Estimate (GAE)

    main

    The calc_target_and_gae function computes the returns and the GAE advantages used for policy updates. It uses AssocScan for an accelerated implementation of the backward scan required for GAE.

    Arguments:

    • rewards: Tensor of rewards [... n].
    • values: Tensor of values [... n+1] (including the value of the terminal state).
    • masks: Boolean tensor indicating if the next state is terminal [... n].
    • gamma: Discount factor.
    • lam: GAE lambda parameter.
    • use_accelerated: Whether to use the accelerated scan (defaults to True if on CUDA).
    returns, gae = calc_target_and_gae(
        rewards=rewards_tensor,
        values=values_tensor,
        masks=masks_tensor,
        gamma=0.99,
        lam=0.95
    )
  4. Implement an Actor-Critic Agent with Impala, Actor, and Critic

    main

    The Agent class is the primary entrypoint for reinforcement learning. It orchestrates three main components: an Impala network (for visual feature extraction and memory via GRU), an Actor (for policy prediction), and a Critic (for value estimation). The agent supports conditioning the policy on world model embeddings using FiLM layers.

    To initialize an agent, you can pass dictionaries containing the configuration for each component, which the agent will use to instantiate the classes.

    from improving_transformers_world_model.agent import Agent
    
    impala_config = {
        'dims': (64, 64, 128),
        'image_size': 63,
        'channels': 3,
        'dim_rnn': 32,
        'dim_rnn_hidden': 32
    }
    
    actor_config = {
        'dim': 128,
        'num_actions': 10,
        'dim_world_model_embed': 256  # Enables FiLM conditioning
    }
    
    critic_config = {
        'dim': 128,
        'num_layers': 4
    }
    
    agent = Agent(
        impala=impala_config,
        actor=actor_config,
        critic=critic_config,
        actor_lr=1e-4,
        critic_lr=1e-4
    )
  5. Apply min_p_filter to logits

    main

    The min_p_filter is a sampling technique used to prune low-probability tokens from the logits distribution. It keeps only tokens whose probability is at least min_p times the probability of the most likely token.

    This is useful during the WorldModel.sample() process to improve sample quality by removing the 'long tail' of unlikely tokens.

    from improving_transformers_world_model.world_model import min_p_filter
    
    # logits shape: [batch, ..., vocab_size]
    filtered_logits = min_p_filter(logits, min_p=0.1)
  6. Use the WorldModel class for training and sampling

    main

    The WorldModel is the primary interface for training a world model that predicts future states, rewards, and terminality. It uses a NearestNeighborTokenizer for state representation and a BlockCausalTransformer for temporal modeling.

    Training

    Call forward() with state tensors (or token IDs), and optionally rewards, actions, or is_terminal labels. The method returns the total loss and a breakdown of individual losses (state, reward, terminal).

    Sampling

    Call sample() to generate trajectories. You can provide a prompt (initial states), time_steps to sample, and optionally actions or rewards to condition the generation. It supports custom filter_fn (like min_p_filter) and temperature control.

    Key Configuration Parameters

    • image_size, patch_size, channels: Define the input video dimensions.
    • num_actions: If $>0$, enables action conditioning.
    • reward_num_bins: If $>0$, enables reward prediction using HLGaussLoss.
    • tokenizer: A NearestNeighborTokenizer instance or a config dict.
    • transformer: A BlockCausalTransformer instance or a config dict.
    from improving_transformers_world_model.world_model import WorldModel
    
    model = WorldModel(
        image_size = 64,
        patch_size = 4,
        channels = 3,
        num_actions = 6,
        reward_num_bins = 10,
        tokenizer = dict(
            dim = 128,
            distance_threshold = 0.01
        ),
        transformer = dict(
            dim = 256,
            depth = 8,
            block_size = 256, # patches_per_image
            heads = 8
        )
    )
    
    # Training step example
    # state: [batch, channels, time, height, width]
    loss, breakdown = model(state, rewards=rewards, actions=actions, is_terminal=is_terminal)
    
    # Sampling example
    # prompt: [batch, channels, prompt_time, height, width]
    sampled_states, sampled_rewards, sampled_dones = model.sample(
        prompt=prompt,
        time_steps=50,
        actions=actions,
        temperature=1.5
    )
  7. Use the Agent API

    main

    The Agent and Impala classes provide the interface for interacting with the world model in a Reinforcement Learning context. Impala is a specific implementation of an agent designed to work with these transformer-based world models.

    from improving_transformers_world_model import Agent, Impala
    
    # Example usage of an Impala agent
    agent = Impala(
        # ... configuration parameters
    )
  8. Train the Agent using `learn()`

    main

    The learn method performs a PPO-style update on the agent's parameters using collected memories. It calculates Generalized Advantage Estimation (GAE), computes policy and value losses, and updates the actor and critic optimizers.

    Arguments:

    • memories: A MemoriesWithNextState object or a list of them.
    • lam: GAE lambda parameter (default 0.95).
    • gamma: Discount factor (default 0.99).
    • batch_size: Size of training batches.
    • epochs: Number of training epochs.
    # Assuming 'memories_with_next' is a MemoriesWithNextState object
    loss_tuple = agent.learn(
        memories=memories_with_next,
        lam=0.95,
        gamma=0.99,
        batch_size=32,
        epochs=4
    )
  9. Generate imaginary experiences with `forward()`

    main

    The Agent.forward method allows for 'dreaming' or generating trajectories using a WorldModel instead of a real environment. This is used for training on simulated data.

    Arguments:

    • world_model: The WorldModel to sample from.
    • init_state: The starting frame.
    • max_steps: Maximum number of steps to simulate.
    • use_world_model_embed: If True, the agent uses world model embeddings to condition the actor.
    # Generating trajectories from a world model
    memories_with_next = agent.forward(
        world_model=my_world_model,
        init_state=initial_frame,
        max_steps=100,
        use_world_model_embed=True
    )
  10. Configure BlockCausalAttention with Flex Attention

    main

    The BlockCausalAttention module supports high-performance attention via PyTorch's flex_attention.

    To use it, ensure torch.cuda.is_available() and that your environment supports torch.nn.attention.flex_attention. When use_flex_attn=True is passed to the BlockCausalTransformer, it will attempt to use the optimized kernel with a block_mask created via create_block_causal_mask.

  11. Collect experiences with `interact_with_env()`

    main

    Use interact_with_env to run the agent in a real environment. This method collects transitions (state, action, reward, etc.) and returns a MemoriesWithNextState object containing the episode's data.

    If a world_model is provided, the agent will use it to generate embeddings that condition the actor's policy during interaction.

    # Interaction with a real environment
    memories_with_next = agent.interact_with_env(
        env=my_env,
        world_model=my_world_model
    )
  12. Use the WorldModel API

    main

    The WorldModel class is the primary entrypoint for the world model component. It is used to model environment dynamics, typically involving a tokenizer for observations and a transformer-based architecture for predicting future states or actions.

    from improving_transformers_world_model import WorldModel
    
    # Example initialization (exact parameters depend on implementation details)
    world_model = WorldModel(
        # ... configuration parameters
    )