feat(perception): add PointPillars transfer gate

This commit is contained in:
DCCONSTRUCTIONS
2026-07-31 10:48:27 +03:00
parent 29fee5c0ac
commit a9a5ca5a26
23 changed files with 5407 additions and 0 deletions
@@ -0,0 +1,67 @@
{
"datasets": [
{
"annotations": [
"point-semantic-labels",
"point-instance-labels"
],
"dataset_id": "goose-3d/v2025-08-22",
"independent_ground_truth": true,
"installed": true,
"license": "CC-BY-SA-4.0",
"point_fields": [
"x",
"y",
"z",
"intensity"
],
"release_identity_sha256": "0be9e0f8459bafcbc92ff7c3cc366e9b4e2f6e1e9bdf50e6439e1557e864c26f",
"splits": [
"validation"
]
},
{
"annotations": [
"point-semantic-labels",
"point-instance-labels"
],
"dataset_id": "rellis-3d/v1.1",
"independent_ground_truth": true,
"installed": true,
"license": "CC-BY-NC-SA-3.0",
"point_fields": [
"x",
"y",
"z",
"intensity"
],
"release_identity_sha256": "a3f3f161a5a7edccdf66cea75ecf9004b8f6a895282faabe661c075c15a82774",
"splits": [
"train",
"validation",
"test"
]
},
{
"annotations": [
"oriented-3d-boxes"
],
"dataset_id": "kitti-3d-object/v2017",
"independent_ground_truth": true,
"installed": true,
"license": "CC-BY-NC-SA-3.0",
"point_fields": [
"x",
"y",
"z",
"intensity"
],
"release_identity_sha256": "2c9615bedca56b492b204b614d4419db6431626e2a6867e207a95999beefcf47",
"splits": [
"validation"
]
}
],
"observed_at_utc": "2026-07-31T06:45:42.249612Z",
"schema_version": "missioncore.l3-lidar-dataset-inventory/v1"
}
@@ -0,0 +1,139 @@
{
"authority": {
"commands_enabled": false,
"navigation_or_safety_accepted": false,
"shadow_only": true
},
"detector": {
"batch_size": 1,
"candidate_frozen": true,
"candidate_model_version": "deployable_v1.1",
"candidate_label_sha256": "0adaeb5a374421b61bf83b8fa4522e11abd68461f239a4c72cf5627de913b3da",
"candidate_source_sha256": "2dcabddc3a365e9608a112d7bbbb7db769a6dddeeaa59aa03611a83113326da1",
"model_classes": [
"Vehicle",
"Pedestrian",
"Cyclist"
],
"onnx_contract_sha256": "2fd29cd054ab058c2cfec3dfba305c71e123ef3f04b457d0c64de0c8dac2e1be",
"family": "nvidia-tao-pointpillars",
"input_coordinate_frame": "sensor/lidar",
"input_fields": [
"x",
"y",
"z",
"intensity"
],
"input_representation": "native-sensor-scan",
"maximum_points": 204800,
"point_cloud_range": [
-51.20000076293945,
-51.20000076293945,
-1.399999976158142,
51.20000076293945,
51.20000076293945,
4.400000095367432
],
"postprocessing": {
"class_agnostic_nms": true,
"embedded_contract_source": "onnx-node-attributes",
"embedded_score_threshold": 0.1,
"nms_iou_threshold": 0.01,
"output_row_fields": [
"x",
"y",
"z",
"length",
"width",
"height",
"yaw",
"class_id",
"score"
],
"pre_nms_top_n": 4096,
"reference_commit": "a540badc47812a17a94e924b537d49ad3969b5a8",
"reference_repository": "https://github.com/NVIDIA-AI-IOT/tao_toolkit_recipes"
},
"required_source_format": "onnx",
"training_domain": "proprietary-solid-state-lidar",
"training_ground_truth_publicly_reproducible": false,
"triton_model_name": "pointpillars",
"upstream_model_id": "nvidia/tao/pointpillarnet"
},
"k1_transfer_stability": {
"accuracy_claim_allowed": false,
"metrics": [
"input-admission-rate",
"output-schema-valid-rate",
"deterministic-replay-rate",
"end-to-end-latency-ms",
"queue-wait-ms",
"drop-rate"
],
"requires_completed_public_cross_domain_probe": true,
"retuning_allowed": false
},
"public_cross_domain_probe": {
"benchmark_classes": [
"Car",
"Pedestrian",
"Cyclist"
],
"independent_ground_truth_required": true,
"metrics": [
"bev-map",
"3d-map",
"center-error-m",
"range-error-m",
"yaw-error-rad",
"distance-bucket-recall",
"false-occupied-rate",
"end-to-end-latency-ms"
],
"metric_contract": {
"ap_interpolation": "40-point",
"difficulty_filtering": false,
"distance_buckets_m": [
[
0,
20
],
[
20,
40
],
[
40,
70
]
],
"iou_thresholds": {
"Car": 0.7,
"Cyclist": 0.5,
"Pedestrian": 0.5
},
"evaluation_kind": "public-cross-domain-transfer-probe",
"official_kitti_server_metric": false,
"predictions_outside_shared_range_ignored": true
},
"model_to_benchmark_class_mapping": {
"Cyclist": "Cyclist",
"Pedestrian": "Pedestrian",
"Vehicle": "Car"
},
"native_accuracy_claim_allowed": false,
"required_ground_truth": "oriented-3d-boxes",
"required_split": "validation",
"retuning_allowed": false
},
"profile_id": "l3-pointpillars-public-transfer-probe-v1",
"runtime_policy": {
"engine_built_on_target_required": true,
"existing_triton_only": true,
"precision": "strongly-typed",
"second_serving_stack_allowed": false,
"triton_image": "nvcr.io/nvidia/tritonserver:26.06-py3",
"triton_image_digest": "58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794"
},
"schema_version": "missioncore.l3-pointpillars-benchmark-profile/v1"
}
@@ -0,0 +1,125 @@
{
"schema_version": "missioncore.l3-pointpillars-onnx-contract/v1",
"source": {
"model_id": "nvidia/tao/pointpillarnet",
"model_version": "deployable_v1.1",
"onnx_sha256": "2dcabddc3a365e9608a112d7bbbb7db769a6dddeeaa59aa03611a83113326da1"
},
"extraction": {
"onnx_version": "1.22.0",
"method": "read-only ONNX graph attribute inspection",
"observed_at_utc": "2026-07-31T07:16:00Z"
},
"inputs": [
{
"dtype": "FP32",
"name": "points",
"shape": [
"batch",
204800,
4
]
},
{
"dtype": "INT32",
"name": "num_points",
"shape": [
"batch"
]
}
],
"outputs": [
{
"dtype": "FP32",
"name": "output_boxes",
"shape": [
"batch",
393216,
9
]
},
{
"dtype": "INT32",
"name": "num_boxes",
"shape": [
"batch"
]
}
],
"plugins": {
"DecodeBbox3DPlugin": {
"anchor_bottom_height": [
-1.7799999713897705,
-0.6000000238418579,
-0.6000000238418579
],
"anchors": [
3.9000000953674316,
1.600000023841858,
1.559999942779541,
0.0,
3.9000000953674316,
1.600000023841858,
1.559999942779541,
1.5700000524520874,
0.800000011920929,
0.6000000238418579,
1.7300000190734863,
0.0,
0.800000011920929,
0.6000000238418579,
1.7300000190734863,
1.5700000524520874,
1.7599999904632568,
0.6000000238418579,
1.7300000190734863,
0.0,
1.7599999904632568,
0.6000000238418579,
1.7300000190734863,
1.5700000524520874
],
"dir_limit_offset": 0.0,
"dir_offset": 0.7853900194168091,
"num_dir_bins": 2,
"point_cloud_range": [
-51.20000076293945,
-51.20000076293945,
-1.399999976158142,
51.20000076293945,
51.20000076293945,
4.400000095367432
],
"score_threshold": 0.10000000149011612
},
"PillarScatterPlugin": {
"dense_shape": [
512,
512
]
},
"VoxelGeneratorPlugin": {
"max_num_points_per_voxel": 32,
"max_voxels": 10000,
"point_cloud_range": [
-51.20000076293945,
-51.20000076293945,
-1.399999976158142,
51.20000076293945,
51.20000076293945,
4.400000095367432
],
"voxel_feature_num": 10,
"voxel_size": [
0.20000000298023224,
0.20000000298023224,
5.800000190734863
]
}
},
"claim_boundary": {
"model_card_training_domain": "proprietary-solid-state-lidar",
"public_training_truth_available": false,
"public_kitti_is_cross_domain": true
}
}
@@ -0,0 +1,163 @@
{
"gpu": {
"driver_version": "610.47",
"memory_total_mib": 24564,
"name": "NVIDIA GeForce RTX 4090"
},
"host_id": "worker-006",
"observed_at_utc": "2026-07-31T06:50:46.660883Z",
"schema_version": "missioncore.l3-worker-inventory/v1",
"serving_stack_count": 1,
"staged_models": [
{
"artifact_sha256": "12005d972a4632d56342a5da44442b632c1dcc5144fa3c70b162dec334532481",
"backend": "tensorrt",
"model_classes": [
"Vehicle",
"Pedestrian",
"Cyclist"
],
"engine_built_on_target": true,
"input_fields": [
"x",
"y",
"z",
"intensity"
],
"maximum_points": 204800,
"name": "pointpillars",
"outputs": [
{
"dtype": "FP32",
"name": "output_boxes",
"shape": [
1,
393216,
9
]
},
{
"dtype": "INT32",
"name": "num_boxes",
"shape": [
1
]
}
],
"point_cloud_range": [
-51.20000076293945,
-51.20000076293945,
-1.399999976158142,
51.20000076293945,
51.20000076293945,
4.400000095367432
],
"precision": "strongly-typed",
"provenance_verified": true,
"representation_smoke": {
"accuracy_evaluated": false,
"input_artifact_sha256": "95be16aec8496260ec25ff716c79d343a3fd9e3f4957df99bb8007c6b21c9f59",
"input_point_count": 169883,
"navigation_or_safety_accepted": false,
"single_query_gpu_compute_ms": 55.2069,
"source_frame_id": "2022-07-22_flight__0071_1658494234334310308",
"source_id": "goose-3d/v2025-08-22",
"status": "engine-executed"
},
"source_format": "onnx",
"source_label_sha256": "0adaeb5a374421b61bf83b8fa4522e11abd68461f239a4c72cf5627de913b3da",
"source_model_sha256": "2dcabddc3a365e9608a112d7bbbb7db769a6dddeeaa59aa03611a83113326da1",
"upstream_version": "deployable_v1.1"
}
],
"triton": {
"container_name": "ndc-mission-core-triton",
"healthy": true,
"image": "nvcr.io/nvidia/tritonserver:26.06-py3",
"image_digest": "58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794",
"model_control_mode": "explicit",
"model_repository_read_only": true,
"models": [
{
"artifact_sha256": "c5c2d13e59ae883e6af3b45daea64af4833a4951c92d116ec270d9ddbe998063",
"backend": "onnxruntime",
"name": "yolox_s"
},
{
"artifact_sha256": "12005d972a4632d56342a5da44442b632c1dcc5144fa3c70b162dec334532481",
"backend": "tensorrt",
"engine_built_on_target": true,
"input_fields": [
"x",
"y",
"z",
"intensity"
],
"live_schema_smoke": {
"accuracy_evaluated": false,
"inference_ms": 106.79901000548853,
"input_artifact_sha256": "59a02fdaaab3b7e903713cb618e8f53efcaf71c144436ddfcdf4f28bdbd73d20",
"input_point_count": 120268,
"observed_model_classes": [
"Cyclist",
"Vehicle"
],
"output_box_count": 58,
"source_frame_id": "000001",
"source_id": "kitti-3d-object/v2017",
"status": "engine-schema-executed"
},
"maximum_points": 204800,
"model_classes": [
"Vehicle",
"Pedestrian",
"Cyclist"
],
"name": "pointpillars",
"outputs": [
{
"dtype": "FP32",
"name": "output_boxes",
"shape": [
1,
393216,
9
]
},
{
"dtype": "INT32",
"name": "num_boxes",
"shape": [
1
]
}
],
"point_cloud_range": [
-51.20000076293945,
-51.20000076293945,
-1.399999976158142,
51.20000076293945,
51.20000076293945,
4.400000095367432
],
"precision": "strongly-typed",
"provenance_verified": true,
"representation_smoke": {
"accuracy_evaluated": false,
"input_artifact_sha256": "95be16aec8496260ec25ff716c79d343a3fd9e3f4957df99bb8007c6b21c9f59",
"input_point_count": 169883,
"navigation_or_safety_accepted": false,
"single_query_gpu_compute_ms": 55.2069,
"source_frame_id": "2022-07-22_flight__0071_1658494234334310308",
"source_id": "goose-3d/v2025-08-22",
"status": "engine-executed"
},
"source_format": "onnx",
"source_label_sha256": "0adaeb5a374421b61bf83b8fa4522e11abd68461f239a4c72cf5627de913b3da",
"source_model_sha256": "2dcabddc3a365e9608a112d7bbbb7db769a6dddeeaa59aa03611a83113326da1",
"upstream_version": "deployable_v1.1"
}
],
"strict_readiness": true
}
}
@@ -0,0 +1,312 @@
#!/usr/bin/env python3
"""Build the minimal immutable L3 PointPillars package for Worker 006."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import shutil
import uuid
from datetime import UTC, datetime
from pathlib import Path
from typing import Any
SCHEMA = "missioncore.l3-pointpillars-worker-package/v1"
_SOURCE_FILES = {
"runtime/k1link/__init__.py": "src/k1link/__init__.py",
"runtime/k1link/artifacts.py": "src/k1link/artifacts.py",
"runtime/k1link/compute/kitti_pointpillars_benchmark.py": (
"src/k1link/compute/kitti_pointpillars_benchmark.py"
),
"runtime/k1link/compute/l3_pointpillars_admission.py": (
"src/k1link/compute/l3_pointpillars_admission.py"
),
"runtime/k1link/compute/pointpillars_postprocess.py": (
"src/k1link/compute/pointpillars_postprocess.py"
),
"runtime/k1link/datasets/kitti_3d_admission.py": (
"src/k1link/datasets/kitti_3d_admission.py"
),
"runtime/install_l3_pointpillars_triton_model.py": (
"experiments/perception/worker/install_l3_pointpillars_triton_model.py"
),
"runtime/admit_l3_kitti_release.py": (
"experiments/perception/worker/admit_l3_kitti_release.py"
),
"runtime/run_l3_pointpillars_admission.py": (
"experiments/perception/run_l3_pointpillars_admission.py"
),
"runtime/run_l3_pointpillars_public_baseline.py": (
"experiments/perception/worker/run_l3_pointpillars_public_baseline.py"
),
"runtime/smoke_l3_pointpillars_live.py": (
"experiments/perception/worker/smoke_l3_pointpillars_live.py"
),
}
_GENERATED_FILES = {
"runtime/k1link/compute/__init__.py": (
'"""Minimal L3 worker projection; import compute modules explicitly."""\n'
),
"runtime/k1link/datasets/__init__.py": (
'"""Minimal L3 worker projection; import KITTI admission explicitly."""\n'
),
}
_INPUT_FILES = {
"input/profile.json": "experiments/perception/l3_pointpillars_benchmark_profile.json",
"input/onnx-contract.json": (
"experiments/perception/l3_pointpillars_onnx_contract_2026-07-31.json"
),
"input/dataset-inventory.json": (
"experiments/perception/l3_dataset_inventory_2026-07-30.json"
),
"input/worker-inventory.json": (
"experiments/perception/l3_worker_inventory_2026-07-30.json"
),
"input/triton/config.pbtxt": "experiments/perception/triton/pointpillars/config.pbtxt",
}
class L3WorkerPackageError(RuntimeError):
"""The L3 worker package source or immutable package is invalid."""
def build_l3_worker_package(
*,
repository_root: Path,
output_root: Path,
admission_result: Path | None = None,
) -> Path:
"""Build or reopen a content-addressed minimal Worker 006 runtime."""
repository = repository_root.resolve(strict=True)
sources: dict[str, Path | None] = {
target: repository / relative for target, relative in _SOURCE_FILES.items()
}
sources.update(
{
target: repository / relative
for target, relative in _INPUT_FILES.items()
}
)
sources.update({target: None for target in _GENERATED_FILES})
if admission_result is not None:
result = admission_result.resolve(strict=True)
if not result.is_dir() or result.is_symlink():
raise L3WorkerPackageError("L3 admission result root is invalid")
admission_root = f"input/admission/{result.name}"
sources[f"{admission_root}/manifest.json"] = result / "manifest.json"
sources[f"{admission_root}/admission-report.json"] = (
result / "admission-report.json"
)
descriptors: list[dict[str, Any]] = []
for relative, source in sorted(sources.items()):
payload = _payload(relative, source)
descriptors.append(
{
"path": relative,
"byte_length": len(payload),
"sha256": hashlib.sha256(payload).hexdigest(),
}
)
identity = {
"schema_version": SCHEMA,
"classification": "minimal-l3-pointpillars-worker-runtime",
"worker_host_id": "worker-006",
"source_artifacts": descriptors,
"artifact_paths": [row["path"] for row in descriptors],
"execution_policy": {
"sequential": True,
"parallel_workers": 1,
"existing_triton_only": True,
"container_creation_allowed": False,
"container_restart_allowed": False,
"raw_tensor_export_allowed": False,
},
"authority": {
"shadow_only": True,
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
identity_sha256 = hashlib.sha256(_canonical_json(identity)).hexdigest()
package_id = f"l3-pointpillars-worker-package-{identity_sha256}"
output = output_root.expanduser().absolute()
output.mkdir(mode=0o700, parents=True, exist_ok=True)
destination = output / package_id
if destination.exists():
validate_l3_worker_package(destination)
return destination
staging = output / f".{package_id}.{uuid.uuid4().hex}.tmp"
staging.mkdir(mode=0o700, exist_ok=False)
try:
for relative, source in sources.items():
target = staging / relative
target.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
if source is None:
target.write_text(_GENERATED_FILES[relative], encoding="utf-8")
else:
shutil.copyfile(source, target)
artifacts = [
{
"kind": relative,
"path": relative,
"byte_length": (staging / relative).stat().st_size,
"sha256": _sha256(staging / relative),
}
for relative in sorted(sources)
]
manifest = {
"schema_version": SCHEMA,
"package_id": package_id,
"identity_sha256": identity_sha256,
"identity": identity,
"created_at_utc": datetime.now(UTC)
.isoformat(timespec="milliseconds")
.replace("+00:00", "Z"),
"artifacts": artifacts,
}
_write_json(staging / "manifest.json", manifest)
validate_l3_worker_package(staging, allow_staging=True)
os.replace(staging, destination)
except BaseException:
shutil.rmtree(staging, ignore_errors=True)
raise
validate_l3_worker_package(destination)
return destination
def validate_l3_worker_package(
root: Path,
*,
allow_staging: bool = False,
) -> dict[str, Any]:
"""Validate package identity, exact file set, and every member digest."""
resolved = root.resolve(strict=True)
manifest = _read_json(resolved / "manifest.json")
identity = manifest.get("identity")
identity_sha256 = manifest.get("identity_sha256")
package_id = manifest.get("package_id")
artifacts = manifest.get("artifacts")
expected_name = (
isinstance(package_id, str)
and (
resolved.name == package_id
or (
allow_staging
and resolved.name.startswith(f".{package_id}.")
and resolved.name.endswith(".tmp")
)
)
)
if (
manifest.get("schema_version") != SCHEMA
or not isinstance(identity, dict)
or not isinstance(identity_sha256, str)
or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
or package_id != f"l3-pointpillars-worker-package-{identity_sha256}"
or not expected_name
or not isinstance(artifacts, list)
):
raise L3WorkerPackageError("L3 worker package identity is invalid")
expected_paths = set(identity.get("artifact_paths", []))
actual_paths = {
path.relative_to(resolved).as_posix()
for path in resolved.rglob("*")
if path.is_file()
}
if (
not expected_paths
or actual_paths != expected_paths | {"manifest.json"}
or len(artifacts) != len(expected_paths)
):
raise L3WorkerPackageError("L3 worker package file set changed")
observed: set[str] = set()
for row in artifacts:
if not isinstance(row, dict):
raise L3WorkerPackageError("L3 worker package artifact is invalid")
relative = row.get("path")
path = resolved / str(relative)
if (
not isinstance(relative, str)
or relative not in expected_paths
or relative in observed
or Path(relative).is_absolute()
or ".." in Path(relative).parts
or not path.is_file()
or path.is_symlink()
or row.get("kind") != relative
or row.get("byte_length") != path.stat().st_size
or row.get("sha256") != _sha256(path)
):
raise L3WorkerPackageError("L3 worker package artifact changed")
observed.add(relative)
if observed != expected_paths:
raise L3WorkerPackageError("L3 worker package artifact coverage changed")
return manifest
def _payload(relative: str, source: Path | None) -> bytes:
if source is None:
return _GENERATED_FILES[relative].encode()
if not source.is_file() or source.is_symlink():
raise L3WorkerPackageError(f"L3 package source is invalid: {relative}")
return source.read_bytes()
def _canonical_json(value: object) -> bytes:
return json.dumps(
value,
sort_keys=True,
separators=(",", ":"),
allow_nan=False,
).encode()
def _sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while chunk := stream.read(1024 * 1024):
digest.update(chunk)
return digest.hexdigest()
def _read_json(path: Path) -> dict[str, Any]:
try:
value = json.loads(path.read_text(encoding="utf-8-sig"))
except (OSError, json.JSONDecodeError) as exc:
raise L3WorkerPackageError("L3 worker package manifest is invalid") from exc
if not isinstance(value, dict):
raise L3WorkerPackageError("L3 worker package manifest is invalid")
return value
def _write_json(path: Path, value: object) -> None:
with path.open("x", encoding="utf-8", newline="\n") as stream:
json.dump(value, stream, indent=2, sort_keys=True)
stream.write("\n")
stream.flush()
os.fsync(stream.fileno())
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--repository-root", type=Path, required=True)
parser.add_argument("--output-root", type=Path, required=True)
parser.add_argument("--admission-result", type=Path)
args = parser.parse_args()
package = build_l3_worker_package(
repository_root=args.repository_root,
output_root=args.output_root,
admission_result=args.admission_result,
)
print(package)
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,49 @@
#!/usr/bin/env python3
"""Build the immutable L3 NVIDIA PointPillars benchmark admission."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from k1link.compute.l3_pointpillars_admission import (
build_l3_pointpillars_admission,
)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--profile", type=Path, required=True)
parser.add_argument("--dataset-inventory", type=Path, required=True)
parser.add_argument("--worker-inventory", type=Path, required=True)
parser.add_argument(
"--output-root",
type=Path,
default=Path(".runtime/compute-experiments/l3/pointpillars-admissions"),
)
args = parser.parse_args()
result = build_l3_pointpillars_admission(
profile_path=args.profile,
dataset_inventory_path=args.dataset_inventory,
worker_inventory_path=args.worker_inventory,
output_root=args.output_root,
)
print(
json.dumps(
{
"result_id": result.result_id,
"result_root": str(result.result_root),
"status": result.report["status"],
"blocker_codes": result.report["blocker_codes"],
"next_gate": result.report["next_gate"],
},
ensure_ascii=False,
sort_keys=True,
)
)
return 0 if result.public_transfer_probe_authorized else 3
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,42 @@
name: "pointpillars"
platform: "tensorrt_plan"
max_batch_size: 0
input [
{
name: "points"
data_type: TYPE_FP32
dims: [1, 204800, 4]
},
{
name: "num_points"
data_type: TYPE_INT32
dims: [1]
}
]
output [
{
name: "output_boxes"
data_type: TYPE_FP32
dims: [1, 393216, 9]
},
{
name: "num_boxes"
data_type: TYPE_INT32
dims: [1]
}
]
instance_group [
{
count: 1
kind: KIND_GPU
}
]
version_policy {
specific {
versions: 1
}
}
@@ -0,0 +1,45 @@
#!/usr/bin/env python3
"""Admit the canonical archive-only KITTI release on Worker 006."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from k1link.datasets.kitti_3d_admission import (
admit_kitti_3d_object_release,
)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
"--dataset-root",
type=Path,
default=Path("/mnt/d/NDC_MISSIONCORE/datasets"),
)
args = parser.parse_args()
result = admit_kitti_3d_object_release(args.dataset_root)
print(
json.dumps(
{
"source_id": result["source_id"],
"status": result["status"],
"release_identity_sha256": result["release_identity_sha256"],
"training_frame_count": result["alignment"][
"training_frame_count"
],
"validation_frame_count": result["alignment"]["split_counts"][
"validation"
],
"next_action": result["next_action"],
},
sort_keys=True,
)
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,244 @@
#!/usr/bin/env python3
"""Promote the verified PointPillars engine into canonical Triton exactly once."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import shutil
import tempfile
import urllib.request
from contextlib import suppress
from datetime import UTC, datetime
from pathlib import Path
from typing import Any
from k1link.compute.l3_pointpillars_admission import (
read_l3_pointpillars_admission,
)
PROVENANCE_SCHEMA = "missioncore.triton-model-provenance/v1"
MODEL_NAME = "pointpillars"
EXPECTED_ENGINE_SHA256 = (
"12005d972a4632d56342a5da44442b632c1dcc5144fa3c70b162dec334532481"
)
EXPECTED_ENGINE_BYTES = 8_785_436
EXPECTED_CONFIG_SHA256 = (
"a68e7e37ae611b7d4c3fb633b31360ddbdf26ab0a37a363cc566357e614a385c"
)
EXPECTED_SOURCE_SHA256 = (
"2dcabddc3a365e9608a112d7bbbb7db769a6dddeeaa59aa03611a83113326da1"
)
EXPECTED_LABEL_SHA256 = (
"0adaeb5a374421b61bf83b8fa4522e11abd68461f239a4c72cf5627de913b3da"
)
CANONICAL_MODEL_REPOSITORY = Path("/mnt/d/NDC_MISSIONCORE/runtime/models")
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--admission-result", type=Path, required=True)
parser.add_argument("--engine", type=Path, required=True)
parser.add_argument("--config", type=Path, required=True)
parser.add_argument(
"--model-repository",
type=Path,
default=CANONICAL_MODEL_REPOSITORY,
)
parser.add_argument("--triton-url", default="http://127.0.0.1:8000")
args = parser.parse_args()
admission = read_l3_pointpillars_admission(args.admission_result)
if (
admission.report.get("status") != "blocked-foundation-assets"
or admission.report.get("blocker_codes")
!= ["pointpillars-model-not-installed-live"]
or admission.report.get("eligible_public_probe_dataset_ids")
!= ["kitti-3d-object/v2017"]
or admission.report.get("detector", {}).get("staged_target_engine_ready")
is not True
):
raise RuntimeError(
"L3 admission does not authorize canonical PointPillars promotion"
)
engine = args.engine.resolve(strict=True)
config = args.config.resolve(strict=True)
if engine.stat().st_size != EXPECTED_ENGINE_BYTES or _sha256(
engine
) != EXPECTED_ENGINE_SHA256:
raise RuntimeError("PointPillars target engine identity changed")
if _sha256(config) != EXPECTED_CONFIG_SHA256:
raise RuntimeError("PointPillars Triton configuration identity changed")
repository = args.model_repository.expanduser().absolute()
if repository != CANONICAL_MODEL_REPOSITORY or not repository.is_dir():
raise RuntimeError("PointPillars promotion requires the canonical model repository")
destination = repository / MODEL_NAME
if destination.exists():
_validate_existing(destination)
_require_model_ready(args.triton_url)
print(
json.dumps(
{"status": "already-installed", "model": MODEL_NAME},
sort_keys=True,
)
)
return 0
provenance = {
"schema_version": PROVENANCE_SCHEMA,
"model_name": MODEL_NAME,
"upstream_model_id": "nvidia/tao/pointpillarnet",
"upstream_version": "deployable_v1.1",
"source_format": "onnx",
"source_model_sha256": EXPECTED_SOURCE_SHA256,
"source_label_sha256": EXPECTED_LABEL_SHA256,
"engine_sha256": EXPECTED_ENGINE_SHA256,
"engine_byte_length": EXPECTED_ENGINE_BYTES,
"config_sha256": EXPECTED_CONFIG_SHA256,
"engine_built_on_target": True,
"worker_host_id": "worker-006",
"gpu": "NVIDIA GeForce RTX 4090",
"compute_capability": "8.9",
"tensorrt_version": "11.0.0",
"precision": "strongly-typed",
"admission_result_id": admission.result_id,
"installed_at_utc": datetime.now(UTC).isoformat().replace("+00:00", "Z"),
"authority": {
"shadow_only": True,
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
staging = Path(
tempfile.mkdtemp(
dir=repository,
prefix=f".{MODEL_NAME}.",
suffix=".incomplete",
)
)
try:
version = staging / "1"
version.mkdir(mode=0o700)
shutil.copyfile(engine, version / "model.plan")
shutil.copyfile(config, staging / "config.pbtxt")
_atomic_json(staging / "provenance.json", provenance)
if (
_sha256(version / "model.plan") != EXPECTED_ENGINE_SHA256
or _sha256(staging / "config.pbtxt") != EXPECTED_CONFIG_SHA256
):
raise RuntimeError("PointPillars staged model package changed during copy")
os.replace(staging, destination)
except BaseException:
shutil.rmtree(staging, ignore_errors=True)
raise
request = urllib.request.Request(
f"{args.triton_url.rstrip('/')}/v2/repository/models/{MODEL_NAME}/load",
data=b"{}",
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=180) as response:
if response.status != 200:
raise RuntimeError("canonical Triton rejected PointPillars load")
_require_model_ready(args.triton_url)
except OSError as exc:
raise RuntimeError(
"PointPillars package is installed but canonical Triton did not load it"
) from exc
print(
json.dumps(
{
"status": "installed-and-ready",
"model": MODEL_NAME,
"engine_sha256": EXPECTED_ENGINE_SHA256,
"provenance_sha256": _sha256(destination / "provenance.json"),
},
sort_keys=True,
)
)
return 0
def _validate_existing(destination: Path) -> None:
engine = destination / "1/model.plan"
config = destination / "config.pbtxt"
provenance_path = destination / "provenance.json"
if (
not engine.is_file()
or not config.is_file()
or not provenance_path.is_file()
or engine.stat().st_size != EXPECTED_ENGINE_BYTES
or _sha256(engine) != EXPECTED_ENGINE_SHA256
or _sha256(config) != EXPECTED_CONFIG_SHA256
):
raise RuntimeError("existing PointPillars model package is not admitted")
try:
provenance = json.loads(provenance_path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise RuntimeError("existing PointPillars provenance is invalid") from exc
if (
not isinstance(provenance, dict)
or provenance.get("schema_version") != PROVENANCE_SCHEMA
or provenance.get("model_name") != MODEL_NAME
or provenance.get("engine_sha256") != EXPECTED_ENGINE_SHA256
or provenance.get("source_model_sha256") != EXPECTED_SOURCE_SHA256
or provenance.get("source_label_sha256") != EXPECTED_LABEL_SHA256
or provenance.get("engine_built_on_target") is not True
):
raise RuntimeError("existing PointPillars provenance is invalid")
def _require_model_ready(url: str) -> None:
request = urllib.request.Request(
f"{url.rstrip('/')}/v2/models/{MODEL_NAME}/ready",
method="GET",
)
try:
with urllib.request.urlopen(request, timeout=30) as response:
if response.status != 200:
raise RuntimeError("PointPillars is not ready")
except OSError as exc:
raise RuntimeError("PointPillars is not ready in canonical Triton") from exc
def _sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as source:
for chunk in iter(lambda: source.read(8 * 1024**2), b""):
digest.update(chunk)
return digest.hexdigest()
def _canonical_json(payload: Any) -> bytes:
return json.dumps(
payload,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
).encode("utf-8")
def _atomic_json(path: Path, payload: dict[str, Any]) -> None:
descriptor, temporary = tempfile.mkstemp(
dir=path.parent,
prefix=f".{path.name}.",
suffix=".tmp",
)
try:
with os.fdopen(descriptor, "wb") as target:
target.write(_canonical_json(payload) + b"\n")
target.flush()
os.fsync(target.fileno())
os.replace(temporary, path)
except BaseException:
with suppress(OSError):
os.unlink(temporary)
raise
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,588 @@
#!/usr/bin/env python3
"""Run the complete KITTI validation baseline through canonical Triton."""
from __future__ import annotations
import argparse
import hashlib
import json
import math
import os
import tempfile
import time
import urllib.request
import zipfile
from contextlib import suppress
from datetime import UTC, datetime
from pathlib import Path
from typing import Any
import numpy as np
from k1link.compute.kitti_pointpillars_benchmark import (
PointPillarsFramePrediction,
evaluate_pointpillars_predictions,
read_kitti_validation_truth,
)
from k1link.compute.pointpillars_postprocess import (
POINTPILLARS_EMBEDDED_SCORE_THRESHOLD,
POINTPILLARS_MODEL_POINT_CLOUD_RANGE,
PointPillarsBox,
decode_pointpillars_output,
)
from k1link.datasets.kitti_3d_admission import (
KITTI_3D_RELEASE_ROOT,
KITTI_CALIB_ARCHIVE,
KITTI_LABEL_ARCHIVE,
KITTI_VELODYNE_ARCHIVE,
read_kitti_3d_admission,
read_kitti_standard_splits,
)
RUN_SCHEMA = "missioncore.l3-pointpillars-kitti-transfer-run/v1"
FRAME_SCHEMA = "missioncore.l3-pointpillars-kitti-transfer-frame/v1"
REPORT_SCHEMA = "missioncore.l3-pointpillars-kitti-transfer-report/v1"
MANIFEST_SCHEMA = "missioncore.l3-pointpillars-kitti-transfer-result/v1"
WORKER_PACKAGE_SCHEMA = "missioncore.l3-pointpillars-worker-package/v1"
MODEL_NAME = "pointpillars"
MAXIMUM_POINTS = 204_800
EXPECTED_MODEL_SHA256 = (
"2dcabddc3a365e9608a112d7bbbb7db769a6dddeeaa59aa03611a83113326da1"
)
EXPECTED_LABEL_SHA256 = (
"0adaeb5a374421b61bf83b8fa4522e11abd68461f239a4c72cf5627de913b3da"
)
EXPECTED_ENGINE_SHA256 = (
"12005d972a4632d56342a5da44442b632c1dcc5144fa3c70b162dec334532481"
)
EXPECTED_ONNX_CONTRACT_SHA256 = (
"2fd29cd054ab058c2cfec3dfba305c71e123ef3f04b457d0c64de0c8dac2e1be"
)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--dataset-root", type=Path, required=True)
parser.add_argument("--profile", type=Path, required=True)
parser.add_argument("--model-provenance", type=Path, required=True)
parser.add_argument("--worker-package", type=Path, required=True)
parser.add_argument(
"--output-root",
type=Path,
default=Path(
"/mnt/d/NDC_MISSIONCORE/runtime/experiments/l3/pointpillars-kitti"
),
)
parser.add_argument("--triton-url", default="http://127.0.0.1:8000")
args = parser.parse_args()
dataset_root = args.dataset_root.expanduser().absolute()
admission = read_kitti_3d_admission(dataset_root)
splits = read_kitti_standard_splits(dataset_root)
validation_frame_ids = splits["validation"]
profile_path = args.profile.resolve(strict=True)
provenance_path = args.model_provenance.resolve(strict=True)
profile = _read_json(profile_path)
provenance = _read_json(provenance_path)
_validate_profile_and_provenance(profile, provenance)
worker_package = _read_worker_package(args.worker_package)
_require_triton_ready(args.triton_url)
identity = {
"schema_version": RUN_SCHEMA,
"dataset_source_id": admission["source_id"],
"dataset_release_identity_sha256": admission["release_identity_sha256"],
"validation_frame_count": len(validation_frame_ids),
"validation_frame_ids_sha256": hashlib.sha256(
"\n".join(validation_frame_ids).encode("ascii") + b"\n"
).hexdigest(),
"profile_sha256": _sha256(profile_path),
"model_provenance_sha256": _sha256(provenance_path),
"worker_package_id": worker_package["package_id"],
"worker_package_identity_sha256": worker_package["identity_sha256"],
"engine_sha256": EXPECTED_ENGINE_SHA256,
"producer_sha256": _sha256(Path(__file__)),
"execution": {
"worker_host_id": "worker-006",
"triton_model_name": MODEL_NAME,
"sequential": True,
"parallel_workers": 1,
},
"authority": {
"shadow_only": True,
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
identity_sha256 = hashlib.sha256(_canonical_json(identity)).hexdigest()
run_id = f"l3-pointpillars-kitti-{identity_sha256}"
run_root = args.output_root.expanduser().absolute() / run_id
frames_root = run_root / "frames"
frames_root.mkdir(mode=0o700, parents=True, exist_ok=True)
_write_once(run_root / "identity.json", identity)
archive_root = dataset_root / KITTI_3D_RELEASE_ROOT / "archives"
points_archive = archive_root / KITTI_VELODYNE_ARCHIVE
labels_archive = archive_root / KITTI_LABEL_ARCHIVE
calibrations_archive = archive_root / KITTI_CALIB_ARCHIVE
truth_by_frame = read_kitti_validation_truth(
labels_archive=labels_archive,
calibrations_archive=calibrations_archive,
validation_frame_ids=validation_frame_ids,
)
predictions: list[PointPillarsFramePrediction] = []
try:
with zipfile.ZipFile(points_archive.resolve(strict=True)) as points_zip:
for completed, frame_id in enumerate(validation_frame_ids, start=1):
member = f"training/velodyne/{frame_id}.bin"
point_bytes = points_zip.read(member)
point_sha256 = hashlib.sha256(point_bytes).hexdigest()
frame_path = frames_root / f"{frame_id}.json"
if frame_path.exists():
prediction = _read_frame(
frame_path,
frame_id=frame_id,
point_sha256=point_sha256,
)
else:
prediction = _run_frame(
triton_url=args.triton_url,
frame_id=frame_id,
point_bytes=point_bytes,
)
_atomic_json(
frame_path,
_frame_payload(prediction, point_sha256=point_sha256),
)
predictions.append(prediction)
if completed == 1 or completed % 50 == 0:
print(
json.dumps(
{
"run_id": run_id,
"completed": completed,
"total": len(validation_frame_ids),
"frame_id": frame_id,
},
sort_keys=True,
),
flush=True,
)
except (OSError, KeyError, zipfile.BadZipFile) as exc:
raise RuntimeError("KITTI validation point clouds could not be read") from exc
metrics = evaluate_pointpillars_predictions(
truth_by_frame=truth_by_frame,
predictions=tuple(predictions),
)
report = {
"schema_version": REPORT_SCHEMA,
"run_id": run_id,
"status": "public-cross-domain-transfer-probe-measured",
"dataset_source_id": admission["source_id"],
"dataset_release_identity_sha256": admission["release_identity_sha256"],
"model": {
"name": MODEL_NAME,
"source_model_sha256": EXPECTED_MODEL_SHA256,
"source_label_sha256": EXPECTED_LABEL_SHA256,
"engine_sha256": EXPECTED_ENGINE_SHA256,
},
"metrics": metrics,
"completed_at_utc": datetime.now(UTC).isoformat().replace("+00:00", "Z"),
"authority": identity["authority"],
}
_atomic_json(run_root / "report.json", report)
manifest = {
"schema_version": MANIFEST_SCHEMA,
"run_id": run_id,
"identity_sha256": identity_sha256,
"identity": identity,
"status": report["status"],
"artifacts": [
_artifact(run_root / "identity.json", "run-identity"),
_artifact(run_root / "report.json", "benchmark-report"),
],
"frame_result_count": len(predictions),
"frame_results_identity_sha256": _frame_results_identity(frames_root),
"authority": identity["authority"],
}
_atomic_json(run_root / "manifest.json", manifest)
print(
json.dumps(
{
"run_id": run_id,
"status": report["status"],
"frame_count": len(predictions),
"bev_map40": metrics["aggregates"]["bev_map40"],
"3d_map40": metrics["aggregates"]["3d_map40"],
"false_occupied_rate": metrics["aggregates"][
"false_occupied_rate"
],
},
sort_keys=True,
),
flush=True,
)
return 0
def _run_frame(
*,
triton_url: str,
frame_id: str,
point_bytes: bytes,
) -> PointPillarsFramePrediction:
if not point_bytes or len(point_bytes) % 16:
raise RuntimeError("KITTI point frame is not packed XYZI")
native = np.frombuffer(point_bytes, dtype="<f4").reshape(-1, 4)
if not np.isfinite(native).all() or native.shape[0] > MAXIMUM_POINTS:
raise RuntimeError("KITTI point frame violates the model input contract")
points = np.zeros((1, MAXIMUM_POINTS, 4), dtype=np.float32)
points[0, : native.shape[0]] = native
num_points = np.asarray([native.shape[0]], dtype=np.int32)
output_boxes, output_count, elapsed_ms = _infer(
triton_url,
points,
num_points,
)
boxes = decode_pointpillars_output(output_boxes, output_count)
return PointPillarsFramePrediction(
frame_id=frame_id,
boxes=boxes,
inference_ms=elapsed_ms,
)
def _infer(
triton_url: str,
points: np.ndarray,
num_points: np.ndarray,
) -> tuple[np.ndarray, np.ndarray, float]:
points_binary = np.ascontiguousarray(points, dtype=np.float32).tobytes()
count_binary = np.ascontiguousarray(num_points, dtype=np.int32).tobytes()
header = {
"inputs": [
{
"name": "points",
"shape": [1, MAXIMUM_POINTS, 4],
"datatype": "FP32",
"parameters": {"binary_data_size": len(points_binary)},
},
{
"name": "num_points",
"shape": [1],
"datatype": "INT32",
"parameters": {"binary_data_size": len(count_binary)},
},
],
"outputs": [
{"name": "output_boxes", "parameters": {"binary_data": True}},
{"name": "num_boxes", "parameters": {"binary_data": True}},
],
}
encoded_header = _canonical_json(header)
request = urllib.request.Request(
f"{triton_url.rstrip('/')}/v2/models/{MODEL_NAME}/infer",
data=encoded_header + points_binary + count_binary,
headers={
"Content-Type": "application/octet-stream",
"Inference-Header-Content-Length": str(len(encoded_header)),
},
method="POST",
)
started = time.perf_counter()
with urllib.request.urlopen(request, timeout=120) as response:
payload = response.read()
header_length = int(response.headers["Inference-Header-Content-Length"])
elapsed_ms = (time.perf_counter() - started) * 1000.0
response_header = json.loads(payload[:header_length])
outputs = response_header.get("outputs")
if not isinstance(outputs, list) or len(outputs) != 2:
raise RuntimeError("Triton PointPillars output set changed")
offset = header_length
decoded: dict[str, np.ndarray] = {}
for descriptor in outputs:
if not isinstance(descriptor, dict):
raise RuntimeError("Triton PointPillars output descriptor is invalid")
name = descriptor.get("name")
parameters = descriptor.get("parameters")
if not isinstance(name, str) or not isinstance(parameters, dict):
raise RuntimeError("Triton PointPillars output descriptor is invalid")
byte_length = parameters.get("binary_data_size")
if (
isinstance(byte_length, bool)
or not isinstance(byte_length, int)
or byte_length < 1
):
raise RuntimeError("Triton PointPillars binary output size is invalid")
binary = payload[offset : offset + byte_length]
if len(binary) != byte_length:
raise RuntimeError("Triton PointPillars binary output is truncated")
offset += byte_length
if name == "output_boxes" and descriptor.get("datatype") == "FP32":
decoded[name] = np.frombuffer(binary, dtype="<f4").reshape(
1, 393_216, 9
)
elif name == "num_boxes" and descriptor.get("datatype") == "INT32":
decoded[name] = np.frombuffer(binary, dtype="<i4").reshape(1)
else:
raise RuntimeError("Triton PointPillars output contract changed")
if offset != len(payload) or set(decoded) != {"output_boxes", "num_boxes"}:
raise RuntimeError("Triton PointPillars binary payload is invalid")
return decoded["output_boxes"], decoded["num_boxes"], elapsed_ms
def _require_triton_ready(url: str) -> None:
for endpoint in ("/v2/health/ready", f"/v2/models/{MODEL_NAME}/ready"):
request = urllib.request.Request(f"{url.rstrip('/')}{endpoint}", method="GET")
try:
with urllib.request.urlopen(request, timeout=10) as response:
if response.status != 200:
raise RuntimeError("canonical Triton is not ready")
except OSError as exc:
raise RuntimeError("canonical Triton or PointPillars is not ready") from exc
def _validate_profile_and_provenance(
profile: dict[str, Any],
provenance: dict[str, Any],
) -> None:
detector = profile.get("detector")
postprocessing = (
detector.get("postprocessing") if isinstance(detector, dict) else None
)
if (
profile.get("schema_version")
!= "missioncore.l3-pointpillars-benchmark-profile/v1"
or not isinstance(detector, dict)
or not isinstance(postprocessing, dict)
or detector.get("candidate_source_sha256") != EXPECTED_MODEL_SHA256
or detector.get("candidate_label_sha256") != EXPECTED_LABEL_SHA256
or detector.get("triton_model_name") != MODEL_NAME
or detector.get("model_classes")
!= ["Vehicle", "Pedestrian", "Cyclist"]
or detector.get("point_cloud_range")
!= list(POINTPILLARS_MODEL_POINT_CLOUD_RANGE)
or detector.get("training_domain")
!= "proprietary-solid-state-lidar"
or detector.get("training_ground_truth_publicly_reproducible") is not False
or detector.get("onnx_contract_sha256")
!= EXPECTED_ONNX_CONTRACT_SHA256
or postprocessing.get("embedded_score_threshold")
!= POINTPILLARS_EMBEDDED_SCORE_THRESHOLD
or postprocessing.get("embedded_contract_source")
!= "onnx-node-attributes"
):
raise RuntimeError("L3 PointPillars profile is invalid")
if (
provenance.get("model_name") != MODEL_NAME
or provenance.get("source_model_sha256") != EXPECTED_MODEL_SHA256
or provenance.get("source_label_sha256") != EXPECTED_LABEL_SHA256
or provenance.get("engine_sha256") != EXPECTED_ENGINE_SHA256
or provenance.get("engine_built_on_target") is not True
or provenance.get("worker_host_id") != "worker-006"
):
raise RuntimeError("live PointPillars provenance is invalid")
def _read_worker_package(path: Path) -> dict[str, Any]:
package_root = path.expanduser().resolve(strict=True)
runtime_package_root = Path(__file__).resolve(strict=True).parents[1]
if (
not package_root.is_dir()
or package_root != runtime_package_root
or package_root.is_symlink()
):
raise RuntimeError("L3 runner is not executing from its declared worker package")
manifest = _read_json(package_root / "manifest.json")
identity = manifest.get("identity")
identity_sha256 = manifest.get("identity_sha256")
package_id = manifest.get("package_id")
artifacts = manifest.get("artifacts")
if (
manifest.get("schema_version") != WORKER_PACKAGE_SCHEMA
or not isinstance(identity, dict)
or not isinstance(identity_sha256, str)
or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
or package_id != f"l3-pointpillars-worker-package-{identity_sha256}"
or package_root.name != package_id
or not isinstance(artifacts, list)
):
raise RuntimeError("L3 worker package identity is invalid")
expected_paths = identity.get("artifact_paths")
if not isinstance(expected_paths, list) or not expected_paths:
raise RuntimeError("L3 worker package file set is invalid")
expected = set(expected_paths)
actual = {
member.relative_to(package_root).as_posix()
for member in package_root.rglob("*")
if member.is_file()
}
if actual != expected | {"manifest.json"} or len(artifacts) != len(expected):
raise RuntimeError("L3 worker package file set changed")
observed: set[str] = set()
for descriptor in artifacts:
if not isinstance(descriptor, dict):
raise RuntimeError("L3 worker package artifact is invalid")
relative = descriptor.get("path")
artifact = package_root / str(relative)
if (
not isinstance(relative, str)
or relative not in expected
or relative in observed
or Path(relative).is_absolute()
or ".." in Path(relative).parts
or not artifact.is_file()
or artifact.is_symlink()
or descriptor.get("kind") != relative
or descriptor.get("byte_length") != artifact.stat().st_size
or descriptor.get("sha256") != _sha256(artifact)
):
raise RuntimeError("L3 worker package artifact changed")
observed.add(relative)
if observed != expected:
raise RuntimeError("L3 worker package artifact coverage changed")
return manifest
def _frame_payload(
prediction: PointPillarsFramePrediction,
*,
point_sha256: str,
) -> dict[str, Any]:
return {
"schema_version": FRAME_SCHEMA,
"frame_id": prediction.frame_id,
"point_sha256": point_sha256,
"inference_ms": prediction.inference_ms,
"boxes": [
{
"x_m": box.x_m,
"y_m": box.y_m,
"z_m": box.z_m,
"length_m": box.length_m,
"width_m": box.width_m,
"height_m": box.height_m,
"yaw_rad": box.yaw_rad,
"class_id": box.class_id,
"model_class": box.model_class,
"score": box.score,
}
for box in prediction.boxes
],
}
def _read_frame(
path: Path,
*,
frame_id: str,
point_sha256: str,
) -> PointPillarsFramePrediction:
payload = _read_json(path)
boxes = payload.get("boxes")
if (
payload.get("schema_version") != FRAME_SCHEMA
or payload.get("frame_id") != frame_id
or payload.get("point_sha256") != point_sha256
or not isinstance(boxes, list)
):
raise RuntimeError("cached PointPillars frame result is invalid")
try:
decoded = tuple(PointPillarsBox(**box) for box in boxes)
inference_ms = float(payload["inference_ms"])
except (KeyError, TypeError, ValueError) as exc:
raise RuntimeError("cached PointPillars frame result is invalid") from exc
if not math.isfinite(inference_ms) or inference_ms <= 0.0:
raise RuntimeError("cached PointPillars frame latency is invalid")
return PointPillarsFramePrediction(
frame_id=frame_id,
boxes=decoded,
inference_ms=inference_ms,
)
def _frame_results_identity(frames_root: Path) -> str:
descriptors = [
{
"name": path.name,
"sha256": _sha256(path),
"byte_length": path.stat().st_size,
}
for path in sorted(frames_root.glob("*.json"))
]
return hashlib.sha256(_canonical_json(descriptors)).hexdigest()
def _artifact(path: Path, role: str) -> dict[str, Any]:
return {
"path": path.name,
"role": role,
"media_type": "application/json",
"sha256": _sha256(path),
"byte_length": path.stat().st_size,
}
def _read_json(path: Path) -> dict[str, Any]:
try:
payload = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise RuntimeError(f"{path.name} is invalid") from exc
if not isinstance(payload, dict):
raise RuntimeError(f"{path.name} is not an object")
return payload
def _sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as source:
for chunk in iter(lambda: source.read(8 * 1024**2), b""):
digest.update(chunk)
return digest.hexdigest()
def _canonical_json(payload: Any) -> bytes:
return json.dumps(
payload,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
).encode("utf-8")
def _write_once(path: Path, payload: dict[str, Any]) -> None:
encoded = _canonical_json(payload) + b"\n"
if path.exists():
if path.read_bytes() != encoded:
raise RuntimeError(f"{path.name} identity changed")
return
_atomic_bytes(path, encoded)
def _atomic_json(path: Path, payload: dict[str, Any]) -> None:
_atomic_bytes(path, _canonical_json(payload) + b"\n")
def _atomic_bytes(path: Path, payload: bytes) -> None:
path.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
descriptor, temporary = tempfile.mkstemp(
dir=path.parent,
prefix=f".{path.name}.",
suffix=".tmp",
)
try:
with os.fdopen(descriptor, "wb") as target:
target.write(payload)
target.flush()
os.fsync(target.fileno())
os.replace(temporary, path)
except BaseException:
with suppress(OSError):
os.unlink(temporary)
raise
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""Execute one schema-only PointPillars smoke frame in canonical Triton."""
from __future__ import annotations
import argparse
import hashlib
import json
import zipfile
from datetime import UTC, datetime
from pathlib import Path
from run_l3_pointpillars_public_baseline import (
EXPECTED_ENGINE_SHA256,
EXPECTED_LABEL_SHA256,
EXPECTED_MODEL_SHA256,
_atomic_json,
_read_json,
_require_triton_ready,
_run_frame,
_validate_profile_and_provenance,
)
from k1link.datasets.kitti_3d_admission import (
KITTI_3D_RELEASE_ROOT,
KITTI_VELODYNE_ARCHIVE,
read_kitti_3d_admission,
read_kitti_standard_splits,
)
SCHEMA = "missioncore.l3-pointpillars-live-smoke/v1"
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--dataset-root", type=Path, required=True)
parser.add_argument("--profile", type=Path, required=True)
parser.add_argument("--model-provenance", type=Path, required=True)
parser.add_argument("--frame-id")
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--triton-url", default="http://127.0.0.1:8000")
args = parser.parse_args()
dataset_root = args.dataset_root.expanduser().absolute()
admission = read_kitti_3d_admission(dataset_root)
validation = read_kitti_standard_splits(dataset_root)["validation"]
frame_id = args.frame_id or validation[0]
if frame_id not in validation:
raise RuntimeError("smoke frame is not in the admitted validation split")
profile = _read_json(args.profile.resolve(strict=True))
provenance = _read_json(args.model_provenance.resolve(strict=True))
_validate_profile_and_provenance(profile, provenance)
_require_triton_ready(args.triton_url)
points_archive = (
dataset_root
/ KITTI_3D_RELEASE_ROOT
/ "archives"
/ KITTI_VELODYNE_ARCHIVE
)
member = f"training/velodyne/{frame_id}.bin"
try:
with zipfile.ZipFile(points_archive.resolve(strict=True)) as source:
point_bytes = source.read(member)
except (OSError, KeyError, zipfile.BadZipFile) as exc:
raise RuntimeError("smoke point frame could not be read") from exc
prediction = _run_frame(
triton_url=args.triton_url,
frame_id=frame_id,
point_bytes=point_bytes,
)
result = {
"schema_version": SCHEMA,
"status": "engine-schema-executed",
"source_id": admission["source_id"],
"dataset_release_identity_sha256": admission[
"release_identity_sha256"
],
"frame_id": frame_id,
"point_frame_sha256": hashlib.sha256(point_bytes).hexdigest(),
"point_count": len(point_bytes) // 16,
"post_nms_box_count": len(prediction.boxes),
"observed_model_classes": sorted(
{box.model_class for box in prediction.boxes}
),
"inference_ms": prediction.inference_ms,
"model": {
"name": "pointpillars",
"source_model_sha256": EXPECTED_MODEL_SHA256,
"source_label_sha256": EXPECTED_LABEL_SHA256,
"engine_sha256": EXPECTED_ENGINE_SHA256,
},
"observed_at_utc": datetime.now(UTC).isoformat().replace("+00:00", "Z"),
"claim_boundary": {
"accuracy_measured": False,
"k1_transfer_evaluated": False,
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
_atomic_json(args.output.expanduser().absolute(), result)
print(json.dumps(result, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())