| |
| |
| |
| |
|
|
| """Model registry mapping HuggingFace model_type to model classes.""" |
|
|
| from dataclasses import dataclass |
| from functools import lru_cache |
|
|
| import torch.nn as nn |
|
|
|
|
| @dataclass |
| class ModelEntry: |
| """Registry entry for a model family.""" |
|
|
| macos_class: type[nn.Module] | None = None |
| ios_class: type[nn.Module] | None = None |
| |
| |
| |
| |
| |
| |
| hf_config_attr: str | None = None |
| hf_state_dict_prefix: str = "" |
|
|
|
|
| @lru_cache(maxsize=1) |
| def _get_registry() -> dict[str, ModelEntry]: |
| """Build the model registry (cached singleton). Lazy imports to avoid circular deps.""" |
| from coreai_models.models.ios.mistral import MistralForCausalLMForiOS |
| from coreai_models.models.ios.qwen2 import Qwen2ForCausalLMForiOS |
| from coreai_models.models.ios.qwen3 import Qwen3ForCausalLMForiOS |
| from coreai_models.models.macos.gemma3_text import Gemma3ForCausalLM |
| from coreai_models.models.macos.gpt_oss import GptOssForCausalLM |
| from coreai_models.models.macos.lfm2 import Lfm2ForCausalLM |
| from coreai_models.models.macos.lfm2_moe import Lfm2MoeForCausalLM |
| from coreai_models.models.macos.mistral import MistralForCausalLM |
| from coreai_models.models.macos.mixtral import MixtralForCausalLM |
| from coreai_models.models.macos.qwen2 import Qwen2ForCausalLM |
| from coreai_models.models.macos.qwen3 import Qwen3ForCausalLM |
| from coreai_models.models.macos.qwen3_moe import Qwen3MoeForCausalLM |
|
|
| return { |
| "gemma3_text": ModelEntry( |
| macos_class=Gemma3ForCausalLM, |
| hf_config_attr="text_config", |
| hf_state_dict_prefix="language_model.", |
| ), |
| "gpt_oss": ModelEntry( |
| macos_class=GptOssForCausalLM, |
| ), |
| "lfm2": ModelEntry( |
| macos_class=Lfm2ForCausalLM, |
| ), |
| "lfm2_moe": ModelEntry( |
| macos_class=Lfm2MoeForCausalLM, |
| ), |
| "mistral": ModelEntry( |
| macos_class=MistralForCausalLM, |
| ios_class=MistralForCausalLMForiOS, |
| ), |
| "mixtral": ModelEntry( |
| macos_class=MixtralForCausalLM, |
| ), |
| "qwen2": ModelEntry( |
| macos_class=Qwen2ForCausalLM, |
| ios_class=Qwen2ForCausalLMForiOS, |
| ), |
| "qwen3": ModelEntry( |
| macos_class=Qwen3ForCausalLM, |
| ios_class=Qwen3ForCausalLMForiOS, |
| ), |
| "qwen3_moe": ModelEntry( |
| macos_class=Qwen3MoeForCausalLM, |
| ), |
| } |
|
|
|
|
| |
| MODEL_TYPE_REMAPPING: dict[str, str] = { |
| "gemma3": "gemma3_text", |
| "qwen2_5": "qwen2", |
| } |
|
|
|
|
| def get_model_entry(model_type: str) -> ModelEntry: |
| """Look up a model by HuggingFace model_type.""" |
| registry = _get_registry() |
| remapped = MODEL_TYPE_REMAPPING.get(model_type, model_type) |
| if remapped not in registry: |
| available = ", ".join(sorted(registry.keys())) |
| raise KeyError(f"Unknown model type '{model_type}'. Available: {available}") |
| return registry[remapped] |
|
|
|
|
| def list_models() -> list[str]: |
| """List all supported model types.""" |
| return sorted(_get_registry().keys()) |
|
|