Skip to main content

LingBot V2 Action Inference

Overview

LingBot V2 is a VLA model. It predicts the next sequence of actions by receiving camera images, task instructions, and robot states. You can first run the input example to confirm that the environment and model work properly, then connect your own images and robot states.

Architecture

A single inference pass goes through the following process.
LingBotV2Processor converts images, task text, and robot states into the input format required by the model. Engine loads the model through the lingbot_v2 plugin. The model first processes the visual and language inputs, then iteratively generates a sequence of actions using the Euler method. kernel_policy.yaml is used to select the operator implementations used by the model. The example uses the configuration provided in the repository.

Running

1. Install PhyAI

This guide uses Linux, Python 3.12 or later, uv, and an NVIDIA GPU that supports BF16.
Check whether PyTorch can access the GPU.
The expected output is as follows.

2. Download the Model Resources

Download the LingBot V2 RoboTwin checkpoint.
Use the following directory as the model path in subsequent steps.
This directory should contain config.json, model.safetensors.index.json, and multiple .safetensors files. Download the Qwen3-VL Processor resources.
This bash command downloads only the files required by the Processor and tokenizer; there is no need to download the Qwen model weights.

3. Set the Paths

Open examples/lingbot_v2/run_lingbot_v2.py and modify the two paths at the top of the file.
These paths are relative to the PhyAI repository root directory.

4. Run the Example

Check the GPU status.
Select a GPU to run the example.
The example uses three synthetic images, the task instruction pick up the cup, and an all-zero state vector. It loads the model, runs inference once, prints the results, and then closes Engine. The default output shape is as follows.
The three dimensions represent the batch size, the number of action time steps, and the action dimension at each step, respectively. In this example, one observation corresponds to 50 action time steps, each containing 55 model action values. The example does not provide dataset statistics, so the output has not yet been converted into control values for a specific robot.

End-to-end Example

The following code shows the complete Python calling process. Save it as run_lingbot_demo.py in the repository root directory, then run it.
The core calls are as follows.
preprocess() converts the raw inputs into request tensors. engine.step() performs model inference. postprocess() retains the action dimensions specified in the configuration, performs optional denormalization, and returns a float32 tensor on the CPU. To save the results, you can add the following code.

Use Your Own Images

images is a list containing images from three cameras. For a single observation, the image from each camera has shape (1, 3, H, W), using RGB channel order and the uint8 data type. Batched inputs have shape (B, 3, H, W). If the original image is a NumPy array with shape (H, W, 3), you can convert it as follows.
The camera order must match the training data. RoboTwin uses the following order. cam_high cam_left_wrist cam_right_wrist After changing the image resolution, you need to call processor.preprocess() again and calculate max_vision_tokens based on the new pixel_values.

Use Your Own Task Instructions

Each observation corresponds to one task instruction. “task”: [“pick up the cup”] The Processor handles the chat template and tokenization, so there is no need to construct token IDs manually.

Use Your Own Robot States

Keep the state tensor on the CPU before preprocessing.
The Processor first handles state normalization and dimension padding, then moves the tensors required for computation to the GPU. The meaning and order of every value in the state must match the checkpoint. RoboTwin’s raw state contains joint and gripper values for the left and right robot arms, while LingBot V2 uses a 55-dimensional model state layout. You cannot convert an arbitrary 14-dimensional state into a valid input merely by appending zeros, nor can you directly use the first 14 values of the model output as robot actions. When connecting a real robot, you need to define the state layout, normalization statistics, and action mapping.

Use Fixed Noise to Compare Results

When comparing the results of two inference runs, you need to pass the same noise tensor to both requests, with the following shape. (B, chunk_size, max_action_dim) When noise is not provided, the model resamples the initial noise for each request, so two runs may generate different actions.

limitation

  • When connecting a real robot, you need to match the camera order, state layout, normalization statistics, and action mapping.
  • This guide does not cover multi-GPU execution.