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

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``. 

5 

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. 

8 

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 

14 

15import logging 

16from enum import Enum 

17from typing import Any 

18 

19logger = logging.getLogger(__name__) 

20 

21 

22class ModelingBackend(str, Enum): 

23 """Which implementation builds the model. 

24 

25 ``str``-mixin so a raw ``"gen"`` from YAML compares equal to 

26 ``ModelingBackend.GEN`` without callers having to convert first. 

27 """ 

28 

29 HF = "hf" 

30 CUSTOM = "custom" 

31 GEN = "gen" 

32 

33 

34def is_custom_model_available(hf_config: Any) -> bool: 

35 """Whether a custom implementation is available for this config. 

36 

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. 

43 

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) 

54 

55 

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. 

63 

64 Precedence, highest first: 

65 

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``. 

72 

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 

86 

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 

93 

94 

95__all__ = [ 

96 "ModelingBackend", 

97 "is_custom_model_available", 

98 "resolve_modeling_backend", 

99]