#10662·LlamaFactory

[BUG] Unsloth booster fails on composite VLM LoRA: "No layers to finetune?" due to target_modules format mismatch

Author: abhijeet-kaithCreated Jul 19, 2026Updated Sep 22, 2026
Labelsbugpending

Reminder

  • I have read the above rules and searched the existing issues.

System Info

Environment

  • LLaMA-Factory: 0.9.6.dev0
  • Unsloth: 2026.x
  • Model: Qwen/Qwen3.5-4B
  • Stage: SFT, LoRA
  • Booster: unsloth
  • GPU: NVIDIA A100 40GB
  • OS: Linux

Reproduction

Describe the bug

When Booster = unsloth is enabled for LoRA SFT on a composite / vision-language model (e.g. Qwen/Qwen3.5-4B, model_type=qwen3_5), training crashes during LoRA adapter setup with:

The same training config works when Booster = auto (standard PEFT path).

To Reproduce

Steps to reproduce the behavior:

  1. Install LLaMA-Factory with Unsloth support (use_unsloth / Booster unsloth).
  2. Configure SFT with a composite VLM:
    • Model: Qwen/Qwen3.5-4B
    • Template: qwen3_5_nothink
    • Finetuning type: LoRA (lora_target=all)
    • Freeze vision tower: true
    • Booster: unsloth
  3. Use any valid SFT dataset (text-only is sufficient).
  4. Start training via CLI or WebUI.

Training fails in get_unsloth_peft_model() → FastLanguageModel.get_peft_model().

Expected behavior

Unsloth booster should attach LoRA adapters to the intended language-model linear layers on composite VLMs, consistent with the standard PEFT path (with vision/projector frozen when configured).

Actual behavior

LoRA setup fails because LlamaFactory passes full module paths as target_modules, while Unsloth expects leaf module names.

Root cause

There is a format mismatch between two LlamaFactory code paths:

  1. adapter.py builds LoRA targets, then calls patch_target_modules() in model_utils/visual.py.
  2. For models in COMPOSITE_MODELS (e.g. qwen3_5, qwen2_vl, llava, …), patch_target_modules() expands short targets like out_proj into full paths: model.language_model.layers.0.linear_attn.out_proj

This is correct for standard HuggingFace PEFT.

  1. When use_unsloth=True, those expanded paths are passed to:
python
FastLanguageModel.get_peft_model(target_modules=...)
  1. Unsloth’s get_peft_regex() treats target_modules as leaf names and builds regexes that match module paths ending in those names. Passing a full path as the “leaf” matches nothing → 0 trainable layers → crash.

Proposed fix

In the Unsloth integration path only, convert expanded VLM target_modules back to unique leaf names before calling FastLanguageModel.get_peft_model().

Suggested change in model_utils/unsloth.py:

python
def _coerce_unsloth_target_modules(model, target_modules: list[str]) -> list[str]:
    """Unsloth expects LoRA leaf names; VLMs get full paths from patch_target_modules."""
    model_type = getattr(model.config, "model_type", None)
    if model_type not in COMPOSITE_MODELS:
        return target_modules
    if not target_modules or all("." not in name for name in target_modules):
        return target_modules
    return sorted({name.rsplit(".", 1)[-1] for name in target_modules})

Others

No response