From de9cb64165eadff8afaa09f5b5fdce43ef9a4a07 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Fri, 4 Sep 2026 22:47:02 -0500 Subject: [PATCH] Four Score & 7 --- selfdrive/modeld/modeld.py | 10 +++++----- selfdrive/modeld/tests/test_model_laboratory.py | 15 +++++++++------ starpilot/common/model_lab.py | 4 ---- starpilot/common/tests/test_model_lab.py | 5 ++--- .../assets/components/tools/model_laboratory.js | 8 +++----- .../the_galaxy/tests/test_dashboard_stats.py | 10 +++++++--- .../tests/test_frontend_module_graph.py | 3 ++- 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index bb57c2186..f30ccb92e 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -851,18 +851,19 @@ def _isolate_next_model_artifact_load() -> int: def _load_model_lab_models(cam_w: int, cam_h: int, lateral_id: str, longitudinal_id: str, - version: str, CP=None, demo: bool = False) -> tuple[ModelState, ModelState] | None: + lateral_version: str, longitudinal_version: str, + CP=None, demo: bool = False) -> tuple[ModelState, ModelState] | None: try: if not demo: wait_for_external_gpu_power_ready(CP) _set_hcq_wait_timeout(BIG_MODEL_LOAD_WAIT_TIMEOUT_MS) wait_usbgpu_link() _isolate_next_model_artifact_load() - lateral = _load_model_lab_model(cam_w, cam_h, lateral_id, version) + lateral = _load_model_lab_model(cam_w, cam_h, lateral_id, lateral_version) lateral.warmup() evicted = _isolate_next_model_artifact_load() cloudlog.info(f"Model Laboratory isolated {evicted} realized buffer UOps before loading the second model") - longitudinal = _load_model_lab_model(cam_w, cam_h, longitudinal_id, version) + longitudinal = _load_model_lab_model(cam_w, cam_h, longitudinal_id, longitudinal_version) longitudinal.warmup() return lateral, longitudinal except Exception: @@ -906,8 +907,6 @@ def _model_lab_runtime_request(params: Params, chestnut_ready: bool) -> tuple[di return config, f"{role} model {model_id} has no precompiled AMD artifact in the manifest" if not model_accelerator_artifact_installed(model_id): return config, f"{role} model {model_id} AMD artifact is not installed by Model Manager" - if versions[lateral_id] != versions[longitudinal_id]: - return config, "the two models must use the same behavior version" return config, None @@ -1038,6 +1037,7 @@ def main(demo=False): lateral_id, longitudinal_id, versions[lateral_id], + versions[longitudinal_id], CP, demo, ) diff --git a/selfdrive/modeld/tests/test_model_laboratory.py b/selfdrive/modeld/tests/test_model_laboratory.py index 7c5274e59..8230105ed 100644 --- a/selfdrive/modeld/tests/test_model_laboratory.py +++ b/selfdrive/modeld/tests/test_model_laboratory.py @@ -21,10 +21,10 @@ class FakeParams: self.values[key] = value -def test_runtime_request_accepts_only_two_ready_small_same_version_models(tmp_path, monkeypatch): +def test_runtime_request_accepts_two_ready_small_mixed_version_models(tmp_path, monkeypatch): config = {"enabled": True, "lateralModel": "lat", "longitudinalModel": "long"} params = FakeParams(config) - (tmp_path / ".model_versions.json").write_text(json.dumps({"lat": "v15", "long": "v15"})) + (tmp_path / ".model_versions.json").write_text(json.dumps({"lat": "v15", "long": "v9"})) (tmp_path / "lat_driving_tinygrad.pkl").write_bytes(b"lat") (tmp_path / "long_driving_tinygrad.pkl").write_bytes(b"long") monkeypatch.setattr(modeld, "MODELS_PATH", tmp_path) @@ -53,9 +53,12 @@ def test_runtime_request_revalidates_hardware_version_and_size(tmp_path, monkeyp monkeypatch.setattr(modeld, "model_accelerator_artifact_installed", lambda _model_id: True) assert "Chestnut" in modeld._model_lab_runtime_request(params, chestnut_ready=False)[1] - assert "same behavior version" in modeld._model_lab_runtime_request(params, chestnut_ready=True)[1] + assert modeld._model_lab_runtime_request(params, chestnut_ready=True)[1] is None - (tmp_path / ".model_versions.json").write_text(json.dumps({"lat": "v15", "long": "v15"})) + (tmp_path / ".model_versions.json").write_text(json.dumps({"lat": "v15", "long": "v7"})) + assert "compatible small model" in modeld._model_lab_runtime_request(params, chestnut_ready=True)[1] + + (tmp_path / ".model_versions.json").write_text(json.dumps({"lat": "v15", "long": "v9"})) monkeypatch.setattr( modeld, "load_model_artifact_metadata", @@ -127,7 +130,7 @@ def test_model_lab_loads_and_warms_both_amd_models_before_returning(monkeypatch) lambda _w, _h, model_id, version: calls.append(("load", model_id, version)) or FakeModel(model_id), ) - pair = modeld._load_model_lab_models(1928, 1208, "lat", "long", "v15", "car-params") + pair = modeld._load_model_lab_models(1928, 1208, "lat", "long", "v15", "v9", "car-params") assert [model.model_id for model in pair] == ["lat", "long"] assert calls == [ @@ -138,7 +141,7 @@ def test_model_lab_loads_and_warms_both_amd_models_before_returning(monkeypatch) ("load", "lat", "v15"), ("warmup", "lat"), "isolate_buffers", - ("load", "long", "v15"), + ("load", "long", "v9"), ("warmup", "long"), "close_cache", ("timeout", modeld.BIG_MODEL_RUN_WAIT_TIMEOUT_MS), diff --git a/starpilot/common/model_lab.py b/starpilot/common/model_lab.py index 0c8135fdf..d4fee326f 100644 --- a/starpilot/common/model_lab.py +++ b/starpilot/common/model_lab.py @@ -124,10 +124,6 @@ def validate_model_lab_selection( if require_installed and not bool(model.get("modelLabArtifactInstalled", False)): return f"{role} model '{model_id}' has not downloaded its precompiled AMD artifact." - lateral_version = str(catalog[lateral_id].get("version") or "").strip() - longitudinal_version = str(catalog[longitudinal_id].get("version") or "").strip() - if lateral_version != longitudinal_version: - return "Choose models from the same behavior version; the longitudinal planner currently has one shared version contract." return None diff --git a/starpilot/common/tests/test_model_lab.py b/starpilot/common/tests/test_model_lab.py index 48ab94e49..b9c922ab2 100644 --- a/starpilot/common/tests/test_model_lab.py +++ b/starpilot/common/tests/test_model_lab.py @@ -56,7 +56,6 @@ def test_config_normalization_is_closed_by_default(): (True, {"lat": _catalog_model(small=False), "long": _catalog_model()}, "lat", "long", "Chestnut-class"), (True, {"lat": _catalog_model(artifact_available=False), "long": _catalog_model()}, "lat", "long", "no precompiled AMD"), (True, {"lat": _catalog_model(artifact_installed=False), "long": _catalog_model()}, "lat", "long", "not downloaded"), - (True, {"lat": _catalog_model("v15"), "long": _catalog_model("v9")}, "lat", "long", "same behavior version"), ], ) def test_selection_validation_rejects_unsafe_pairs(chestnut_ready, catalog, lateral, longitudinal, expected): @@ -68,8 +67,8 @@ def test_selection_validation_rejects_unsafe_pairs(chestnut_ready, catalog, late assert expected in error -def test_selection_validation_accepts_distinct_ready_small_same_version_models(): - catalog = {"lat": _catalog_model(), "long": _catalog_model()} +def test_selection_validation_accepts_distinct_ready_small_mixed_version_models(): + catalog = {"lat": _catalog_model("v15"), "long": _catalog_model("v9")} assert validate_model_lab_selection( {"enabled": True, "lateralModel": "lat", "longitudinalModel": "long"}, catalog, diff --git a/starpilot/system/the_galaxy/assets/components/tools/model_laboratory.js b/starpilot/system/the_galaxy/assets/components/tools/model_laboratory.js index 8efb23c11..cdce53bde 100644 --- a/starpilot/system/the_galaxy/assets/components/tools/model_laboratory.js +++ b/starpilot/system/the_galaxy/assets/components/tools/model_laboratory.js @@ -35,7 +35,7 @@ function candidateModels(role) { if (role !== "longitudinal") return ready const lateral = modelById(state.configuration.lateralModel) if (!lateral) return ready - return ready.filter(model => model.value !== lateral.value && model.version === lateral.version) + return ready.filter(model => model.value !== lateral.value) } function selectionError() { @@ -51,7 +51,6 @@ function selectionError() { if (!lateral.modelLabArtifactInstalled || !longitudinal.modelLabArtifactInstalled) { return "Prepare both precompiled AMD artifacts first." } - if (lateral.version !== longitudinal.version) return "Both models must use the same behavior version." return "" } @@ -78,8 +77,7 @@ function applyPayload(payload) { } if (!modelById(state.configuration.longitudinalModel) && ready.length > 1) { state.configuration.longitudinalModel = ready.find(model => ( - model.value !== state.configuration.lateralModel && - model.version === modelById(state.configuration.lateralModel)?.version + model.value !== state.configuration.lateralModel ))?.value || "" } } @@ -178,7 +176,7 @@ function bindControls() { state.configuration.lateralModel = event.target.value const long = modelById(state.configuration.longitudinalModel) const lat = modelById(event.target.value) - if (long && lat && (long.value === lat.value || long.version !== lat.version)) { + if (long && lat && long.value === lat.value) { state.configuration.longitudinalModel = candidateModels("longitudinal")[0]?.value || "" if (longitudinal) longitudinal.value = state.configuration.longitudinalModel } diff --git a/starpilot/system/the_galaxy/tests/test_dashboard_stats.py b/starpilot/system/the_galaxy/tests/test_dashboard_stats.py index b1c75e8aa..244c692e9 100644 --- a/starpilot/system/the_galaxy/tests/test_dashboard_stats.py +++ b/starpilot/system/the_galaxy/tests/test_dashboard_stats.py @@ -1854,13 +1854,17 @@ def test_model_laboratory_api_uses_installed_models_and_enforces_hardware_size_v assert params.values["Model"] == params.values["DrivingModel"] == "lat" assert params.values["ModelVersion"] == params.values["DrivingModelVersion"] == "v15" - mismatched = client.put("/api/model-laboratory", json={ + mixed_version = client.put("/api/model-laboratory", json={ "enabled": True, "lateralModel": "lat", "longitudinalModel": "old", }) - assert mismatched.status_code == 409 - assert "same behavior version" in mismatched.get_json()["error"] + assert mixed_version.status_code == 200 + assert params.values["ModelLabConfig"] == { + "enabled": True, + "lateralModel": "lat", + "longitudinalModel": "old", + } oversized = client.put("/api/model-laboratory", json={ "enabled": True, diff --git a/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py b/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py index 7b9c2866e..bfee7245c 100644 --- a/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py +++ b/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py @@ -119,6 +119,7 @@ def test_model_laboratory_frontend_exposes_guards_and_role_copy(): assert "model.modelLabArtifactInstalled" in source assert "Nothing is compiled on the comma" in source assert "run every camera frame on Chestnut's AMD GPU" in source - assert 'lateral.version !== longitudinal.version' in source + assert 'lateral.value === longitudinal.value' in source + assert 'lateral.version !== longitudinal.version' not in source assert "Path shape, curvature, lane geometry" in source assert "Speed, acceleration, stopping, leads" in source