[JAX] triangle attention#122
Conversation
mariogeiger
commented
Jun 25, 2025
- VJP rule
- Call cuda code only if we are running on a GPU
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a new triangle_attention operator in the JAX backend, complete with custom VJP support and optional CUDA acceleration, and updates documentation and tests accordingly.
- Added the
triangle_attentionimplementation with a custom forward/backward rule and GPU fallback. - Updated the API reference to include a new Triangle section for
triangle_attention. - Introduced unit tests for gradient correctness and basic functionality on CPU and CUDA.
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| docs/api/cuequivariance_jax.rst | Added a Triangle section in the API docs and autogeneration entry. |
| cuequivariance_jax/tests/triangle_attention_test.py | New tests covering gradient checks and output shapes for triangle_attention. |
| cuequivariance_jax/cuequivariance_jax/triangle/_triangle_attention.py | Implemented triangle_attention with custom VJP, JAX reference, and CUDA fallback. |
| cuequivariance_jax/cuequivariance_jax/triangle/init.py | Added license header in new triangle package directory. |
| cuequivariance_jax/cuequivariance_jax/init.py | Exported triangle_attention in the root module’s public API. |
Comments suppressed due to low confidence (2)
cuequivariance_jax/cuequivariance_jax/triangle/_triangle_attention.py:42
- The return type annotation '-> jax.Array' does not reflect that this function returns a tuple of three arrays; consider annotating it as '-> tuple[jax.Array, jax.Array, jax.Array]' for clarity.
) -> jax.Array: # [B, N, H, S_qo, D]
cuequivariance_jax/cuequivariance_jax/triangle/_triangle_attention.py:69
- [nitpick] The variable 'a' is ambiguous; consider renaming it to 'attn_logits' or 'attention_scores' to clarify its purpose.
a = jnp.einsum("...ai,...bi->...ab", q, k, precision=precision)
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. |
There was a problem hiding this comment.
Empty file. Do we need this?
I see imports are already taken care of in cuequivariance_jax/cuequivariance_jax/init.py
| def triangle_attention_fwd(q, k, v, mask, bias, scale, precision=None): | ||
| a, lse, amax = fwd_p.bind(q, k, v, mask, bias, scale=scale, precision=precision) | ||
| residuals = (a, lse, q, k, v, mask, bias) | ||
| return (a, lse, amax), residuals |
There was a problem hiding this comment.
why are we returning residuals? Is it a JAX requirement?
| da, dlse, damax = cotangents | ||
|
|
||
| dq, dk, dv, dbias = bwd_p.bind( | ||
| da, a, lse, q, k, v, mask, bias, scale=scale, precision=precision |
There was a problem hiding this comment.
For consistency with torch, isn't it better to do bias,mask rather than mask,bias ?
There was a problem hiding this comment.
good catch, done
| def fn(q, k, v, mask, bias): | ||
| return cuex.triangle_attention(q, k, v, mask, bias, scale) | ||
|
|
||
| output, lse, amax = fn(q, k, v, mask, bias) |
There was a problem hiding this comment.
why dont we have more elaborate parametrized tests for triattn in jax like in trimul (shapes, precision etc.)