Repository navigation
transpiler: op routing, fusion & JAX-capture correctness - #706
Conversation
|
@ncylich not sure how to reproduce this bug, dont know if theres a model that trips any of these issues and dont wanna potentially introduce bugs regressing some model that we support |
|
@kar-m good call wanting repro + regression confidence before merging. I reproduced each of these against
On the regression worry directly: the new code in every file is gated to fire only on the exact buggy trigger. I ran the no-op cases — Your call on scope: since 5/6 are defensive guards for patterns no current model emits, I'm happy to slim this PR to just the |
|
@jakmro with the context given by Noah about reproducibility I don't know if this should be merged -- deferring to you. |
e8aa357 to
7b73b7a
Compare
|
@kar-m @jakmro following up on the reproducibility/regression concern — and correcting something I said above. Correction: I previously called So I took the conservative path and removed every change that no model — current or future — can reach on the FP16 engine + eval-mode export pipeline:
What remains — each is reachable, and none can regress a model we support today:
Net: the removed changes restore origin behavior exactly for every supported model; the kept changes are a crash-fix, a fail-closed guard against silent wrong output, a mask-preservation fix, and JAX-path slice/gather correctness. Verified green: |
7b73b7a to
e22e099
Compare
|
@kar-m @jakmro I went back and actually ran each change against Reached (kept):
Dropped as unreachable by any model on the FP16 engine / standard import pipeline:
Verified green with JAX installed so the capture tests actually run: |
Runnable repros that reach each path #706 touches and show the dropped ones are unreachable: aten_ops mis-routing, scaled-addmm fail-closed, rms_norm non-last-dim mis-fusion, capture_jax strided-slice aliasing, plus the unreachable SDPA mask/dropout and no-training batchnorm cases. This commit is reverted immediately so it stays referenceable by SHA without entering the squash/merge. Signed-off-by: Noah Cylich <noahcylich@gmail.com>
…for merge)" This reverts commit 94fc381. Signed-off-by: Noah Cylich <noahcylich@gmail.com>
|
For anyone who wants to re-run the reachability checks: I committed the repro scripts in 4d4f745 and immediately reverted them in the next commit, so they're checkout-able by SHA but stay out of the squash/merge (the PR's net diff is still just the 4 fix files). git checkout 4d4f7451ee36 -- python/tests/transpile/tools/repro_706
python python/tests/transpile/tools/repro_706/repro_pytorch.py # routing, batchnorm form, scaled-addmm, SDPA mask, rms_norm
pip install "jax[cpu]" && python python/tests/transpile/tools/repro_706/repro_jax.py # strided-slice aliasing
bash python/tests/transpile/tools/repro_706/origin_vs_pr.sh # origin/main vs this branch, one file swapped at a time
|
aten_ops.py: match the longest op prefix first so minimum/maximum/slice_scatter/select_scatter/addmm aren't shadowed by a shorter prefix (origin mis-routed addmm->add, minimum->min, maximum->max, slice_scatter->slice, select_scatter->index). importers.py: fail closed on scaled addmm (beta/alpha != 1) instead of silently dropping the scale. fusion/rms_norm.py: only fuse RMSNorm when the mean reduces the last dim, so a non-last-dim mean-square chain isn't mis-fused into a last-dim kernel with a wrong-sized weight. capture_jax.py: stride-aware slice aliasing so a strided slice (e.g. x[::2]) isn't treated as a no-op alias, plus avoid registering a duplicate gather-squeeze reshape. Signed-off-by: Noah Cylich <noahcylich@gmail.com>
Runnable repros that reach each path #706 touches and show the dropped ones are unreachable: aten_ops mis-routing, scaled-addmm fail-closed, rms_norm non-last-dim mis-fusion, capture_jax strided-slice aliasing, plus the unreachable SDPA mask/dropout and no-training batchnorm cases. This commit is reverted immediately so it stays referenceable by SHA without entering the squash/merge. Signed-off-by: Noah Cylich <noahcylich@gmail.com>
…for merge)" This reverts commit 4d4f745. Signed-off-by: Noah Cylich <noahcylich@gmail.com>
ffb392b to
8dbe3be
Compare
Surgical transpiler correctness fixes. Each change below was reached with a runnable repro on the real capture/import pipeline; changes that no model can reach were dropped (see review thread).
normalize_targeton origin mis-routesaten.addmm→add,aten.minimum→min,aten.maximum→max,aten.slice_scatter→slice,aten.select_scatter→index; a model usingtorch.minimum/torch.maximum/torch.addmmreaches this.addmm(beta/alpha != 1) instead of silently dropping the scale. Reached:torch.addmm(bias, a, b, beta=2.0)now raises a clear capture error.meanreduces the last dim. Reached: a channel-wisex * rsqrt(x.pow(2).mean(1, keepdim=True) + eps) * wover(B,C,H,W)(FP16) is otherwise fused into a last-dim kernel with a wrong-sized weight (observed: weight(5,)for a channel dim of 4) → silently wrong output. The guard skips that fusion while leaving normal last-dim RMSNorm fused (no regression).x[::2]on a length-6 vector returns the full length-6 input aliased as a no-op on origin (out_shape=(6,)), vs a correct length-3sliceon this branch.Dropped as unreachable by any model on the FP16 engine / standard import pipeline (verified empirically):
lower.pyclamp/finite-scalar changes — the only behavioral change is the non-FP16 branch, which the FP16 working precision never executes.import_semantics.py— the SDPA nonzero-dropout guard (dropout_pis always 0 aftermodel.eval()), and the literal-mask passthrough (attrs["mask"]is only set for a non-tensor literal mask, but SDPAattn_maskis always a Tensor/None, so it is never produced).importers.pyBatchNorm no-training branch —_native_batch_norm_legit_no_trainingonly appears afterrun_decompositions, which in this repo runs solely on the NPU→CoreML path; the IR importer always sees the 8-argaten.batch_norm.default, handled identically before and after.Verified:
pytest python/tests+pytest python/cactus/convert/tests(264 passed, 1 skipped; JAX capture tests included).