186 lines
6.8 KiB
Python
186 lines
6.8 KiB
Python
from typing import Any, Optional, Sequence, Union
|
|
|
|
import cloudpickle
|
|
import vllm.envs as envs
|
|
from pydantic import ValidationError
|
|
from vllm.config import CompilationConfig, is_init_field
|
|
from vllm.engine.arg_utils import HfOverrides
|
|
from vllm.entrypoints.llm import LLM
|
|
from vllm.inputs import PromptType
|
|
from vllm.logger import init_logger
|
|
from vllm.sampling_params import SamplingParams
|
|
from vllm.usage.usage_lib import UsageContext
|
|
from vllm.utils import Counter
|
|
from vllm.v1.engine.llm_engine import LLMEngine
|
|
|
|
from vllm_omni.engine.arg_utils import OmniEngineArgs
|
|
from vllm_omni.engine.output_processor import MultimodalOutputProcessor
|
|
from vllm_omni.engine.processor import OmniProcessor
|
|
from vllm_omni.entrypoints.omni_stage import OmniStage
|
|
from vllm_omni.entrypoints.utils import load_stage_configs_from_model
|
|
from vllm_omni.outputs import OmniRequestOutput
|
|
|
|
logger = init_logger(__name__)
|
|
|
|
|
|
class OmniLLM:
|
|
def __init__(
|
|
self, model: str, stage_configs=None, log_stats: bool = False, **kwargs
|
|
):
|
|
if stage_configs is None:
|
|
self.initialize_stage_configs(model)
|
|
else:
|
|
self.stage_configs = stage_configs
|
|
|
|
self.stage_list = []
|
|
self.initialize_stages(model)
|
|
|
|
def initialize_stage_configs(self, model: str):
|
|
self.stage_configs = load_stage_configs_from_model(model)
|
|
|
|
def initialize_stages(self, model: str):
|
|
for stage_config in self.stage_configs:
|
|
stage = OmniStage(stage_config)
|
|
stage_llm = OmniStageLLM(model=model, **stage_config.engine_args)
|
|
stage.set_engine(stage_llm)
|
|
self.stage_list.append(stage)
|
|
|
|
def generate(
|
|
self,
|
|
prompts: Union[PromptType, Sequence[PromptType]],
|
|
sampling_params_list: Optional[
|
|
Union[SamplingParams, Sequence[SamplingParams]]
|
|
] = None,
|
|
) -> list[OmniRequestOutput]:
|
|
"""Generate text outputs for the given prompts."""
|
|
final_outputs: list[OmniRequestOutput] = []
|
|
if len(sampling_params_list) != len(self.stage_list):
|
|
raise ValueError(
|
|
f"Expected {len(self.stage_list)} sampling params, "
|
|
f"got {len(sampling_params_list)}"
|
|
)
|
|
for stage_id, stage in enumerate(self.stage_list):
|
|
if stage_id > 0:
|
|
engine_inputs = stage.process_engine_inputs(self.stage_list, prompts)
|
|
else:
|
|
engine_inputs = prompts
|
|
engine_outputs = self._run_generation(
|
|
stage, sampling_params_list[stage_id], engine_inputs
|
|
)
|
|
stage.set_engine_outputs(engine_outputs)
|
|
if hasattr(stage, "final_output") and stage.final_output:
|
|
final_outputs.append(
|
|
OmniRequestOutput(
|
|
stage_id=stage_id,
|
|
final_output_type=stage.final_output_type,
|
|
request_output=engine_outputs,
|
|
)
|
|
)
|
|
return final_outputs
|
|
|
|
def _run_generation(
|
|
self,
|
|
stage: OmniStage,
|
|
sampling_params: SamplingParams,
|
|
prompts: Union[PromptType, Sequence[PromptType]],
|
|
):
|
|
engine_outputs = []
|
|
for ro in stage.engine.generate(prompts, sampling_params):
|
|
engine_outputs.append(ro)
|
|
return engine_outputs
|
|
|
|
|
|
class OmniStageLLM(LLM):
|
|
def __init__(
|
|
self,
|
|
model: str,
|
|
compilation_config: Optional[
|
|
Union[int, dict[str, Any], CompilationConfig]
|
|
] = None,
|
|
hf_overrides: Optional[HfOverrides] = None,
|
|
**kwargs,
|
|
):
|
|
"""LLM constructor."""
|
|
if "disable_log_stats" not in kwargs:
|
|
kwargs["disable_log_stats"] = True
|
|
|
|
if "worker_cls" in kwargs:
|
|
worker_cls = kwargs["worker_cls"]
|
|
# if the worker_cls is not qualified string name,
|
|
# we serialize it using cloudpickle to avoid pickling issues
|
|
if isinstance(worker_cls, type):
|
|
kwargs["worker_cls"] = cloudpickle.dumps(worker_cls)
|
|
|
|
if "kv_transfer_config" in kwargs and isinstance(
|
|
kwargs["kv_transfer_config"], dict
|
|
):
|
|
from vllm.config import KVTransferConfig
|
|
|
|
raw_config_dict = kwargs["kv_transfer_config"]
|
|
try:
|
|
kwargs["kv_transfer_config"] = KVTransferConfig(**raw_config_dict)
|
|
except ValidationError as e:
|
|
logger.error(
|
|
"Failed to convert 'kv_transfer_config' dict to "
|
|
"KVTransferConfig object. Dict: %s. Error: %s",
|
|
raw_config_dict,
|
|
e,
|
|
)
|
|
# Consider re-raising a more specific vLLM error or ValueError
|
|
# to provide better context to the user.
|
|
raise ValueError(f"Invalid 'kv_transfer_config' provided: {e}") from e
|
|
|
|
if hf_overrides is None:
|
|
hf_overrides = {}
|
|
|
|
if compilation_config is not None:
|
|
if isinstance(compilation_config, int):
|
|
compilation_config_instance = CompilationConfig(
|
|
level=compilation_config
|
|
)
|
|
elif isinstance(compilation_config, dict):
|
|
|
|
def predicate(x):
|
|
return is_init_field(CompilationConfig, x[0])
|
|
|
|
compilation_config_instance = CompilationConfig(
|
|
**dict(filter(predicate, compilation_config.items()))
|
|
)
|
|
else:
|
|
compilation_config_instance = compilation_config
|
|
else:
|
|
compilation_config_instance = CompilationConfig()
|
|
|
|
engine_args = OmniEngineArgs(
|
|
model=model,
|
|
hf_overrides=hf_overrides,
|
|
compilation_config=compilation_config_instance,
|
|
**kwargs,
|
|
)
|
|
|
|
# Create the Engine (autoselects V0 vs V1)
|
|
self.llm_engine = LLMEngine.from_engine_args(
|
|
engine_args=engine_args, usage_context=UsageContext.LLM_CLASS
|
|
)
|
|
self.llm_engine.output_processor = MultimodalOutputProcessor(
|
|
tokenizer=self.llm_engine.tokenizer,
|
|
log_stats=self.llm_engine.log_stats,
|
|
engine_core_output_type=engine_args.engine_output_type,
|
|
)
|
|
self.llm_engine.processor = OmniProcessor(
|
|
vllm_config=self.llm_engine.vllm_config, tokenizer=self.llm_engine.tokenizer
|
|
)
|
|
self.engine_class = type(self.llm_engine)
|
|
|
|
self.request_counter = Counter()
|
|
self.default_sampling_params: Union[dict[str, Any], None] = None
|
|
|
|
if envs.VLLM_USE_V1:
|
|
supported_tasks = self.llm_engine.get_supported_tasks() # type: ignore
|
|
else:
|
|
supported_tasks = self.llm_engine.model_config.supported_tasks
|
|
|
|
logger.info("Supported_tasks: %s", supported_tasks)
|
|
|
|
self.supported_tasks = supported_tasks
|