Chapter 19: Research Frontiers in Advanced Robotics

Lesson 1: Foundation Models / Vision-Language-Action Robots

This lesson introduces foundation models for robotics, with a focus on vision-language-action (VLA) robots. We formalize VLAs as large sequence models that map rich multimodal context (images, text, robot state) to low-level actions, analyze their probabilistic structure, and connect transformer-based architectures to continuous robot control. Practical sections cover minimal Python, C++, Java, MATLAB/Simulink, and Mathematica implementations at the level of interfaces and core computations.

1. Conceptual Overview of Foundation Models and VLAs

A foundation model is a very large neural network trained on broad, heterogeneous data with a generic objective (e.g., next-token prediction), then adapted to a wide range of downstream tasks via prompting, fine-tuning, or additional heads. In robotics, a vision-language-action model (VLA) is a foundation model that ingests visual observations and natural language instructions and directly outputs robot actions.

Let \( o_t \in \mathcal{O} \) denote the observation at time step \( t \) (images, depth, proprioception), \( u \) a language instruction, and \( a_t \in \mathbb{R}^d \) the continuous action. A VLA policy can be written as a conditional distribution

\[ \pi_{\theta}(a_t \mid h_t, u) \equiv p_{\theta}(a_t \mid o_{\leq t}, a_{< t}, u), \]

where the history \( h_t = (o_1, a_1, \dots, o_t) \) is compressed into a finite-dimensional state by a high-capacity sequence model (typically a transformer).

The trajectory distribution over a finite horizon \( T \) factorizes via the chain rule of probability as

\[ p_{\theta}(a_{1:T} \mid o_{1:T}, u) = \prod_{t=1}^{T} p_{\theta}(a_t \mid o_{\leq t}, a_{< t}, u). \]

Foundation models become powerful in robotics when trained on large, diverse multi-task datasets of robot experience, so that a \emph{single} set of parameters can solve many tasks, generalize to new objects, and exploit web-scale visual-language knowledge.

flowchart TD
  U["Text instruction u"] --> ELM["Language encoder"]
  I["Camera images o_t"] --> EVI["Vision encoder"]
  S["Robot state (q_t, dot q_t, etc.)"] --> EST["State MLP"]
  ELM --> FUSE["Token fusion (sequence)"]
  EVI --> FUSE
  EST --> FUSE
  FUSE --> TRF["Transformer backbone"]
  TRF --> HEAD["Action head"]
  HEAD --> ACT["Low-level actions a_t"]
        

2. Probabilistic Formulation of Vision-Language-Action Policies

We adopt an episodic Markov decision process (MDP) with continuous actions and partial observations. Let \( s_t \in \mathcal{S} \) be the (unobserved) state and \( o_t = \psi(s_t) \) the observation. A language instruction \( u \) parametrizes the task. A VLA policy is a conditional density \( \pi_{\theta}(a_t \mid h_t, u) \) as above. Given a dataset of demonstration trajectories \( \mathcal{D} = \{ (o_{1:T}^{(n)}, a_{1:T}^{(n)}, u^{(n)}) \}_{n=1}^N \), the behavior cloning objective is

\[ \mathcal{L}_{\text{BC}}(\theta) = - \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T^{(n)}} \log \pi_{\theta}\!\bigl( a_t^{(n)} \mid h_t^{(n)}, u^{(n)} \bigr). \]

This is maximum-likelihood estimation (MLE) on trajectory data. When actions are discrete tokens \( a_t \in \{1,\dots,K\} \), the negative log-likelihood coincides with the token-level cross-entropy. To see this, define one-hot targets \( y_{t,k}^{(n)} = \mathbb{I}[a_t^{(n)} = k] \) and model probabilities \( p_{t,k}^{(n)} = p_{\theta}(a_t = k \mid h_t^{(n)}, u^{(n)}) \). The empirical cross-entropy is

\[ \begin{aligned} \mathcal{L}_{\text{CE}}(\theta) &= - \frac{1}{N} \sum_{n,t} \sum_{k=1}^K y_{t,k}^{(n)} \log p_{t,k}^{(n)} \\ &= - \frac{1}{N} \sum_{n,t} \log p_{t,a_t^{(n)}}^{(n)} = \mathcal{L}_{\text{BC}}(\theta). \end{aligned} \]

Hence minimizing cross-entropy over action tokens is equivalent to maximizing the likelihood of observed actions, and standard transformer language-model training machinery applies.

3. Transformer Architectures for Vision-Language-Action Robots

The core of modern VLAs is a transformer that processes a sequence of tokens:

  • image patch tokens and/or pooled visual embeddings;
  • language tokens for the instruction \( u \);
  • state tokens (joint angles, velocities);
  • past action tokens \( a_{< t} \);
  • optionally, task or robot-ID tokens for multi-robot settings.

Given an input matrix \( \mathbf{X} \in \mathbb{R}^{L \times d_{\text{model}}} \) of token embeddings at a layer, self-attention computes

\[ \mathbf{Q} = \mathbf{X}\mathbf{W}_Q,\quad \mathbf{K} = \mathbf{X}\mathbf{W}_K,\quad \mathbf{V} = \mathbf{X}\mathbf{W}_V, \]

\[ \text{Attn}(\mathbf{X}) = \text{softmax}\!\left( \frac{\mathbf{Q}\mathbf{K}^{\top}}{\sqrt{d_k}} + \mathbf{M} \right)\mathbf{V}, \]

where \( \mathbf{M} \) encodes masking (e.g., causal masks to enforce autoregressive ordering) and attention biases (e.g., modality-specific biases to encourage certain token interactions).

For VLA, the autoregressive structure is usually configured so that:

  • visual and instruction tokens attend bidirectionally to each other;
  • action tokens at time \( t \) attend to all context tokens and to previous action tokens but not to future actions;
  • the final action token position is used to parameterize the distribution of \( a_t \).

Concretely, if \( z_t \) is the hidden state at an action position, a simple Gaussian policy head is

\[ \mu_t = \mathbf{W}_{\mu} z_t + b_{\mu},\quad \log \sigma_t = \mathbf{W}_{\sigma} z_t + b_{\sigma},\quad a_t \sim \mathcal{N}(\mu_t, \operatorname{diag}(\sigma_t^2)). \]

The negative log-likelihood for Gaussian actions gives a continuous control analogue of token-level cross-entropy.

4. Action Tokenization and Discretization

Many VLAs discretize continuous actions into tokens to reuse language-model infrastructures. Suppose each action dimension \( a_t^{(j)} \) is bounded in \( [\ell_j, u_j] \) and we choose \( K \) bins of width \( \Delta_j = (u_j - \ell_j)/K \). Define bins \( B_{j,k} = [\ell_j + (k-1)\Delta_j,\; \ell_j + k\Delta_j) \). We encode \( a_t^{(j)} \) by its bin index \( k \).

The discretized model predicts \( p_{\theta}(k_j \mid h_t, u) \), and a continuous action is reconstructed via bin centers \( \tilde{a}_t^{(j)} = \ell_j + (k_j - \tfrac{1}{2})\Delta_j \). The discretization error per dimension is bounded as

\[ \bigl| a_t^{(j)} - \tilde{a}_t^{(j)} \bigr| \leq \tfrac{1}{2}\Delta_j = \tfrac{1}{2}\frac{u_j - \ell_j}{K}. \]

For a \( d \)-dimensional action with independent binning, we have the Euclidean error bound

\[ \lVert a_t - \tilde{a}_t \rVert_2 \leq \frac{1}{2} \sqrt{ \sum_{j=1}^{d} \left(\frac{u_j - \ell_j}{K}\right)^2 }. \]

Increasing \( K \) tightens this bound but increases the token vocabulary and softmax cost. Practical systems therefore balance action resolution, sequence length, and computational budget.

flowchart TD
  A0["Continuous action a_t in R^d"]
  A0 --> NORM["Normalize to [0,1]^d"]
  NORM --> BIN["Uniform or learned bins per dim"]
  BIN --> TOK["Action tokens k_j"]
  TOK --> LM["Transformer LM over tokens"]
  LM --> TOK2["Predicted tokens k'_j"]
  TOK2 --> DECODE["Decode to centers"]
  DECODE --> A1["Reconstructed action a'_t"]
        

5. Loss Functions and KL Regularization

Beyond plain behavior cloning, VLAs often incorporate auxiliary losses or regularization. Suppose we have a teacher distribution \( q(a_t \mid h_t,u) \) (e.g., a smaller control policy or analytic controller), and we train a student VLA \( p_{\theta}(a_t \mid h_t,u) \) by minimizing the Kullback–Leibler divergence \( D_{\mathrm{KL}}(q \,\|\, p_{\theta}) \).

In the discrete case:

\[ D_{\mathrm{KL}}(q \,\|\, p_{\theta}) = \sum_{k} q_k \log \frac{q_k}{p_{\theta,k}} = - \sum_{k} q_k \log p_{\theta,k} + \sum_{k} q_k \log q_k. \]

The second term does not depend on \( \theta \), hence minimizing \( D_{\mathrm{KL}}(q \,\|\, p_{\theta}) \) is equivalent to minimizing the cross-entropy

\[ \mathcal{L}_{\text{KD}}(\theta) = - \sum_{k} q_k \log p_{\theta,k}, \]

a standard knowledge distillation objective. This allows VLAs to absorb policies from RL-trained controllers or analytic planners, while still being trained as large sequence models.

6. Python Implementation Sketch (PyTorch + ROS 2)

We show a minimal VLA policy interface in Python using PyTorch. Visual and language encoders are treated as black boxes (e.g., pre-trained models), and a small transformer predicts a Gaussian action distribution. ROS 2 is used to connect to a manipulator.


import torch
import torch.nn as nn
import torch.nn.functional as F

# Example image encoder (replace with real vision model, e.g. ViT or ResNet)
class ImageEncoder(nn.Module):
    def __init__(self, embed_dim: int):
        super().__init__()
        self.conv = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1)
        self.fc = nn.Linear(32 * 16 * 16, embed_dim)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # x: (B, 3, H, W)
        h = F.relu(self.conv(x))
        h = F.adaptive_avg_pool2d(h, (16, 16))
        h = h.view(h.size(0), -1)
        return self.fc(h)  # (B, D)

# Example language encoder stub (replace with a real LM encoder)
class TextEncoder(nn.Module):
    def __init__(self, vocab_size: int, embed_dim: int):
        super().__init__()
        self.emb = nn.Embedding(vocab_size, embed_dim)
        self.fc = nn.Linear(embed_dim, embed_dim)

    def forward(self, tokens: torch.Tensor) -> torch.Tensor:
        # tokens: (B, L_text)
        e = self.emb(tokens)                 # (B, L_text, D)
        e = e.mean(dim=1)                    # simple pooling
        return self.fc(e)                    # (B, D)

class SimpleVLATransformer(nn.Module):
    def __init__(self, embed_dim: int, nhead: int, num_layers: int, action_dim: int):
        super().__init__()
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=embed_dim, nhead=nhead, batch_first=True
        )
        self.trf = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
        self.fc_mu = nn.Linear(embed_dim, action_dim)
        self.fc_logstd = nn.Linear(embed_dim, action_dim)

    def forward(self, seq_tokens: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
        # seq_tokens: (B, L_total, D)
        h = self.trf(seq_tokens)             # (B, L_total, D)
        h_action = h[:, -1, :]               # last token as action token
        mu = self.fc_mu(h_action)
        log_std = torch.clamp(self.fc_logstd(h_action), min=-5.0, max=2.0)
        return mu, log_std

class VisionLanguageActionPolicy(nn.Module):
    def __init__(self, vocab_size: int, action_dim: int, embed_dim: int = 256):
        super().__init__()
        self.img_enc = ImageEncoder(embed_dim)
        self.txt_enc = TextEncoder(vocab_size, embed_dim)
        self.state_fc = nn.Linear(14, embed_dim)  # e.g. 7 joint pos + 7 vel
        self.trf = SimpleVLATransformer(embed_dim, nhead=4, num_layers=4,
                                        action_dim=action_dim)

    def forward(self, img, tokens, state) -> tuple[torch.Tensor, torch.Tensor]:
        # img: (B, 3, H, W), tokens: (B, L_text), state: (B, 14)
        v = self.img_enc(img)                        # (B, D)
        l = self.txt_enc(tokens)                     # (B, D)
        s = F.relu(self.state_fc(state))             # (B, D)

        # Create a short sequence: [lang, vision, state, action_query]
        B, D = v.shape
        action_query = torch.zeros(B, 1, D, device=v.device)
        seq = torch.stack([l, v, s], dim=1)          # (B, 3, D)
        seq = torch.cat([seq, action_query], dim=1)  # (B, 4, D)
        mu, log_std = self.trf(seq)
        return mu, log_std

    def sample(self, img, tokens, state) -> torch.Tensor:
        mu, log_std = self.forward(img, tokens, state)
        std = log_std.exp()
        eps = torch.randn_like(std)
        return mu + std * eps

# Example loss for Gaussian policy
def nll_gaussian(mu: torch.Tensor, log_std: torch.Tensor, a: torch.Tensor) -> torch.Tensor:
    # mu, log_std, a: (B, d)
    var = (2.0 * log_std).exp()
    log_prob = -0.5 * ((a - mu) ** 2 / var + 2.0 * log_std + torch.log(torch.tensor(2.0 * 3.141592653589793)))
    return -log_prob.sum(dim=-1).mean()

# ROS 2 integration sketch (node subscribes to camera, state, instruction)
# and publishes joint velocity commands.
#
# NOTE: This is schematic; message types and topics should match your setup.

"""
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image, JointState
from std_msgs.msg import String
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint

class VLAControlNode(Node):
    def __init__(self, policy: VisionLanguageActionPolicy):
        super().__init__("vla_control_node")
        self.policy = policy.eval()
        self.img = None
        self.state = None
        self.instr_tokens = None

        self.create_subscription(Image, "/camera/image_raw", self.image_cb, 10)
        self.create_subscription(JointState, "/joint_states", self.state_cb, 10)
        self.create_subscription(String, "/instruction", self.instr_cb, 10)

        self.cmd_pub = self.create_publisher(JointTrajectory, "/arm_controller/joint_trajectory", 10)
        self.timer = self.create_timer(0.1, self.control_loop)

    def image_cb(self, msg: Image):
        # TODO: convert msg to torch.Tensor (B, 3, H, W)
        self.img = ...

    def state_cb(self, msg: JointState):
        # TODO: convert to torch.Tensor (B, 14)
        self.state = ...

    def instr_cb(self, msg: String):
        # TODO: tokenize msg.data to ids
        self.instr_tokens = ...

    @torch.no_grad()
    def control_loop(self):
        if self.img is None or self.state is None or self.instr_tokens is None:
            return
        a = self.policy.sample(self.img, self.instr_tokens, self.state)  # (B, d)

        traj = JointTrajectory()
        # fill trajectory based on a
        self.cmd_pub.publish(traj)
"""
      

The important structural idea is the fusion of visual, language, and state embeddings into a short sequence processed by a transformer, followed by a probabilistic action head. This same pattern underlies large-scale VLA systems.

7. C++ Implementation Sketch (ROS 2 + ONNX Runtime)

In C++, VLAs are typically deployed as inference-only models, for example via ONNX Runtime, inside a ROS 2 node. The heavy training remains in Python. Below is an interface sketch.


#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <sensor_msgs/msg/joint_state.hpp>
#include <std_msgs/msg/string.hpp>
#include <trajectory_msgs/msg/joint_trajectory.hpp>
#include <onnxruntime_cxx_api.h>

class VLAControlNode : public rclcpp::Node {
public:
    VLAControlNode()
    : Node("vla_control_node"),
      env_(ORT_LOGGING_LEVEL_WARNING, "vla"),
      session_(nullptr)
    {
        Ort::SessionOptions opts;
        opts.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
        session_ = Ort::Session(env_, "vla_policy.onnx", opts);

        img_sub_ = create_subscription<sensor_msgs::msg::Image>(
            "/camera/image_raw", 10,
            std::bind(&VLAControlNode::imageCallback, this, std::placeholders::_1));

        state_sub_ = create_subscription<sensor_msgs::msg::JointState>(
            "/joint_states", 10,
            std::bind(&VLAControlNode::stateCallback, this, std::placeholders::_1));

        instr_sub_ = create_subscription<std_msgs::msg::String>(
            "/instruction", 10,
            std::bind(&VLAControlNode::instructionCallback, this, std::placeholders::_1));

        cmd_pub_ = create_publisher<trajectory_msgs::msg::Joint_trajectory>(
            "/arm_controller/joint_trajectory", 10);

        timer_ = create_wall_timer(
            std::chrono::milliseconds(100),
            std::bind(&VLAControlNode::controlLoop, this));
    }

private:
    void imageCallback(const sensor_msgs::msg::Image::SharedPtr msg) {
        // TODO: convert to float tensor [1, 3, H, W]
        last_image_ = msg;
    }

    void stateCallback(const sensor_msgs::msg::JointState::SharedPtr msg) {
        last_state_ = msg;
    }

    void instructionCallback(const std_msgs::msg::String::SharedPtr msg) {
        last_instruction_ = msg->data;
        // TODO: tokenize using the same vocabulary as training
    }

    void controlLoop() {
        if (!last_image_ || !last_state_ || last_instruction_.empty()) return;

        // Build ONNX input tensors: image, state, tokens
        std::vector<const char*> input_names = {"image", "state", "tokens"};
        std::vector<Ort::Value> input_tensors;
        // TODO: fill input_tensors with Ort::Value::CreateTensor(...)

        std::vector<const char*> output_names = {"mu", "log_std"};
        auto outputs = session_.Run(
            Ort::RunOptions{nullptr},
            input_names.data(), input_tensors.data(), input_tensors.size(),
            output_names.data(), output_names.size());

        // Extract mu from outputs[0] and construct a JointTrajectory
        trajectory_msgs::msg::Joint_trajectory traj;
        // TODO: map mu to joint velocities or positions
        cmd_pub_->publish(traj);
    }

    Ort::Env env_;
    Ort::Session session_;

    rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr img_sub_;
    rclcpp::Subscription<sensor_msgs::msg::JointState>::SharedPtr state_sub_;
    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr instr_sub_;
    rclcpp::Publisher<trajectory_msgs::msg::Joint_trajectory>::SharedPtr cmd_pub_;
    rclcpp::TimerBase::SharedPtr timer_;

    sensor_msgs::msg::Image::SharedPtr last_image_;
    sensor_msgs::msg::JointState::SharedPtr last_state_;
    std::string last_instruction_;
};
      

This pattern mirrors deployment of other deep policies: the model is exported to ONNX, loaded in a real-time C++ node, and connected to ROS 2 topics.

8. Java Implementation Sketch (DL4J / ONNX Runtime Java)

Java-based robotics stacks (e.g., via rosjava) can call into a VLA model through the Java bindings of ONNX Runtime or a deep learning library such as DeepLearning4J. The code fragment below is schematic and omits ROS message glue for brevity.


import ai.onnxruntime.*;
import java.nio.FloatBuffer;
import java.util.*;

public class VLAPolicy {
    private final OrtEnvironment env;
    private final OrtSession session;

    public VLAPolicy(String onnxPath) throws OrtException {
        env = OrtEnvironment.getEnvironment();
        OrtSession.SessionOptions opts = new OrtSession.SessionOptions();
        opts.setOptimizationLevel(OrtSession.SessionOptions.OptLevel.ALL_OPT);
        session = env.createSession(onnxPath, opts);
    }

    public float[] infer(float[] image, long[] imgShape,
                         float[] state, long[] stateShape,
                         long[] tokenIds, long[] tokenShape) throws OrtException {

        Map<String, OnnxTensor> inputs = new HashMap<>();
        inputs.put("image", OnnxTensor.createTensor(env, FloatBuffer.wrap(image), imgShape));
        inputs.put("state", OnnxTensor.createTensor(env, FloatBuffer.wrap(state), stateShape));
        inputs.put("tokens", OnnxTensor.createTensor(env, tokenIds, tokenShape));

        String[] outputNames = new String[]{"mu"};
        OrtSession.Result res = session.run(inputs, new HashSet<>(Arrays.asList(outputNames)));

        OnnxValue muVal = res.get("mu");
        float[] mu = (float[]) muVal.getValue();
        muVal.close();
        res.close();
        for (OnnxTensor t : inputs.values()) {
            t.close();
        }
        return mu; // continuous action vector
    }
}
      

Integration with a Java-based robot controller follows the same pattern: read sensor data, convert to tensors, call the VLA model, and apply actions to the robot actuators.

9. MATLAB/Simulink and Mathematica Sketches

MATLAB provides Deep Learning Toolbox and Robotics System Toolbox for prototyping VLA-style controllers in simulation. Below is a minimal example that composes a vision encoder, a language embedding, and a small transformer-like network for action prediction.


% Assume imgFeat: [D_img x 1], txtFeat: [D_txt x 1], state: [D_state x 1]
D = 128;
layers = [
    featureInputLayer(D, "Name", "in")
    fullyConnectedLayer(256, "Name", "fc1")
    reluLayer("Name", "relu1")
    fullyConnectedLayer(7, "Name", "fc_out")  % e.g. 7 joint velocities
];

lgraph = layerGraph(layers);
dlnet = dlnetwork(lgraph);

% Build fused input vector
fused = [imgFeat; txtFeat; state];   % dimension D
dlX = dlarray(fused, "CB");

dlY = predict(dlnet, dlX);  % action prediction

% Simulink integration:
% 1. Export dlnet to a Simulink block using "Deep Learning Network" block.
% 2. Feed camera images through a separate vision network, text tokens
%    through a text encoder, and robot states from Robotics System Toolbox.
% 3. Concatenate signals and send to the deep learning block to output
%    joint commands for a Simscape Multibody model.
      

In Wolfram Mathematica, a similar idea can be implemented using NetGraph:


(* Vision-language-action policy sketch in Mathematica *)
imgDim = 128; txtDim = 128; stateDim = 14; actionDim = 7;

vlaNet =
 NetGraph[
  <|
    "imgFC" -> LinearLayer[128],
    "txtFC" -> LinearLayer[128],
    "stateFC" -> LinearLayer[128],
    "join" -> ThreadingLayer[Plus],
    "hidden" -> LinearLayer[256],
    "tanh" -> ElementwiseLayer[Tanh],
    "act" -> LinearLayer[actionDim]
  |>,
  {
    NetPort["img"] -> "imgFC",
    NetPort["txt"] -> "txtFC",
    NetPort["state"] -> "stateFC",
    {"imgFC", "txtFC", "stateFC"} -> "join" -> "hidden" -> "tanh" -> "act"
  }
 ];

(* Inference: provide three inputs imgFeat, txtFeat, stateFeat *)
action = vlaNet[
  <|
    "img" -> imgFeat,
    "txt" -> txtFeat,
    "state" -> stateFeat
  |>
];
      

These high-level sketches mirror the same architectural pattern: encode each modality, fuse embeddings, and predict actions.

10. Problems and Solutions

Problem 1 (Factorization of VLA Trajectories): Let \( a_{1:T} \) be a sequence of actions and \( c \) denote the context \( (o_{1:T}, u) \). Show that for any conditional distribution \( p(a_{1:T} \mid c) \) there exists a factorization

\[ p(a_{1:T} \mid c) = \prod_{t=1}^{T} p(a_t \mid a_{1:t-1}, c). \]

Solution: Use the chain rule of probability on the joint distribution \( p(a_{1:T}, c) \):

\[ \begin{aligned} p(a_{1:T} \mid c) &= \frac{p(a_{1:T}, c)}{p(c)} \\ &= \frac{p(a_T \mid a_{1:T-1}, c)\,p(a_{1:T-1}, c)}{p(c)} \\ &= p(a_T \mid a_{1:T-1}, c)\,p(a_{1:T-1} \mid c). \end{aligned} \]

Iterating this recursion down to \( t = 1 \) yields \( p(a_{1:T} \mid c) = \prod_{t=1}^{T} p(a_t \mid a_{1:t-1}, c) \). This is the factorization implemented by autoregressive VLA transformers.

Problem 2 (Cross-Entropy and Maximum Likelihood): Consider a discrete VLA policy with vocabulary \( \mathcal{A} = \{1,\dots,K\} \) and parameters \( \theta \). For a dataset of tokens \( \{(x^{(n)}, a^{(n)})\}_{n=1}^{N} \), show that minimizing the empirical cross-entropy is equivalent to maximizing the log-likelihood.

Solution: The cross-entropy is

\[ \mathcal{L}_{\text{CE}}(\theta) = - \frac{1}{N} \sum_{n=1}^{N} \sum_{k=1}^{K} \mathbb{I}[a^{(n)} = k] \log p_{\theta}(k \mid x^{(n)}). \]

For each \( n \), only the term \( k = a^{(n)} \) survives:

\[ \mathcal{L}_{\text{CE}}(\theta) = - \frac{1}{N} \sum_{n=1}^{N} \log p_{\theta}(a^{(n)} \mid x^{(n)}). \]

The log-likelihood of the dataset is \( \log p_{\theta}(\{a^{(n)}\} \mid \{x^{(n)}\}) = \sum_{n} \log p_{\theta}(a^{(n)} \mid x^{(n)}) \). Thus maximizing log-likelihood is equivalent to minimizing the average negative log-likelihood, which is exactly \( \mathcal{L}_{\text{CE}}(\theta) \).

Problem 3 (Discretization Error Bound): Suppose each action dimension is discretized into \( K \) uniform bins on \( [\ell, u] \). Show that the worst-case relative error in one dimension

\[ \varepsilon_{\text{rel}} = \max_{a \in [\ell,u]} \frac{|a - \tilde{a}|}{u - \ell} \]

satisfies \( \varepsilon_{\text{rel}} \leq \tfrac{1}{2K} \).

Solution: The bin width is \( \Delta = (u - \ell)/K \). The reconstruction \( \tilde{a} \) is the bin center, so for any \( a \) in a bin,

\[ |a - \tilde{a}| \leq \tfrac{1}{2}\Delta = \tfrac{1}{2} \frac{u - \ell}{K}. \]

Therefore,

\[ \varepsilon_{\text{rel}} \leq \frac{\tfrac{1}{2}(u - \ell)/K}{u - \ell} = \frac{1}{2K}. \]

Increasing \( K \) reduces the worst-case relative error linearly.

Problem 4 (Gaussian Policy Loss): For a VLA with Gaussian policy \( \pi_{\theta}(a \mid h) = \mathcal{N}(a; \mu_{\theta}(h), \Sigma_{\theta}(h)) \), derive the negative log-likelihood loss and show that (up to a constant) it is a weighted quadratic error.

Solution: For a single sample \( (h,a) \) with full-rank covariance \( \Sigma \), the density is

\[ \pi_{\theta}(a \mid h) = \frac{1}{(2\pi)^{d/2} |\Sigma|^{1/2}} \exp\!\left( -\tfrac{1}{2} (a - \mu)^{\top}\Sigma^{-1}(a - \mu) \right). \]

Taking minus log,

\[ -\log \pi_{\theta}(a \mid h) = \tfrac{1}{2}(a - \mu)^{\top}\Sigma^{-1}(a - \mu) + \tfrac{1}{2}\log|\Sigma| + \tfrac{d}{2}\log(2\pi). \]

The last term is constant. Thus, up to constants, the loss is \( \tfrac{1}{2}(a - \mu)^{\top}\Sigma^{-1}(a - \mu) + \tfrac{1}{2}\log|\Sigma| \), a quadratic form penalizing deviations weighted by the inverse covariance plus a regularizer on the covariance volume.

Problem 5 (Knowledge Distillation for VLAs): Let \( q(a \mid h) \) be a deterministic teacher policy that outputs one action \( a^{\ast}(h) \). Show that minimizing \( D_{\mathrm{KL}}(q \,\|\, p_{\theta}) \) reduces to behavior cloning on the teacher’s actions.

Solution: Since \( q \) is deterministic,

\[ q(a \mid h) = \delta(a - a^{\ast}(h)). \]

In the discrete case, \( q \) is one-hot at \( a^{\ast} \), and in the continuous case it is a Dirac measure. The KL is

\[ D_{\mathrm{KL}}(q \,\|\, p_{\theta}) = - \int q(a \mid h) \log p_{\theta}(a \mid h) \, \mathrm{d}a + \text{const} = - \log p_{\theta}(a^{\ast}(h) \mid h) + \text{const}. \]

Averaging over a dataset of states \( h \), minimizing KL is equivalent (up to an additive constant) to maximizing \( p_{\theta}(a^{\ast}(h) \mid h) \), i.e., behavior cloning on the teacher’s actions.

11. Summary

In this lesson we formalized vision-language-action robots as conditional sequence models over actions given rich perceptual and linguistic context. We showed how autoregressive factorization, cross-entropy, and Gaussian negative log-likelihood provide a principled probabilistic basis for training VLAs at scale. We discussed transformer architectures, action discretization and error bounds, and knowledge distillation. Finally, we outlined implementation sketches in Python, C++, Java, MATLAB/Simulink, and Mathematica that instantiate the same conceptual pattern: encode, fuse, and act. These ideas underpin current research frontiers in generalist robot policies and embodied foundation models.

12. References

  1. Brohan, A., Brown, N., Carbajal, J., Chebotar, Y., Chen, X., et al. (2022). RT-1: Robotics Transformer for Real-World Control at Scale. Robotics: Science and Systems (RSS). arXiv:2212.06817.
  2. Brohan, A., Brown, N., Carbajal, J., Chebotar, Y., Chen, X., et al. (2023). RT-2: Vision-Language-Action Models Transfer Web Knowledge to Robotic Control. Proceedings of the 7th Conference on Robot Learning (CoRL).
  3. Driess, D., Xia, F., Sajjadi, M. S. M., Lynch, C., Chowdhery, A., et al. (2023). PaLM-E: An Embodied Multimodal Language Model. Proceedings of the 40th International Conference on Machine Learning (ICML).
  4. Reed, S., Zolna, K., Parisotto, E., Gomez Colmenarejo, S., Novikov, A., et al. (2022). A Generalist Agent. arXiv preprint arXiv:2205.06175.
  5. Bommasani, R., Hudson, D., Adeli, E., Altman, R., Arora, S., et al. (2021). On the Opportunities and Risks of Foundation Models. arXiv preprint arXiv:2108.07258.
  6. Radosavovic, I., Shi, B., Fu, L., Goldberg, K., Darrell, T., & Malik, J. (2023). Robot Learning with Sensorimotor Pre-training. arXiv preprint arXiv:2306.10007.
  7. Jeong, H., Lee, H., Kim, C., & Shin, S. (2024). A Survey of Robot Intelligence with Large Language Models. Applied Sciences, 14(20), 1–24.
  8. Ma, Y., Song, Z., Zhuang, Y., Hao, J., & King, I. (2025). A Survey on Vision-Language-Action Models for Embodied AI. arXiv preprint.
  9. Black, K., Brown, N., Driess, D., Esmail, A., Equi, M., et al. (2024). \( \pi_0 \): A Vision-Language-Action Flow Model for General Robot Control. arXiv preprint.
  10. Kira, Z. (2022). Awesome-LLM-Robotics: A Curated List of LLM-based Robotics Papers. GitHub repository.