Writing
I Tried Running Two Robot Foundation Models on a Six-Core Desktop
OpenPI's Pi0 never produced an action. The operating system killed it while JAX was still restoring the checkpoint. SmolVLA did run, but needed a median 7.1 seconds to generate 50 actions that cover 2.5 seconds of control time.
Those are not flattering numbers, but they answer the question I had. I do not have a robotics background, and I wanted to see how far ordinary AI engineering could take me without a robot lab or an expensive GPU. So I built a reproducible path from a simulation task to two real vision-language-action model stacks, then ran both on the six-core desktop already sitting on my desk.
Getting to a fair input
I started with ManiSkill's PushCube-v1: a Panda arm has to push a blue cube onto a red and white target. I replayed published demonstrations, kept each trajectory through its first successful transition, clipped actions to the simulator's declared bounds, and exported four successful episodes as a LeRobot v3 dataset. That left 62 frames, each with one RGB image, 25 state values, an 8-value joint action, and a language instruction.
Before timing a model, I made each preprocessing path prove that it accepted the same ordered tensors. SmolVLA and OpenPI Pi0 both passed all 62 frames. Both turned the source into a 32-value state and a 50 x 32 action chunk, although their image and token paths differ. The dataset checksum, model commits, tokenizer versions, normalization statistics, and output checksums are all in the public comparison repository.
The benchmark
The latency test uses the first checksum-verified PushCube frame, batch size one, ten flow-matching denoising steps, and the same all-zero noise tensor. I timed model action sampling only, excluding preprocessing, postprocessing, checkpoint download, and model loading. Each process received six CPU threads. There is no supported accelerator in the machine, only an Intel Core i5-8500T, 14 GiB of RAM, and 4 GiB of swap.
| Result | SmolVLA | OpenPI Pi0 |
|---|---|---|
| Checkpoint repository | 0.915 GB | 12.014 GB |
| Load or restore | 11.04 s | Failed during restore |
| First inference | 7.069 s | Not reached |
| Warm median | 7.112 s | Not reached |
| Warm p95 | 8.240 s | Not reached |
| Peak process memory | 3.669 GiB | 8.754 GiB before termination |
SmolVLA completed the first run and five warmed measurements. The warmed range was 6.930 to 8.464 seconds. A 50-action chunk at the dataset's 20 Hz control rate lasts 2.5 seconds, so median generation was 2.84 times slower than the robot would consume the chunk. Putting inference on another thread would not fix that deficit. The action queue would still drain.
OpenPI publishes a much larger base Pi0 checkpoint and recommends an NVIDIA GPU with more than 8 GB for inference. I tried the CPU path anyway because the boundary itself mattered. After 59.09 seconds, the process had reached 9,179,400 KiB of resident memory while restoring parameters. It was terminated by signal 9 before constructing the model, so there is no Pi0 latency number in my table.
What the failure tells me
The clean comparison is about deployability on this machine. SmolVLA fits and runs. Pi0 does not fit through its JAX restoration path in this shared 14 GiB desktop environment. SmolVLA's policy repository is under one gigabyte; Pi0's checkpoint is over 12 GB. That difference determines which experiments I can even start locally.
SmolVLA fitting does not make it real-time. At 7.1 seconds per chunk, I could inspect outputs, test adapters, or run slow offline evaluations. I could not keep a 20 Hz controller supplied continuously. The next latency comparison belongs on accelerator hardware where both models complete, with synchronization around every timed call and enough runs to characterize variance.
This also is not a policy-quality result. These are base checkpoints, neither is fine-tuned for PushCube, and I did not score the generated actions in simulation. The test measures whether the software and model can turn the same valid observation into an action chunk under a fixed local resource budget.
Why I count this as robotics work
The useful work was mostly engineering: tracing observation and action contracts, adapting one dataset to two model APIs, pinning revisions, checking tensor semantics, isolating memory-heavy processes, and refusing to turn a failed run into a made-up comparison. The OpenPI failure took more care to report than a successful stopwatch reading. It needed a separate subprocess and an external resource monitor so the out-of-memory kill could not erase the evidence.
The full benchmark, including scripts, tests, raw measurements, and the partial-result label, is in Experiment 005. My next useful run needs a GPU for the missing Pi0 number, followed by a larger PushCube dataset and held-out rollout seeds. That will move the comparison from plumbing and deployment constraints toward whether either model can learn the task.