Skip to content

Commit bbede19

Browse files
committed
feat(llama): enhance chat template initialization with full special tokens
Update Llama.__init__ to register additional tokenizer special tokens and improve stop token handling for chat templates. - Expose extra special tokens (EOT, SEP, NL, PAD, MASK) via `special_tokens_map` to Jinja2ChatFormatter. - Keep BOS and EOS tokens as explicit parameters, no longer redundantly put them in `special_tokens_map`. - Build `stop_token_ids` once, including EOS and EOT tokens, skipping invalid (-1) ids. - Update try-block comment: now `{% generation %}` blocks are supported, guard only against malformed or model-specific templates. - This ensures better compatibility with HuggingFace-style chat templates while maintaining llama-cpp-python prompt-rendering behavior. Signed-off-by: JamePeng <jame_peng@sina.com>
1 parent a7db23a commit bbede19

1 file changed

Lines changed: 35 additions & 13 deletions

File tree

llama_cpp/llama.py

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,6 @@ def __init__(
692692
self._n_vocab = self.n_vocab()
693693
self._n_ctx = self.n_ctx()
694694

695-
self._token_nl = self.token_nl()
696-
self._token_eos = self.token_eos()
697-
698695
self._candidates = internals.LlamaTokenDataArray(n_vocab=self._n_vocab)
699696

700697
self.n_tokens = 0
@@ -720,13 +717,38 @@ def __init__(
720717

721718
eos_token_id = self.token_eos()
722719
bos_token_id = self.token_bos()
720+
eot_token_id = self.token_eot()
721+
sep_token_id = self.token_sep()
722+
nl_token_id = self.token_nl()
723+
pad_token_id = self.token_pad()
724+
mask_token_id = self.token_mask()
725+
726+
def _token_text(token_id: int) -> str:
727+
return self._model.token_get_text(token_id) if token_id != -1 else ""
728+
729+
bos_token = _token_text(bos_token_id)
730+
eos_token = _token_text(eos_token_id)
731+
732+
special_tokens_map = {
733+
name: text
734+
for name, token_id in {
735+
"eot_token": eot_token_id,
736+
"sep_token": sep_token_id,
737+
"nl_token": nl_token_id,
738+
"pad_token": pad_token_id,
739+
"mask_token": mask_token_id,
740+
}.items()
741+
if token_id != -1 and (text := _token_text(token_id))
742+
}
723743

724-
eos_token = (
725-
self._model.token_get_text(eos_token_id) if eos_token_id != -1 else ""
726-
)
727-
bos_token = (
728-
self._model.token_get_text(bos_token_id) if bos_token_id != -1 else ""
729-
)
744+
stop_token_ids = [
745+
token_id
746+
for token_id in (eos_token_id, eot_token_id)
747+
if token_id != -1
748+
]
749+
750+
if not stop_token_ids:
751+
stop_token_ids = None
730752

731753
# Unfortunately the llama.cpp API does not return metadata arrays, so we can't get template names from tokenizer.chat_templates
732754
template_choices = dict(
@@ -750,14 +772,14 @@ def __init__(
750772
for name, template in template_choices.items():
751773
try:
752774
# Attempt to parse and register the template as a valid chat handler.
753-
# We wrap this in a try-block because some models (like LLaVA) contain
754-
# non-standard Jinja2 tags (e.g., {% generation %}) that cause the
755-
# standard parser to crash.
775+
# Keep this guarded because model metadata may contain malformed or
776+
# model-specific Jinja templates that still cannot be rendered by this runtime.
756777
self._chat_handlers[name] = llama_chat_format.Jinja2ChatFormatter(
757778
template=template,
758779
eos_token=eos_token,
759780
bos_token=bos_token,
760-
stop_token_ids=[eos_token_id],
781+
stop_token_ids=stop_token_ids,
782+
special_tokens_map=special_tokens_map,
761783
).to_chat_handler()
762784
except Exception as e:
763785
# If parsing fails (e.g., TemplateSyntaxError), log a warning but do not crash.

0 commit comments

Comments
 (0)