Skip to content

M10 (partial): quantized inference primitives - #19

Merged
ausimian merged 1 commit into
mainfrom
m10-quantized-inference
Apr 15, 2026
Merged

M10 (partial): quantized inference primitives#19
ausimian merged 1 commit into
mainfrom
m10-quantized-inference

Conversation

@ausimian

Copy link
Copy Markdown
Owner

Summary

  • Binds MLX's affine int4/int8 group-wise quantization — Native.quantize/3, Native.dequantize/5, Native.quantized_matmul/7 — plus Emily.QuantizedWeight (Nx.Container-derived struct) and Emily.Quantization.quantized_matmul/2 direct-call helper for eager use.
  • Scope narrowed vs. PLAN.md: Axon layer-op dispatch, Backend.dot/7 routing, and the Qwen3-0.6B-AWQ conformance test are deferred to M10.5. Investigation uncovered that Nx.dot/2 collapses multi-tensor containers before reaching the backend, and Nx.Defn.Evaluator has no public hook to inject a custom op that isn't already a Nx.Backend callback. Three candidate approaches for M10.5 are documented in PLAN.md (defn-native dequantize, Emily.Compiler custom-op intercept, upstream Nx extension).
  • Tests: +7 Native cases, 13 Elixir cases in test/emily/quantization/, and a 1k-iter memory soak. mix precommit: 238 tests, 0 failures, credo clean.

Scope note

The quantized_matmul/7 NIF takes transpose as an explicit arg rather than PLAN's /6 signature — AWQ packed layouts need transpose=false while fresh-from-dense weights use transpose=true, and MLX exposes it as a required parameter.

Test plan

  • mix precommit (compile --warnings-as-errors, format, credo --strict, full test suite)
  • mix test test/emily/native_test.exs --only describe:quantization — 7/7
  • mix test test/emily/quantization/ — 13/13
  • mix test test/soak/quantized_memory_test.exs — 1/1 (under 1 s wall)

Binds MLX's affine int4/int8 group-wise quantization at the Native
and Elixir levels plus a direct-call helper for eager use. Scope
narrowed vs. PLAN.md's original M10 — the Axon-layer dispatch,
Bumblebee AWQ conformance, and Backend.dot/7 routing are deferred
to M10.5 because `Nx.Defn.Evaluator` has no public hook to inject a
custom op that isn't an `Nx.Backend` callback, and `Nx.dot/2`
collapses multi-tensor containers before reaching the backend. See
RELEASE.md and PLAN.md §M10.5 for the three candidate defn-
integration approaches.

- Native NIFs (c_src/ops/linalg.cpp): quantize/3 returning a
  3-tuple {w_q, scales, biases}, dequantize/5, quantized_matmul/7
  with explicit transpose (AWQ layouts need transpose=false).
- Emily.QuantizedWeight — Nx.Container-derived struct with keep:
  so scalar metadata (group_size, bits, transpose) survives
  container traversal. Validates rank, last-axis divisibility,
  dtype, bit count before dispatch.
- Emily.Quantization.quantized_matmul/2 — direct-call helper for
  eager/benchmark use over materialized tensors.
- Tests: +7 cases in test/emily/native_test.exs, 13 cases across
  test/emily/quantization/, and a 1k-iter memory soak in
  test/soak/quantized_memory_test.exs asserting packed-weight
  footprint invariants.

mix precommit: 238 tests, 0 failures, credo clean.
@ausimian
ausimian merged commit 2c1f3e0 into main Apr 15, 2026
1 check passed
@ausimian
ausimian deleted the m10-quantized-inference branch April 15, 2026 07:22
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.

1 participant