diff --git a/pyproject.toml b/pyproject.toml index e7debf78dc..bdcbd77801 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,9 +46,6 @@ dependencies = [ "libusb1", "spidev; platform_system == 'Linux'", - # modeld - "onnx >= 1.14.0", - # logging "pyzmq", "sentry-sdk", diff --git a/scripts/reporter.py b/scripts/reporter.py index 903fcc8911..d894b8af48 100755 --- a/scripts/reporter.py +++ b/scripts/reporter.py @@ -1,17 +1,33 @@ #!/usr/bin/env python3 import os import glob -import onnx + +from tinygrad.nn.onnx import OnnxPBParser BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")) + MASTER_PATH = os.getenv("MASTER_PATH", BASEDIR) MODEL_PATH = "/selfdrive/modeld/models/" + +class MetadataOnnxPBParser(OnnxPBParser): + def _parse_ModelProto(self) -> dict: + obj = {"metadata_props": []} + for fid, wire_type in self._parse_message(self.reader.len): + match fid: + case 14: + obj["metadata_props"].append(self._parse_StringStringEntryProto()) + case _: + self.reader.skip_field(wire_type) + return obj + + def get_checkpoint(f): - model = onnx.load(f) - metadata = {prop.key: prop.value for prop in model.metadata_props} + model = MetadataOnnxPBParser(f).parse() + metadata = {prop["key"]: prop["value"] for prop in model["metadata_props"]} return metadata['model_checkpoint'].split('/')[0] + if __name__ == "__main__": print("| | master | PR branch |") print("|-| ----- | --------- |") @@ -24,8 +40,4 @@ if __name__ == "__main__": fn = os.path.basename(f) master = get_checkpoint(MASTER_PATH + MODEL_PATH + fn) pr = get_checkpoint(BASEDIR + MODEL_PATH + fn) - print( - "|", fn, "|", - f"[{master}](https://reporter.comma.life/experiment/{master})", "|", - f"[{pr}](https://reporter.comma.life/experiment/{pr})", "|" - ) + print("|", fn, "|", f"[{master}](https://reporter.comma.life/experiment/{master})", "|", f"[{pr}](https://reporter.comma.life/experiment/{pr})", "|") diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index ed5c50beb3..95ac06bb1a 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -13,19 +13,20 @@ tinygrad_files = ["#"+x for x in glob.glob(env.Dir("#tinygrad_repo").relpath + " def estimate_pickle_max_size(onnx_size): return 1.2 * onnx_size + 10 * 1024 * 1024 # 20% + 10MB is plenty -# Get model metadata -for model_name in ['driving_vision', 'driving_policy', 'dmonitoring_model']: - fn = File(f"models/{model_name}").abspath - script_files = [File(Dir("#selfdrive/modeld").File("get_model_metadata.py").abspath)] - cmd = f'python3 {Dir("#selfdrive/modeld").abspath}/get_model_metadata.py {fn}.onnx' - lenv.Command(fn + "_metadata.pkl", [fn + ".onnx"] + tinygrad_files + script_files, cmd) - # compile warp # THREADS=0 is need to prevent bug: https://github.com/tinygrad/tinygrad/issues/14689 tg_flags = { 'larch64': 'DEV=QCOM FLOAT16=1 NOLOCALS=1 JIT_BATCH_SIZE=0', 'Darwin': f'DEV=CPU THREADS=0 HOME={os.path.expanduser("~")}', # tinygrad calls brew which needs a $HOME in the env }.get(arch, 'DEV=CPU CPU_LLVM=1 THREADS=0') + +# Get model metadata +for model_name in ['driving_vision', 'driving_policy', 'dmonitoring_model']: + fn = File(f"models/{model_name}").abspath + script_files = [File(Dir("#selfdrive/modeld").File("get_model_metadata.py").abspath)] + cmd = f'{tg_flags} python3 {Dir("#selfdrive/modeld").abspath}/get_model_metadata.py {fn}.onnx' + lenv.Command(fn + "_metadata.pkl", [fn + ".onnx"] + tinygrad_files + script_files, cmd) + image_flag = { 'larch64': 'IMAGE=2', }.get(arch, 'IMAGE=0') diff --git a/selfdrive/modeld/get_model_metadata.py b/selfdrive/modeld/get_model_metadata.py index 2001d23d75..838b1e9f40 100755 --- a/selfdrive/modeld/get_model_metadata.py +++ b/selfdrive/modeld/get_model_metadata.py @@ -1,33 +1,51 @@ #!/usr/bin/env python3 import sys import pathlib -import onnx import codecs import pickle from typing import Any -def get_name_and_shape(value_info:onnx.ValueInfoProto) -> tuple[str, tuple[int,...]]: - shape = tuple([int(dim.dim_value) for dim in value_info.type.tensor_type.shape.dim]) - name = value_info.name +from tinygrad.nn.onnx import OnnxPBParser + + +class MetadataOnnxPBParser(OnnxPBParser): + def _parse_ModelProto(self) -> dict: + obj: dict[str, Any] = {"graph": {"input": [], "output": []}, "metadata_props": []} + for fid, wire_type in self._parse_message(self.reader.len): + match fid: + case 7: + obj["graph"] = self._parse_GraphProto() + case 14: + obj["metadata_props"].append(self._parse_StringStringEntryProto()) + case _: + self.reader.skip_field(wire_type) + return obj + + +def get_name_and_shape(value_info: dict[str, Any]) -> tuple[str, tuple[int, ...]]: + shape = tuple(int(dim) if isinstance(dim, int) else 0 for dim in value_info["parsed_type"].shape) + name = value_info["name"] return name, shape -def get_metadata_value_by_name(model:onnx.ModelProto, name:str) -> str | Any: - for prop in model.metadata_props: - if prop.key == name: - return prop.value + +def get_metadata_value_by_name(model: dict[str, Any], name: str) -> str | Any: + for prop in model["metadata_props"]: + if prop["key"] == name: + return prop["value"] return None + if __name__ == "__main__": model_path = pathlib.Path(sys.argv[1]) - model = onnx.load(str(model_path)) + model = MetadataOnnxPBParser(model_path).parse() output_slices = get_metadata_value_by_name(model, 'output_slices') assert output_slices is not None, 'output_slices not found in metadata' metadata = { 'model_checkpoint': get_metadata_value_by_name(model, 'model_checkpoint'), 'output_slices': pickle.loads(codecs.decode(output_slices.encode(), "base64")), - 'input_shapes': dict([get_name_and_shape(x) for x in model.graph.input]), - 'output_shapes': dict([get_name_and_shape(x) for x in model.graph.output]) + 'input_shapes': dict(get_name_and_shape(x) for x in model["graph"]["input"]), + 'output_shapes': dict(get_name_and_shape(x) for x in model["graph"]["output"]), } metadata_path = model_path.parent / (model_path.stem + '_metadata.pkl') diff --git a/uv.lock b/uv.lock index 658f62a331..9094417693 100644 --- a/uv.lock +++ b/uv.lock @@ -696,22 +696,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, ] -[[package]] -name = "ml-dtypes" -version = "0.5.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/c27b42ed9b1c7d13d9ba8b6905dece787d6259152f2309338aed29b2447b/ml_dtypes-0.5.4.tar.gz", hash = "sha256:8ab06a50fb9bf9666dd0fe5dfb4676fa2b0ac0f31ecff72a6c3af8e22c063453", size = 692314, upload-time = "2025-11-17T22:32:31.031Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/b8/3c70881695e056f8a32f8b941126cf78775d9a4d7feba8abcb52cb7b04f2/ml_dtypes-0.5.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a174837a64f5b16cab6f368171a1a03a27936b31699d167684073ff1c4237dac", size = 676927, upload-time = "2025-11-17T22:31:48.182Z" }, - { url = "https://files.pythonhosted.org/packages/54/0f/428ef6881782e5ebb7eca459689448c0394fa0a80bea3aa9262cba5445ea/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7f7c643e8b1320fd958bf098aa7ecf70623a42ec5154e3be3be673f4c34d900", size = 5028464, upload-time = "2025-11-17T22:31:50.135Z" }, - { url = "https://files.pythonhosted.org/packages/3a/cb/28ce52eb94390dda42599c98ea0204d74799e4d8047a0eb559b6fd648056/ml_dtypes-0.5.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ad459e99793fa6e13bd5b7e6792c8f9190b4e5a1b45c63aba14a4d0a7f1d5ff", size = 5009002, upload-time = "2025-11-17T22:31:52.001Z" }, - { url = "https://files.pythonhosted.org/packages/f5/f0/0cfadd537c5470378b1b32bd859cf2824972174b51b873c9d95cfd7475a5/ml_dtypes-0.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:c1a953995cccb9e25a4ae19e34316671e4e2edaebe4cf538229b1fc7109087b7", size = 212222, upload-time = "2025-11-17T22:31:53.742Z" }, - { url = "https://files.pythonhosted.org/packages/16/2e/9acc86985bfad8f2c2d30291b27cd2bb4c74cea08695bd540906ed744249/ml_dtypes-0.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:9bad06436568442575beb2d03389aa7456c690a5b05892c471215bfd8cf39460", size = 160793, upload-time = "2025-11-17T22:31:55.358Z" }, -] - [[package]] name = "mpmath" version = "1.3.0" @@ -772,26 +756,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2f/a3/56c5c604fae6dd40fa2ed3040d005fca97e91bd320d232ac9931d77ba13c/numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa", size = 10220171, upload-time = "2026-01-31T23:11:14.684Z" }, ] -[[package]] -name = "onnx" -version = "1.20.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ml-dtypes" }, - { name = "numpy" }, - { name = "protobuf" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3b/8a/335c03a8683a88a32f9a6bb98899ea6df241a41df64b37b9696772414794/onnx-1.20.1.tar.gz", hash = "sha256:ded16de1df563d51fbc1ad885f2a426f814039d8b5f4feb77febe09c0295ad67", size = 12048980, upload-time = "2026-01-10T01:40:03.043Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/4c/4b17e82f91ab9aa07ff595771e935ca73547b035030dc5f5a76e63fbfea9/onnx-1.20.1-cp312-abi3-macosx_12_0_universal2.whl", hash = "sha256:1d923bb4f0ce1b24c6859222a7e6b2f123e7bfe7623683662805f2e7b9e95af2", size = 17903547, upload-time = "2026-01-10T01:39:31.015Z" }, - { url = "https://files.pythonhosted.org/packages/64/5e/1bfa100a9cb3f2d3d5f2f05f52f7e60323b0e20bb0abace1ae64dbc88f25/onnx-1.20.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ddc0b7d8b5a94627dc86c533d5e415af94cbfd103019a582669dad1f56d30281", size = 17412021, upload-time = "2026-01-10T01:39:33.885Z" }, - { url = "https://files.pythonhosted.org/packages/fb/71/d3fec0dcf9a7a99e7368112d9c765154e81da70fcba1e3121131a45c245b/onnx-1.20.1-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9336b6b8e6efcf5c490a845f6afd7e041c89a56199aeda384ed7d58fb953b080", size = 17510450, upload-time = "2026-01-10T01:39:36.589Z" }, - { url = "https://files.pythonhosted.org/packages/74/a7/edce1403e05a46e59b502fae8e3350ceeac5841f8e8f1561e98562ed9b09/onnx-1.20.1-cp312-abi3-win32.whl", hash = "sha256:564c35a94811979808ab5800d9eb4f3f32c12daedba7e33ed0845f7c61ef2431", size = 16238216, upload-time = "2026-01-10T01:39:39.46Z" }, - { url = "https://files.pythonhosted.org/packages/8b/c7/8690c81200ae652ac550c1df52f89d7795e6cc941f3cb38c9ef821419e80/onnx-1.20.1-cp312-abi3-win_amd64.whl", hash = "sha256:9fe7f9a633979d50984b94bda8ceb7807403f59a341d09d19342dc544d0ca1d5", size = 16389207, upload-time = "2026-01-10T01:39:41.955Z" }, - { url = "https://files.pythonhosted.org/packages/01/a0/4fb0e6d36eaf079af366b2c1f68bafe92df6db963e2295da84388af64abc/onnx-1.20.1-cp312-abi3-win_arm64.whl", hash = "sha256:21d747348b1c8207406fa2f3e12b82f53e0d5bb3958bcd0288bd27d3cb6ebb00", size = 16344155, upload-time = "2026-01-10T01:39:45.536Z" }, -] - [[package]] name = "opencv-python-headless" version = "4.13.0.92" @@ -833,7 +797,6 @@ dependencies = [ { name = "libusb1" }, { name = "ncurses" }, { name = "numpy" }, - { name = "onnx" }, { name = "openssl3" }, { name = "psutil" }, { name = "pycapnp" }, @@ -918,7 +881,6 @@ requires-dist = [ { name = "mkdocs", marker = "extra == 'docs'" }, { name = "ncurses", git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=releases" }, { name = "numpy", specifier = ">=2.0" }, - { name = "onnx", specifier = ">=1.14.0" }, { name = "opencv-python-headless", marker = "extra == 'dev'" }, { name = "openssl3", git = "https://github.com/commaai/dependencies.git?subdirectory=openssl3&rev=releases" }, { name = "pre-commit-hooks", marker = "extra == 'testing'" }, @@ -1091,21 +1053,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, ] -[[package]] -name = "protobuf" -version = "6.33.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/25/7c72c307aafc96fa87062aa6291d9f7c94836e43214d43722e86037aac02/protobuf-6.33.5.tar.gz", hash = "sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c", size = 444465, upload-time = "2026-01-29T21:51:33.494Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/79/af92d0a8369732b027e6d6084251dd8e782c685c72da161bd4a2e00fbabb/protobuf-6.33.5-cp310-abi3-win32.whl", hash = "sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b", size = 425769, upload-time = "2026-01-29T21:51:21.751Z" }, - { url = "https://files.pythonhosted.org/packages/55/75/bb9bc917d10e9ee13dee8607eb9ab963b7cf8be607c46e7862c748aa2af7/protobuf-6.33.5-cp310-abi3-win_amd64.whl", hash = "sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c", size = 437118, upload-time = "2026-01-29T21:51:24.022Z" }, - { url = "https://files.pythonhosted.org/packages/a2/6b/e48dfc1191bc5b52950246275bf4089773e91cb5ba3592621723cdddca62/protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5", size = 427766, upload-time = "2026-01-29T21:51:25.413Z" }, - { url = "https://files.pythonhosted.org/packages/4e/b1/c79468184310de09d75095ed1314b839eb2f72df71097db9d1404a1b2717/protobuf-6.33.5-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190", size = 324638, upload-time = "2026-01-29T21:51:26.423Z" }, - { url = "https://files.pythonhosted.org/packages/c5/f5/65d838092fd01c44d16037953fd4c2cc851e783de9b8f02b27ec4ffd906f/protobuf-6.33.5-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd", size = 339411, upload-time = "2026-01-29T21:51:27.446Z" }, - { url = "https://files.pythonhosted.org/packages/9b/53/a9443aa3ca9ba8724fdfa02dd1887c1bcd8e89556b715cfbacca6b63dbec/protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0", size = 323465, upload-time = "2026-01-29T21:51:28.925Z" }, - { url = "https://files.pythonhosted.org/packages/57/bf/2086963c69bdac3d7cff1cc7ff79b8ce5ea0bec6797a017e1be338a46248/protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02", size = 170687, upload-time = "2026-01-29T21:51:32.557Z" }, -] - [[package]] name = "psutil" version = "7.2.2"