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 1/3] 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 From c823e52b2d9a308443e78795002e08b887f9b837 Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Mon, 29 Dec 2025 19:07:51 +0800 Subject: [PATCH 2/3] fix: propagate revision parameter to vLLM and PEFT loaders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add revision to load_vllm_kwargs in llama.py to fix config/weights mismatch - Add revision to PEFT AutoConfig calls in loader.py (FastLanguageModel & FastModel) Addresses reviewer feedback from @chatgpt-codex-connector and @Datta0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 (cherry picked from commit 14f89e453173f3279c885ed37d5f2a9cf10793df) --- unsloth/models/llama.py | 1 + unsloth/models/loader.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/unsloth/models/llama.py b/unsloth/models/llama.py index 0498c11734..fd2b3044c0 100644 --- a/unsloth/models/llama.py +++ b/unsloth/models/llama.py @@ -2471,6 +2471,7 @@ class FastLlamaModel: disable_log_stats = disable_log_stats, use_bitsandbytes = load_in_4bit, unsloth_vllm_standby = unsloth_vllm_standby, + revision = revision, fp8_mode = fp8_mode, ) for allowed_arg in allowed_args: diff --git a/unsloth/models/loader.py b/unsloth/models/loader.py index bd15ed5281..3155cd0d09 100644 --- a/unsloth/models/loader.py +++ b/unsloth/models/loader.py @@ -553,6 +553,7 @@ class FastLanguageModel(FastLlamaModel): model_config = AutoConfig.from_pretrained( model_name, token = token, + revision = revision, trust_remote_code = trust_remote_code, ) @@ -1304,6 +1305,7 @@ class FastModel(FastBaseModel): model_config = AutoConfig.from_pretrained( model_name, token = token, + revision = revision, trust_remote_code = trust_remote_code, ) From ae38c3639de6965e24600e07eddc467dae15c332 Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Tue, 30 Dec 2025 14:16:23 +0800 Subject: [PATCH 3/3] fix: add revision parameter to FastBaseModel in vision.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Propagate revision parameter to all from_pretrained calls in vision.py to ensure consistent version pinning for vision models. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 (cherry picked from commit c5aa4ec92783345eaa0286bd876386cb2767d990) --- unsloth/models/vision.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/unsloth/models/vision.py b/unsloth/models/vision.py index a8adba99e7..835bbcb850 100644 --- a/unsloth/models/vision.py +++ b/unsloth/models/vision.py @@ -421,6 +421,7 @@ class FastBaseModel: auto_config = None, offload_embedding = False, float32_mixed_precision = None, # Forces float32 mixed precision + revision = None, # vLLM parameters fast_inference = False, gpu_memory_utilization = 0.5, @@ -720,6 +721,7 @@ class FastBaseModel: model_name, token = token, trust_remote_code = trust_remote_code, + revision = revision, ) if hasattr(auto_config, "quantization_config"): from transformers.quantizers.auto import ( @@ -776,12 +778,12 @@ class FastBaseModel: model_name, token = token, trust_remote_code = trust_remote_code, + revision = revision, ) setattr(auto_config, "_attn_implementation", config_attn_impl) if hasattr(auto_config, "attn_implementation"): setattr(auto_config, "attn_implementation", config_attn_impl) model_config = auto_config - verify_fp8_support_if_applicable(model_config) raise_handler = RaiseUninitialized() @@ -796,6 +798,7 @@ class FastBaseModel: # quantization_config = bnb_config, token = token, trust_remote_code = trust_remote_code, + revision = revision, # attn_implementation = attn_implementation, **kwargs, )