mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 08:14:00 +08:00
The smallest promotion
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user