Repository navigation
Conversation
`resolveBeginningTokenToPrepend` returned `null` for `ugm` vocabulary models unconditionally, so UGM models with `add_bos_token = true` in their GGUF metadata (such as bge-m3) never got the BOS token prepended to embedding, ranking and completion inputs. This diverged from `llama.cpp`, which prepends BOS for UGM when `add_bos` is set, and broke CLS-pooled embeddings, where the first content token was pooled instead of `<s>`. Respect `tokens.shouldPrependBosToken` for `ugm` models to match the `llama.cpp` behavior. Models that don't request BOS (such as T5) are unaffected. Closes: withcatai#683
This branch has not been deployed
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 #683.
For models with a
ugmvocabulary (e.g.BAAI/bge-m3),resolveBeginningTokenToPrepend()returnednullunconditionally, so the BOS token was never prepended, even when the GGUF setstokenizer.ggml.add_bos_token = trueandmodel.tokens.shouldPrependBosTokenistrue. Since bge-m3 uses CLS pooling, the first content token was pooled instead of<s>, shifting embeddings away from the reference.llama.cppprepends BOS for UGM whenadd_bosis set (llama_vocab::impl::tokenize,case LLAMA_VOCAB_TYPE_UGMinllama-vocab.cpp:if (add_special && add_bos) output.push_back(special_bos_id);), andadd_bositself comes from the GGUFtokenizer.ggml.add_bos_tokenmetadata (defaulting tofalsefor UGM). The addon'sshouldPrependBosToken()already exposes exactly that flag viallama_vocab_get_add_bos().Changes
src/utils/tokenizerUtils.ts: forugmvocabularies, returntokens.boswhentokens.shouldPrependBosTokenistrue, andnullotherwise. Models that don't request BOS (e.g. T5, whose GGUFs haveadd_bos_token = false) behave exactly as before. The ranking and completion paths share this helper, so they now matchllama.cpptoo.test/standalone/utils/tokenizerUtils.test.ts: new standalone tests covering beginning/end token resolution forugm(with and withoutadd_bos_token),spm,bpe,wpm, andrwkv.Verification
vitest run ./test/standalone/utils- 68 tests pass (12 new)tsc --noEmit --project tsconfig.json- cleaneslinton the changed files - cleangpustack/bge-m3-GGUFbge-m3-Q8_0.gguf, a Hugging Face mirror ofBAAI/bge-m3; metadata read from the file:tokenizer.ggml.model = t5(UGM),tokenizer.ggml.add_bos_token = true,tokenizer.ggml.bos_token_id = 0,bert.pooling_type = CLS):resolveBeginningTokenToPrepend()returnsnullonmasterand0(<s>, the model's BOS) with this fix, so embedding inputs now start with<s>, matching the GGUF metadata and llama.cpp's own UGM path.masterand this fix: cosine similarity 0.533-0.997, with short inputs shifting the most. This shows the missing BOS materially changes model outputs; I did not run a retrieval benchmark and did not compare against the native llama.cpp CLI binary.BAAI/bge-m3(tokenizer_config.json) isXLMRobertaTokenizerwithbos_token = <s>, which prepends<s>by default - consistent with the GGUF'sadd_bos_token = true.