Description
gm.text.Sampler unconditionally includes tokenizer.special_tokens.BEGIN_OF_TOOL_RESPONSE when building end_tokens for SamplerLoop. The Gemma2 tokenizer’s special-tokens enum (_Gemma2SpecialTokens) does not define BEGIN_OF_TOOL_RESPONSE (that token was introduced in Gemma3 for tool/function calling). As a result, using the Sampler with a Gemma2 model (or any model that uses tokenizer version 2) raises:
AttributeError: type object '_Gemma2SpecialTokens' has no attribute 'BEGIN_OF_TOOL_RESPONSE'
Location
- File:
gemma/gm/text/_sampler.py
- Approximate lines: 344–357 (inside
Sampler.sample(), when constructing _sampler_loop.SamplerLoop)
- Relevant tokenizer definitions:
gemma/gm/text/_tokenizer.py
_Gemma2SpecialTokens (lines 79–99): has EOS, END_OF_TURN, etc.; no BEGIN_OF_TOOL_RESPONSE
_Gemma3SpecialTokens (lines 102–128): defines BEGIN_OF_TOOL_RESPONSE = 50
Steps to reproduce
- Create a
Sampler with a model that uses tokenizer version 2 (e.g. Gemma2), or explicitly pass a Gemma2Tokenizer.
- Call
sampler.sample(prompt) (or any code path that builds the SamplerLoop and thus end_tokens).
- The crash occurs when the code builds
end_tokens and accesses self.tokenizer.special_tokens.BEGIN_OF_TOOL_RESPONSE.
Minimal repro: use a dummy model with INFO.tokenizer_version = 2, instantiate Sampler(model=..., params=...), then call sampler.sample("test"). The failure happens before any real model forward pass.
Expected behavior
Sampling with a Gemma2 model (tokenizer version 2) should not crash. The tool-response token should only be included in end_tokens when the tokenizer actually defines it (Gemma3+).
Actual behavior
AttributeError when building end_tokens for Gemma2, because _Gemma2SpecialTokens has no attribute BEGIN_OF_TOOL_RESPONSE.
Environment
- Repository: google-deepmind/gemma (or fork)
- Branch: main
- Python: 3.12+
- Relevant code:
gemma/gm/text/_sampler.py, gemma/gm/text/_tokenizer.py

Description
gm.text.Samplerunconditionally includestokenizer.special_tokens.BEGIN_OF_TOOL_RESPONSEwhen buildingend_tokensforSamplerLoop. The Gemma2 tokenizer’s special-tokens enum (_Gemma2SpecialTokens) does not defineBEGIN_OF_TOOL_RESPONSE(that token was introduced in Gemma3 for tool/function calling). As a result, using the Sampler with a Gemma2 model (or any model that uses tokenizer version 2) raises:Location
gemma/gm/text/_sampler.pySampler.sample(), when constructing_sampler_loop.SamplerLoop)gemma/gm/text/_tokenizer.py_Gemma2SpecialTokens(lines 79–99): hasEOS,END_OF_TURN, etc.; noBEGIN_OF_TOOL_RESPONSE_Gemma3SpecialTokens(lines 102–128): definesBEGIN_OF_TOOL_RESPONSE = 50Steps to reproduce
Samplerwith a model that uses tokenizer version 2 (e.g. Gemma2), or explicitly pass aGemma2Tokenizer.sampler.sample(prompt)(or any code path that builds theSamplerLoopand thusend_tokens).end_tokensand accessesself.tokenizer.special_tokens.BEGIN_OF_TOOL_RESPONSE.Minimal repro: use a dummy model with
INFO.tokenizer_version = 2, instantiateSampler(model=..., params=...), then callsampler.sample("test"). The failure happens before any real model forward pass.Expected behavior
Sampling with a Gemma2 model (tokenizer version 2) should not crash. The tool-response token should only be included in
end_tokenswhen the tokenizer actually defines it (Gemma3+).Actual behavior
AttributeErrorwhen buildingend_tokensfor Gemma2, because_Gemma2SpecialTokenshas no attributeBEGIN_OF_TOOL_RESPONSE.Environment
gemma/gm/text/_sampler.py,gemma/gm/text/_tokenizer.py