Skip to content

sync: whisper support in base-convert (open-core source) - #40

Merged
prabod merged 3 commits into
mainfrom
sync/whisper-converter
Aug 9, 2026
Merged

sync: whisper support in base-convert (open-core source)#40
prabod merged 3 commits into
mainfrom
sync/whisper-converter

Conversation

@prabod

@prabod prabod commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Brings the Whisper HF-safetensors mapper across so the public converter can build the .base bundles the 0.2.1 engine transcribes. base-arch had no whisper.rs at all, so basert convert could not produce a Whisper bundle — even though converted Whisper bundles are already published for people to pull.

Scope

Converter only. The whisper C API and its bindings are deliberately not here: they call into libbaseRT, and the released 0.2.0 binary has no transcription entry points, so shipping those bindings now would break against the engine users actually have. They belong with the 0.2.1 release sync — same ordering as the 0.1.7 and 0.2.0 syncs.

Included

  • crates/base-arch/src/whisper.rs — the mapper. All twelve variants (tinylarge-v3-turbo, incl. .en), tensor renaming, and special-token IDs read from each model's own tokenizer.json rather than inferred from vocabulary size — the inference is what mis-mapped large-v3's ids.
  • crates/base-arch/tests/fixtures/whisper-tiny-added-tokens.json — the genuine added_tokens array trimmed to ids ≤ 50364. whisper.rs include_bytes!s this, so it is a build dependency, not just test data.
  • base-arch/src/lib.rs — dispatch entry, arch list, and the encoder-decoder ArchConfig fields (encoder layers/heads/ffn, mel bins, source/target positions) plus their header emission.
  • base-format/src/header.rs — the top-level metadata map the whisper token ids are written into; three test files updated for the new struct field.
  • base-convert/src/main.rs — the whisper convert path.
  • profiles/whisper-{f16,q8,q4}.json — see the judgement call below.
  • The whisper case in base-quant/src/profile.rs's tests.

Excluded (unchanged from the #37 policy)

The tuned per-family quant profiles stay private. Concretely, profile.rs upstream also gained tests for gemma4-moe-mlx, moe-q4mix and q3-aggressive; those load profile files that are not published, and the tests resolve profiles from disk at run time, so bringing them would fail here on a missing file. Only the whisper test came across.

Also excluded as unrelated drift: base-arch/src/gemma.rs and base-convert/src/hub.rs.

One judgement call

The whisper profiles are included. They are architecture-enabling rather than a tuned recipe — they say which tensor classes may be quantized for this architecture (block linear projections only; the convolutional front end, positional and token embeddings, norms and biases stay f16), in the same spirit as the published default-* profiles. Without them the public converter could only emit f16, while quantized Whisper bundles are published — users could pull them but never reproduce them. Say the word if you'd rather hold them back.

Validation

In this tree:

  • cargo build --locked --workspace
  • cargo test --workspace218 passed, 0 failed (13 whisper, including the real-tokenizer test, which runs only because the fixture is here)
  • cargo clippy --all-targets --workspace -- -D warnings ✓ clean
  • Every profile referenced anywhere in crates/ is present in profiles/

End to end, with the binary built from this branch:

  • openai/whisper-tiny → f16 .base (167 tensors, 75 MB)
  • openai/whisper-tiny → q8 .base via the shipped profile (59 MB)
  • the f16 bundle transcribes jfk.wav: "And so my fellow Americans ask not what your country can do for you, ask what you can do for your country."

prabod added 3 commits August 9, 2026 20:21
Brings the Whisper HF-safetensors mapper across so the public converter can
produce the .base bundles the 0.2.1 engine transcribes. Until now base-arch
had no whisper.rs at all, so 'basert convert' could not build a Whisper
bundle even though converted bundles are published for it.

Scoped to the converter. The whisper C API and its bindings are deliberately
NOT here: they call into libbaseRT, and the released 0.2.0 binary has no
transcription entry points — shipping those bindings now would break against
the engine users actually have. They belong with the 0.2.1 release sync, the
way 0.1.7 and 0.2.0 were done.

Included:
- crates/base-arch/src/whisper.rs — the mapper: all twelve variants
  (tiny..large-v3-turbo incl. .en), tensor renaming, and special-token IDs
  read from each model's own tokenizer.json rather than inferred from vocab
  size (which is what mis-mapped large-v3's ids).
- crates/base-arch/tests/fixtures/whisper-tiny-added-tokens.json — the real
  added_tokens array, trimmed to ids <= 50364. whisper.rs include_bytes! this,
  so it is a build dependency, not just test data.
- base-arch/src/lib.rs — dispatch entry, arch list, and the encoder-decoder
  ArchConfig fields (encoder_layers/heads/ffn, mel bins, source/target
  positions) plus their header emission.
- base-format/src/header.rs — the top-level metadata map the whisper token
  ids are written into; three test files updated for the new struct field.
- base-convert/src/main.rs — the whisper convert path.
- profiles/whisper-{f16,q8,q4}.json — architecture-enabling, in the same
  spirit as the default-* profiles: they say which tensor classes may be
  quantized for this architecture (block linears only; conv front end,
  positional/token embeddings, norms and biases stay f16). The tuned
  per-family mixes remain private.
- The whisper case in base-quant/src/profile.rs's tests. The other new tests
  there load gemma4-moe-* / *-q4mix profiles that stay private, so they are
  omitted — they would fail here on a missing file.

Validated in this tree: cargo build --locked --workspace, cargo test
--workspace (218 passed, 0 failed, 13 of them whisper), cargo clippy
--all-targets -D warnings clean, and every profile referenced by code is
present. End to end: converted openai/whisper-tiny to f16 (75 MB) and to q8
via the shipped profile (59 MB), and the f16 bundle transcribes jfk.wav
correctly.
Missed in the first pass and found by tools/sync_public.py, which derives the
public surface from rules rather than from memory. It builds a synthetic HF
whisper checkpoint, converts it through the real binary with the two shipped
whisper profiles, and pins the on-disk contract: block linears carry the
packed scheme, the conv front end / positional embeddings / token embedding /
norms / biases stay f16, the header records the profile, and a no-profile
conversion stays all-f16.

Depends only on whisper-q8.json and whisper-q4.json, both in this PR.
3 passed here.
Publishes the eighteen tuned quantization profiles that were previously held
back, per a deliberate call to open them.

It removes a structural wart as well as a policy one. base-quant's profile
tests resolve profiles from disk at run time, so a test covering a withheld
profile could not be published either — profile.rs had to be hand-curated on
every sync, the one file where a file-granular allow-list did not work. With
every profile public the file syncs whole, and its gemma4-moe-mlx, moe-q4mix
and q3-aggressive cases run here for the first time.

Also completes the converter to 0.2.1: the gemma mapper, hub resolution, and
the workspace version bump, so the published source matches the engine the
0.2.1 tag will ship rather than trailing it.

cargo build --locked --workspace, 226 tests passing (59 in base-quant), clippy
--all-targets -D warnings clean.
@prabod prabod closed this Aug 9, 2026
@prabod prabod reopened this Aug 9, 2026
@prabod
prabod merged commit 4d80919 into main Aug 9, 2026
10 of 13 checks passed
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