Skip to content

Commit 08d1576

Browse files
committed
M7: PLAN + RELEASE notes
- Renumber milestones: M7 = conformance breadth (this), M8 = native conv (lift Backend.conv off the BinaryBackend fallback), M9 = 1.0 release (was M7). - M7 section documents the two new models and the rationale (vision, encoder-decoder, conv coverage) and records that MoE / Mixtral is deferred pending upstream Bumblebee support. - RELEASE.md accumulates the added test suites, the shared ConformanceHelper, the test_helper exclude-list update, and the via_binary default-backend fix surfaced by ViT tiny-random.
1 parent a524c12 commit 08d1576

2 files changed

Lines changed: 108 additions & 1 deletion

File tree

PLAN.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,47 @@ If MLX gains matmul-adjacent fusion (bias-fused matmul, attention
214214
fusion outside `fast::scaled_dot_product_attention`), re-run the bench
215215
and revisit.
216216

217-
### M7 — 1.0 release
217+
### M7 — Bumblebee conformance breadth: ViT + Whisper
218+
219+
DistilBERT (M3) and Qwen3 (M4) cover encoder-only and decoder-only
220+
transformers but leave three architectural shapes untested: 2-D
221+
convolution, encoder-decoder cross-attention, and the Bumblebee
222+
vision/audio pipelines. M7 closes the first two gaps.
223+
224+
- **ViT** (`google/vit-base-patch16-224`): vision, encoder-only,
225+
conv patch embedding, GELU FFN, classifier head. First suite to
226+
exercise the `conv` fallback in anger (`lib/emily/backend.ex` still
227+
routes `conv` through BinaryBackend as of M7 — correct but slow).
228+
- **Whisper** (`openai/whisper-tiny`): audio, encoder-decoder, 1-D
229+
conv encoder frontend, sinusoidal position encodings, and
230+
cross-attention KV-cache in the decoder.
231+
232+
Each suite ships two tiers: a tiny-random tier that mirrors
233+
Bumblebee's own test (HuggingFace Transformers reference slices) and
234+
a full-checkpoint tier with deterministic synthetic inputs pinned
235+
against the real-weight forward pass on Emily. Both gated as in M3
236+
and M4: `:conformance` for tiny (opt in via `--only conformance`),
237+
per-model `:*_full` tag for full (opt in separately).
238+
239+
Shared scaffolding (`test/support/conformance_helper.ex`) lifts the
240+
`setup_all` backend swap and `assert_all_close/3` out of each suite.
241+
242+
**MoE / Mixtral deferred**: the pinned Bumblebee ref ships no
243+
Mixtral or MoE architecture. Track as a follow-up; revisit when
244+
upstream lands.
245+
246+
**Exit:** ViT and Whisper each pass both tiers on Apple Silicon;
247+
`mix test --only conformance` aggregates 14 tiny-random tests across
248+
all four Bumblebee models.
249+
250+
### M8 — Native conv
251+
252+
Lift `Backend.conv` onto `Native.conv_general` (the NIF already
253+
exists; only the Backend callback still routes through the
254+
BinaryBackend fallback). Gated on the M7 ViT and Whisper suites
255+
staying green through the switchover.
256+
257+
### M9 — 1.0 release
218258

219259
- API docs, HexDocs, README with a worked Bumblebee example
220260
- Hex release (public), versioned per conventions (`@version` in mix.exs)

RELEASE.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,72 @@
11
# Release notes for next release
22

3+
## Added
4+
5+
- M7 — Bumblebee conformance breadth. Two new models across four
6+
new test suites extend M3 (DistilBERT) and M4 (Qwen3) beyond
7+
encoder-only/decoder-only text into vision and audio.
8+
- **`test/emily/conformance/vit_test.exs`**
9+
(`@moduletag :conformance`) — ports `Bumblebee.Vision.VitTest`
10+
verbatim: three tiny-random architectures (`:base`,
11+
`:for_image_classification`, `:for_masked_image_modeling`)
12+
driven with synthetic pixel input `Nx.broadcast(0.5, {1, 30, 30,
13+
3})`, asserted against the same PyTorch-produced reference
14+
slices Bumblebee's own suite pins. First conformance suite to
15+
exercise the `conv` fallback path in anger.
16+
- **`test/emily/conformance/vit_full_test.exs`**
17+
(`@moduletag :vit_full`, excluded from `--only conformance`
18+
because the checkpoint is ~330 MB) — loads
19+
`google/vit-base-patch16-224`, runs a forward pass on a
20+
deterministic constant-gray pixel tensor, asserts a pinned
21+
leading-5 logits slice plus argmax == 763 (ImageNet class
22+
"revolver"). Uses synthetic input rather than a checked-in JPEG
23+
fixture so the repo stays free of binary assets and the
24+
featurizer doesn't enter the assertion surface. Run with
25+
`mix test --only vit_full`.
26+
- **`test/emily/conformance/whisper_test.exs`**
27+
(`@moduletag :conformance`) — ports `Bumblebee.Audio.WhisperTest`
28+
verbatim: two tiny-random architectures (`:base`,
29+
`:for_conditional_generation`) driven with the same
30+
`Nx.sin(Nx.iota({1, 60, 80}))` mel features and decoder ids,
31+
asserted against Bumblebee's reference slices. First
32+
conformance suite to exercise encoder-decoder cross-attention on
33+
Emily, and the first with strided 1-D conv in the encoder
34+
frontend.
35+
- **`test/emily/conformance/whisper_full_test.exs`**
36+
(`@moduletag :whisper_full`, excluded from `--only conformance`
37+
because the checkpoint is ~150 MB) — loads
38+
`openai/whisper-tiny`, runs a forward pass on a synthetic 30-s
39+
mel window (`sin(iota({1, 3000, 80}) * 0.01)`), asserts pinned
40+
leading 3×3 logits slice + decoder-last-step argmax. Run with
41+
`mix test --only whisper_full`.
42+
- **`test/support/conformance_helper.ex`** — shared `use`-able
43+
module lifting the `setup_all` backend-swap block and
44+
`assert_all_close/3` out of DistilBERT, Qwen3, ViT, and Whisper
45+
suites. Net change before the two new suites was ~zero LOC;
46+
keeps future conformance additions terse.
47+
- **`test_helper.exs`** — exclude list extended with `:vit_full`
48+
and `:whisper_full`. Comment rewritten to document each
49+
heavyweight tag and its cache footprint.
50+
- **`PLAN.md`** — renumbered: M7 = conformance breadth (this),
51+
M8 = native conv, M9 = 1.0 release (was M7). MoE / Mixtral
52+
tracked as deferred pending upstream Bumblebee support.
53+
54+
## Fixed
55+
56+
- `Emily.Backend.via_binary/via_binary_tuple` — pin the default
57+
backend to `Nx.BinaryBackend` for the duration of the fallback
58+
`fun` call. Surfaced when ViT tiny-random exercised `conv`: the
59+
helpers transferred input tensors correctly, but `Nx.conv`
60+
constructs a scalar internally (`Nx.pad(t, 0, ...)` builds a
61+
zero-pad tensor) and that scalar landed on whatever the current
62+
global default was — `Emily.Backend`, because the conformance
63+
`setup_all` installs it. BinaryBackend then saw a mixed-backend
64+
operand list and crashed with a FunctionClauseError on `to_binary`.
65+
Never surfaced before because `test/emily/backend_fallbacks_test.exs`
66+
doesn't install Emily as the global default (tensors built with
67+
`backend: Emily.Backend` opt-in) and every prior Bumblebee suite
68+
had its hot-path ops off the fallback by M4.
69+
370
## Changed
471

572
- M6 — `mlx::core::compile` wrapping: **dropped** after Phase-1

0 commit comments

Comments
 (0)