main
py 73 lines 2.31 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import importlib
5
6 from vllm.config import VllmConfig
7 from vllm.logger import init_logger
8
9 logger = init_logger(__name__)
10
11
12 def create_custom_proposer(vllm_config: VllmConfig):
13 """Load and instantiate a user-provided proposer class.
14
15 The class path is read from ``speculative_config.model``
16 (e.g., ``"my_module.MyCustomProposer"``). The class is
17 imported, instantiated with *vllm_config*, and returned
18 directly so the caller can use it without any wrapper.
19
20 The returned object must expose a callable ``propose`` method.
21 """
22 assert vllm_config.speculative_config is not None
23 spec_config = vllm_config.speculative_config
24
25 backend = spec_config.model
26 assert backend is not None
27
28 if "." not in backend:
29 raise ValueError(
30 f"Invalid custom proposer module path '{backend}'. "
31 "It must be a full module path (e.g., 'module.MyProposerClass')."
32 )
33
34 module_path, class_name = backend.rsplit(".", 1)
35 try:
36 module = importlib.import_module(module_path)
37 except ImportError as e:
38 raise ImportError(
39 f"Cannot import module '{module_path}' for custom proposer '{backend}': {e}"
40 ) from e
41
42 user_class = getattr(module, class_name, None)
43 if user_class is None:
44 raise AttributeError(
45 f"Module '{module_path}' has no attribute '{class_name}' "
46 f"(speculative_config.model='{backend}')"
47 )
48
49 try:
50 instance = user_class(vllm_config)
51 except Exception as e:
52 raise RuntimeError(
53 f"Failed to instantiate custom proposer class '{backend}': {e}. "
54 "The class constructor must accept VllmConfig as argument."
55 ) from e
56
57 if not hasattr(instance, "propose"):
58 raise AttributeError(
59 f"Custom proposer class '{backend}' must have a 'propose' method."
60 )
61 if not callable(instance.propose):
62 raise AttributeError(
63 f"Custom proposer class '{backend}' has a 'propose' attribute "
64 "but it is not callable."
65 )
66
67 logger.info(
68 "Loaded custom proposer class '%s' with num_speculative_tokens=%d",
69 backend,
70 spec_config.num_speculative_tokens,
71 )
72
73 return instance