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:
commit
f12c5f61ef
2 changed files with 75 additions and 1 deletions
|
|
@ -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
|
||||
|
|
|
|||
40
studio/tests/test_remote_lora_detection.py
Normal file
40
studio/tests/test_remote_lora_detection.py
Normal 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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue