From 302515df108096ede771e302157b2e483038c440 Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Mon, 27 Jul 2026 15:35:17 -0700 Subject: [PATCH 1/7] Support recurrent modeld KV caches --- openpilot/selfdrive/modeld/SConscript | 4 +- openpilot/selfdrive/modeld/compile_modeld.py | 57 +++++++++++++++----- openpilot/selfdrive/modeld/modeld.py | 3 +- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/openpilot/selfdrive/modeld/SConscript b/openpilot/selfdrive/modeld/SConscript index f046be99154411..2169805772e32f 100644 --- a/openpilot/selfdrive/modeld/SConscript +++ b/openpilot/selfdrive/modeld/SConscript @@ -24,7 +24,9 @@ tinygrad_files = ["#"+x for x in glob.glob(env.Dir("#tinygrad_repo").relpath + " if 'pycache' not in x and os.path.isfile(os.path.join(tinygrad_root, x))] def estimate_pickle_max_size(onnx_size): - return 1.2 * onnx_size + 10 * 1024 * 1024 # 20% + 10MB is plenty + # QCOM programs for models with spatial recurrent features can approach 2x + # the ONNX size. Overestimating only adds an empty trailing chunk. + return 2.0 * onnx_size + 10 * 1024 * 1024 if arch == 'comma_arm64': tg_backend = 'QCOM' diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 2d27a41496e8b4..9353e9540fbbfc 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -38,7 +38,8 @@ def fetch_fw(path, name, sha256): NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size']) WARP_INPUTS = ['tfm', 'big_tfm'] -POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs'] +POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs', + 'off_policy_cache', 'on_policy_cache'] UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) @@ -139,16 +140,16 @@ def get_policy_npy_shapes(input_shapes): dp = input_shapes['desire_pulse'] # (1, 25, 8) tc = input_shapes['traffic_convention'] # (1, 2) at = input_shapes['action_t'] # (1, 2) - fb = input_shapes['features_buffer'] # (1, 24, 512) - # TODO prev_feat shouldn't exist and be handled inside the JIT, but corrupt on QCOM for now - shapes = {'desire': (dp[2],), 'traffic_convention': tuple(tc), 'action_t': tuple(at), 'prev_feat': (fb[0], fb[2])} + shapes = {'desire': (dp[2],), 'traffic_convention': tuple(tc), 'action_t': tuple(at)} + if (fb := input_shapes.get('features_buffer')) is not None: + # TODO prev_feat shouldn't exist and be handled inside the JIT, but corrupt on QCOM for now + shapes['prev_feat'] = (fb[0], fb[2]) return shapes, [math.prod(s) for s in shapes.values()] def make_input_queues(input_shapes, frame_skip, device): input_queues, npy = make_warp_input_queues(input_shapes, frame_skip, device) - fb = input_shapes['features_buffer'] # (1, 24, 512), past features only; the model appends the current frame's feature dp = input_shapes['desire_pulse'] # (1, 25, 8) shapes, sizes = get_policy_npy_shapes(input_shapes) @@ -156,10 +157,18 @@ def make_input_queues(input_shapes, frame_skip, device): # views into the packed inputs, to be refilled at runtime npy.update({k: v.reshape(s) for (k, s), v in zip(shapes.items(), np.split(packed_npy_inputs, np.cumsum(sizes[:-1])), strict=True)}) input_queues.update({ - 'feat_q': Tensor(np.zeros((frame_skip * fb[1], fb[0], fb[2]), dtype=np.float32), device=device).contiguous().realize(), 'desire_q': Tensor(np.zeros((frame_skip * dp[1], dp[0], dp[2]), dtype=np.float32), device=device).contiguous().realize(), 'packed_npy_inputs': Tensor(packed_npy_inputs, device='NPY').realize(), }) + if (fb := input_shapes.get('features_buffer')) is not None: + input_queues['feat_q'] = Tensor( + np.zeros((frame_skip * fb[1], fb[0], fb[2]), dtype=np.float32), + device=device).contiguous().realize() + for name in ('off_policy_cache', 'on_policy_cache'): + if name in input_shapes: + input_queues[name] = Tensor( + np.zeros(input_shapes[name], dtype=np.float16), + device=device).contiguous().realize() return input_queues, npy @@ -196,7 +205,8 @@ def make_run_policy(model_runner, model_metadata, frame_skip): sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['input_shapes']) - def run_policy(warped, img_q, big_img_q, feat_q, desire_q, packed_npy_inputs): + def run_policy(warped, img_q, big_img_q, desire_q, packed_npy_inputs, + feat_q=None, off_policy_cache=None, on_policy_cache=None): packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT) warped = warped.to(Device.DEFAULT) Tensor.realize(packed_npy_inputs, warped) @@ -204,19 +214,42 @@ def run_policy(warped, img_q, big_img_q, feat_q, desire_q, packed_npy_inputs): img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) - desire, traffic_convention, action_t, prev_feat = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) + packed_values = { + name: value.reshape(shape) + for (name, shape), value in zip(npy_shapes.items(), packed_npy_inputs.split(npy_sizes), strict=True) + } + desire = packed_values['desire'] + traffic_convention = packed_values['traffic_convention'] + action_t = packed_values['action_t'] desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) - feat_buf = shift_and_sample(feat_q, prev_feat.reshape(1, 1, -1), sample_skip_fn) inputs = { 'img': img, 'big_img': big_img, - 'features_buffer': feat_buf, 'desire_pulse': desire_buf, 'traffic_convention': traffic_convention, 'action_t': action_t, } - out = next(iter(model_runner(inputs).values())).cast('float32') + if 'features_buffer' in model_metadata['input_shapes']: + assert feat_q is not None + inputs['features_buffer'] = shift_and_sample( + feat_q, packed_values['prev_feat'].reshape(1, 1, -1), sample_skip_fn) + caches = { + 'off_policy_cache': off_policy_cache, + 'on_policy_cache': on_policy_cache, + } + for name, cache in caches.items(): + if name in model_metadata['input_shapes']: + assert cache is not None + inputs[name] = cache + + model_outputs = model_runner(inputs) + out = model_outputs.get('outputs', next(iter(model_outputs.values()))).cast('float32') + cache_updates = [] + for name, cache in caches.items(): + if name in model_metadata['input_shapes']: + cache_updates.append(cache.assign(model_outputs[f'{name}_out'].cast(cache.dtype).contiguous())) + Tensor.realize(out, *cache_updates) return out, return run_policy @@ -237,7 +270,7 @@ def random_inputs_run(fn, seed, test_val=None, test_buffers=None, expect_match=T Device.default.synchronize() random_inputs = make_random_inputs() st = time.perf_counter() - outs = fn(**{k: input_queues[k] for k in input_keys}, **random_inputs) + outs = fn(**{k: input_queues[k] for k in input_keys if k in input_queues}, **random_inputs) mt = time.perf_counter() Device.default.synchronize() et = time.perf_counter() diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index a795f366ce4865..650c07a26395b2 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -232,7 +232,8 @@ def run(self, bufs: dict[str, VisionBuf], transforms: dict[str, np.ndarray], if self.chestnut and not np.all(np.isfinite(model_output)): raise RuntimeError("model output not finite") outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices)) - self.npy['prev_feat'][:] = model_output[self.output_slices['hidden_state']] + if 'prev_feat' in self.npy: + self.npy['prev_feat'][:] = model_output[self.output_slices['hidden_state']] if SEND_RAW_PRED: outputs_dict['raw_pred'] = model_output.copy() From a11a58f6c0ade30b98966d358e0585c0f252deae Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Thu, 20 Aug 2026 12:13:27 -0700 Subject: [PATCH 2/7] spatial supercombo: rldriving 26ef89ec + spatial features_buffer support Model: torchtitan rldriving 26ef89ec-405e-59fb-89cf-ed70a569f842 on spatial path 849a624a-8a7d-8946-bf04-86148e5e0ef8/56320. features_buffer/hidden_state now carry (S=32, C=512) spatial features per frame instead of pooled (512,); compile_modeld packs them through feat_q and prev_feat by trailing-dim product so the JIT shape contract holds. --- openpilot/selfdrive/modeld/compile_modeld.py | 59 +++++-------------- openpilot/selfdrive/modeld/modeld.py | 3 +- .../modeld/models/big_driving_supercombo.onnx | 4 +- 3 files changed, 17 insertions(+), 49 deletions(-) diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 9353e9540fbbfc..f54d09e86972af 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -38,8 +38,7 @@ def fetch_fw(path, name, sha256): NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size']) WARP_INPUTS = ['tfm', 'big_tfm'] -POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs', - 'off_policy_cache', 'on_policy_cache'] +POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs'] UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) @@ -140,16 +139,18 @@ def get_policy_npy_shapes(input_shapes): dp = input_shapes['desire_pulse'] # (1, 25, 8) tc = input_shapes['traffic_convention'] # (1, 2) at = input_shapes['action_t'] # (1, 2) - shapes = {'desire': (dp[2],), 'traffic_convention': tuple(tc), 'action_t': tuple(at)} - if (fb := input_shapes.get('features_buffer')) is not None: - # TODO prev_feat shouldn't exist and be handled inside the JIT, but corrupt on QCOM for now - shapes['prev_feat'] = (fb[0], fb[2]) + fb = input_shapes['features_buffer'] # (1, T-1, ...) e.g. (1, 24, 32, 512) with spatial features + feat_dim = math.prod(fb[2:]) + # TODO prev_feat shouldn't exist and be handled inside the JIT, but corrupt on QCOM for now + shapes = {'desire': (dp[2],), 'traffic_convention': tuple(tc), 'action_t': tuple(at), 'prev_feat': (fb[0], feat_dim)} return shapes, [math.prod(s) for s in shapes.values()] def make_input_queues(input_shapes, frame_skip, device): input_queues, npy = make_warp_input_queues(input_shapes, frame_skip, device) + fb = input_shapes['features_buffer'] # (1, T-1, ...), past features only; the model appends the current frame's feature + feat_dim = math.prod(fb[2:]) dp = input_shapes['desire_pulse'] # (1, 25, 8) shapes, sizes = get_policy_npy_shapes(input_shapes) @@ -157,18 +158,10 @@ def make_input_queues(input_shapes, frame_skip, device): # views into the packed inputs, to be refilled at runtime npy.update({k: v.reshape(s) for (k, s), v in zip(shapes.items(), np.split(packed_npy_inputs, np.cumsum(sizes[:-1])), strict=True)}) input_queues.update({ + 'feat_q': Tensor(np.zeros((frame_skip * fb[1], fb[0], feat_dim), dtype=np.float32), device=device).contiguous().realize(), 'desire_q': Tensor(np.zeros((frame_skip * dp[1], dp[0], dp[2]), dtype=np.float32), device=device).contiguous().realize(), 'packed_npy_inputs': Tensor(packed_npy_inputs, device='NPY').realize(), }) - if (fb := input_shapes.get('features_buffer')) is not None: - input_queues['feat_q'] = Tensor( - np.zeros((frame_skip * fb[1], fb[0], fb[2]), dtype=np.float32), - device=device).contiguous().realize() - for name in ('off_policy_cache', 'on_policy_cache'): - if name in input_shapes: - input_queues[name] = Tensor( - np.zeros(input_shapes[name], dtype=np.float16), - device=device).contiguous().realize() return input_queues, npy @@ -205,8 +198,7 @@ def make_run_policy(model_runner, model_metadata, frame_skip): sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['input_shapes']) - def run_policy(warped, img_q, big_img_q, desire_q, packed_npy_inputs, - feat_q=None, off_policy_cache=None, on_policy_cache=None): + def run_policy(warped, img_q, big_img_q, feat_q, desire_q, packed_npy_inputs): packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT) warped = warped.to(Device.DEFAULT) Tensor.realize(packed_npy_inputs, warped) @@ -214,42 +206,19 @@ def run_policy(warped, img_q, big_img_q, desire_q, packed_npy_inputs, img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) - packed_values = { - name: value.reshape(shape) - for (name, shape), value in zip(npy_shapes.items(), packed_npy_inputs.split(npy_sizes), strict=True) - } - desire = packed_values['desire'] - traffic_convention = packed_values['traffic_convention'] - action_t = packed_values['action_t'] + desire, traffic_convention, action_t, prev_feat = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) + feat_buf = shift_and_sample(feat_q, prev_feat.reshape(1, 1, -1), sample_skip_fn) inputs = { 'img': img, 'big_img': big_img, + 'features_buffer': feat_buf.reshape(model_metadata['input_shapes']['features_buffer']), 'desire_pulse': desire_buf, 'traffic_convention': traffic_convention, 'action_t': action_t, } - if 'features_buffer' in model_metadata['input_shapes']: - assert feat_q is not None - inputs['features_buffer'] = shift_and_sample( - feat_q, packed_values['prev_feat'].reshape(1, 1, -1), sample_skip_fn) - caches = { - 'off_policy_cache': off_policy_cache, - 'on_policy_cache': on_policy_cache, - } - for name, cache in caches.items(): - if name in model_metadata['input_shapes']: - assert cache is not None - inputs[name] = cache - - model_outputs = model_runner(inputs) - out = model_outputs.get('outputs', next(iter(model_outputs.values()))).cast('float32') - cache_updates = [] - for name, cache in caches.items(): - if name in model_metadata['input_shapes']: - cache_updates.append(cache.assign(model_outputs[f'{name}_out'].cast(cache.dtype).contiguous())) - Tensor.realize(out, *cache_updates) + out = next(iter(model_runner(inputs).values())).cast('float32') return out, return run_policy @@ -270,7 +239,7 @@ def random_inputs_run(fn, seed, test_val=None, test_buffers=None, expect_match=T Device.default.synchronize() random_inputs = make_random_inputs() st = time.perf_counter() - outs = fn(**{k: input_queues[k] for k in input_keys if k in input_queues}, **random_inputs) + outs = fn(**{k: input_queues[k] for k in input_keys}, **random_inputs) mt = time.perf_counter() Device.default.synchronize() et = time.perf_counter() diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 650c07a26395b2..a795f366ce4865 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -232,8 +232,7 @@ def run(self, bufs: dict[str, VisionBuf], transforms: dict[str, np.ndarray], if self.chestnut and not np.all(np.isfinite(model_output)): raise RuntimeError("model output not finite") outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices)) - if 'prev_feat' in self.npy: - self.npy['prev_feat'][:] = model_output[self.output_slices['hidden_state']] + self.npy['prev_feat'][:] = model_output[self.output_slices['hidden_state']] if SEND_RAW_PRED: outputs_dict['raw_pred'] = model_output.copy() diff --git a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx index 4a04bd78330f3e..2bf3135e2da44f 100644 --- a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx +++ b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a501760a9d1d5fef0eab2b8c5d122d06124fc26dc8e0782e0aa94b82a208f0ff -size 1757355221 +oid sha256:40f9ee6b9a4624cbee05d053b959cf8ff9f72fef9724629b6596815b81ab4fb8 +size 1764417969 From 556e41df593c450bea6d4209d967b5387415adeb Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Thu, 20 Aug 2026 16:18:43 -0700 Subject: [PATCH 3/7] spatial supercombo: rldriving 34417250-25e2-f847-f18f-172ef4f207f2 Rerun of rldriving on spatial path 849a624a-8a7d-8946-bf04-86148e5e0ef8/56320, replacing 26ef89ec-405e-59fb-89cf-ed70a569f842. --- openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx index 2bf3135e2da44f..da8f43c1859e1a 100644 --- a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx +++ b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40f9ee6b9a4624cbee05d053b959cf8ff9f72fef9724629b6596815b81ab4fb8 +oid sha256:57a3bf0c312dbf14c054b8f7f9282d1bc9216b44476f2c842c18bb9bca0a41f8 size 1764417969 From bed2130fae729f565fab4ca418d3871e36ae359b Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Mon, 24 Aug 2026 19:40:36 -0700 Subject: [PATCH 4/7] spatial supercombo: rldriving 2004ef3b-0461-b0f9-a1c6-23f444b6ef71/12864 Path model 594c0fe7-649a-4e06-5239-f3cc64a67aac/56320. --- openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx index da8f43c1859e1a..4c6834093e29cb 100644 --- a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx +++ b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57a3bf0c312dbf14c054b8f7f9282d1bc9216b44476f2c842c18bb9bca0a41f8 -size 1764417969 +oid sha256:6afb28d58bfa7d7639832db8a61ff9209ef704ce1a9de2cdc20dd9004ec42bec +size 1757861459 From 0680e74d8e59b5488b4f5a89466fd00f6f6b22aa Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Wed, 26 Aug 2026 19:52:14 -0700 Subject: [PATCH 5/7] 45634de5-cf5a-418e-ad63-65498d0aaea3/12864 --- openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx index 4c6834093e29cb..a468305f2d5604 100644 --- a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx +++ b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6afb28d58bfa7d7639832db8a61ff9209ef704ce1a9de2cdc20dd9004ec42bec +oid sha256:9ef28165590af9be949230a36336e6d578bc656798e3d17c86656a2105460bea size 1757861459 From 83a461eb4f0cb5737132c24b7a5ad5de46fc0fbb Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Wed, 26 Aug 2026 19:57:43 -0700 Subject: [PATCH 6/7] faster compile --- openpilot/selfdrive/modeld/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpilot/selfdrive/modeld/SConscript b/openpilot/selfdrive/modeld/SConscript index 2169805772e32f..f65aebf2f91fe9 100644 --- a/openpilot/selfdrive/modeld/SConscript +++ b/openpilot/selfdrive/modeld/SConscript @@ -47,7 +47,7 @@ tg_devices = { # which device to put jit inputs to at runtime CHESTNUT = chestnut_present() if CHESTNUT: - chestnut_tg_flags = f'DEBUG=2 DEV=USB+AMD:LLVM WARP_DEV={tg_backend} FLOAT16=1 JIT_BATCH_SIZE=0 GMMU=0 TC_OPT=2' + chestnut_tg_flags = f'DEBUG=1 DEV=USB+AMD:LLVM WARP_DEV={tg_backend} FLOAT16=1 JIT_BATCH_SIZE=0 GMMU=0 TC_OPT=2' # the USB+AMD GPU takes an exclusive flock; serialize all targets that touch it chestnut_lock = File("models/.chestnut.lock").abspath From f877d7a0ccc3cce943c76e285214c020cd65c899 Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Sun, 30 Aug 2026 17:41:06 -0700 Subject: [PATCH 7/7] 23e6a04e-e6e5-462b-a0bb-e4088275ee43/12864 --- openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx index a468305f2d5604..bd92b1b8763c0a 100644 --- a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx +++ b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ef28165590af9be949230a36336e6d578bc656798e3d17c86656a2105460bea -size 1757861459 +oid sha256:a086d5249fc308bb73993d1e64630c669d4c7df5bde85f42ad61902543648525 +size 765953504