The smallest promotion

This commit is contained in:
firestar5683
2026-08-10 22:53:46 -05:00
parent d938c9daa6
commit 6bd48c28e8
582 changed files with 64651 additions and 17100 deletions
+56 -14
View File
@@ -23,7 +23,8 @@ from openpilot.starpilot.common.model_versions import (
from openpilot.starpilot.common.starpilot_utilities import delete_file
from openpilot.starpilot.common.starpilot_variables import MODELS_PATH
MANIFEST_CANDIDATES = ("v22",)
MANIFEST_CANDIDATES = ("v23",)
MODEL_NAMESPACE_SUFFIX = "3"
DEFAULT_MODEL_KEY = "rdf"
LOCAL_MODEL_PREFIX = "local-"
LOCAL_MODEL_SERIES = "Local Series"
@@ -32,6 +33,9 @@ ARTIFACT_METADATA_CACHE = ".model_artifacts.json"
MODEL_KEY_CANONICAL_MAP = {
"sc": "sc2",
}
LEGACY_DRIVING_PREFIXES = (
"driving_",
)
CANCEL_DOWNLOAD_PARAM = "CancelModelDownload"
DOWNLOAD_PROGRESS_PARAM = "ModelDownloadProgress"
@@ -58,6 +62,11 @@ def is_local_model_key(model_key: str) -> bool:
return canonical_model_key(model_key).startswith(LOCAL_MODEL_PREFIX)
def is_driving_artifact_file(filename: str) -> bool:
"""Match both namespaced unified artifacts and pre-v23 split driving files."""
return "_driving_" in filename or filename.startswith(LEGACY_DRIVING_PREFIXES)
def model_key_aliases(model_key: str) -> list[str]:
canonical_key = canonical_model_key(model_key)
aliases = [canonical_key]
@@ -161,10 +170,7 @@ class ModelManager:
@staticmethod
def _manifest_paths(manifest_version: str) -> tuple[str, ...]:
return (
f"Versions/model_names_{manifest_version}.json",
f"model_names_{manifest_version}.json",
)
return (f"Models/model_names_{manifest_version}.json",)
def _set_model_param_keys(self, model_key: str | None = None, model_name: str | None = None, model_version: str | None = None):
if model_key is not None and model_key != "":
@@ -208,6 +214,18 @@ class ModelManager:
if index < len(self.artifact_formats) and model_key
}
def _resolve_manifest_model_key(self, model_key: str) -> str:
"""Resolve an old manifest ID to its namespaced v23 replacement."""
canonical_key = self._canonical_model_key(model_key)
if canonical_key in self.available_models or is_builtin_model_key(canonical_key):
return canonical_key
for alias in self._model_key_aliases(canonical_key):
candidate = f"{alias}{MODEL_NAMESPACE_SUFFIX}"
if candidate in self.available_models:
return candidate
return canonical_key
def _blacklisted_model_keys(self) -> set[str]:
return {
self._canonical_model_key(entry)
@@ -448,11 +466,11 @@ class ModelManager:
def _remove_stale_model_files(self):
valid_keys = set(self.available_models)
for model_file in MODELS_PATH.glob("*_driving_*"):
model_key = model_file.name.split("_driving_", 1)[0]
if is_local_model_key(model_key):
for model_file in MODELS_PATH.iterdir():
if not model_file.is_file() or not is_driving_artifact_file(model_file.name):
continue
if model_key not in valid_keys:
model_key = model_file.name.split("_driving_", 1)[0] if "_driving_" in model_file.name else ""
if not model_key or not is_local_model_key(model_key) and model_key not in valid_keys:
delete_file(model_file, print_error=False)
for temp_file in MODELS_PATH.glob("tmp*"):
@@ -463,6 +481,17 @@ class ModelManager:
return
selected = self._selected_model()
if is_builtin_model_key(selected):
self._sync_selected_model_version()
return
resolved_selected = self._resolve_manifest_model_key(selected)
if resolved_selected != selected:
selected_index = self.available_models.index(resolved_selected)
selected_name = self.available_model_names[selected_index] if selected_index < len(self.available_model_names) else resolved_selected
self._set_model_param_keys(resolved_selected, selected_name, None)
selected = resolved_selected
aliases = self._model_key_aliases(selected)
if any(alias in self.available_models for alias in aliases):
self._sync_selected_model_version()
@@ -568,14 +597,17 @@ class ModelManager:
def _migrate_to_unified_artifacts(self, selected_model: str):
removed = 0
for model_file in MODELS_PATH.glob("*_driving_*"):
if is_local_model_key(model_file.name.split("_driving_", 1)[0]):
for model_file in MODELS_PATH.iterdir():
if not model_file.is_file() or not is_driving_artifact_file(model_file.name):
continue
model_key = model_file.name.split("_driving_", 1)[0] if "_driving_" in model_file.name else ""
if model_key and is_local_model_key(model_key):
continue
if model_file.is_file() or model_file.is_symlink():
delete_file(model_file, print_error=False)
removed += 1
if removed:
print(f"Removed {removed} incompatible pre-v22 model artifacts.")
print(f"Removed {removed} incompatible model artifacts during manifest migration.")
if selected_model and not is_builtin_model_key(selected_model):
self.params_memory.put(DOWNLOAD_PROGRESS_PARAM, f"Downloading selected model \"{selected_model}\"...")
@@ -618,6 +650,13 @@ class ModelManager:
previous_manifest = self._param_text("ModelManifestVersion")
resolved_manifest = manifest_version or "unknown"
self.update_model_params(model_info, resolved_manifest)
migrated_model = self._resolve_manifest_model_key(selected_model)
if migrated_model != selected_model:
migrated_index = self.available_models.index(migrated_model)
migrated_name = self.available_model_names[migrated_index] if migrated_index < len(self.available_model_names) else migrated_model
migrated_version = self.model_versions[migrated_index] if migrated_index < len(self.model_versions) else ""
self._set_model_param_keys(migrated_model, migrated_name, migrated_version)
selected_model = migrated_model
if previous_manifest != resolved_manifest:
self._migrate_to_unified_artifacts(selected_model)
self.check_models(boot_run)
@@ -762,8 +801,11 @@ class ModelManager:
# This branch ships tinygrad runtime in-tree. "Update" here refreshes local model files.
self.params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Updating...")
for model_file in MODELS_PATH.glob("*_driving_*"):
if is_local_model_key(model_file.name.split("_driving_", 1)[0]):
for model_file in MODELS_PATH.iterdir():
if not model_file.is_file() or not is_driving_artifact_file(model_file.name):
continue
model_key = model_file.name.split("_driving_", 1)[0] if "_driving_" in model_file.name else ""
if model_key and is_local_model_key(model_key):
continue
if model_file.is_file():
delete_file(model_file, print_error=False)
+22 -2
View File
@@ -14,8 +14,28 @@ from openpilot.starpilot.assets.model_manager import MANIFEST_CANDIDATES, ModelM
from openpilot.starpilot.common.model_versions import UNIFIED_ARTIFACT_FORMAT
def test_v22_is_the_only_manifest_candidate():
assert MANIFEST_CANDIDATES == ("v22",)
def test_v23_is_the_only_manifest_candidate():
assert MANIFEST_CANDIDATES == ("v23",)
def test_v23_manifest_is_loaded_from_models_checkout():
assert ModelManager._manifest_paths("v23") == ("Models/model_names_v23.json",)
def test_old_manifest_ids_resolve_to_v23_namespace():
manager = object.__new__(ModelManager)
manager.available_models = ["pop223", "tr14223"]
assert manager._resolve_manifest_model_key("pop22") == "pop223"
assert manager._resolve_manifest_model_key("tr1422") == "tr14223"
assert manager._resolve_manifest_model_key("missing") == "missing"
def test_model_cleanup_matches_legacy_split_artifacts():
assert model_manager.is_driving_artifact_file("pop223_driving_tinygrad.pkl")
assert model_manager.is_driving_artifact_file("driving_vision_tinygrad.pkl")
assert model_manager.is_driving_artifact_file("driving_off_policy_tinygrad.pkl.p00")
assert not model_manager.is_driving_artifact_file("dmonitoring_model_tinygrad.pkl")
assert not model_manager.is_driving_artifact_file("local-test_driving_tinygrad.pkl")
def test_behavior_version_does_not_control_artifact_layout():
+1 -1
View File
@@ -30,7 +30,7 @@ def uses_combined_driving_artifacts(version: str | None) -> bool:
def is_supported_artifact_format(artifact_format: str | None) -> bool:
# v22 manifests are unified by definition. Keep the explicit field optional
# Unified manifests are the default. Keep the explicit field optional
# for compatibility with generated or externally hosted entries.
return str(artifact_format or "").strip() in {"", UNIFIED_ARTIFACT_FORMAT}