From 42d94df27953b1b3e5efc147c05416529b789095 Mon Sep 17 00:00:00 2001 From: Etherll <61019402+Etherll@users.noreply.github.com> Date: Sat, 28 Feb 2026 05:58:32 +0200 Subject: [PATCH 1/3] Add Qwen3.5 to FORCE_FLOAT32 --- unsloth/models/loader.py | 1 + 1 file changed, 1 insertion(+) diff --git a/unsloth/models/loader.py b/unsloth/models/loader.py index 711476b759..58f5f4811c 100644 --- a/unsloth/models/loader.py +++ b/unsloth/models/loader.py @@ -106,6 +106,7 @@ "gemma3text", # Gemma3TextModel (EmbeddingGemma, standalone text-only Gemma3) "gemma3n", "gpt_oss", + "qwen3_5", # Qwen3.5 RMSNorm uses (1+w) pattern like Gemma3, overflows float16 ] global DISABLE_COMPILE_MODEL_NAMES From 52769a6c9a6fcdf2447ed71463cb3bb2c6e91d79 Mon Sep 17 00:00:00 2001 From: Etherll <61019402+Etherll@users.noreply.github.com> Date: Sat, 28 Feb 2026 06:03:12 +0200 Subject: [PATCH 2/3] fix vision encoder dtype mismatch Add dtype casting for vision encoder when using FORCE_FLOAT32. --- unsloth/models/vision.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/unsloth/models/vision.py b/unsloth/models/vision.py index 5aea471263..4c7cfb137d 100644 --- a/unsloth/models/vision.py +++ b/unsloth/models/vision.py @@ -1054,6 +1054,19 @@ def from_pretrained( do_forced_float32 = do_forced_float32, correct_dtype = correct_dtype, ) + + # FORCE_FLOAT32 converts all params to float16, but the vision encoder + # receives float32 pixel values. Cast it back to float32 to avoid dtype + # mismatches in nn.LayerNorm / nn.Linear (e.g. Qwen3.5, Gemma3). + if do_forced_float32: + _vision_attrs = ("visual", "vision_tower", "vision_model", "vision_encoder") + _inner = model.model if hasattr(model, "model") else model + for _va in _vision_attrs: + _ve = getattr(_inner, _va, None) + if _ve is not None: + _ve.to(torch.float32) + break + try: model, tokenizer = patch_tokenizer(model, tokenizer) except Exception as _patch_err: From 24f2ac51c207f788c9df8d82cbf84e75f4febf44 Mon Sep 17 00:00:00 2001 From: Etherll <61019402+Etherll@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:21:11 +0200 Subject: [PATCH 3/3] revert vision cast changes --- unsloth/models/vision.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/unsloth/models/vision.py b/unsloth/models/vision.py index 4c7cfb137d..28c624c213 100644 --- a/unsloth/models/vision.py +++ b/unsloth/models/vision.py @@ -1055,18 +1055,6 @@ def from_pretrained( correct_dtype = correct_dtype, ) - # FORCE_FLOAT32 converts all params to float16, but the vision encoder - # receives float32 pixel values. Cast it back to float32 to avoid dtype - # mismatches in nn.LayerNorm / nn.Linear (e.g. Qwen3.5, Gemma3). - if do_forced_float32: - _vision_attrs = ("visual", "vision_tower", "vision_model", "vision_encoder") - _inner = model.model if hasattr(model, "model") else model - for _va in _vision_attrs: - _ve = getattr(_inner, _va, None) - if _ve is not None: - _ve.to(torch.float32) - break - try: model, tokenizer = patch_tokenizer(model, tokenizer) except Exception as _patch_err: