Repository navigation
Conversation
The five-value encoder weights were stored as 4-bit level codes (fv5-pair16-v1), so the GGUF was 330.6 MB, against 177 MB for Fermion's own container. fv5-b5x3t7-v1 stores three panel vectors' levels as one base-5 code per lane (< 125, so 7 bits) and packs 8 code vectors into 7: 2.35-2.41 bits per weight, 208.9 MB in all. Both layouts decode to the same int8 panels, so results are bit-identical. Every tier gets a decoder: scalar, NEON (dotprod and i8mm), and AVX2. The loader accepts both formats; the converter writes b5x3t7 by default and pair16 with --layout pair16. --verify checks both against the container. tools/bench-fv5-packing.cpp measures the decode cost per GEMM shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What
A denser code layout for Phonon-2's five-value encoder weights. The GGUF shrinks from 330.6 MB to 208.9 MB (−37%), with bit-identical results.
fv5-pair16-v1(current)fv5-b5x3t7-v1(this PR, default)phonon-2-fv5.ggufELIZA_ASR_USE_MMAP=0, peak RssAnon)Why the GGUF was bigger than the published 164 MB
The 164 MB on Hugging Face is
phonon-2.bps.tar.zst. It unpacks tomodel.fermion, 177.4 MB.In
model.fermion, the 604M five-value weights take 159.4 MB (2.11 bits/weight):That bit stream has variable length, so a kernel cannot start decoding at an arbitrary block without prefix counts.
fv5-pair16-v1gave every weight a 4-bit code, so 302 MB of the 331 MB GGUF were codes. The rest is the int8 decoder tables (22.4 MB), F32 lo/hi (3.5 MB) and small F32 tensors.For reference: log2(5) = 2.32 bits, and the measured level entropy is 1.95 bits (levels {−hi, −lo, 0, +lo, +hi} = 9.1/15.3/51.3/15.3/9.1%).
Layout (
pk-kernels.h,convert_phonon2_to_gguf.pypack_b5x3t7)Per 8-row block, take the K/2 16-byte panel vectors of the int8 GEMM three at a time. Lane j of a code vector = l(3t) + 5·l(3t+1) + 25·l(3t+2), which is below 125.
Because codes fit in 7 bits, 8 code vectors go into 7 stored vectors: byte m = code m | (bit m of code 7) << 7.
The decoder makes exactly the panel that pair16 makes, with the same 16-byte LUTs. Per code vector it runs:
x/5 = ((x+1)·51) >> 8: 2UMULL+UZP2, exact on 0..124 (checked at bench start);/25by a 32-byteTBL;MLS;ORR+TBL).Code 7 costs a 7-step
SRIgather.The AVX2 tier does the same with
PMULLW/PACKUSWB/PSHUFB. The scalar tier is the reference.The loader accepts both formats (
parakeet.weights.format). Tensors are named<w>.fv5t7, I8 [O/8, block bytes].The converter defaults to
--layout b5x3t7, and--layout pair16is still there.--verifyre-expands either layout against the container bit for bit. Output is byte-reproducible (two runs: same sha256).pins.jsonpins the new GGUF (sha256c0f6ad42…) and records the pair16 output of the same converter.Alternatives measured with a prototype (same bench)
Decode cost (
tools/parakeet/tools/bench-fv5-packing.cpp, new)Single thread, decode + the shipped tile per 8-row block, summed over the 24 layers' linears (ms per encoder pass). N = tokens (80 ms of audio each):
Equivalence evidence
test-parakeet-kernels: new checks.gemm_q8is bit-identical for both layouts.convert_phonon2_to_gguf.py --verify: OK for both layouts (264 five-value + 11 int records bit-identical, 723 records consumed, mel filterbank equal to librosa 0.11.0).parakeet-cli, 10 clips (5sayvoices + 5 Paradee samples), batch and--stream:eliza-inference-test-parakeet-asron the TB336FU (NDK r29, arm64, Release): passes with both GGUFs, matching the exact expected transcript, mapped (5 runs each) and private (3 runs each).Not covered
test-parakeet-paritywas not run: it needs the reference fixtures fromdump_parakeet_reference.py, which need torch. It is implied by the bit-identical panels and transcripts above.Downstream
packages/app/platforms/android/paradee-voice/inputs.json,voice-model-versions.json, Gracevoice.lock.json) need the new size and sha256.AI-assisted change.
🤖 Generated with Claude Code