Follow torch.sign in the engram gate - #177
Open
truong-v wants to merge 1 commit into
Open
Conversation
engram_gate_value_rms_kernel gates with tl.where(gate_raw >= 0, 1.0, -1.0), which has two outcomes, while the eager module in the same file gates with gate.sign(), which returns 0 for a zero input. At gate_raw == 0 - an all-zero query row, which is what a masked or padded position looks like - the law gives sigmoid(0) = 0.5 and the kernel gives sigmoid(sqrt(1e-6)) = 0.50025, because clamp_min(1e-6) keeps the tie from being degenerate. Use the three-way sign so the two paths agree, and add a test that compares the fused and eager modules on masked query rows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
engram_gate_value_rms_kernelgates withtl.where(gate_raw >= 0, 1.0, -1.0), which has two outcomes, whileEngramPt.forwardin the same file gates withgate.sign(), which returns 0 for a zero input. With theclamp_min(1e-6)in front of the square root, the tie is not degenerate: atgate_raw == 0the module givessigmoid(0) = 0.5and the kernel givessigmoid(sqrt(1e-6)) = 0.50025. A zerogate_rawis what a masked or padded position produces, since its query row is all zeros.Changes:
Measured on an L40S with both modules at the same weights and one masked position (
kernel_size=1, conv weight 1.0, so the fused path's half buffers are exact and only the gate can differ): masked rows had max abs error 6.85e-4 against ordinary rows at 6.20e-6 before this change, and 0.0 against 6.20e-6 after. Performance is unchanged — the sign is computed once per program, outside the channel loop: gate kernel atB=8, T=256, G=4, C=1024,do_benchinterleaved three times, 177.5–177.7 us before and 177.1–177.9 us after.Tests
The op had no test file. Added
tests/kernels/test_engram.py, which comparesEngramTriagainstEngramPton masked query rows in the shapeEngramPt.forwardsupports. It fails on the unfixed kernel (4838 of 5120 masked elements mismatched, max 6.85e-4 against a 1e-5 tolerance) and passes with the fix. The existing in-filetest_engram()passes unchanged.Fixes #176
Environment
main@ 26271d1