From 9376c9064b4ec0ffeec6e5a95048aed03e1e3a18 Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Mon, 29 Dec 2025 13:45:07 +0800 Subject: [PATCH] fix: add revision parameter support and escape quotes in chat templates - Fix #3544: Add revision parameter to AutoConfig, AutoModelForCausalLM, AutoModelForSequenceClassification, and load_correct_tokenizer calls in FastLlamaModel.from_pretrained. This enables loading specific model revisions/branches from HuggingFace Hub. - Fix #3667: Escape single quotes in system messages before substituting into Jinja2 templates. This prevents TemplateSyntaxError when system messages contain apostrophes (e.g., "user's" in Vicuna templates). Signed-off-by: majiayu000 <1835304752@qq.com> (cherry picked from commit b0a6e4154b1bca9ed9bc06bdd1a83da1007dd6bf) --- unsloth/chat_templates.py | 8 ++++++-- unsloth/models/llama.py | 4 ++++ unsloth/tokenizer_utils.py | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/unsloth/chat_templates.py b/unsloth/chat_templates.py index 35eb871529..50e7a1f380 100644 --- a/unsloth/chat_templates.py +++ b/unsloth/chat_templates.py @@ -1667,14 +1667,18 @@ def _change_system_message(template: str, type_chat_template: str, system_messag if has_placeholder: if system_message is None: raise ValueError("Unsloth: You need to provide a system message for custom templates.") - new_template = re.sub(system_message_pattern, system_message, template) + # Escape single quotes to prevent Jinja2 template syntax errors + escaped_message = system_message.replace("'", "\\'") + new_template = re.sub(system_message_pattern, escaped_message, template) return new_template, system_message return template, system_message # For predefined templates with default system message message_to_use = system_message if system_message is not None else default_system_message - new_template = re.sub(system_message_pattern, message_to_use, template) + # Escape single quotes to prevent Jinja2 template syntax errors + escaped_message = message_to_use.replace("'", "\\'") + new_template = re.sub(system_message_pattern, escaped_message, template) return new_template, message_to_use diff --git a/unsloth/models/llama.py b/unsloth/models/llama.py index 93d93e26d6..0498c11734 100644 --- a/unsloth/models/llama.py +++ b/unsloth/models/llama.py @@ -2331,6 +2331,7 @@ class FastLlamaModel: model_name, token = token, attn_implementation = "sdpa", + revision = revision, ) model_config.model_name = model_name model_max_seq_length = model_config.max_position_embeddings @@ -2424,6 +2425,7 @@ class FastLlamaModel: max_position_embeddings = max_position_embeddings, trust_remote_code = trust_remote_code, attn_implementation = preferred_attn_impl, + revision = revision, **kwargs, ) elif not fast_inference: @@ -2436,6 +2438,7 @@ class FastLlamaModel: max_position_embeddings = max_position_embeddings, trust_remote_code = trust_remote_code, attn_implementation = preferred_attn_impl, + revision = revision, **kwargs, ) model.fast_generate = make_fast_generate_wrapper(model.generate) @@ -2505,6 +2508,7 @@ class FastLlamaModel: token = token, trust_remote_code = trust_remote_code, fix_tokenizer = fix_tokenizer, + revision = revision, ) model, tokenizer = patch_tokenizer(model, tokenizer) diff --git a/unsloth/tokenizer_utils.py b/unsloth/tokenizer_utils.py index c445879df7..ccd0249209 100644 --- a/unsloth/tokenizer_utils.py +++ b/unsloth/tokenizer_utils.py @@ -503,6 +503,7 @@ def _load_correct_tokenizer( trust_remote_code = False, cache_dir = "huggingface_tokenizers_cache", fix_tokenizer = True, + revision = None, ): if IS_COLAB_ENVIRONMENT: cache_dir = cache_dir @@ -528,6 +529,7 @@ def _load_correct_tokenizer( legacy = False, from_slow = True, cache_dir = cache_dir, + revision = revision, ) except: slow_tokenizer = None @@ -546,6 +548,7 @@ def _load_correct_tokenizer( token = token, trust_remote_code = trust_remote_code, cache_dir = cache_dir, + revision = revision, ) if not fix_tokenizer or tokenizer_name in IGNORED_TOKENIZER_NAMES: @@ -587,6 +590,7 @@ def load_correct_tokenizer( trust_remote_code = False, cache_dir = "huggingface_tokenizers_cache", fix_tokenizer = True, + revision = None, ): tokenizer = _load_correct_tokenizer( tokenizer_name = tokenizer_name, @@ -596,6 +600,7 @@ def load_correct_tokenizer( trust_remote_code = trust_remote_code, cache_dir = cache_dir, fix_tokenizer = fix_tokenizer, + revision = revision, ) ### 1. Fixup tokenizer's chat_template