Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / codegen / modeling_backend.py: 48%
25 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +0800
1# Copyright 2026 Huawei Technologies Co., Ltd
2# Licensed under the Apache License, Version 2.0
3# ============================================================================
4"""Three-state modeling backend resolution: ``hf`` / ``custom`` / ``gen``.
6``HF`` is wired through the trainer, while ``GEN`` loads a generated artifact.
7``CUSTOM`` falls back to HF when no matching implementation is registered.
9This module deliberately imports nothing from ``transformers`` at module
10scope: ``hf_config`` is duck-typed on ``architectures``, which keeps the
11resolver importable (and testable) in environments without torch installed.
12"""
13from __future__ import annotations
15import logging
16from enum import Enum
17from typing import Any
19logger = logging.getLogger(__name__)
22class ModelingBackend(str, Enum):
23 """Which implementation builds the model.
25 ``str``-mixin so a raw ``"gen"`` from YAML compares equal to
26 ``ModelingBackend.GEN`` without callers having to convert first.
27 """
29 HF = "hf"
30 CUSTOM = "custom"
31 GEN = "gen"
34def is_custom_model_available(hf_config: Any) -> bool:
35 """Whether a custom implementation is available for this config.
37 Delegates to the native :func:`get_is_hf_model` so the family's lazy
38 registration (directory-convention discovery importing each family's
39 ``adapter/registration.py`` and filling ``MODEL_ARCH_MAPPING``) is
40 triggered exactly as on master — a re-implementation that consults the
41 table directly would miss not-yet-imported families (and any custom
42 registration a user adds) and silently resolve them to HF.
44 Imported lazily: ``config_resolver`` pulls in ``transformers``, and this
45 module is meant to stay importable without it.
46 """
47 try:
48 from hyper_parallel.models._transformers.config_resolver import ( # pylint: disable=C0415
49 get_is_hf_model,
50 )
51 except ImportError: # pragma: no cover - no transformers in this env
52 return False
53 return not get_is_hf_model(hf_config, force_hf=False)
56def resolve_modeling_backend(
57 hf_config: Any,
58 *,
59 force_hf: bool = False,
60 codegen_enabled: bool = False,
61) -> ModelingBackend:
62 """Resolve the backend from ``force_hf`` and the ``codegen`` switch.
64 Precedence, highest first:
66 1. ``force_hf=True`` — an escape hatch, so it wins over everything.
67 2. ``codegen=True`` implies ``GEN`` — turning codegen on is what makes the
68 artifact authoritative; a second selector would just be a way to get
69 them out of sync.
70 3. A custom implementation registered for this architecture.
71 4. ``HF``.
73 Args:
74 hf_config: The ``PretrainedConfig``; only ``architectures`` is read.
75 force_hf: Force the HF-native path regardless of everything else.
76 codegen_enabled: The ``TrainerConfig.codegen`` switch.
77 """
78 if force_hf:
79 resolved = ModelingBackend.HF
80 elif codegen_enabled:
81 resolved = ModelingBackend.GEN
82 elif is_custom_model_available(hf_config):
83 resolved = ModelingBackend.CUSTOM
84 else:
85 resolved = ModelingBackend.HF
87 if force_hf and codegen_enabled:
88 logger.warning(
89 "codegen is enabled but force_hf=True, so the generated modeling "
90 "file will not be used; drop force_hf to build from the artifact",
91 )
92 return resolved
95__all__ = [
96 "ModelingBackend",
97 "is_custom_model_available",
98 "resolve_modeling_backend",
99]