Skip to content

Add ANE quantization probe and expand project scope to GPT-2 - #16

Closed
m0at wants to merge 7 commits into
maderix:mainfrom
m0at:claude/explore-repo-planning-sriBk
Closed

Add ANE quantization probe and expand project scope to GPT-2#16
m0at wants to merge 7 commits into
maderix:mainfrom
m0at:claude/explore-repo-planning-sriBk

Conversation

@m0at

@m0at m0at commented Mar 3, 2026

Copy link
Copy Markdown

Summary

This PR adds a comprehensive quantization probe for Apple Neural Engine (quant_probe.m) and significantly expands the project README to document GPT-2 inference, M5 hardware investigation, and fused kernel benchmarking work.

Key Changes

New Files

  • quant_probe.m (551 lines) — Systematic probe to determine if ANE executes int8/int4 quantized operations natively or only dequantizes to fp16:
    • Tests 5 quantization schemes: FP16 baseline, INT8 affine dequantize, UINT4 affine dequantize, UINT4 blockwise (block_size=32), and LUT4 palettized
    • Generates MIL programs at runtime for each quantization type with proper weight blob builders
    • Benchmarks each variant across representative transformer dimensions (768→768, 768→2048, 2048→768, 1024→1024, 2048→2048)
    • Interprets results: 2x speedup indicates native int8, 4x indicates native int4, same speed indicates dequant-only
    • Includes weight blob builders for fp16, int8, int4 (packed nibbles), scale/zero-point tensors, and LUT indices

Documentation Updates

  • README.md — Completely restructured to reflect project evolution:
    • Reframed as "Running Transformers on Apple's Neural Engine" with GPT-2 as primary focus
    • Added GPT-2 inference section with two-phase architecture (ANE prefill + CPU KV-cache decode)
    • Documented M5 hardware investigation findings (weight swapping, weightsBuffer override, QoS effects, chaining API rejection)
    • Added fused kernel benchmark results and dispatch overhead analysis
    • Expanded file structure to include all new test files and investigation documents
    • Clarified that project extends upstream maderix/ANEtransformers work

Implementation Details

Quantization Probe Architecture:

  • Reuses ANE private API boilerplate (class resolution, IOSurface creation, mach_timebase timing)
  • MIL generators for each quantization scheme with proper tensor type annotations (int8, uint4, uint8)
  • Uses constexpr_affine_dequantize for per-channel quantization and constexpr_blockwise_shift_scale for block-wise int4
  • Uses constexpr_lut_to_dense for palettized weights with shared 16-entry lookup table
  • Benchmarks with 10 warmup iterations + 100 timed iterations, reports ms/eval and TFLOPS

Weight Blob Format:

  • Consistent 128-byte header structure across all blob types (magic bytes, size, offset)
  • FP16: 2 bytes per weight; INT8: 1 byte per weight; INT4: packed nibbles (2 per byte)
  • Scale/zero-point blobs for affine dequantization; blockwise scale as [oc, n_blocks, 1, 1]
  • LUT blob as [1, 1, 16] shared across all output channels

The probe enables empirical determination of ANE quantization capabilities without relying on undocumented compiler behavior or reverse-engineering binary outputs.

https://claude.ai/code/session_01U5HLjsm4iUzL9iDaHbxeRB

m0at and others added 7 commits March 2, 2026 13:02
Forked the project and updated the README to reflect changes.
Updated README to clarify implementation details and added NEON CPU decode.
…ttribution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Probe whether Apple Neural Engine executes quantized ops natively
(faster int8-int8 compute path) or just dequantizes to fp16 at load time.

Tests 5 approaches at transformer-representative dimensions:
1. FP16 baseline conv (baked weights)
2. INT8 via constexpr_affine_dequantize (per-channel scale+zp)
3. UINT4 via constexpr_affine_dequantize (per-channel)
4. UINT4 via constexpr_blockwise_shift_scale (block_size=32)
5. 4-bit palettized via constexpr_lut_to_dense (16-entry LUT)

Each test compiles MIL → ANE kernel, benchmarks 100 evals, reports
TFLOPS. If int8 shows ~2x fp16 TFLOPS, ANE has native int8 compute.
If same TFLOPS, it's dequant-only (still useful for memory savings).

Build: xcrun clang -O2 -fobjc-arc -o quant_probe quant_probe.m \
       -framework Foundation -framework IOSurface -ldl

https://claude.ai/code/session_01U5HLjsm4iUzL9iDaHbxeRB
@m0at m0at closed this Mar 3, 2026
ebowwa pushed a commit to ebowwa/ANE that referenced this pull request Aug 4, 2026
…uristics

ane_mil.parse() extracts funcs (signature inputs/outputs) and statements (op, args, attrs,
output dtype/shape) via balanced bracket matching; ane_mil.validate() checks the Orion
catalog precisely — banned ops (concat/gelu) by op-name, conv bias=, matmul transpose-const
(maderix#12), 32K-channel conv (maderix#16), output liveness (maderix#14), multi-output uniform (#2) +
alphabetical binding (maderix#3), multi-input alphabetical (maderix#19).

ane_lint.lint_mil uses the parser as primary and falls back to the regex checks when a
program won't parse; size checks (maderix#4 min / maderix#18 input-uniform) and perf advisories always
run. End-to-end via /raw/lint (func-wrapped gelu -> ANE010, relu -> ok). 71 tests (9 new
parser tests).

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants