Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b671ffd
harden gguf arch probe and evo1 input guards
anindex Jul 3, 2026
1186f06
bitvla: absmean ternarize, cache embd reader, fold qkv transpose
anindex Jul 3, 2026
7510833
vla-server: bound image size and payload, clean shutdown
anindex Jul 3, 2026
1ebc270
build pi0/pi0.5/smolvla vision towers in-tree, fetch llama.cpp b9866,…
anindex Jul 3, 2026
370b525
add dockerfile, github actions build gate, converter deps, tests, docs
anindex Jul 3, 2026
46d6ef6
evo1: sample base noise from N(0,1), mask padded DiT cross-attention …
anindex Jul 3, 2026
c2c826f
smolvla: reject out-of-range lang tokens before the embedding gather
anindex Jul 3, 2026
7d4e279
docs: action chunk is padded to max_action_dim; bitvla converter find…
anindex Jul 3, 2026
32a7ff1
evo1: leave DiT cross-attention unmasked to match the reference
anindex Jul 3, 2026
1480f75
silence -Wall warnings in pi0.5, gr00t-n1.7, vla-adapter
anindex Jul 3, 2026
c79a65c
vla_jepa: reject precomputed_img_emb, guard against null images
anindex Jul 4, 2026
8c6408e
openvla_oft, vla_adapter: reject precomputed_img_emb, guard null images
anindex Jul 4, 2026
595bcb4
reject out-of-range tokens and zero padded action dims
anindex Jul 4, 2026
aae3bf9
add vla-cli for one-shot inference without a server
anindex Jul 4, 2026
1f32405
ship vla-cli in the docker image and ci build
anindex Jul 4, 2026
c18f927
note vla-cli and the token/padding fixes in changelog
anindex Jul 4, 2026
05168b0
validate vla-cli inputs before load and guard stop_id
anindex Jul 4, 2026
ee2a149
share one gguf reader across the model loaders
anindex Jul 4, 2026
625dcb7
load quantized weights and add gguf requantizer
anindex Jul 4, 2026
43a5a0f
document quantization and the shared reader
anindex Jul 4, 2026
920478b
offer only the quant types the writer can pack
anindex Jul 4, 2026
bdb9db0
release v0.1.1
anindex Jul 4, 2026
906030b
reject mis-sized images in vla-adapter and openvla-oft
anindex Jul 4, 2026
16f1d87
harden evo1 config, bitvla cuda alloc, and server message caps
anindex Jul 4, 2026
15f7c26
scale cpu threads to core count across the loaders
anindex Jul 4, 2026
b703b24
use 64-bit gguf offsets, guard row dtype, cap vlm images
anindex Jul 4, 2026
543f1d1
reuse the prefix cross-attention cache across denoise steps
anindex Jul 4, 2026
7f2bf27
add architecture doc and quickstart, note fixes under 0.1.1
anindex Jul 4, 2026
48ab1b8
add script merge mmproj for pi05, update eval scripts accordingly
khanhnd61-vr Jul 6, 2026
2efef28
fix evo1: use uniform[-1,1) noise
khanhnd61-vr Jul 6, 2026
b6e58cc
update converter scripts to bake vision mmproj*.gguf to model.gguf
khanhnd61-vr Jul 6, 2026
1c22959
run regression test and update README.md
khanhnd61-vr Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Keep the build context small: llama.cpp is fetched inside the image, models
# are mounted at runtime, and build/output dirs are host artifacts.
.git/
models/
build/
build-*/
outputs/
third_party/
eval/sim/
*.gguf
52 changes: 52 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Fast build + unit gate on GitHub-hosted runners. The heavier cross-platform
# LIBERO regression sweep lives in vla-ci.yml (self-hosted).
name: build

on:
push:
branches: [main, dev]
pull_request:
branches: [main]

concurrency:
group: build-${{ github.ref }}
cancel-in-progress: true

jobs:
cpp-unit:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: pixel-shuffle channel order
run: |
g++ -std=c++17 -Isrc -Wall -Wextra tests/test_vision_common.cpp -o /tmp/test_vision_common
/tmp/test_vision_common

py-tooling:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: converter remap
run: python tests/py/test_converters.py

build-gate:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: deps
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq --no-install-recommends \
build-essential cmake git ca-certificates pkg-config \
libzmq3-dev cppzmq-dev libprotobuf-dev protobuf-compiler
- uses: actions/cache@v4
with:
path: build/_deps
key: llama-b9866-${{ runner.os }}
- name: build vla-server + vlm-server + vla-cli (CPU, -Wall -Wextra)
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=OFF
cmake --build build -j"$(nproc)" --target vla-server vlm-server vla-cli
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ eval/sim/libero/LIBERO/
eval/sim/libero/libero_uv/
eval/sim/simpler/SimplerEnv/
eval/sim/simpler/simpler_uv/
/models/
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Changelog

Notable changes to vla.cpp. Format loosely follows [Keep a Changelog](https://keepachangelog.com).

## [0.1.1] - 2026-07-04

### Added
- `vla-cli`: one-shot inference from the command line (image + tokens to action), no server needed.
- `scripts/quantize_gguf.py`: repack LM weights to Q8_0/Q4_0. The loader runs quantized GGUFs directly (Q8_0 roughly halves the LM, near-lossless).

### Changed
- One shared GGUF reader across the model loaders, replacing the per-arch copies.
- Cap inbound message size (256 MiB) and image count (16) on `vla-server` and `vlm-server`.
- Scale CPU threads to the machine core count across all loaders instead of a fixed 4.
- Read GGUF file offsets as 64-bit and reject non-float embedding tensors in row-fetch.

### Fixed
- Reject out-of-range language tokens in OpenVLA-OFT and VLA-Adapter.
- Zero the padded action dimensions so only real action dims carry values.
- Reject images that do not match the model input size in VLA-Adapter and OpenVLA-OFT (out-of-bounds read on a smaller view).
- Validate Evo-1 action dims at load so a client-supplied noise buffer cannot underrun.
- Only enable the BitVLA CUDA path once every device buffer allocates.

## [0.1.0] - 2026-07-03

First tagged release. One self-contained GGUF per model (vision tower + LM + action
expert + dataset stats), CPU or CUDA, no external mmproj and no patch to llama.cpp.

### Added
- Seven VLA policies auto-detected from the GGUF: SmolVLA, pi0, BitVLA, Evo-1, GR00T N1.5/N1.6/N1.7.
- In-tree vision towers (SigLIP, BitSigLIP, InternViT, RADIO) on stable public ggml/llama APIs.
- ZeroMQ + protobuf `vla-server`; a separate `vlm-server` for VLM chat.
- BitVLA 1.58-bit custom ternary CUDA kernels.
- Per-arch HuggingFace -> GGUF converters and mmproj-merge helpers (`scripts/`).
- Robot eval harness for LIBERO, SimplerEnv, and ALOHA (`eval/`), with device benchmark reports.
- Minimal CI: pixel-shuffle unit test, converter-remap test, CPU build gate.
- `pyproject.toml` for the Python tooling and a CUDA `Dockerfile` for `vla-server`.

### Changed
- llama.cpp is fetched + pinned via CMake `FetchContent` (tag `b9866`); bumping is a
one-line `GIT_TAG` change. Removed the `patches/` fetch script.

[0.1.1]: https://github.com/VinRobotics/vla.cpp/releases/tag/v0.1.1
[0.1.0]: https://github.com/VinRobotics/vla.cpp/releases/tag/v0.1.0
83 changes: 74 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ set(LLAMA_BUILD_TOOLS ON CACHE BOOL "" FORCE)
set(LLAMA_BUILD_SERVER OFF CACHE BOOL "" FORCE)
set(LLAMA_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(LLAMA_BUILD_TESTS OFF CACHE BOOL "" FORCE)
add_subdirectory(third_party/llama.cpp)
# llama.cpp fetched + pinned at configure; bump = one-line GIT_TAG change.
include(FetchContent)
FetchContent_Declare(llama
GIT_REPOSITORY https://github.com/ggml-org/llama.cpp
GIT_TAG b9866
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(llama)

add_library(vla_core
src/model.cpp
Expand All @@ -35,18 +42,31 @@ add_library(vla_core
target_include_directories(vla_core
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/tools/mtmd
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/vendor
${llama_SOURCE_DIR}/vendor
)
target_link_libraries(vla_core PUBLIC llama ggml mtmd)
target_link_libraries(vla_core PUBLIC llama ggml)

if(GGML_CUDA)
target_compile_definitions(vla_core PUBLIC GGML_USE_CUDA)

enable_language(CUDA)
find_package(CUDAToolkit REQUIRED)
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 80 86 87 89 90 100 120 CACHE STRING "" FORCE)
# Emit SASS per supported GPU (real) and PTX (virtual) only for the newest
# arch, so future cards can JIT without shipping PTX for every target.
# Blackwell sm_100/sm_120 require CUDA >= 12.8.
set(_vla_cuda_archs 80-real 86-real 87-real 89-real 90-real)
set(_vla_cuda_ptx 90-virtual)
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.8)
list(APPEND _vla_cuda_archs 100-real 120-real)
set(_vla_cuda_ptx 120-virtual)
else()
message(WARNING
"CUDA ${CUDAToolkit_VERSION} < 12.8: omitting Blackwell sm_100/sm_120. "
"Pass -DCMAKE_CUDA_ARCHITECTURES=<arch> explicitly to override.")
endif()
set(CMAKE_CUDA_ARCHITECTURES ${_vla_cuda_archs} ${_vla_cuda_ptx}
CACHE STRING "" FORCE)
endif()
add_library(bitvla_cuda_kernels STATIC
src/kernels/bitvla/bitnet_kernels.cu
Expand Down Expand Up @@ -79,16 +99,25 @@ target_include_directories(vlm_core
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/common
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/tools/mtmd
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/vendor
${llama_SOURCE_DIR}/common
${llama_SOURCE_DIR}/tools/mtmd
${llama_SOURCE_DIR}/vendor
)
target_link_libraries(vlm_core PUBLIC llama ggml mtmd llama-common)

find_package(Protobuf REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(ZeroMQ REQUIRED IMPORTED_TARGET libzmq)

# cppzmq (zmq.hpp) is the header-only C++ binding, packaged separately from the
# libzmq C library (Debian/Ubuntu: cppzmq-dev). The servers #include <zmq.hpp>.
find_path(CPPZMQ_INCLUDE_DIR NAMES zmq.hpp)
if(NOT CPPZMQ_INCLUDE_DIR)
message(FATAL_ERROR
"cppzmq (zmq.hpp) not found. Install 'cppzmq-dev' (Debian/Ubuntu) or set "
"CMAKE_PREFIX_PATH to your cppzmq install prefix.")
endif()

set(VLA_PROTO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/serving/vla.proto)
set(VLA_PROTO_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/proto-gen/serving)
file(MAKE_DIRECTORY ${VLA_PROTO_GEN_DIR})
Expand All @@ -110,7 +139,8 @@ add_executable(vla-server
)
target_include_directories(vla-server PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/proto-gen
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/vendor/stb
${llama_SOURCE_DIR}/vendor/stb
${CPPZMQ_INCLUDE_DIR}
)
target_link_libraries(vla-server PRIVATE
vla_core
Expand Down Expand Up @@ -139,9 +169,44 @@ add_executable(vlm-server
)
target_include_directories(vlm-server PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/proto-gen
${CPPZMQ_INCLUDE_DIR}
)
target_link_libraries(vlm-server PRIVATE
vlm_core
protobuf::libprotobuf
PkgConfig::ZeroMQ
)

# One-shot inference CLI: image + tokens -> action, no server or simulator.
add_executable(vla-cli
src/serving/vla-cli.cpp
)
target_include_directories(vla-cli PRIVATE
${llama_SOURCE_DIR}/vendor/stb
)
target_link_libraries(vla-cli PRIVATE vla_core)

# --- First-party build hygiene (never applied to the vendored llama.cpp subtree) --
set(VLA_FIRST_PARTY_TARGETS vla_core vlm_core vla-server vlm-server vla-cli)

foreach(tgt IN LISTS VLA_FIRST_PARTY_TARGETS)
# Warn on our own C++ only; nvcc device code keeps its own diagnostics.
target_compile_options(${tgt} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall -Wextra>)
endforeach()

# Link-time optimization on Release builds when the toolchain supports it.
include(CheckIPOSupported)
check_ipo_supported(RESULT VLA_IPO_OK OUTPUT VLA_IPO_MSG)
if(VLA_IPO_OK AND CMAKE_BUILD_TYPE STREQUAL "Release")
foreach(tgt IN LISTS VLA_FIRST_PARTY_TARGETS)
set_property(TARGET ${tgt} PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endforeach()
else()
message(STATUS "vla: IPO/LTO disabled (${VLA_IPO_MSG})")
endif()

option(VLA_BUILD_TESTS "Build vla.cpp test harnesses and unit tests" OFF)
if(VLA_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
39 changes: 39 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# vla-server, CPU or CUDA. cmake fetches llama.cpp at build time.
# GPU sm_120 (default): docker build -t vla-cpp .
# GPU other arch: --build-arg CUDA_ARCH=89 (89=RTX40 90=H100 87=Orin; sm_120 needs CUDA>=12.8)
# older card: --build-arg BASE_IMAGE=nvidia/cuda:12.4.1-devel-ubuntu24.04 --build-arg CUDA_ARCH=86
# CPU: --build-arg BACKEND=cpu --build-arg BASE_IMAGE=ubuntu:24.04 -t vla-cpp-cpu
# run: docker run --gpus all -p5555:5555 -v $PWD/models:/models vla-cpp --bind tcp://*:5555 /models/M.gguf
# (CDI hosts use --device nvidia.com/gpu=all)

ARG BASE_IMAGE=nvidia/cuda:12.9.1-devel-ubuntu24.04
FROM ${BASE_IMAGE}

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
build-essential cmake git ca-certificates pkg-config \
libzmq3-dev cppzmq-dev libprotobuf-dev protobuf-compiler \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /src
COPY . .

ARG BACKEND=cuda
ARG CUDA_ARCH=120
# nvcc can segfault on the flash-attn kernels under high -j; lower JOBS if so.
ARG JOBS=
# CUDA: -devel ships only a libcuda stub (real driver injected at runtime), so
# link ggml-cuda's driver calls against it. CPU build skips this.
RUN set -eux; \
if [ "$BACKEND" = "cuda" ]; then \
export LIBRARY_PATH=/usr/local/cuda/lib64/stubs; \
cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=ON -DGGML_CUDA_GRAPHS=ON \
-DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCH}" \
-DCMAKE_SHARED_LINKER_FLAGS="-lcuda" -DCMAKE_EXE_LINKER_FLAGS="-lcuda"; \
else \
cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=OFF; \
fi; \
cmake --build build -j"${JOBS:-$(nproc)}" --target vla-server vla-cli; \
cp build/vla-server build/vla-cli /usr/local/bin/

EXPOSE 5555
ENTRYPOINT ["vla-server"]
Loading
Loading