unsloth/unsloth/utils/hf_hub.py
Daniel Han f205be0ea7 Fix correctness bugs across multiple model files (#3813)
1. cohere.py:347-348 - Fixed wrong variable names in QK normalization.
   Used `Q`/`K` but variables were named `Qn`/`Kn`. This caused NameError
   when `use_qk_norm=True` (e.g., c4ai-command-r-plus models).

2. cohere.py:482 - Fixed wrong object reference in inference loop.
   Used `self.mlp` but should be `decoder_layer.mlp` since we're
   iterating through decoder layers. Caused AttributeError during inference.

3. falcon_h1.py:459,461 - Fixed wrong attribute names in inference path.
   Used `post_attention_layernorm` and `mlp` but Falcon H1 uses
   `pre_ff_layernorm` and `feed_forward`. Caused AttributeError during generation.

4. qwen3_moe.py:210 - Fixed wrong module path with incorrect capitalization.
   Used `transformers.models.Qwen3Moe` but should be `transformers.models.qwen3_moe`.
   Caused AttributeError when patching rotary embeddings.

5. qwen3_moe.py:239 - Fixed wrong model_patcher class.
   Used `FastQwen3Model` but should be `FastQwen3MoeModel` for MoE models.
   Caused incorrect patching for Qwen3 MoE models.

6. hf_hub.py:21-22 - Fixed floor division and missing return for billion values.
   Used `//` instead of `/` for millions, and had no return for values >= 1B.
   Caused incorrect formatting and None return for large numbers.

7. save.py:550 - Fixed self-assignment that did nothing.
   `sharded_ram_usage = sharded_ram_usage` should be `= max_shard_size`.
   Caused integer shard sizes to be ignored.

8. rl.py:562-567 - Fixed orphan string not included in length_check.
   The elif branch for max_seq_length validation was a standalone string
   expression, not concatenated to length_check. Caused silent skip of
   the max_seq_length > model_max_seq_length warning.

9. granite.py:49-52 - Fixed wrong model name and version in error message.
   Said "Gemma2" and "4.42.3" but should be "Granite" and "4.45.0".
2026-01-01 02:36:33 -08:00

80 lines
2.1 KiB
Python

from huggingface_hub import HfApi, ModelInfo
_HFAPI: HfApi = None
POPULARITY_PROPERTIES = [
"downloads",
"downloadsAllTime",
"trendingScore",
"likes",
]
THOUSAND = 1000
MILLION = 1000000
BILLION = 1000000000
def formatted_int(value: int) -> str:
if value < THOUSAND:
return str(value)
elif value < MILLION:
return f"{float(value) / 1000:,.1f}K"
elif value < BILLION:
return f"{float(value) / 1000000:,.1f}M"
else:
return f"{float(value) / 1000000000:,.1f}B"
def get_model_info(
model_id: str, properties: list[str] = ["safetensors", "lastModified"]
) -> ModelInfo:
"""
Get the model info for a specific model.
properties: list[str] = See https://huggingface.co/docs/huggingface_hub/api-ref/hf_hub/hf_api/model_info
Default properties: ["safetensors", "lastModified"], only retrieves minimal information.
Set to None to retrieve the full model information.
"""
global _HFAPI
if _HFAPI is None:
_HFAPI = HfApi()
try:
model_info: ModelInfo = _HFAPI.model_info(model_id, expand = properties)
except Exception as e:
print(f"Error getting model info for {model_id}: {e}")
model_info = None
return model_info
def list_models(
properties: list[str] = None,
full: bool = False,
sort: str = "downloads",
author: str = "unsloth",
search: str = None,
limit: int = 10,
) -> list[ModelInfo]:
"""
Retrieve model information from the Hugging Face Hub.
properties: list[str] = See https://huggingface.co/docs/huggingface_hub/api-ref/hf_hub/hf_api/list_models
full: bool = Whether to retrieve the full model information, if True properties will be ignored.
sort: str = The sort order.
author: str = The author of the model.
search: str = The search query for filtering models.
"""
global _HFAPI
if _HFAPI is None:
_HFAPI = HfApi()
if full:
properties = None
models: list[ModelInfo] = _HFAPI.list_models(
author = author,
search = search,
sort = sort,
limit = limit,
expand = properties,
full = full,
)
return models