Summary
runtime/tools/convert_gguf.py claims to take vocab from token_embd.weight when writing config.txt, but the assignment is disabled:
if "token_embd.weight" in ten:
cfg["vocab"] = int(ten["token_embd.weight"].shape[-1]) if False else cfg["vocab"]
The C++ GGUF path always prefers the embedding tensor (emb->dims[1] in runtime/examples/qwen3_gguf_config.h / qwen35.cpp). The Python converter therefore can write a wrong vocab= into config.txt when metadata is missing or disagrees with the tensor, which breaks downstream load_weights / LM-head sizing for this tool path.
Expected
Prefer vocab from token_embd.weight shape (ggml dims[1] / Python shape[1] for 2D), matching the runtime.
Scope
No GPU required — tooling correctness only.
Summary
runtime/tools/convert_gguf.pyclaims to takevocabfromtoken_embd.weightwhen writingconfig.txt, but the assignment is disabled:The C++ GGUF path always prefers the embedding tensor (
emb->dims[1]inruntime/examples/qwen3_gguf_config.h/qwen35.cpp). The Python converter therefore can write a wrongvocab=intoconfig.txtwhen metadata is missing or disagrees with the tensor, which breaks downstreamload_weights/ LM-head sizing for this tool path.Expected
Prefer vocab from
token_embd.weightshape (ggmldims[1]/ Pythonshape[1]for 2D), matching the runtime.Scope
No GPU required — tooling correctness only.