当你打开 whisper.cpp 的词表,发现 50256 不是终点——而是一整套隐藏操控指令的起点
打开whisper.cpp的whisper_vocab结构体,你会看到一个让人困惑的数字:token_eot = 50256。如果你熟悉 GPT-2 的 tokenizer,你可能会下意识地认为这就是 GPT-2 的<|endoftext|>token——毕竟数值一模一样。但是,当你继续往下看,你会发现紧接着 50256 的不是普通词汇,而是一整片由token_sot、token_translate、token_transcribe、token_solm、token_not、token_beg构成的"控制指令区",而且这些 token 的 ID 不是固定写死的——它们会根据模型是否支持多语言、支持多少种语言而动态偏移。更让人意外的是,当你加载一个large-v3模型时,这些 token ID 全都往后挪了两位——因为large-v3比large-v2多支持了两种语言(粤语和 100 号语言),整个控制指令区的起始位置因此发生了连锁位移。
这不是一个无关紧要的细节。如果你在开发多语言 ASR 系统时硬编码了任何一个特殊 token 的 ID,当你从base.en模型切换到large-v3模型时,你的整个解码流程会静悄悄地崩溃——因为你塞进 decoder prompt 的那个"开始转写"指令
