Merge pull request #69 from unslothai/fix/auto-detect-lora-in-model-config

fix: auto-detect LoRA adapters for both local and remote HF models in ModelConfig
This commit is contained in:
Roland Tannous 2026-02-14 00:56:34 +04:00 committed by GitHub
commit f12c5f61ef
2 changed files with 75 additions and 1 deletions

View file

@ -661,10 +661,44 @@ class ModelConfig:
identifier = f"unsloth/{identifier}"
path = identifier
# Auto-detect LoRA for local paths (check adapter_config.json on disk)
if not is_lora and is_local:
detected_base = get_base_model_from_lora(path)
if detected_base:
is_lora = True
logger.info(f"Auto-detected local LoRA adapter at '{path}' (base: {detected_base})")
# Auto-detect LoRA for remote HF models (check repo file listing)
if not is_lora and not is_local:
try:
from huggingface_hub import model_info as hf_model_info
info = hf_model_info(identifier, token=hf_token)
repo_files = [s.rfilename for s in info.siblings]
if "adapter_config.json" in repo_files:
is_lora = True
logger.info(f"Auto-detected remote LoRA adapter: '{identifier}'")
except Exception as e:
logger.debug(f"Could not check remote LoRA status for '{identifier}': {e}")
# Handle LoRA adapters
base_model = None
if is_lora:
base_model = get_base_model_from_lora(path)
if is_local:
# Local LoRA: read adapter_config.json from disk
base_model = get_base_model_from_lora(path)
else:
# Remote LoRA: download adapter_config.json from HF
try:
from huggingface_hub import hf_hub_download
config_path = hf_hub_download(identifier, "adapter_config.json", token=hf_token)
with open(config_path, 'r') as f:
adapter_config = json.load(f)
base_model = adapter_config.get("base_model_name_or_path")
if base_model:
logger.info(f"Resolved remote LoRA base model: '{base_model}'")
except Exception as e:
logger.warning(f"Could not download adapter_config.json for '{identifier}': {e}")
if not base_model:
logger.warning(f"Could not determine base model for LoRA '{path}'")
return None

View file

@ -0,0 +1,40 @@
"""
Test remote LoRA adapter detection via HuggingFace Hub API.
Verifies that we can detect whether a remote HF model is a LoRA adapter
by checking for adapter_config.json in the repo file listing.
"""
import pytest
from huggingface_hub import model_info
def is_remote_lora_adapter(model_id: str, hf_token: str = None) -> bool:
"""
Check if a remote HuggingFace model is a LoRA adapter
by looking for adapter_config.json in its repo files.
"""
try:
info = model_info(model_id, token=hf_token)
filenames = [s.rfilename for s in info.siblings]
return "adapter_config.json" in filenames
except Exception:
return False
class TestRemoteLoRADetection:
"""Test remote LoRA adapter detection via HF Hub API."""
def test_lora_adapter_detected(self):
"""edbeeching/llama-se-rl-adapter is a known LoRA adapter on HF."""
result = is_remote_lora_adapter("edbeeching/llama-se-rl-adapter")
assert result is True, "Expected edbeeching/llama-se-rl-adapter to be detected as a LoRA adapter"
def test_base_model_not_detected_as_lora(self):
"""google/gemma-3-4b-it is a full base model, not a LoRA adapter."""
result = is_remote_lora_adapter("google/gemma-3-4b-it")
assert result is False, "Expected google/gemma-3-4b-it to NOT be detected as a LoRA adapter"
def test_nonexistent_model_returns_false(self):
"""A nonexistent model should return False, not raise."""
result = is_remote_lora_adapter("this-org-does-not-exist/fake-model-12345")
assert result is False, "Expected nonexistent model to return False"