@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 5f5271f1ee
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 14, 05:30 UTC

Move `LoRAConfig` from `config/__init__.py` to `config/lora.py` (#24644)

Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>

Harry Mellor committed Sep 11, 2025 at 12:01 UTC 5f5271f1ee2ef281ed8ecc66b126aa34964e797d
25 files changed +167 -137
tests/core/test_scheduler.py
+2 -1
@@ -10,7 +10,8 @@ import pytest # noqa
10 import torch
11 from torch import Use # noqa
12
13 -from vllm.config import CacheConfig, LoRAConfig, SchedulerConfig
13 +from vllm.config import CacheConfig, SchedulerConfig
14 +from vllm.config.lora import LoRAConfig
15 from vllm.core.interfaces import AllocStatus
16 from vllm.core.scheduler import Scheduler, SchedulingBudget
17 from vllm.lora.request import LoRARequest
tests/lora/test_layers.py
+1 -1
@@ -11,7 +11,7 @@ import pytest
11 import torch
12 import torch.nn.functional as F
13
14 -from vllm.config import LoRAConfig
14 +from vllm.config.lora import LoRAConfig
15 # yapf conflicts with isort for this block
16 # yapf: disable
17 from vllm.lora.layers import (BaseLayerWithLoRA, ColumnParallelLinearWithLoRA,
tests/lora/test_lora_allowed_token_ids.py
+2 -2
@@ -3,8 +3,8 @@
3
4 import pytest
5
6 -from vllm.config import (CacheConfig, DeviceConfig, LoRAConfig, ModelConfig,
7 - VllmConfig)
6 +from vllm.config import CacheConfig, DeviceConfig, ModelConfig, VllmConfig
7 +from vllm.config.lora import LoRAConfig
8 from vllm.lora.request import LoRARequest
9 from vllm.sampling_params import SamplingParams
10 from vllm.transformers_utils.tokenizer_group import init_tokenizer_from_configs
tests/lora/test_lora_manager.py
+1 -1
@@ -8,7 +8,7 @@ import torch
8 from safetensors.torch import load_file
9 from torch import nn
10
11 -from vllm.config import LoRAConfig
11 +from vllm.config.lora import LoRAConfig
12 from vllm.lora.layers import (ColumnParallelLinearWithLoRA,
13 MergedColumnParallelLinearWithLoRA,
14 RowParallelLinearWithLoRA)
tests/lora/test_peft_helper.py
+1 -1
@@ -7,7 +7,7 @@ import shutil
7
8 import pytest
9
10 -from vllm.config import LoRAConfig
10 +from vllm.config.lora import LoRAConfig
11 from vllm.lora.peft_helper import PEFTHelper
12
13 ERROR_CASES = [
tests/lora/test_worker.py
+2 -1
@@ -6,9 +6,10 @@ import random
6 import tempfile
7 from unittest.mock import patch
8
9 -from vllm.config import (CacheConfig, DeviceConfig, LoRAConfig, ModelConfig,
9 +from vllm.config import (CacheConfig, DeviceConfig, ModelConfig,
10 ParallelConfig, SchedulerConfig, VllmConfig)
11 from vllm.config.load import LoadConfig
12 +from vllm.config.lora import LoRAConfig
13 from vllm.lora.models import LoRAMapping
14 from vllm.lora.request import LoRARequest
15 from vllm.v1.worker.gpu_worker import Worker
vllm/config/__init__.py
+1 -110
@@ -36,6 +36,7 @@ from vllm.config.compilation import (CompilationConfig, CompilationLevel,
36 from vllm.config.kv_events import KVEventsConfig
37 from vllm.config.kv_transfer import KVTransferConfig
38 from vllm.config.load import LoadConfig
39 +from vllm.config.lora import LoRAConfig
40 from vllm.config.parallel import (DistributedExecutorBackend, EPLBConfig,
41 ParallelConfig)
42 from vllm.config.scheduler import SchedulerConfig, SchedulerPolicy
@@ -2400,116 +2401,6 @@ class SpeculativeConfig:
2401 return f"SpeculativeConfig({method=}, {model=}, {num_spec_tokens=})"
2402
2403
2403 -LoRADType = Literal["auto", "float16", "bfloat16"]
2404 -
2405 -
2406 -@config
2407 -@dataclass(config=ConfigDict(arbitrary_types_allowed=True))
2408 -class LoRAConfig:
2409 - """Configuration for LoRA."""
2410 -
2411 - max_lora_rank: int = 16
2412 - """Max LoRA rank."""
2413 - max_loras: int = 1
2414 - """Max number of LoRAs in a single batch."""
2415 - fully_sharded_loras: bool = False
2416 - """By default, only half of the LoRA computation is sharded with tensor
2417 - parallelism. Enabling this will use the fully sharded layers. At high
2418 - sequence length, max rank or tensor parallel size, this is likely faster.
2419 - """
2420 - max_cpu_loras: Optional[int] = None
2421 - """Maximum number of LoRAs to store in CPU memory. Must be >= than
2422 - `max_loras`."""
2423 - lora_dtype: Union[torch.dtype, LoRADType] = "auto"
2424 - """Data type for LoRA. If auto, will default to base model dtype."""
2425 - lora_extra_vocab_size: int = 256
2426 - """(Deprecated) Maximum size of extra vocabulary that can be present in a
2427 - LoRA adapter. Will be removed in v0.12.0."""
2428 - lora_vocab_padding_size: ClassVar[int] = current_platform\
2429 - .get_lora_vocab_padding_size()
2430 - default_mm_loras: Optional[dict[str, str]] = None
2431 - """Dictionary mapping specific modalities to LoRA model paths; this field
2432 - is only applicable to multimodal models and should be leveraged when a
2433 - model always expects a LoRA to be active when a given modality is present.
2434 - Note that currently, if a request provides multiple additional
2435 - modalities, each of which have their own LoRA, we do NOT apply
2436 - default_mm_loras because we currently only support one lora adapter
2437 - per prompt. When run in offline mode, the lora IDs for n modalities
2438 - will be automatically assigned to 1-n with the names of the modalities
2439 - in alphabetic order."""
2440 - bias_enabled: bool = False
2441 - """[DEPRECATED] Enable bias for LoRA adapters. This option will be
2442 - removed in v0.12.0."""
2443 -
2444 - def compute_hash(self) -> str:
2445 - """
2446 - WARNING: Whenever a new field is added to this config,
2447 - ensure that it is included in the factors list if
2448 - it affects the computation graph.
2449 -
2450 - Provide a hash that uniquely identifies all the configs
2451 - that affect the structure of the computation
2452 - graph from input ids/embeddings to the final hidden states,
2453 - excluding anything before input ids/embeddings and after
2454 - the final hidden states.
2455 - """
2456 - factors: list[Any] = []
2457 - factors.append(self.max_lora_rank)
2458 - factors.append(self.max_loras)
2459 - factors.append(self.fully_sharded_loras)
2460 - factors.append(self.lora_dtype)
2461 - factors.append(self.lora_extra_vocab_size)
2462 - factors.append(self.lora_vocab_padding_size)
2463 - factors.append(self.bias_enabled)
2464 - hash_str = hashlib.md5(str(factors).encode(),
2465 - usedforsecurity=False).hexdigest()
2466 - return hash_str
2467 -
2468 - def __post_init__(self):
2469 - # Deprecation warning for lora_extra_vocab_size
2470 - logger.warning(
2471 - "`lora_extra_vocab_size` is deprecated and will be removed "
2472 - "in v0.12.0. Additional vocabulary support for "
2473 - "LoRA adapters is being phased out.")
2474 -
2475 - # Deprecation warning for enable_lora_bias
2476 - if self.bias_enabled:
2477 - logger.warning("`enable_lora_bias` is deprecated "
2478 - "and will be removed in v0.12.0.")
2479 -
2480 - # Setting the maximum rank to 512 should be able to satisfy the vast
2481 - # majority of applications.
2482 - possible_max_ranks = (8, 16, 32, 64, 128, 256, 320, 512)
2483 - possible_lora_extra_vocab_size = (256, 512)
2484 - if self.max_lora_rank not in possible_max_ranks:
2485 - raise ValueError(
2486 - f"max_lora_rank ({self.max_lora_rank}) must be one of "
2487 - f"{possible_max_ranks}.")
2488 - if self.lora_extra_vocab_size not in possible_lora_extra_vocab_size:
2489 - raise ValueError(
2490 - f"lora_extra_vocab_size ({self.lora_extra_vocab_size}) "
2491 - f"must be one of {possible_lora_extra_vocab_size}.")
2492 - if self.max_loras < 1:
2493 - raise ValueError(f"max_loras ({self.max_loras}) must be >= 1.")
2494 - if self.max_cpu_loras is None:
2495 - self.max_cpu_loras = self.max_loras
2496 - elif self.max_cpu_loras < self.max_loras:
2497 - raise ValueError(
2498 - f"max_cpu_loras ({self.max_cpu_loras}) must be >= "
2499 - f"max_loras ({self.max_loras})")
2500 -
2501 - def verify_with_cache_config(self, cache_config: CacheConfig):
2502 - if cache_config.cpu_offload_gb > 0 and not envs.VLLM_USE_V1:
2503 - raise ValueError(
2504 - "V0 LoRA does not support CPU offload, please use V1.")
2505 -
2506 - def verify_with_model_config(self, model_config: ModelConfig):
2507 - if self.lora_dtype in (None, "auto"):
2508 - self.lora_dtype = model_config.dtype
2509 - elif isinstance(self.lora_dtype, str):
2510 - self.lora_dtype = getattr(torch, self.lora_dtype)
2511 -
2512 -
2404 @config
2405 @dataclass
2406 class MultiModalConfig:
vllm/config/lora.py new
+132
@@ -0,0 +1,132 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +
4 +import hashlib
5 +from typing import TYPE_CHECKING, Any, ClassVar, Literal, Optional, Union
6 +
7 +import torch
8 +from pydantic import ConfigDict
9 +from pydantic.dataclasses import dataclass
10 +
11 +import vllm.envs as envs
12 +from vllm.config.utils import config
13 +from vllm.logger import init_logger
14 +from vllm.platforms import current_platform
15 +
16 +if TYPE_CHECKING:
17 + from vllm.config import ModelConfig
18 + from vllm.config.cache import CacheConfig
19 +else:
20 + ModelConfig = Any
21 + CacheConfig = Any
22 +
23 +logger = init_logger(__name__)
24 +
25 +LoRADType = Literal["auto", "float16", "bfloat16"]
26 +
27 +
28 +@config
29 +@dataclass(config=ConfigDict(arbitrary_types_allowed=True))
30 +class LoRAConfig:
31 + """Configuration for LoRA."""
32 +
33 + max_lora_rank: int = 16
34 + """Max LoRA rank."""
35 + max_loras: int = 1
36 + """Max number of LoRAs in a single batch."""
37 + fully_sharded_loras: bool = False
38 + """By default, only half of the LoRA computation is sharded with tensor
39 + parallelism. Enabling this will use the fully sharded layers. At high
40 + sequence length, max rank or tensor parallel size, this is likely faster.
41 + """
42 + max_cpu_loras: Optional[int] = None
43 + """Maximum number of LoRAs to store in CPU memory. Must be >= than
44 + `max_loras`."""
45 + lora_dtype: Union[torch.dtype, LoRADType] = "auto"
46 + """Data type for LoRA. If auto, will default to base model dtype."""
47 + lora_extra_vocab_size: int = 256
48 + """(Deprecated) Maximum size of extra vocabulary that can be present in a
49 + LoRA adapter. Will be removed in v0.12.0."""
50 + lora_vocab_padding_size: ClassVar[int] = current_platform\
51 + .get_lora_vocab_padding_size()
52 + default_mm_loras: Optional[dict[str, str]] = None
53 + """Dictionary mapping specific modalities to LoRA model paths; this field
54 + is only applicable to multimodal models and should be leveraged when a
55 + model always expects a LoRA to be active when a given modality is present.
56 + Note that currently, if a request provides multiple additional
57 + modalities, each of which have their own LoRA, we do NOT apply
58 + default_mm_loras because we currently only support one lora adapter
59 + per prompt. When run in offline mode, the lora IDs for n modalities
60 + will be automatically assigned to 1-n with the names of the modalities
61 + in alphabetic order."""
62 + bias_enabled: bool = False
63 + """[DEPRECATED] Enable bias for LoRA adapters. This option will be
64 + removed in v0.12.0."""
65 +
66 + def compute_hash(self) -> str:
67 + """
68 + WARNING: Whenever a new field is added to this config,
69 + ensure that it is included in the factors list if
70 + it affects the computation graph.
71 +
72 + Provide a hash that uniquely identifies all the configs
73 + that affect the structure of the computation
74 + graph from input ids/embeddings to the final hidden states,
75 + excluding anything before input ids/embeddings and after
76 + the final hidden states.
77 + """
78 + factors: list[Any] = []
79 + factors.append(self.max_lora_rank)
80 + factors.append(self.max_loras)
81 + factors.append(self.fully_sharded_loras)
82 + factors.append(self.lora_dtype)
83 + factors.append(self.lora_extra_vocab_size)
84 + factors.append(self.lora_vocab_padding_size)
85 + factors.append(self.bias_enabled)
86 + hash_str = hashlib.md5(str(factors).encode(),
87 + usedforsecurity=False).hexdigest()
88 + return hash_str
89 +
90 + def __post_init__(self):
91 + # Deprecation warning for lora_extra_vocab_size
92 + logger.warning(
93 + "`lora_extra_vocab_size` is deprecated and will be removed "
94 + "in v0.12.0. Additional vocabulary support for "
95 + "LoRA adapters is being phased out.")
96 +
97 + # Deprecation warning for enable_lora_bias
98 + if self.bias_enabled:
99 + logger.warning("`enable_lora_bias` is deprecated "
100 + "and will be removed in v0.12.0.")
101 +
102 + # Setting the maximum rank to 512 should be able to satisfy the vast
103 + # majority of applications.
104 + possible_max_ranks = (8, 16, 32, 64, 128, 256, 320, 512)
105 + possible_lora_extra_vocab_size = (256, 512)
106 + if self.max_lora_rank not in possible_max_ranks:
107 + raise ValueError(
108 + f"max_lora_rank ({self.max_lora_rank}) must be one of "
109 + f"{possible_max_ranks}.")
110 + if self.lora_extra_vocab_size not in possible_lora_extra_vocab_size:
111 + raise ValueError(
112 + f"lora_extra_vocab_size ({self.lora_extra_vocab_size}) "
113 + f"must be one of {possible_lora_extra_vocab_size}.")
114 + if self.max_loras < 1:
115 + raise ValueError(f"max_loras ({self.max_loras}) must be >= 1.")
116 + if self.max_cpu_loras is None:
117 + self.max_cpu_loras = self.max_loras
118 + elif self.max_cpu_loras < self.max_loras:
119 + raise ValueError(
120 + f"max_cpu_loras ({self.max_cpu_loras}) must be >= "
121 + f"max_loras ({self.max_loras})")
122 +
123 + def verify_with_cache_config(self, cache_config: CacheConfig):
124 + if cache_config.cpu_offload_gb > 0 and not envs.VLLM_USE_V1:
125 + raise ValueError(
126 + "V0 LoRA does not support CPU offload, please use V1.")
127 +
128 + def verify_with_model_config(self, model_config: ModelConfig):
129 + if self.lora_dtype in (None, "auto"):
130 + self.lora_dtype = model_config.dtype
131 + elif isinstance(self.lora_dtype, str):
132 + self.lora_dtype = getattr(torch, self.lora_dtype)
vllm/core/scheduler.py
+2 -1
@@ -11,7 +11,8 @@ from typing import Callable, Deque, Dict, Iterable, List, Optional
11 from typing import Sequence as GenericSequence
12 from typing import Set, Tuple, Union
13
14 -from vllm.config import CacheConfig, LoRAConfig, SchedulerConfig
14 +from vllm.config import CacheConfig, SchedulerConfig
15 +from vllm.config.lora import LoRAConfig
16 from vllm.core.interfaces import AllocStatus, BlockSpaceManager
17 from vllm.logger import init_logger
18 from vllm.lora.request import LoRARequest
vllm/engine/async_llm_engine.py
+3 -2
@@ -10,8 +10,9 @@ from typing import (Any, AsyncGenerator, Callable, Dict, Iterable, List,
10 from weakref import ReferenceType
11
12 import vllm.envs as envs
13 -from vllm.config import (DecodingConfig, LoRAConfig, ModelConfig,
14 - ParallelConfig, SchedulerConfig, VllmConfig)
13 +from vllm.config import (DecodingConfig, ModelConfig, ParallelConfig,
14 + SchedulerConfig, VllmConfig)
15 +from vllm.config.lora import LoRAConfig
16 from vllm.core.scheduler import SchedulerOutputs
17 from vllm.engine.arg_utils import AsyncEngineArgs
18 from vllm.engine.async_timeout import asyncio_timeout
vllm/engine/llm_engine.py
+3 -3
@@ -16,9 +16,9 @@ import torch
16 from typing_extensions import TypeVar
17
18 import vllm.envs as envs
19 -from vllm.config import (DecodingConfig, LoRAConfig, ModelConfig,
20 - ObservabilityConfig, ParallelConfig, SchedulerConfig,
21 - VllmConfig)
19 +from vllm.config import (DecodingConfig, ModelConfig, ObservabilityConfig,
20 + ParallelConfig, SchedulerConfig, VllmConfig)
21 +from vllm.config.lora import LoRAConfig
22 from vllm.core.scheduler import ScheduledSequenceGroup, SchedulerOutputs
23 from vllm.engine.arg_utils import EngineArgs
24 from vllm.engine.metrics_types import StatLoggerBase, Stats
vllm/lora/layers/base.py
+1 -1
@@ -7,7 +7,7 @@ import torch
7 import torch.nn as nn
8 from transformers import PretrainedConfig
9
10 -from vllm.config import LoRAConfig
10 +from vllm.config.lora import LoRAConfig
11
12 if TYPE_CHECKING:
13 from vllm.lora.punica_wrapper import PunicaWrapperBase
vllm/lora/layers/base_linear.py
+1 -1
@@ -6,7 +6,7 @@ from typing import Optional, cast
6 import torch
7 from transformers import PretrainedConfig
8
9 -from vllm.config import LoRAConfig
9 +from vllm.config.lora import LoRAConfig
10 from vllm.distributed.utils import divide
11 # yapf: disable
12 from vllm.model_executor.layers.linear import (ColumnParallelLinear,
vllm/lora/layers/column_parallel_linear.py
+1 -1
@@ -7,7 +7,7 @@ import torch
7 import torch.nn as nn
8 from transformers import PretrainedConfig
9
10 -from vllm.config import LoRAConfig
10 +from vllm.config.lora import LoRAConfig
11 from vllm.distributed import (get_tensor_model_parallel_rank,
12 get_tensor_model_parallel_world_size,
13 tensor_model_parallel_all_gather)
vllm/lora/layers/logits_processor.py
+1 -1
@@ -8,7 +8,7 @@ import torch
8 import torch.nn as nn
9 from transformers import PretrainedConfig
10
11 -from vllm.config import LoRAConfig
11 +from vllm.config.lora import LoRAConfig
12 from vllm.distributed import (get_tensor_model_parallel_rank,
13 get_tensor_model_parallel_world_size)
14 from vllm.model_executor.layers.logits_processor import LogitsProcessor
vllm/lora/layers/replicated_linear.py
+1 -1
@@ -7,7 +7,7 @@ import torch
7 import torch.nn as nn
8 from transformers import PretrainedConfig
9
10 -from vllm.config import LoRAConfig
10 +from vllm.config.lora import LoRAConfig
11 from vllm.model_executor.layers.linear import ReplicatedLinear
12
13 from .base_linear import BaseLinearLayerWithLoRA
vllm/lora/layers/row_parallel_linear.py
+1 -1
@@ -7,7 +7,7 @@ import torch
7 import torch.nn as nn
8 from transformers import PretrainedConfig
9
10 -from vllm.config import LoRAConfig
10 +from vllm.config.lora import LoRAConfig
11 from vllm.distributed import (get_tensor_model_parallel_rank,
12 get_tensor_model_parallel_world_size,
13 split_tensor_along_last_dim,
vllm/lora/layers/vocal_parallel_embedding.py
+1 -1
@@ -8,7 +8,7 @@ import torch.nn as nn
8 import torch.nn.functional as F
9 from transformers import PretrainedConfig
10
11 -from vllm.config import LoRAConfig
11 +from vllm.config.lora import LoRAConfig
12 from vllm.model_executor.layers.vocab_parallel_embedding import (
13 VocabParallelEmbedding)
14 from vllm.platforms import current_platform
vllm/lora/models.py
+1 -1
@@ -16,7 +16,7 @@ from vllm.adapter_commons.models import (AdapterLRUCache, AdapterModel,
16 from vllm.adapter_commons.utils import (add_adapter, deactivate_adapter,
17 get_adapter, list_adapters,
18 remove_adapter, set_adapter_mapping)
19 -from vllm.config import LoRAConfig
19 +from vllm.config.lora import LoRAConfig
20 from vllm.logger import init_logger
21 from vllm.lora.layers import BaseLayerWithLoRA, LoRAMapping
22 from vllm.lora.lora import LoRALayerWeights, PackedLoRALayerWeights
vllm/lora/peft_helper.py
+1 -1
@@ -9,7 +9,7 @@ import os
9 from dataclasses import MISSING, dataclass, field, fields
10 from typing import Literal, Optional, Union
11
12 -from vllm.config import LoRAConfig
12 +from vllm.config.lora import LoRAConfig
13 from vllm.logger import init_logger
14 from vllm.model_executor.model_loader.tensorizer import TensorizerConfig
15
vllm/lora/utils.py
+1 -1
@@ -11,7 +11,7 @@ from huggingface_hub.utils import (EntryNotFoundError, HfHubHTTPError,
11 from torch import nn
12 from transformers import PretrainedConfig
13
14 -from vllm.config import LoRAConfig
14 +from vllm.config.lora import LoRAConfig
15 from vllm.logger import init_logger
16 # being imported for _all_lora_classes below
17 # yapf conflicts with isort for this block
vllm/lora/worker_manager.py
+1 -1
@@ -11,7 +11,7 @@ from vllm.adapter_commons.utils import (add_adapter_worker,
11 list_adapters_worker,
12 set_active_adapters_worker)
13 from vllm.adapter_commons.worker_manager import AbstractWorkerManager
14 -from vllm.config import LoRAConfig
14 +from vllm.config.lora import LoRAConfig
15 from vllm.logger import init_logger
16 from vllm.lora.models import (LoRAModel, LoRAModelManager,
17 LRUCacheLoRAModelManager, create_lora_manager)
vllm/model_executor/models/bart.py
+2 -1
@@ -29,7 +29,8 @@ from transformers import BartConfig
29 from transformers.utils import logging
30
31 from vllm.attention import Attention, AttentionType
32 -from vllm.config import CacheConfig, LoRAConfig, VllmConfig
32 +from vllm.config import CacheConfig, VllmConfig
33 +from vllm.config.lora import LoRAConfig
34 from vllm.distributed import get_tensor_model_parallel_world_size
35 from vllm.model_executor.layers.activation import get_act_fn
36 from vllm.model_executor.layers.linear import (ColumnParallelLinear,
vllm/transformers_utils/tokenizer_group.py
+2 -1
@@ -5,7 +5,8 @@ from typing import Optional
5
6 from typing_extensions import assert_never
7
8 -from vllm.config import LoRAConfig, ModelConfig, SchedulerConfig
8 +from vllm.config import ModelConfig, SchedulerConfig
9 +from vllm.config.lora import LoRAConfig
10 from vllm.lora.request import LoRARequest
11 from vllm.transformers_utils.tokenizer import (AnyTokenizer, encode_tokens,
12 get_lora_tokenizer,
vllm/v1/worker/lora_model_runner_mixin.py
+2 -1
@@ -11,7 +11,8 @@ import numpy as np
11 import torch
12 import torch.nn as nn
13
14 -from vllm.config import LoRAConfig, ModelConfig, SchedulerConfig
14 +from vllm.config import ModelConfig, SchedulerConfig
15 +from vllm.config.lora import LoRAConfig
16 from vllm.logger import init_logger
17 from vllm.lora.layers import LoRAMapping
18 from vllm.lora.request import LoRARequest