gguf: let a finished GGUF be re-converted - #464
Conversation
Re-quantising a GGUF that audiocpp_gguf produced fails today, and the error points at the wrong thing (0xShug0#457): $ audiocpp_gguf --input ACE-Step1.5-XL-Turbo-bf16.gguf --type q8_0 --output test.gguf error: no GGUF sidecars were found ... Three things stand in the way. The conversion's namespaces come from the `namespace=` labels on the command line, so a GGUF whose tensors are already named `dit_xl_turbo_weights/...` presents as one unnamed namespace and matches nothing in its own family. With no `--family`, the catalog search then settles on whichever unrelated spec accepts a single unnamed namespace -- `sense_asr` -- and the run dies later, in sidecar embedding. When it does not die it is worse: re-converting the Kroko GGUF with any small text file beside it succeeds and writes `model_spec_family=sense_asr` into the output. And the sidecars the input already carries go unused, because collection only walks `--root`. So: read the namespaces back out of a GGUF input's tensor names, register its embedded model spec as the top-priority candidate and let it set the default family, and fall back to its embedded sidecars when neither `--root` nor `--sidecar` was given. A re-conversion also stops requiring every namespace the spec declares -- a package built with `--exclude-prefix` (an ACE-Step XL GGUF carries no turbo or base DiT) ships fewer than the spec lists, and the runtime loads it happily. docs/models/ace_step.md said building an XL GGUF "needs the other variants' safetensors on hand". It does not: the namespace check only reads the labels and `--exclude-prefix` drops those tensors before any data is touched, so a 76-byte placeholder works and the build needs 24 GB of downloads rather than 33 GB. The section now shows that, notes that only the two config.json files are genuinely required, and documents quantising the DiT alone -- q8_0's "planner sampling can fail" grade is about the planner LM, and keeping it at bf16 holds a 0.989 waveform correlation against the bf16 build at a fixed seed where a fully quantised build scores 0.09. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AYQxP9KPBeGmGRRhptbQWp
`ace_step_xl_turbo_q8dit` and `ace_step_xl_sft_q8dit` install the q8_0-DiT builds next to the bf16 ones, from the same repo the bf16 rows already point at. 9.97 GiB against 14.2 GiB, and at a fixed seed the output holds a 0.989 waveform correlation with the bf16 build (0.997 on a sung take, 0.999 for XL SFT) where a fully quantised build scores 0.09. `precision` is the validated enum, so these rows carry `q8_0` — the type the conversion was run at. What the planner LM, text encoder and VAE keep is in the id and display name instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AYQxP9KPBeGmGRRhptbQWp
|
Pushed one more commit: I had left these out on the grounds that they point at
|
|
@CaptainArni PR merged! Thank you again for addressing the issue so quickly! |
Re-quantising a GGUF that
audiocpp_ggufitself produced does not work today, and the way it fails is worse than the failure. From #457:That message is a symptom. Three things are going on.
A GGUF input's namespaces are ignored.
select_package_specbuilds the conversion's namespace set from thenamespace=labels on the command line, so a GGUF whose tensors are already nameddit_xl_turbo_weights/…,lm_weights/…, … presents as one unnamed namespace and matches nothing in its own family.Which lets an unrelated family's spec match instead. With no
--family, the catalog is searched andsense_asr— the only spec accepting a single unnamed namespace with no required on-disk sidecars — validates cleanly. The run then dies later, in sidecar embedding, which is the error above. Worse is when it doesn't die: re-convertingkroko-en-community-64-l-q8_0.ggufwith any small text file next to it succeeds and writesmodel_spec_family=sense_asrinto the output.And the sidecars the file already carries go unused. The input GGUF embeds its own configs and tokenizers, but sidecar collection only walks
--root, so a standalone GGUF cannot supply them.Changes
input_namespaces()reads the namespaces back out of a GGUF input's tensor names when no explicit label is given, so an audio.cpp GGUF validates against the spec it was built from.sense_asrmislabel happens.resolve_sidecar_root()falls back tomaterialize_gguf_sidecars()when--rootis not given and the input's directory offers no sidecars and no--sidecarwas passed. Existing invocations resolve exactly as before.Result
and the Kroko case now writes
model_spec_family=kroko_asr.Docs
docs/models/ace_step.mdclaimed that building an XL GGUF "needs the other variants' safetensors on hand". It doesn't: the namespace check only reads the CLI labels, and--exclude-prefixdrops those tensors before any data is read, so a 76-byte placeholder file works and the build needs 24 GB of downloads rather than 33 GB. That was the reporter's main complaint in #457 and it was a fair one — the section now shows the placeholder, notes that only the twoconfig.jsons are genuinely required, and documents the mixed-precision build below.The same section now records that q8_0's
No (planner sampling can fail)grade is about the planner LM rather than the DiT, with the--keep-typeinvocation that quantises the DiT alone. Measured on an RTX 5090 at a fixed seed, 20 s of audio: 9.97 GiB against 14.2 GiB, 9.3 s against 14.2 s, and a 0.989 waveform correlation against the bf16 output (0.997 on a sung 40 s take, 0.999 for XL SFT). A fully quantised build of the same weights correlates 0.09 and sings a different lyric line. Both mixed-precision files are up at CaptainArni/audio.cpp-gguf if you want a package row for them.Testing
There is no harness that drives
audiocpp_ggufend to end, so this was verified by hand on Windows/CUDA (RTX 5090):model_spec_family=ace_step, sidecars re-embedded. Generating from the result at a fixed seed gives a 0.9965 waveform correlation against the bf16 original — closer than the same build made from safetensors (0.989), since it quantises from the same bf16 values.kroko-en-community-64-l-q8_0.ggufwith no--root: nowmodel_spec_family=kroko_asr, where before it either failed on sidecars or silently wrotesense_asr.docs/models/ace_step.mdstill resolves toace_stepwith the same namespaces, exclusions and sidecar flags.--rootstill overrides the embedded sidecars (verified by pointing it at a directory that lacks them and watching validation fail on the missing ones).Happy to add a converter test if you want one — say where it should live.
🤖 Generated with Claude Code