Skip to content

Commit 3cd5d82

Browse files
committed
starvla: integrate seven Qwen policy variants
1 parent 11cc5bf commit 3cd5d82

78 files changed

Lines changed: 4006 additions & 13585 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 118 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
cmake_minimum_required(VERSION 3.16)
22
project(robotcpp VERSION 0.1.0 LANGUAGES C CXX)
33

4+
include(CTest)
5+
46
option(ROBOT_CPP_BUILD_ROBOT_SERVER "Build model-server target" ON)
57
option(ROBOT_CPP_BUILD_MODEL_CLI "Build model-cli target" OFF)
68
option(ROBOT_CPP_BUILD_ROBOT_CLIENT "Build C++ robot client targets" OFF)
9+
option(ROBOT_CPP_BUILD_STARVLA "Build the StarVLA runtime (requires llama.cpp overlay)" OFF)
710

811
set(CMAKE_CXX_STANDARD 17)
912
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -12,6 +15,27 @@ set(CMAKE_CXX_EXTENSIONS OFF)
1215
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/CMakeLists.txt")
1316
message(FATAL_ERROR "third_party/llama.cpp is required; run `git submodule update --init --recursive`")
1417
endif()
18+
if(ROBOT_CPP_BUILD_STARVLA)
19+
file(READ
20+
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/tools/mtmd/models/qwen3vl.cpp"
21+
ROBOT_CPP_QWEN3VL_MTMD_SOURCE)
22+
file(READ
23+
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/include/llama.h"
24+
ROBOT_CPP_LLAMA_PUBLIC_HEADER)
25+
string(FIND "${ROBOT_CPP_QWEN3VL_MTMD_SOURCE}"
26+
"FFN_GELU_ERF" ROBOT_CPP_QWEN3VL_PARITY_PATCH_INDEX)
27+
string(FIND "${ROBOT_CPP_LLAMA_PUBLIC_HEADER}"
28+
"llama_set_backend_native_graphs_enabled" ROBOT_CPP_LLAMA_GRAPH_PATCH_INDEX)
29+
if(ROBOT_CPP_QWEN3VL_PARITY_PATCH_INDEX EQUAL -1 OR
30+
ROBOT_CPP_LLAMA_GRAPH_PATCH_INDEX EQUAL -1)
31+
message(FATAL_ERROR
32+
"StarVLA requires the pinned llama.cpp overlay. Run "
33+
"`./tools/apply_patches.sh` from the repository root, "
34+
"then configure again.")
35+
endif()
36+
unset(ROBOT_CPP_QWEN3VL_MTMD_SOURCE)
37+
unset(ROBOT_CPP_LLAMA_PUBLIC_HEADER)
38+
endif()
1539
set(LLAMA_BUILD_COMMON ON CACHE BOOL "" FORCE)
1640
set(LLAMA_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
1741
set(LLAMA_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
@@ -20,7 +44,16 @@ add_subdirectory(third_party/llama.cpp EXCLUDE_FROM_ALL)
2044
if(NOT TARGET ggml OR NOT TARGET llama)
2145
message(FATAL_ERROR "llama.cpp must provide ggml and llama targets")
2246
endif()
23-
47+
if(ROBOT_CPP_BUILD_STARVLA)
48+
# mtmd normally inherits this variable when llama.cpp builds all tools.
49+
if(NOT LLAMA_INSTALL_VERSION)
50+
set(LLAMA_INSTALL_VERSION ${PROJECT_VERSION})
51+
endif()
52+
add_subdirectory(third_party/llama.cpp/tools/mtmd EXCLUDE_FROM_ALL)
53+
if(NOT TARGET mtmd)
54+
message(FATAL_ERROR "llama.cpp must provide the mtmd target for Qwen-VL")
55+
endif()
56+
endif()
2457
set(ROBOT_CPP_LLAMA_INCLUDE_DIRS
2558
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp
2659
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/include
@@ -30,14 +63,29 @@ set(ROBOT_CPP_LLAMA_INCLUDE_DIRS
3063
)
3164

3265
set(SMOLVLA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/models/smolvla)
66+
set(STARVLA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/models/starvla)
3367
set(ROBOT_SERVER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/robot_server)
3468
set(ROBOT_CLIENT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/robot_client)
3569

36-
add_library(smolvla_runtime STATIC
70+
add_library(robotcpp_model_common STATIC
3771
src/models/ggml_backend.cpp
3872
src/models/ggml_backend.h
3973
src/models/gguf_loader.cpp
4074
src/models/gguf_loader.h
75+
src/models/model_type.cpp
76+
)
77+
target_include_directories(robotcpp_model_common
78+
PUBLIC
79+
${CMAKE_CURRENT_SOURCE_DIR}/src
80+
${ROBOT_CPP_LLAMA_INCLUDE_DIRS}
81+
)
82+
target_link_libraries(robotcpp_model_common PUBLIC ggml)
83+
target_compile_features(robotcpp_model_common PUBLIC cxx_std_17)
84+
if(NOT MSVC)
85+
target_compile_options(robotcpp_model_common PRIVATE -Wno-cast-qual)
86+
endif()
87+
88+
add_library(smolvla_runtime STATIC
4189
${SMOLVLA_DIR}/smolvla_engine.cpp
4290
${SMOLVLA_DIR}/smolvla_engine.h
4391
${SMOLVLA_DIR}/state_proj.cpp
@@ -53,17 +101,13 @@ target_include_directories(smolvla_runtime
53101
${SMOLVLA_DIR}
54102
${ROBOT_CPP_LLAMA_INCLUDE_DIRS}
55103
)
56-
target_link_libraries(smolvla_runtime PUBLIC ggml llama)
104+
target_link_libraries(smolvla_runtime PUBLIC robotcpp_model_common llama)
57105
target_compile_features(smolvla_runtime PUBLIC cxx_std_17)
58106
if(NOT MSVC)
59107
target_compile_options(smolvla_runtime PRIVATE -Wno-cast-qual)
60108
endif()
61109

62110
add_library(pi0_engine STATIC
63-
src/models/ggml_backend.cpp
64-
src/models/ggml_backend.h
65-
src/models/gguf_loader.cpp
66-
src/models/gguf_loader.h
67111
src/models/pi0/types.h
68112
src/models/pi0/action.cpp
69113
src/models/pi0/action.h
@@ -87,13 +131,65 @@ target_include_directories(pi0_engine
87131
${CMAKE_CURRENT_SOURCE_DIR}/src
88132
${ROBOT_CPP_LLAMA_INCLUDE_DIRS}
89133
)
90-
target_link_libraries(pi0_engine PUBLIC ggml llama)
134+
target_link_libraries(pi0_engine PUBLIC robotcpp_model_common llama)
91135
target_compile_features(pi0_engine PUBLIC cxx_std_17)
92136
if(NOT MSVC)
93137
target_compile_options(pi0_engine PRIVATE -Wno-cast-qual)
94138
endif()
95139

140+
if(ROBOT_CPP_BUILD_STARVLA)
141+
add_library(starvla_runtime STATIC
142+
${STARVLA_DIR}/fast_codec.cpp
143+
${STARVLA_DIR}/fast_codec.h
144+
${STARVLA_DIR}/fast_policy.cpp
145+
${STARVLA_DIR}/fast_policy.h
146+
${STARVLA_DIR}/groot_policy.cpp
147+
${STARVLA_DIR}/groot_policy.h
148+
${STARVLA_DIR}/groot_prompt.cpp
149+
${STARVLA_DIR}/groot_prompt.h
150+
${STARVLA_DIR}/normalization.cpp
151+
${STARVLA_DIR}/normalization.h
152+
${STARVLA_DIR}/oft_image_preprocess.cpp
153+
${STARVLA_DIR}/oft_image_preprocess.h
154+
${STARVLA_DIR}/oft_prompt.cpp
155+
${STARVLA_DIR}/oft_prompt.h
156+
${STARVLA_DIR}/oft_policy.cpp
157+
${STARVLA_DIR}/oft_policy.h
158+
${STARVLA_DIR}/pi_policy.cpp
159+
${STARVLA_DIR}/pi_policy.h
160+
${STARVLA_DIR}/pi_v3_policy.cpp
161+
${STARVLA_DIR}/pi_v3_policy.h
162+
${STARVLA_DIR}/policy_gguf.h
163+
${STARVLA_DIR}/qwen3vl_bridge.cpp
164+
${STARVLA_DIR}/qwen3vl_bridge.h
165+
${STARVLA_DIR}/starvla_engine.cpp
166+
${STARVLA_DIR}/starvla_engine.h
167+
third_party/llama.cpp/examples/gguf-hash/deps/sha256/sha256.c
168+
)
169+
target_include_directories(starvla_runtime
170+
PUBLIC
171+
${CMAKE_CURRENT_SOURCE_DIR}/src
172+
${ROBOT_CPP_LLAMA_INCLUDE_DIRS}
173+
PRIVATE
174+
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/vendor
175+
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/examples/gguf-hash/deps
176+
${CMAKE_CURRENT_SOURCE_DIR}/third_party/llama.cpp/examples/gguf-hash/deps/sha256
177+
)
178+
target_link_libraries(starvla_runtime PUBLIC robotcpp_model_common llama mtmd)
179+
target_compile_features(starvla_runtime PUBLIC cxx_std_17)
180+
if(GGML_CUDA)
181+
enable_language(CUDA)
182+
target_sources(starvla_runtime PRIVATE ${STARVLA_DIR}/qwen_bf16_round_cuda.cu)
183+
target_compile_definitions(starvla_runtime PRIVATE ROBOTCPP_STARVLA_CUDA=1)
184+
set_property(TARGET starvla_runtime PROPERTY CUDA_STANDARD 17)
185+
endif()
186+
if(NOT MSVC)
187+
target_compile_options(starvla_runtime PRIVATE -Wno-cast-qual)
188+
endif()
189+
endif()
190+
96191
add_library(robotcpp STATIC
192+
src/models/argument_parse.h
97193
src/models/model.h
98194
src/models/model_factory.cpp
99195
src/models/pi0/pi0_model.cpp
@@ -108,6 +204,19 @@ target_include_directories(robotcpp
108204
)
109205
target_link_libraries(robotcpp PUBLIC smolvla_runtime pi0_engine)
110206
target_compile_features(robotcpp PUBLIC cxx_std_17)
207+
if(ROBOT_CPP_BUILD_STARVLA)
208+
target_sources(robotcpp PRIVATE
209+
${STARVLA_DIR}/starvla_model.cpp
210+
${STARVLA_DIR}/starvla_model.h)
211+
target_link_libraries(robotcpp PUBLIC starvla_runtime)
212+
target_compile_definitions(robotcpp PUBLIC ROBOT_CPP_BUILD_STARVLA=1)
213+
endif()
214+
215+
if(BUILD_TESTING AND ROBOT_CPP_BUILD_STARVLA)
216+
add_executable(robotcpp-starvla-model-test tests/starvla/model_test.cpp)
217+
target_link_libraries(robotcpp-starvla-model-test PRIVATE robotcpp)
218+
add_test(NAME robotcpp-starvla-model-test COMMAND robotcpp-starvla-model-test)
219+
endif()
111220

112221
if(ROBOT_CPP_BUILD_ROBOT_SERVER OR ROBOT_CPP_BUILD_ROBOT_CLIENT)
113222
add_library(robot_server_common STATIC
@@ -139,6 +248,7 @@ if(ROBOT_CPP_BUILD_ROBOT_CLIENT)
139248
set_target_properties(model-cpp-client-example PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
140249
target_link_libraries(model-cpp-client-example PRIVATE model_client_cpp)
141250
target_compile_features(model-cpp-client-example PRIVATE cxx_std_17)
251+
142252
endif()
143253

144254
if(ROBOT_CPP_BUILD_ROBOT_SERVER)
@@ -165,7 +275,6 @@ if(ROBOT_CPP_BUILD_ROBOT_SERVER)
165275
)
166276
target_link_libraries(model-server PRIVATE robot_server_core robotcpp)
167277
target_compile_features(model-server PRIVATE cxx_std_17)
168-
169278
add_executable(smolvla-raw-predict ${ROBOT_SERVER_DIR}/test/smolvla_raw_predict.cpp)
170279
set_target_properties(smolvla-raw-predict PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
171280
target_include_directories(smolvla-raw-predict PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${SMOLVLA_DIR})

patches/llama.cpp/README.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
# StarVLA llama.cpp patches
1+
# llama.cpp patches
22

33
The project pins `third_party/llama.cpp` at commit
4-
`3e941b813b1acbbf06c2203a94ceb33d84748c1e`. The StarVLA runtime needs two
5-
small changes that are not available through that revision's public APIs:
4+
`3e941b813b1acbbf06c2203a94ceb33d84748c1e`. The repository applies two
5+
changes that are not available through that revision's public APIs:
66

7-
1. `0001-qwen3vl-vision-parity.patch` matches the upstream Qwen3-VL reference
8-
implementation's position interpolation and exact GELU operations. These
9-
changes are required for action-value parity with the original checkpoint.
7+
1. `0001-qwen3vl-vision-parity.patch` uses the position interpolation and exact
8+
GELU operations from the Qwen3-VL implementation used by StarVLA.
109
2. `0002-per-context-native-graph-control.patch` adds an optional backend API to
1110
disable CUDA graph capture for the text and vision contexts owned by one
12-
StarVLA instance. It prevents retained CUDA graphs from violating long-loop
13-
memory stability gates without globally changing other llama.cpp users.
11+
StarVLA instance. This avoids retained CUDA graphs growing memory use during
12+
long runs without changing the setting for other llama.cpp users.
1413

15-
Apply both patches before configuring or building the StarVLA runtime:
14+
Apply the repository patch set after initializing submodules and before building:
1615

1716
```bash
18-
./tools/llama_cpp/apply_starvla_patches.sh
17+
./tools/apply_patches.sh
1918
```
2019

2120
The command verifies the exact llama.cpp revision and refuses a dirty or
@@ -24,8 +23,8 @@ partially patched checkout. It is safe to run again after a complete apply.
2423
Inspect or remove the overlay with:
2524

2625
```bash
27-
./tools/llama_cpp/apply_starvla_patches.sh --check
28-
./tools/llama_cpp/apply_starvla_patches.sh --revert
26+
./tools/apply_patches.sh --check
27+
./tools/apply_patches.sh --revert
2928
```
3029

3130
The parent repository commits only these patch assets. It does not advance or

robot_client/cpp/model_client.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ bool make_predict_request(const ModelObservation & obs, proto::predict_request &
5757

5858
req.task = obs.prompt;
5959
req.state = obs.state;
60+
req.initial_noise = obs.initial_noise;
6061
req.images.clear();
6162
req.images.reserve(obs.images.size());
6263

robot_client/cpp/model_client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct ModelImage {
2121
struct ModelObservation {
2222
std::vector<ModelImage> images;
2323
std::vector<float> state;
24+
std::vector<float> initial_noise;
2425
std::string prompt = "grab the block.";
2526
};
2627

robot_client/python/model_client.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
MAGIC = 0x414C5653
12-
VERSION = 3
12+
VERSION = 4
1313
HEADER_SIZE = 32
1414

1515
OP_HEALTH = 1
@@ -21,8 +21,8 @@
2121
IMAGE_RAW_RGB_U8 = 1
2222

2323
HEADER = struct.Struct("<IHHHHIIQI")
24-
PREDICT_REQ_V2_FIXED = struct.Struct("<III")
25-
PREDICT_REQ_V2_IMAGE = struct.Struct("<IIIIIIQ")
24+
PREDICT_REQ_FIXED = struct.Struct("<IIII")
25+
PREDICT_REQ_IMAGE = struct.Struct("<IIIIIIQ")
2626
PREDICT_RESP_FIXED = struct.Struct("<IIII")
2727
PREDICT_RESP_METRIC = struct.Struct("<Id")
2828

@@ -76,6 +76,7 @@ def _recv_message(sock: socket.socket) -> tuple[int, int, int, bytes]:
7676
def encode_predict_observation(observation: dict[str, Any]) -> bytes:
7777
images = observation["images"]
7878
state = state_to_list(observation["state"])
79+
initial_noise = state_to_list(observation.get("initial_noise"))
7980
prompt = str(observation["prompt"])
8081
if not images:
8182
raise ValueError("observation.images must contain at least one image")
@@ -88,13 +89,14 @@ def encode_predict_observation(observation: dict[str, Any]) -> bytes:
8889
encoded_images.append((name, rgb, width, height, stride))
8990

9091
payload = bytearray()
91-
payload += PREDICT_REQ_V2_FIXED.pack(
92+
payload += PREDICT_REQ_FIXED.pack(
9293
len(encoded_images),
9394
len(state),
95+
len(initial_noise),
9496
len(prompt_bytes),
9597
)
9698
for name, rgb, width, height, stride in encoded_images:
97-
payload += PREDICT_REQ_V2_IMAGE.pack(
99+
payload += PREDICT_REQ_IMAGE.pack(
98100
IMAGE_RAW_RGB_U8,
99101
len(name),
100102
width,
@@ -105,6 +107,8 @@ def encode_predict_observation(observation: dict[str, Any]) -> bytes:
105107
)
106108
for value in state:
107109
payload += struct.pack("<f", float(value))
110+
for value in initial_noise:
111+
payload += struct.pack("<f", float(value))
108112
payload += prompt_bytes
109113
for name, rgb, _width, _height, _stride in encoded_images:
110114
payload += name

0 commit comments

Comments
 (0)