一个已经跑了三个月的 7B 模型,微调、转 GGUF、上线,一切照旧。权重没动一个 bit,sha256和上一版的差异只在几层 LoRA 合并进去的矩阵。可这一版加载进llama.cpp之后,单轮问答正常,一到多轮就开始飘:模型说完该停的地方不停,把下一轮的角色标记自己续写出来,偶尔还蹦出几个0x0A这种看着像乱码的东西。回滚到上一版,问题消失。两版的张量逐个allclose比对,最大误差在1e-6量级——就是浮点转换的噪声,模型本身是一样的。差异全在张量之外。GGUF 文件的前半段,那些谁都懒得看一眼的 key-value 元数据里,tokenizer.chat_template变了一个字符,tokenizer.ggml.eos_token_id指向了错误的 id。权重决定模型想说什么,而tokenizer.*这二十几个元数据 key 决定这些话怎么被切成 token、哪几个 token 是"该停下来"的信号、多轮对话怎么拼成一个字符串喂进去。这一层是纯配置,一行代码都没有,却和权重一样能让整个模型对外表现为"坏了"。这篇不讲 GGUF 的字节布局怎么解析——那是另一件事。这篇只钻进tokenizer.*这个命名空间:每个 key 存的是什么、llama.cpp在src/llama-vocab.cpp和src/llama-chat.c