Skip to content

Commit 2902c89

Browse files
committed
starvla: remove unused runtime fallbacks
1 parent 638a171 commit 2902c89

6 files changed

Lines changed: 1 addition & 297 deletions

File tree

src/models/starvla/fast_codec.cpp

Lines changed: 0 additions & 280 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
11
#include "models/starvla/fast_codec.h"
22

3-
#include "nlohmann/json.hpp"
4-
53
#include <algorithm>
6-
#include <array>
74
#include <cmath>
8-
#include <exception>
9-
#include <fstream>
105
#include <limits>
11-
#include <sstream>
126
#include <unordered_map>
137
#include <unordered_set>
148
#include <utility>
159

1610
namespace robotcpp::starvla {
1711
namespace {
1812

19-
using Json = nlohmann::json;
20-
21-
constexpr size_t kMaximumJsonBytes = 16U * 1024U * 1024U;
22-
constexpr size_t kOfficialVocabSize = 2048U;
2313
constexpr size_t kMaximumVocabSize = 65536U;
2414
constexpr size_t kMaximumTimeHorizon = 1024U;
2515
constexpr size_t kMaximumActionDim = 1024U;
@@ -29,56 +19,8 @@ constexpr size_t kMaximumGeneratedSequence = 2048U;
2919
constexpr size_t kMaximumDecodedBytes = 1024U * 1024U;
3020
constexpr size_t kMaximumOutputScalars = 16U * 1024U * 1024U;
3121
constexpr uint64_t kMaximumIdctMultiplyAdds = 64ULL * 1024ULL * 1024ULL;
32-
constexpr const char * kActionTokenPrefix = "<robot_action_";
3322
constexpr double kPi = 3.141592653589793238462643383279502884;
3423

35-
bool read_json(const std::filesystem::path & path, Json & output, std::string & error) {
36-
std::error_code filesystem_error;
37-
const uintmax_t size = std::filesystem::file_size(path, filesystem_error);
38-
if (filesystem_error) {
39-
error = "cannot stat StarVLA FAST JSON asset '" + path.string() + "': " +
40-
filesystem_error.message();
41-
return false;
42-
}
43-
if (size > kMaximumJsonBytes) {
44-
error = "StarVLA FAST JSON asset exceeds the 16 MiB limit: " + path.string();
45-
return false;
46-
}
47-
48-
std::ifstream stream(path, std::ios::binary);
49-
if (!stream) {
50-
error = "cannot open StarVLA FAST JSON asset: " + path.string();
51-
return false;
52-
}
53-
std::string contents;
54-
contents.reserve(static_cast<size_t>(size));
55-
std::array<char, 64U * 1024U> buffer{};
56-
while (stream) {
57-
stream.read(buffer.data(), static_cast<std::streamsize>(buffer.size()));
58-
const std::streamsize count = stream.gcount();
59-
if (count <= 0) {
60-
continue;
61-
}
62-
const size_t chunk_size = static_cast<size_t>(count);
63-
if (contents.size() > kMaximumJsonBytes - chunk_size) {
64-
error = "StarVLA FAST JSON asset exceeds the 16 MiB limit while reading: " +
65-
path.string();
66-
return false;
67-
}
68-
contents.append(buffer.data(), chunk_size);
69-
}
70-
if (!stream.eof() || stream.bad()) {
71-
error = "cannot read StarVLA FAST JSON asset: " + path.string();
72-
return false;
73-
}
74-
output = Json::parse(contents, nullptr, false);
75-
if (output.is_discarded()) {
76-
error = "cannot parse StarVLA FAST JSON asset: " + path.string();
77-
return false;
78-
}
79-
return true;
80-
}
81-
8224
bool decode_utf8_strict(const std::string & input, std::vector<uint32_t> & output,
8325
std::string & error) {
8426
output.clear();
@@ -258,200 +200,6 @@ void decode_utf8_lossy(const std::vector<uint8_t> & input, std::vector<uint32_t>
258200
}
259201
}
260202

261-
bool parse_positive_size(const Json & value, const char * name, size_t & output,
262-
std::string & error) {
263-
if (!value.is_number_integer()) {
264-
error = std::string("StarVLA FAST ") + name + " must be an integer";
265-
return false;
266-
}
267-
try {
268-
const int64_t parsed = value.get<int64_t>();
269-
if (parsed <= 0 || static_cast<uint64_t>(parsed) >
270-
static_cast<uint64_t>(std::numeric_limits<size_t>::max())) {
271-
error = std::string("StarVLA FAST ") + name + " is out of range";
272-
return false;
273-
}
274-
output = static_cast<size_t>(parsed);
275-
return true;
276-
} catch (const std::exception &) {
277-
error = std::string("StarVLA FAST ") + name + " is out of range";
278-
return false;
279-
}
280-
}
281-
282-
bool parse_processor_config(const Json & json, size_t time_horizon_override,
283-
size_t action_dim_override, FastCodecConfig & config,
284-
std::string & error) {
285-
if (!json.is_object() || !json.contains("processor_class") ||
286-
json["processor_class"] != "UniversalActionProcessor" || !json.contains("scale") ||
287-
!json["scale"].is_number() || !json.contains("vocab_size") ||
288-
!json.contains("min_token") || !json["min_token"].is_number_integer()) {
289-
error = "StarVLA FAST processor_config.json has an incompatible schema";
290-
return false;
291-
}
292-
config.scale = json["scale"].get<double>();
293-
if (!std::isfinite(config.scale) || config.scale == 0.0) {
294-
error = "StarVLA FAST processor scale must be finite and non-zero";
295-
return false;
296-
}
297-
if (!parse_positive_size(json["vocab_size"], "vocab_size", config.vocab_size, error)) {
298-
return false;
299-
}
300-
if (config.vocab_size != kOfficialVocabSize) {
301-
error = "StarVLA FAST pinned vocabulary must contain exactly 2048 tokens";
302-
return false;
303-
}
304-
try {
305-
if (json["min_token"].is_number_unsigned()) {
306-
const uint64_t min_token = json["min_token"].get<uint64_t>();
307-
if (min_token > static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) {
308-
error = "StarVLA FAST min_token is out of int32 range";
309-
return false;
310-
}
311-
config.min_token = static_cast<int32_t>(min_token);
312-
} else {
313-
const int64_t min_token = json["min_token"].get<int64_t>();
314-
if (min_token < std::numeric_limits<int32_t>::min() ||
315-
min_token > std::numeric_limits<int32_t>::max()) {
316-
error = "StarVLA FAST min_token is out of int32 range";
317-
return false;
318-
}
319-
config.min_token = static_cast<int32_t>(min_token);
320-
}
321-
} catch (const std::exception &) {
322-
error = "StarVLA FAST min_token is out of int32 range";
323-
return false;
324-
}
325-
326-
auto choose_dimension = [&](const char * name, size_t override_value, size_t & target) {
327-
if (override_value != 0) {
328-
target = override_value;
329-
return true;
330-
}
331-
if (!json.contains(name) || json[name].is_null()) {
332-
error = std::string("StarVLA FAST ") + name +
333-
" is absent; pass the policy dimension explicitly";
334-
return false;
335-
}
336-
return parse_positive_size(json[name], name, target, error);
337-
};
338-
return choose_dimension("time_horizon", time_horizon_override, config.time_horizon) &&
339-
choose_dimension("action_dim", action_dim_override, config.action_dim);
340-
}
341-
342-
bool parse_tokenizer_vocab(const Json & json, size_t expected_vocab_size,
343-
std::vector<std::string> & vocab_by_id, std::string & error) {
344-
if (!json.is_object() || !json.contains("version") || json["version"] != "1.0" ||
345-
!json.contains("added_tokens") || !json["added_tokens"].is_array() ||
346-
!json["added_tokens"].empty() || !json.contains("decoder") ||
347-
!json["decoder"].is_object() || !json["decoder"].contains("type") ||
348-
json["decoder"]["type"] != "ByteLevel" || !json.contains("model") ||
349-
!json["model"].is_object() || !json["model"].contains("type") ||
350-
json["model"]["type"] != "BPE" || !json["model"].contains("vocab") ||
351-
!json["model"]["vocab"].is_object()) {
352-
error = "StarVLA FAST tokenizer.json is not the required ByteLevel BPE schema";
353-
return false;
354-
}
355-
const Json & decoder = json["decoder"];
356-
if (decoder.size() != 4 || !decoder.contains("add_prefix_space") ||
357-
decoder["add_prefix_space"] != true || !decoder.contains("trim_offsets") ||
358-
decoder["trim_offsets"] != true || !decoder.contains("use_regex") ||
359-
decoder["use_regex"] != true) {
360-
error = "StarVLA FAST tokenizer.json has an incompatible ByteLevel decoder contract";
361-
return false;
362-
}
363-
const Json & vocab = json["model"]["vocab"];
364-
if (vocab.size() != expected_vocab_size) {
365-
error = "StarVLA FAST tokenizer vocabulary size does not match processor_config.json";
366-
return false;
367-
}
368-
vocab_by_id.assign(expected_vocab_size, std::string());
369-
std::vector<bool> seen(expected_vocab_size, false);
370-
for (auto iterator = vocab.begin(); iterator != vocab.end(); ++iterator) {
371-
if (!iterator.value().is_number_integer()) {
372-
error = "StarVLA FAST tokenizer vocabulary ID is not an integer";
373-
return false;
374-
}
375-
int64_t token_id = -1;
376-
try {
377-
token_id = iterator.value().get<int64_t>();
378-
} catch (const std::exception &) {
379-
error = "StarVLA FAST tokenizer vocabulary ID is out of range";
380-
return false;
381-
}
382-
if (token_id < 0 || static_cast<uint64_t>(token_id) >= expected_vocab_size ||
383-
seen[static_cast<size_t>(token_id)]) {
384-
error = "StarVLA FAST tokenizer vocabulary IDs are not a bijection";
385-
return false;
386-
}
387-
seen[static_cast<size_t>(token_id)] = true;
388-
vocab_by_id[static_cast<size_t>(token_id)] = iterator.key();
389-
}
390-
return true;
391-
}
392-
393-
bool parse_action_index(const std::string & value, size_t & index) {
394-
const std::string prefix(kActionTokenPrefix);
395-
if (value.size() <= prefix.size() + 1 || value.compare(0, prefix.size(), prefix) != 0 ||
396-
value.back() != '>') {
397-
return false;
398-
}
399-
const std::string digits = value.substr(prefix.size(), value.size() - prefix.size() - 1);
400-
if (digits.empty() || (digits.size() > 1 && digits.front() == '0')) {
401-
return false;
402-
}
403-
size_t parsed = 0;
404-
for (char character : digits) {
405-
if (character < '0' || character > '9') {
406-
return false;
407-
}
408-
const size_t digit = static_cast<size_t>(character - '0');
409-
if (parsed > (std::numeric_limits<size_t>::max() - digit) / 10U) {
410-
return false;
411-
}
412-
parsed = parsed * 10U + digit;
413-
}
414-
index = parsed;
415-
return true;
416-
}
417-
418-
bool parse_action_map(const Json & json, size_t vocab_size,
419-
std::vector<int32_t> & fast_to_vlm, std::string & error) {
420-
if (!json.is_object() || json.size() != vocab_size) {
421-
error = "StarVLA FAST action-token map must contain exactly one entry per FAST token";
422-
return false;
423-
}
424-
fast_to_vlm.assign(vocab_size, -1);
425-
std::vector<bool> seen(vocab_size, false);
426-
std::unordered_set<int32_t> vlm_ids;
427-
for (auto iterator = json.begin(); iterator != json.end(); ++iterator) {
428-
size_t fast_id = 0;
429-
if (!parse_action_index(iterator.key(), fast_id) || fast_id >= vocab_size || seen[fast_id]) {
430-
error = "StarVLA FAST action-token map has a malformed or duplicate token name";
431-
return false;
432-
}
433-
if (!iterator.value().is_number_integer()) {
434-
error = "StarVLA FAST action-token map contains a non-integer VLM ID";
435-
return false;
436-
}
437-
int64_t vlm_id = -1;
438-
try {
439-
vlm_id = iterator.value().get<int64_t>();
440-
} catch (const std::exception &) {
441-
error = "StarVLA FAST action-token VLM ID is out of range";
442-
return false;
443-
}
444-
if (vlm_id < 0 || vlm_id > std::numeric_limits<int32_t>::max() ||
445-
!vlm_ids.insert(static_cast<int32_t>(vlm_id)).second) {
446-
error = "StarVLA FAST action-token VLM IDs must be unique non-negative int32 values";
447-
return false;
448-
}
449-
seen[fast_id] = true;
450-
fast_to_vlm[fast_id] = static_cast<int32_t>(vlm_id);
451-
}
452-
return true;
453-
}
454-
455203
bool checked_action_count(const FastCodecConfig & config, size_t batch_size,
456204
size_t & per_sample, size_t & total, std::string & error) {
457205
if (config.vocab_size > kMaximumVocabSize || config.time_horizon > kMaximumTimeHorizon ||
@@ -602,34 +350,6 @@ std::unique_ptr<FastCodec> FastCodec::create_compiled(
602350
new FastCodec(config, std::move(pieces), std::move(fast_to_vlm_id)));
603351
}
604352

605-
std::unique_ptr<FastCodec> FastCodec::load_hf_assets(
606-
const std::filesystem::path & tokenizer_json,
607-
const std::filesystem::path & processor_config_json,
608-
const std::filesystem::path & action_token_map_json,
609-
size_t time_horizon, size_t action_dim, std::string & error) {
610-
error.clear();
611-
Json processor;
612-
Json tokenizer;
613-
Json action_map;
614-
if (!read_json(processor_config_json, processor, error) ||
615-
!read_json(tokenizer_json, tokenizer, error) ||
616-
!read_json(action_token_map_json, action_map, error)) {
617-
return nullptr;
618-
}
619-
620-
FastCodecConfig config;
621-
std::vector<std::string> vocab_by_id;
622-
std::vector<int32_t> fast_to_vlm;
623-
size_t per_sample = 0;
624-
size_t total = 0;
625-
if (!parse_processor_config(processor, time_horizon, action_dim, config, error) ||
626-
!checked_action_count(config, 1, per_sample, total, error) ||
627-
!parse_tokenizer_vocab(tokenizer, config.vocab_size, vocab_by_id, error) ||
628-
!parse_action_map(action_map, config.vocab_size, fast_to_vlm, error)) {
629-
return nullptr;
630-
}
631-
return create(config, std::move(vocab_by_id), std::move(fast_to_vlm), error);
632-
}
633353

634354
const FastCodecConfig & FastCodec::config() const {
635355
return config_;

src/models/starvla/fast_codec.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
#include <cstddef>
44
#include <cstdint>
5-
#include <filesystem>
65
#include <memory>
76
#include <string>
87
#include <utility>
@@ -39,12 +38,6 @@ class FastCodec {
3938
std::vector<uint8_t> token_bytes,
4039
std::vector<int32_t> fast_to_vlm_id, std::string & error);
4140

42-
static std::unique_ptr<FastCodec> load_hf_assets(
43-
const std::filesystem::path & tokenizer_json,
44-
const std::filesystem::path & processor_config_json,
45-
const std::filesystem::path & action_token_map_json,
46-
size_t time_horizon, size_t action_dim, std::string & error);
47-
4841
const FastCodecConfig & config() const;
4942
const std::vector<int32_t> & fast_to_vlm_ids() const;
5043

src/models/starvla/qwen3vl_bridge.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,4 @@ class Qwen3VLBridge {
177177

178178
// Neutral aliases for new callers. The original names remain the ABI/source
179179
// compatibility surface for the completed Qwen3 integrations.
180-
using QwenVLImageView = Qwen3VLImageView;
181-
using QwenVLBridgeConfig = Qwen3VLBridgeConfig;
182-
using QwenVLBridge = Qwen3VLBridge;
183-
184180
} // namespace robotcpp::starvla

src/models/starvla/starvla_engine.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ bool prepare_pi_qwen_images(
342342
} // namespace
343343

344344
struct StarVLAEngine::Impl {
345-
StarVLAEngineConfig options;
346345
StarVLAVariant variant = StarVLAVariant::qwen3_oft;
347346
std::filesystem::path policy_path;
348347
std::filesystem::path text_path;
@@ -376,7 +375,6 @@ std::unique_ptr<StarVLAEngine> StarVLAEngine::load(const StarVLAEngineConfig & c
376375
}
377376

378377
std::unique_ptr<Impl> impl(new Impl());
379-
impl->options = config;
380378
const int effective_threads = config.n_threads > 0 ? config.n_threads : kDefaultThreadCount;
381379
impl->policy_path = std::filesystem::path(config.policy_path);
382380
if (!require_regular_file(impl->policy_path, "policy GGUF", error)) {

tools/hf2gguf/starvla/generate_starvla_groot_golden.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import hashlib
1010
import importlib.metadata
1111
import json
12-
import os
1312
import platform
1413
import random
1514
import shutil
@@ -25,7 +24,7 @@
2524
if str(TOOLS_DIR) not in sys.path:
2625
sys.path.insert(0, str(TOOLS_DIR))
2726

28-
from generate_starvla_pi_v3_golden import ( # noqa: E402
27+
from generate_starvla_pi_v3_golden import ( # noqa: E402,F401
2928
EXPECTED_ACCELERATE_VERSION,
3029
EXPECTED_DIFFUSERS_VERSION,
3130
EXPECTED_NUMPY_VERSION,

tools/hf2gguf/starvla/validate_starvla_bundle.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from __future__ import annotations
55

66
import argparse
7-
import hashlib
87
import json
98
import math
109
import sys
@@ -16,7 +15,6 @@
1615

1716
from convert_starvla_policy_to_gguf import (
1817
GROOT_BLOCK_COUNT,
19-
GROOT_OFFICIAL_DIMENSIONS,
2018
GROOT_OFFICIAL_DIMENSIONS_BY_BACKBONE,
2119
GROOT_POLICY_TENSOR_COUNT,
2220
GROOT_TENSOR_MAP,

0 commit comments

Comments
 (0)