fix(voxcpm1): extract tokenizer/config directly from GGUF for standalone packages - #396
Closed
jasonchen31 wants to merge 2 commits into
Closed
fix(voxcpm1): extract tokenizer/config directly from GGUF for standalone packages#396jasonchen31 wants to merge 2 commits into
jasonchen31 wants to merge 2 commits into
Conversation
added 2 commits
September 2, 2026 12:32
…one packages Standalone VoxCPM1-GGUF (voxcpm-0.5b-q8_0) is LLama-style (general.architecture=llama, embedded_sidecars=false) with tokenizer.ggml.* and voxcpm_* KV. Previous runtime required external sidecars via load_resource_bundle (model_specs voxcpm1.json sources.files: config/tokenizer_json/tokenizer_config) → missing tokenizer_config. - assets.cpp: parse_config_from_gguf + locate_gguf fallback, relaxed locenc.special_token, load_voxcpm1_assets try/catch builds minimal ResourceBundle via prepare_model_directory when sidecars missing - tokenizer_text.cpp: has_file check → load_tokenizer_from_gguf from tokenizer.ggml.tokens/merges/token_type==3 - minicpm.cpp: flexible locenc.special_token [1,1,1,1024] vs [1024] - audiovae.cpp: flexible snake alpha, missing sr_cond, final conv shape Verified with local SenseVoice-Small-GGUF sense_asr: TTS 'Hello world, this is a test.' → sense_asr correct, clone with reference_text → sense_asr correct, inspect on GGUF-only dir no longer throws. model_specs unchanged.
Port audio8_tts OpenCC fix (0eec2be) to voxcpm1 to avoid Cantonese mis-trigger on Traditional input without yue language. Uses shared engine::text::chinese_variant (TSCharacters 3222) and keeps Traditional only for yue/cantonese/zh-HK/zh-MO.
Owner
|
@jasonchen31 Thanks for the PR! I’ll be AFK most of the day today and will look at the issue tonight. I think it may be a conversion-stage issue and could have a simple fix. |
Owner
|
@jasonchen31 I'm a little confused here. The voxcpm1 gguf from audio.cpp HF repo does contain the tokenizer and can work without the PR. Looks like you try to support non audio.cpp-native, third-party GGUFs? I’m not sure we should spend much effort supporting non-native GGUFs. |
Contributor
Author
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.

Summary
Fixes
failed to load model resources using builtin model spec for family 'voxcpm1' source 'gguf': missing model package file 'tokenizer_config': /.../VoxCPM1-GGUF/tokenizer_config.jsonfor standalone LLama-style GGUFs.Published
VoxCPM1-GGUF(voxcpm-0.5b-q8_0-audiovae-f16.gguf) isgeneral.architecture=llamawithembedded_sidecars=false. It embeds:tokenizer.ggml.tokens(73448) /tokenizer.ggml.merges(104297) /tokenizer.ggml.token_type/bos=1voxcpm_lm_config_*,voxcpm_encoder_config_*,voxcpm_dit_config_*,voxcpm_audio_vae_config_*,voxcpm_patch_sizeetc.Runtime previously required external sidecars via
engine::model_spec::load_resource_bundlewithmodel_specs/voxcpm1.json:263sources[gguf].files: {config, tokenizer_json, tokenizer_config}→src/framework/model_spec/package.cpp:283threw beforeVoxCPM1TextTokenizercould fallback.Changes
git diff origin/main --stat– 4 files, 520 insertions(+), 70 deletions(-)src/community_models/voxcpm1/assets.cppengine/framework/io/filesystem.h,ggml.h,gguf.h,<optional>locate_gguf()(viaopen_tensor_source("weights")/find_directory_gguf),gguf_get_i64/gguf_get_f32_or/gguf_get_str_or/gguf_get_i64_array/gguf_get_f32_arrayparse_config_from_gguf(gguf_path)– reads allvoxcpm_*KV (voxcpm_architecture,lm_configincl.longropefactors,encoder/dit/audio_vae,patch_size,feat_dim,max_length,device/dtype,sample_rate16000/44100)parse_config(resources)–has_file("config")? JSON elselocate_gguf()→ GGUFvalidate_weight_anchorsforlocenc.special_token(element-count check[1024]vs[1,1,1,1024])load_voxcpm1_assets()wrapsload_resource_bundleintry/catch(missing tokenizer_config|tokenizer_json|config.json)→prepare_model_directoryminimalResourceBundlewithweights/audiovae_weights+ optional sidecars viatry_addsrc/community_models/voxcpm1/tokenizer_text.cppengine/framework/assets/tensor_source.h,ggml.h,gguf.h,<optional>locate_gguf_for_tokenizer(),load_tokenizer_from_gguf(gguf_path)– vocab fromtokens, merges,token_type==3→special_tokens(23 control incl.<|audio_start|>), fallback ensuresaudio_start/end,bos=1/eos=2/unk=0has_file("tokenizer_json" && "tokenizer_config")else GGUFsrc/community_models/voxcpm1/minicpm.cpp:200locenc.special_tokenload:require_metadata→ try[1,1,1,hidden]then[hidden]src/community_models/voxcpm1/audiovae.cppload_snake()tries{1,channels,1}→{channels,1}→{channels}load_sr_condition()synthesizesscale=1/bias=0whensr_cond_model.*missing (custom GGUF)load_wn_conv1d()fallback for omitted leading1(decoder.model.7 [96,7]vs[1,96,7]) with element-count checkVerification – local sense_asr
Model:
models/SenseVoice-Small-GGUF/sensevoice-small-q8-audiocpp-v1.gguf(243M,family=sense_asr, CPU)Notes
model_specs/voxcpm1.jsonunchanged (git diffshows 0 for this file) per review.cmake -B /tmp/build_fix && cmake --build /tmp/build_fix --parallel 8(CPU),bin/audiocpp_cli/bin/audiocpp_serverlink OK.Related Issue
voxcpm1 model extract the tokenizer directly from the gguf files. However somehow it report: