forked from Karylab-cklius/vllm
Compare commits
9
Commits
v0.6.4
...
v0.6.4.post1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6221a144a | ||
|
|
79ee45b428 | ||
|
|
691a3ec047 | ||
|
|
3a763ba0c3 | ||
|
|
f2056f726d | ||
|
|
1d65ec7eeb | ||
|
|
26908554b2 | ||
|
|
b311efd0bd | ||
|
|
3d158cdc8d |
@@ -17,7 +17,7 @@ pillow # Required for image processing
|
||||
prometheus_client >= 0.18.0
|
||||
prometheus-fastapi-instrumentator >= 7.0.0
|
||||
tiktoken >= 0.6.0 # Required for DBRX tokenizer
|
||||
lm-format-enforcer == 0.10.6
|
||||
lm-format-enforcer >= 0.10.9, < 0.11
|
||||
outlines >= 0.0.43, < 0.1
|
||||
typing_extensions >= 4.10
|
||||
filelock >= 3.10.4 # filelock starts to support `mode` argument from 3.10.4
|
||||
@@ -26,9 +26,9 @@ pyzmq
|
||||
msgspec
|
||||
gguf == 0.10.0
|
||||
importlib_metadata
|
||||
mistral_common[opencv] >= 1.4.4
|
||||
mistral_common[opencv] >= 1.5.0
|
||||
pyyaml
|
||||
six>=1.16.0; python_version > '3.11' # transitive dependency of pandas that needs to be the latest version for python 3.12
|
||||
setuptools>=74.1.1; python_version > '3.11' # Setuptools is used by triton, we need to ensure a modern version is installed for 3.12+ so that it does not try to import distutils, which was removed in 3.12
|
||||
einops # Required for Qwen2-VL.
|
||||
compressed-tensors == 0.8.0 # required for compressed-tensors
|
||||
compressed-tensors == 0.8.0 # required for compressed-tensors
|
||||
|
||||
@@ -45,7 +45,7 @@ def test_fused_moe(
|
||||
score = torch.randn((m, e), device="cuda", dtype=dtype)
|
||||
triton_output = fused_moe(a, w1, w2, score, topk, renormalize=False)
|
||||
torch_output = torch_moe(a, w1, w2, score, topk)
|
||||
torch.testing.assert_close(triton_output, torch_output, atol=1e-2, rtol=0)
|
||||
torch.testing.assert_close(triton_output, torch_output, atol=2e-2, rtol=0)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("dtype",
|
||||
|
||||
@@ -8,10 +8,12 @@ from unittest.mock import MagicMock, patch
|
||||
import openai
|
||||
import pytest
|
||||
import torch
|
||||
from huggingface_hub import snapshot_download
|
||||
from tensorizer import EncryptionParams
|
||||
|
||||
from vllm import SamplingParams
|
||||
from vllm.engine.arg_utils import EngineArgs
|
||||
# yapf conflicts with isort for this docstring
|
||||
# yapf: disable
|
||||
from vllm.model_executor.model_loader.tensorizer import (TensorizerConfig,
|
||||
TensorSerializer,
|
||||
@@ -20,13 +22,14 @@ from vllm.model_executor.model_loader.tensorizer import (TensorizerConfig,
|
||||
open_stream,
|
||||
serialize_vllm_model,
|
||||
tensorize_vllm_model)
|
||||
# yapf: enable
|
||||
from vllm.utils import import_from_path
|
||||
|
||||
from ..conftest import VllmRunner
|
||||
from ..utils import RemoteOpenAIServer
|
||||
from ..utils import VLLM_PATH, RemoteOpenAIServer
|
||||
from .conftest import retry_until_skip
|
||||
|
||||
# yapf conflicts with isort for this docstring
|
||||
|
||||
EXAMPLES_PATH = VLLM_PATH / "examples"
|
||||
|
||||
prompts = [
|
||||
"Hello, my name is",
|
||||
@@ -94,8 +97,8 @@ def test_can_deserialize_s3(vllm_runner):
|
||||
num_readers=1,
|
||||
s3_endpoint="object.ord1.coreweave.com",
|
||||
)) as loaded_hf_model:
|
||||
deserialized_outputs = loaded_hf_model.generate(prompts,
|
||||
sampling_params)
|
||||
deserialized_outputs = loaded_hf_model.generate(
|
||||
prompts, sampling_params)
|
||||
# noqa: E501
|
||||
|
||||
assert deserialized_outputs
|
||||
@@ -111,23 +114,21 @@ def test_deserialized_encrypted_vllm_model_has_same_outputs(
|
||||
|
||||
outputs = vllm_model.generate(prompts, sampling_params)
|
||||
|
||||
config_for_serializing = TensorizerConfig(
|
||||
tensorizer_uri=model_path,
|
||||
encryption_keyfile=key_path
|
||||
)
|
||||
config_for_serializing = TensorizerConfig(tensorizer_uri=model_path,
|
||||
encryption_keyfile=key_path)
|
||||
serialize_vllm_model(get_torch_model(vllm_model),
|
||||
config_for_serializing)
|
||||
|
||||
config_for_deserializing = TensorizerConfig(tensorizer_uri=model_path,
|
||||
encryption_keyfile=key_path)
|
||||
|
||||
with vllm_runner(
|
||||
model_ref,
|
||||
load_format="tensorizer",
|
||||
model_loader_extra_config=config_for_deserializing) as loaded_vllm_model: # noqa: E501
|
||||
with vllm_runner(model_ref,
|
||||
load_format="tensorizer",
|
||||
model_loader_extra_config=config_for_deserializing
|
||||
) as loaded_vllm_model: # noqa: E501
|
||||
|
||||
deserialized_outputs = loaded_vllm_model.generate(prompts,
|
||||
sampling_params)
|
||||
deserialized_outputs = loaded_vllm_model.generate(
|
||||
prompts, sampling_params)
|
||||
# noqa: E501
|
||||
|
||||
assert outputs == deserialized_outputs
|
||||
@@ -156,14 +157,14 @@ def test_deserialized_hf_model_has_same_outputs(hf_runner, vllm_runner,
|
||||
|
||||
|
||||
def test_vllm_model_can_load_with_lora(vllm_runner, tmp_path):
|
||||
from huggingface_hub import snapshot_download
|
||||
|
||||
from examples.multilora_inference import (create_test_prompts,
|
||||
process_requests)
|
||||
multilora_inference = import_from_path(
|
||||
"examples.multilora_inference",
|
||||
EXAMPLES_PATH / "multilora_inference.py",
|
||||
)
|
||||
|
||||
model_ref = "meta-llama/Llama-2-7b-hf"
|
||||
lora_path = snapshot_download(repo_id="yard1/llama-2-7b-sql-lora-test")
|
||||
test_prompts = create_test_prompts(lora_path)
|
||||
test_prompts = multilora_inference.create_test_prompts(lora_path)
|
||||
|
||||
# Serialize model before deserializing and binding LoRA adapters
|
||||
with vllm_runner(model_ref, ) as vllm_model:
|
||||
@@ -186,7 +187,8 @@ def test_vllm_model_can_load_with_lora(vllm_runner, tmp_path):
|
||||
max_num_seqs=50,
|
||||
max_model_len=1000,
|
||||
) as loaded_vllm_model:
|
||||
process_requests(loaded_vllm_model.model.llm_engine, test_prompts)
|
||||
multilora_inference.process_requests(
|
||||
loaded_vllm_model.model.llm_engine, test_prompts)
|
||||
|
||||
assert loaded_vllm_model
|
||||
|
||||
@@ -217,8 +219,11 @@ def test_openai_apiserver_with_tensorizer(vllm_runner, tmp_path):
|
||||
|
||||
## Start OpenAI API server
|
||||
openai_args = [
|
||||
"--dtype", "float16", "--load-format",
|
||||
"tensorizer", "--model-loader-extra-config",
|
||||
"--dtype",
|
||||
"float16",
|
||||
"--load-format",
|
||||
"tensorizer",
|
||||
"--model-loader-extra-config",
|
||||
json.dumps(model_loader_extra_config),
|
||||
]
|
||||
|
||||
@@ -251,8 +256,7 @@ def test_raise_value_error_on_invalid_load_format(vllm_runner):
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
|
||||
@pytest.mark.skipif(torch.cuda.device_count() < 2,
|
||||
reason="Requires 2 GPUs")
|
||||
@pytest.mark.skipif(torch.cuda.device_count() < 2, reason="Requires 2 GPUs")
|
||||
def test_tensorizer_with_tp_path_without_template(vllm_runner):
|
||||
with pytest.raises(ValueError):
|
||||
model_ref = "EleutherAI/pythia-1.4b"
|
||||
@@ -271,10 +275,9 @@ def test_tensorizer_with_tp_path_without_template(vllm_runner):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(torch.cuda.device_count() < 2,
|
||||
reason="Requires 2 GPUs")
|
||||
def test_deserialized_encrypted_vllm_model_with_tp_has_same_outputs(vllm_runner,
|
||||
tmp_path):
|
||||
@pytest.mark.skipif(torch.cuda.device_count() < 2, reason="Requires 2 GPUs")
|
||||
def test_deserialized_encrypted_vllm_model_with_tp_has_same_outputs(
|
||||
vllm_runner, tmp_path):
|
||||
model_ref = "EleutherAI/pythia-1.4b"
|
||||
# record outputs from un-sharded un-tensorized model
|
||||
with vllm_runner(
|
||||
@@ -313,13 +316,12 @@ def test_deserialized_encrypted_vllm_model_with_tp_has_same_outputs(vllm_runner,
|
||||
disable_custom_all_reduce=True,
|
||||
enforce_eager=True,
|
||||
model_loader_extra_config=tensorizer_config) as loaded_vllm_model:
|
||||
deserialized_outputs = loaded_vllm_model.generate(prompts,
|
||||
sampling_params)
|
||||
deserialized_outputs = loaded_vllm_model.generate(
|
||||
prompts, sampling_params)
|
||||
|
||||
assert outputs == deserialized_outputs
|
||||
|
||||
|
||||
|
||||
@retry_until_skip(3)
|
||||
def test_vllm_tensorized_model_has_same_outputs(vllm_runner, tmp_path):
|
||||
gc.collect()
|
||||
@@ -337,8 +339,8 @@ def test_vllm_tensorized_model_has_same_outputs(vllm_runner, tmp_path):
|
||||
with vllm_runner(model_ref,
|
||||
load_format="tensorizer",
|
||||
model_loader_extra_config=config) as loaded_vllm_model:
|
||||
deserialized_outputs = loaded_vllm_model.generate(prompts,
|
||||
sampling_params)
|
||||
deserialized_outputs = loaded_vllm_model.generate(
|
||||
prompts, sampling_params)
|
||||
# noqa: E501
|
||||
|
||||
assert outputs == deserialized_outputs
|
||||
|
||||
+13
-13
@@ -272,10 +272,10 @@ class EngineArgs:
|
||||
parser.add_argument(
|
||||
'--allowed-local-media-path',
|
||||
type=str,
|
||||
help="Allowing API requests to read local images or videos"
|
||||
"from directories specified by the server file system."
|
||||
"This is a security risk."
|
||||
"Should only be enabled in trusted environments")
|
||||
help="Allowing API requests to read local images or videos "
|
||||
"from directories specified by the server file system. "
|
||||
"This is a security risk. "
|
||||
"Should only be enabled in trusted environments.")
|
||||
parser.add_argument('--download-dir',
|
||||
type=nullable_str,
|
||||
default=EngineArgs.download_dir,
|
||||
@@ -340,7 +340,7 @@ class EngineArgs:
|
||||
'scaling factors. This should generally be supplied, when '
|
||||
'KV cache dtype is FP8. Otherwise, KV cache scaling factors '
|
||||
'default to 1.0, which may cause accuracy issues. '
|
||||
'FP8_E5M2 (without scaling) is only supported on cuda version'
|
||||
'FP8_E5M2 (without scaling) is only supported on cuda version '
|
||||
'greater than 11.8. On ROCm (AMD GPU), FP8_E4M3 is instead '
|
||||
'supported for common inference criteria.')
|
||||
parser.add_argument('--max-model-len',
|
||||
@@ -446,9 +446,9 @@ class EngineArgs:
|
||||
'this argument can be seen as a virtual way to increase '
|
||||
'the GPU memory size. For example, if you have one 24 GB '
|
||||
'GPU and set this to 10, virtually you can think of it as '
|
||||
'a 34 GB GPU. Then you can load a 13B model with BF16 weight,'
|
||||
'a 34 GB GPU. Then you can load a 13B model with BF16 weight, '
|
||||
'which requires at least 26GB GPU memory. Note that this '
|
||||
'requires fast CPU-GPU interconnect, as part of the model is'
|
||||
'requires fast CPU-GPU interconnect, as part of the model is '
|
||||
'loaded from CPU memory to GPU memory on the fly in each '
|
||||
'model forward pass.')
|
||||
parser.add_argument(
|
||||
@@ -468,7 +468,7 @@ class EngineArgs:
|
||||
type=int,
|
||||
default=None,
|
||||
help='If specified, ignore GPU profiling result and use this number'
|
||||
'of GPU blocks. Used for testing preemption.')
|
||||
' of GPU blocks. Used for testing preemption.')
|
||||
parser.add_argument('--max-num-batched-tokens',
|
||||
type=int,
|
||||
default=EngineArgs.max_num_batched_tokens,
|
||||
@@ -514,7 +514,7 @@ class EngineArgs:
|
||||
parser.add_argument('--hf-overrides',
|
||||
type=json.loads,
|
||||
default=EngineArgs.hf_overrides,
|
||||
help='Extra arguments for the HuggingFace config.'
|
||||
help='Extra arguments for the HuggingFace config. '
|
||||
'This should be a JSON string that will be '
|
||||
'parsed into a dictionary.')
|
||||
parser.add_argument('--enforce-eager',
|
||||
@@ -572,7 +572,7 @@ class EngineArgs:
|
||||
'--mm-processor-kwargs',
|
||||
default=None,
|
||||
type=json.loads,
|
||||
help=('Overrides for the multimodal input mapping/processing,'
|
||||
help=('Overrides for the multimodal input mapping/processing, '
|
||||
'e.g., image processor. For example: {"num_crops": 4}.'))
|
||||
|
||||
# LoRA related configs
|
||||
@@ -601,7 +601,7 @@ class EngineArgs:
|
||||
'--lora-dtype',
|
||||
type=str,
|
||||
default=EngineArgs.lora_dtype,
|
||||
choices=['auto', 'float16', 'bfloat16', 'float32'],
|
||||
choices=['auto', 'float16', 'bfloat16'],
|
||||
help=('Data type for LoRA. If auto, will default to '
|
||||
'base model dtype.'))
|
||||
parser.add_argument(
|
||||
@@ -822,9 +822,9 @@ class EngineArgs:
|
||||
"of the provided names. The model name in the model "
|
||||
"field of a response will be the first name in this "
|
||||
"list. If not specified, the model name will be the "
|
||||
"same as the `--model` argument. Noted that this name(s)"
|
||||
"same as the `--model` argument. Noted that this name(s) "
|
||||
"will also be used in `model_name` tag content of "
|
||||
"prometheus metrics, if multiple names provided, metrics"
|
||||
"prometheus metrics, if multiple names provided, metrics "
|
||||
"tag will take the first one.")
|
||||
parser.add_argument('--qlora-adapter-name-or-path',
|
||||
type=str,
|
||||
|
||||
@@ -2002,9 +2002,6 @@ class LLMEngine:
|
||||
SpanAttributes.LLM_LATENCY_TIME_IN_MODEL_EXECUTE,
|
||||
metrics.model_execute_time)
|
||||
|
||||
def is_encoder_decoder_model(self):
|
||||
return self.input_preprocessor.is_encoder_decoder_model()
|
||||
|
||||
def _validate_model_inputs(self, inputs: ProcessorInputs,
|
||||
lora_request: Optional[LoRARequest]):
|
||||
if is_encoder_decoder_inputs(inputs):
|
||||
|
||||
@@ -964,6 +964,3 @@ class LLM:
|
||||
# This is necessary because some requests may be finished earlier than
|
||||
# its previous requests.
|
||||
return sorted(outputs, key=lambda x: int(x.request_id))
|
||||
|
||||
def _is_encoder_decoder_model(self):
|
||||
return self.llm_engine.is_encoder_decoder_model()
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import importlib
|
||||
import importlib.util
|
||||
import os
|
||||
from functools import cached_property
|
||||
from typing import Callable, Dict, List, Optional, Sequence, Type, Union
|
||||
@@ -9,7 +7,7 @@ from vllm.entrypoints.openai.protocol import (ChatCompletionRequest,
|
||||
ExtractedToolCallInformation)
|
||||
from vllm.logger import init_logger
|
||||
from vllm.transformers_utils.tokenizer import AnyTokenizer
|
||||
from vllm.utils import is_list_of
|
||||
from vllm.utils import import_from_path, is_list_of
|
||||
|
||||
logger = init_logger(__name__)
|
||||
|
||||
@@ -149,13 +147,14 @@ class ToolParserManager:
|
||||
@classmethod
|
||||
def import_tool_parser(cls, plugin_path: str) -> None:
|
||||
"""
|
||||
Import a user defined tool parser by the path of the tool parser define
|
||||
Import a user-defined tool parser by the path of the tool parser define
|
||||
file.
|
||||
"""
|
||||
module_name = os.path.splitext(os.path.basename(plugin_path))[0]
|
||||
spec = importlib.util.spec_from_file_location(module_name, plugin_path)
|
||||
if spec is None or spec.loader is None:
|
||||
logger.error("load %s from %s failed.", module_name, plugin_path)
|
||||
|
||||
try:
|
||||
import_from_path(module_name, plugin_path)
|
||||
except Exception:
|
||||
logger.exception("Failed to load module '%s' from %s.",
|
||||
module_name, plugin_path)
|
||||
return
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
@@ -67,7 +67,7 @@ class InputPreprocessor:
|
||||
model config is unavailable.
|
||||
'''
|
||||
|
||||
if not self.is_encoder_decoder_model():
|
||||
if not self.model_config.is_encoder_decoder:
|
||||
print_warning_once("Using None for decoder start token id because "
|
||||
"this is not an encoder/decoder model.")
|
||||
return None
|
||||
@@ -632,7 +632,7 @@ class InputPreprocessor:
|
||||
prompt_adapter_request: Optional[PromptAdapterRequest] = None,
|
||||
) -> ProcessorInputs:
|
||||
"""Preprocess the input prompt."""
|
||||
if self.is_encoder_decoder_model():
|
||||
if self.model_config.is_encoder_decoder:
|
||||
# Encoder-decoder model requires special mapping of
|
||||
# input prompts to encoder & decoder
|
||||
return self._process_encoder_decoder_prompt(
|
||||
@@ -660,7 +660,7 @@ class InputPreprocessor:
|
||||
prompt_adapter_request: Optional[PromptAdapterRequest] = None,
|
||||
) -> ProcessorInputs:
|
||||
"""Async version of :meth:`preprocess`."""
|
||||
if self.is_encoder_decoder_model():
|
||||
if self.model_config.is_encoder_decoder:
|
||||
# Encoder-decoder model requires special mapping of
|
||||
# input prompts to encoder & decoder
|
||||
return await self._process_encoder_decoder_prompt_async(
|
||||
@@ -679,6 +679,3 @@ class InputPreprocessor:
|
||||
lora_request=lora_request,
|
||||
prompt_adapter_request=prompt_adapter_request,
|
||||
)
|
||||
|
||||
def is_encoder_decoder_model(self):
|
||||
return self.model_config.is_encoder_decoder
|
||||
|
||||
@@ -165,15 +165,14 @@ class MergedColumnParallelLinearWithShardedLoRA(
|
||||
def slice_lora_a(
|
||||
self, lora_a: List[Union[torch.Tensor, None]]
|
||||
) -> List[Union[torch.Tensor, None]]:
|
||||
if lora_a[0] is None or lora_a[1] is None:
|
||||
return lora_a
|
||||
#NOTE: lora_a contains 2 subloras, and each sublora could be None.
|
||||
output_shard_size = self.lora_a_stacked[0].shape[2]
|
||||
output_start_idx = self.tp_rank * output_shard_size
|
||||
lora_a = [
|
||||
lora_a[0][:,
|
||||
output_start_idx:output_start_idx + output_shard_size],
|
||||
lora_a[1][:,
|
||||
output_start_idx:output_start_idx + output_shard_size],
|
||||
lora_a[0][:, output_start_idx:output_start_idx +
|
||||
output_shard_size] if lora_a[0] is not None else None,
|
||||
lora_a[1][:, output_start_idx:output_start_idx +
|
||||
output_shard_size] if lora_a[1] is not None else None,
|
||||
]
|
||||
return lora_a
|
||||
|
||||
@@ -261,14 +260,16 @@ class MergedQKVParallelLinearWithShardedLora(MergedQKVParallelLinearWithLora):
|
||||
def slice_lora_a(
|
||||
self, lora_a: List[Union[torch.Tensor, None]]
|
||||
) -> List[Union[torch.Tensor, None]]:
|
||||
if lora_a[0] is None or lora_a[1] is None or lora_a[2] is None:
|
||||
return lora_a
|
||||
# NOTE: lora_a contains 3 subloras, and each sublora could be None.
|
||||
shard_size = [self.lora_a_stacked[i].shape[2] for i in range(3)]
|
||||
start_idx = [self.tp_rank * shard_size[i] for i in range(3)]
|
||||
lora_a = [
|
||||
lora_a[0][:, start_idx[0]:start_idx[0] + shard_size[0]],
|
||||
lora_a[1][:, start_idx[1]:start_idx[1] + shard_size[1]],
|
||||
lora_a[2][:, start_idx[2]:start_idx[2] + shard_size[2]],
|
||||
lora_a[0][:, start_idx[0]:start_idx[0] +
|
||||
shard_size[0]] if lora_a[0] is not None else None,
|
||||
lora_a[1][:, start_idx[1]:start_idx[1] +
|
||||
shard_size[1]] if lora_a[1] is not None else None,
|
||||
lora_a[2][:, start_idx[2]:start_idx[2] +
|
||||
shard_size[2]] if lora_a[2] is not None else None,
|
||||
]
|
||||
return lora_a
|
||||
|
||||
|
||||
+8
-7
@@ -685,26 +685,27 @@ class MergedColumnParallelLinearWithLoRA(ColumnParallelLinearWithLoRA):
|
||||
def slice_lora_b(
|
||||
self, lora_b: List[Union[torch.Tensor, None]]
|
||||
) -> List[Union[torch.Tensor, None]]:
|
||||
if lora_b[0] is None or lora_b[1] is None:
|
||||
return lora_b
|
||||
#NOTE: lora_b contains 2 subloras, and each sublora could be None.
|
||||
shard_size = self.output_dim
|
||||
start_idx = self.tp_rank * shard_size
|
||||
end_idx = (self.tp_rank + 1) * shard_size
|
||||
lora_b = [
|
||||
lora_b[0][:, start_idx:end_idx],
|
||||
lora_b[1][:, start_idx:end_idx],
|
||||
lora_b[0][:, start_idx:end_idx] if lora_b[0] is not None else None,
|
||||
lora_b[1][:, start_idx:end_idx] if lora_b[1] is not None else None,
|
||||
]
|
||||
return lora_b
|
||||
|
||||
def slice_bias(
|
||||
self, bias: List[Union[torch.Tensor,
|
||||
None]]) -> List[Union[torch.Tensor, None]]:
|
||||
if bias[0] is None or bias[1] is None:
|
||||
return bias
|
||||
# NOTE : each bias could be None.
|
||||
shard_size = self.output_dim
|
||||
start_idx = self.tp_rank * shard_size
|
||||
end_idx = (self.tp_rank + 1) * shard_size
|
||||
bias = [bias[0][start_idx:end_idx], bias[1][start_idx:end_idx]]
|
||||
bias = [
|
||||
bias[0][start_idx:end_idx] if bias[0] is not None else None,
|
||||
bias[1][start_idx:end_idx] if bias[1] is not None else None
|
||||
]
|
||||
return bias
|
||||
|
||||
def set_lora(
|
||||
|
||||
@@ -94,18 +94,34 @@ def _initialize_model(vllm_config: VllmConfig, prefix: str = "") -> nn.Module:
|
||||
model_config = vllm_config.model_config
|
||||
model_class, _ = get_model_architecture(model_config)
|
||||
signatures = inspect.signature(model_class.__init__)
|
||||
# collect all kw-only parameters
|
||||
kw_only_params = [
|
||||
param.name for param in signatures.parameters.values()
|
||||
if param.kind == inspect.Parameter.KEYWORD_ONLY
|
||||
]
|
||||
assert "vllm_config" in kw_only_params and "prefix" in kw_only_params, \
|
||||
("vLLM model class must accept `vllm_config` and `prefix` as kw-only "
|
||||
"arguments. Possibly you have an old-style model class registered from "
|
||||
"out of tree and it is used for new vLLM version. "
|
||||
"Please check https://docs.vllm.ai/en/latest/design/class_hierarchy.html "
|
||||
"for the design and update the model class accordingly.")
|
||||
return model_class(vllm_config=vllm_config, prefix=prefix)
|
||||
all_params = [param.name for param in signatures.parameters.values()]
|
||||
if "vllm_config" in all_params and "prefix" in all_params:
|
||||
# new-style model class
|
||||
return model_class(vllm_config=vllm_config, prefix=prefix)
|
||||
msg = ("vLLM model class should accept `vllm_config` and `prefix` as "
|
||||
"input arguments. Possibly you have an old-style model class"
|
||||
" registered from out of tree and it is used for new vLLM version. "
|
||||
"Check https://docs.vllm.ai/en/latest/design/class_hierarchy.html "
|
||||
"for the design and update the model class accordingly.")
|
||||
logger.warning(msg)
|
||||
logger.warning(
|
||||
"Trying to guess the arguments for old-style model class %s",
|
||||
model_class)
|
||||
# try to be compatible with old-style model class
|
||||
kwargs = {}
|
||||
if "prefix" in all_params:
|
||||
kwargs["prefix"] = prefix
|
||||
if "config" in all_params:
|
||||
kwargs["config"] = model_config.hf_config
|
||||
if "cache_config" in all_params:
|
||||
kwargs["cache_config"] = vllm_config.cache_config
|
||||
if "quant_config" in all_params:
|
||||
kwargs["quant_config"] = vllm_config.quant_config
|
||||
if "lora_config" in all_params:
|
||||
kwargs["lora_config"] = vllm_config.lora_config
|
||||
if "scheduler_config" in all_params:
|
||||
kwargs["scheduler_config"] = vllm_config.scheduler_config
|
||||
return model_class(**kwargs)
|
||||
|
||||
|
||||
class BaseModelLoader(ABC):
|
||||
|
||||
@@ -250,6 +250,9 @@ class FalconDecoderLayer(nn.Module):
|
||||
self.mlp = FalconMLP(config, quant_config)
|
||||
self.config = config
|
||||
|
||||
if (not hasattr(config, "num_ln_in_parallel_attn")):
|
||||
config.num_ln_in_parallel_attn = None
|
||||
|
||||
if (config.num_ln_in_parallel_attn is None
|
||||
and config.new_decoder_architecture):
|
||||
config.num_ln_in_parallel_attn = 2
|
||||
|
||||
@@ -174,18 +174,29 @@ class MistralTokenizer:
|
||||
revision=revision)
|
||||
return tokenizer_file
|
||||
|
||||
# the following attributes are set to fit VLLM's design
|
||||
# the following attributes are set to fit VLLM's design and are used
|
||||
# by the guided structured output backends.
|
||||
@property
|
||||
def all_special_tokens_extended(self) -> List[str]:
|
||||
return []
|
||||
# tekken defines its own extended special tokens list
|
||||
if hasattr(self.tokenizer, "SPECIAL_TOKENS"):
|
||||
special_tokens = self.tokenizer.SPECIAL_TOKENS
|
||||
else:
|
||||
special_tokens = list(SpecialTokens)
|
||||
return [
|
||||
s.value if isinstance(s, SpecialTokens) else s
|
||||
for s in special_tokens
|
||||
]
|
||||
|
||||
@property
|
||||
def all_special_tokens(self) -> List[str]:
|
||||
return []
|
||||
return self.all_special_tokens_extended
|
||||
|
||||
@property
|
||||
def all_special_ids(self) -> List[int]:
|
||||
return []
|
||||
return [
|
||||
self.all_special_tokens.index(t) for t in self.all_special_tokens
|
||||
]
|
||||
|
||||
@property
|
||||
def bos_token_id(self) -> int:
|
||||
|
||||
@@ -5,6 +5,7 @@ import datetime
|
||||
import enum
|
||||
import gc
|
||||
import getpass
|
||||
import importlib.util
|
||||
import inspect
|
||||
import ipaddress
|
||||
import os
|
||||
@@ -1539,6 +1540,25 @@ def is_in_doc_build() -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def import_from_path(module_name: str, file_path: Union[str, os.PathLike]):
|
||||
"""
|
||||
Import a Python file according to its file path.
|
||||
|
||||
Based on the official recipe:
|
||||
https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
|
||||
"""
|
||||
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
||||
if spec is None:
|
||||
raise ModuleNotFoundError(f"No module named '{module_name}'")
|
||||
|
||||
assert spec.loader is not None
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[module_name] = module
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
# create a library to hold the custom op
|
||||
vllm_lib = Library("vllm", "FRAGMENT") # noqa
|
||||
|
||||
|
||||
@@ -163,9 +163,6 @@ class LLMEngine:
|
||||
def get_model_config(self):
|
||||
pass
|
||||
|
||||
def is_encoder_decoder_model(self):
|
||||
pass
|
||||
|
||||
def start_profile(self):
|
||||
pass
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ class Worker(LocalOrDistributedWorkerBase):
|
||||
logger.info(
|
||||
"Memory profiling results: total_gpu_memory=%.2fGiB"
|
||||
" initial_memory_usage=%.2fGiB peak_torch_memory=%.2fGiB"
|
||||
" memory_usage_post_profile=%.2fGib"
|
||||
" memory_usage_post_profile=%.2fGiB"
|
||||
" non_torch_memory=%.2fGiB kv_cache_size=%.2fGiB"
|
||||
" gpu_memory_utilization=%.2f", total_gpu_memory / (1024**3),
|
||||
(total_gpu_memory - free_memory_pre_profile) / (1024**3),
|
||||
|
||||
Reference in New Issue
Block a user