Skip to content

Repository files navigation

Armory

Action Chunk Scheduling for Batched Robot Policy Serving

Rohan Bansal*, David He*, Nadun Ranawaka Arachchige, Zhenyang Chen, Soobum Kim, Kexin Rong, Danfei Xu

Georgia Institute of Technology
* Equal contribution    Equal advising

Paper arXiv Twitter

Armory serves one robot policy to many robots from a remote GPU. It tracks each robot's action queue and schedules batched inference to reduce starvation when robots consume actions at different rates.

This repository contains the server, robot clients, policy adapters, and evaluation code used in the paper.

Try commanding 10 robots at once using a single cloud-served Pi-05 model!

uv run modal run scripts/modal/run.py \
  --mode gpu \
  --server-config ./configs/modal_server_lookahead.json \
  --client-config ./configs/modal_10_robots_libero.json

See the Modal deployment section below for more info.

Setup

Armory requires Python 3.11 and uv. Initialize the pinned third-party repositories, then install the base environment:

git submodule update --init --recursive
GIT_LFS_SKIP_SMUDGE=1 uv sync

Repository structure

  • src/armory/ contains the serving engine, schedulers, and policy server.
  • armory-client/ is the lightweight client package used by each robot.
  • src/backends/ contains the OpenPI and NVIDIA Isaac GR00T adapters.
  • src/evaluation/ contains robot runtimes, LIBERO integration, metrics, and result saving.
  • configs/ stores server and fleet configurations.
  • scripts/ contains local, Modal, Slurm, and plotting entry points.
  • third_party/ contains the pinned OpenPI, LIBERO, and Isaac GR00T repositories.

Deployment

Modal

For GPU evaluations, Modal runs the policy server and LIBERO client in separate containers. See the Modal deployment guide for image setup, single runs, and sweeps.

uv run modal setup
uv run modal run scripts/modal/run.py \
  --mode gpu \
  --server-config configs/modal_server_lookahead.json \
  --client-config configs/modal_single_robot_libero.json

Local or self-hosted

scripts/serve.py runs the policy server and scripts/run.py launches a client fleet. It is recommended to use the self-host architecture in a cluster environment where GPU and CPU nodes are available for the policy/client servers.

To run with a server GPU:

uv sync --extra evaluation --extra serving-web

# Terminal 1: policy server
uv run python -m scripts.serve \
  --port 8080 \
  --model PI05 \
  --env LIBERO \
  --server.max-batch-size 4 \
  --server.scheduler.scheduling-algorithm lookahead-actions

# Terminal 2: one robot
uv run python -m scripts.run \
  --host 127.0.0.1 \
  --port 8080 \
  --scheduler-config.scheduling-algorithm lookahead-actions \
  --output-dir output/demo \
  --overwrite

When the client runs on another machine, replace 127.0.0.1 with the server's reachable address and make sure port 8080 is open.

If no GPU is present, you may run in mock mode, which has no real robot rollouts but will simulate the GPU and client communication.

uv run python -m scripts.serve \
  --port 8080 \
  --server.max-batch-size 4 \
  --server.scheduler.scheduling-algorithm lookahead-actions \
  policy:mock

Acknowledgments

Parts of Armory's policy-serving stack were adapted from OpenPI. We thank the Physical Intelligence team for releasing OpenPI and its model checkpoints. Our evaluations also build on LIBERO and NVIDIA Isaac GR00T.

About

multi-robot serving engine for cloud robot foundation models

Topics

Resources

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages