test_peft_helper.py 2.89 KB
Newer Older
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3

4
5
6
7
8
9
import json
import math
import shutil

import pytest

10
from vllm.config.lora import LoRAConfig
11
12
13
14
15
from vllm.lora.peft_helper import PEFTHelper

ERROR_CASES = [
    (
        "test_rank",
16
        {"r": 1024},
17
18
        "is greater than max_lora_rank",
    ),
19
    ("test_dora", {"use_dora": True}, "does not yet support DoRA"),
20
21
    (
        "test_modules_to_save",
22
        {"modules_to_save": ["lm_head"]},
23
24
25
26
27
        "only supports modules_to_save being None",
    ),
]


28
def test_peft_helper_pass(llama32_lora_files, tmp_path):
29
    peft_helper = PEFTHelper.from_local_dir(
30
        llama32_lora_files, max_position_embeddings=4096
31
    )
32
33
34
    lora_config = LoRAConfig(max_lora_rank=16, max_cpu_loras=3, max_loras=2)
    peft_helper.validate_legal(lora_config)
    assert peft_helper.r == 8
35
36
37
38
    assert peft_helper.lora_alpha == 32
    target_modules = sorted(peft_helper.target_modules)

    assert target_modules == [
39
40
        "down_proj",
        "embed_tokens",
41
42
        "gate_proj",
        "k_proj",
43
        "lm_head",
44
45
46
47
        "o_proj",
        "q_proj",
        "up_proj",
        "v_proj",
48
49
    ]
    assert peft_helper.vllm_max_position_embeddings == 4096
50

51
52
53
    # test RSLoRA
    rslora_config = dict(use_rslora=True)
    test_dir = tmp_path / "test_rslora"
54
    shutil.copytree(llama32_lora_files, test_dir)
55
56
57
58
59
60
61
62
63
64
65
66

    # Load and modify configuration
    config_path = test_dir / "adapter_config.json"
    with open(config_path) as f:
        adapter_config = json.load(f)
    # Apply configuration changes
    adapter_config.update(rslora_config)

    # Save modified configuration
    with open(config_path, "w") as f:
        json.dump(adapter_config, f)

67
    peft_helper = PEFTHelper.from_local_dir(test_dir, max_position_embeddings=4096)
68
69
70
71
72
73
74
    peft_helper.validate_legal(lora_config)
    scaling = peft_helper.lora_alpha / math.sqrt(peft_helper.r)
    assert abs(peft_helper.vllm_lora_scaling_factor - scaling) < 1e-3


@pytest.mark.parametrize("test_name,config_change,expected_error", ERROR_CASES)
def test_peft_helper_error(
75
    llama32_lora_files,
76
77
78
79
80
81
    tmp_path,
    test_name: str,
    config_change: dict,
    expected_error: str,
):
    test_dir = tmp_path / test_name
82
    shutil.copytree(llama32_lora_files, test_dir)
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

    # Load and modify configuration
    config_path = test_dir / "adapter_config.json"
    with open(config_path) as f:
        adapter_config = json.load(f)
    # Apply configuration changes
    adapter_config.update(config_change)

    # Save modified configuration
    with open(config_path, "w") as f:
        json.dump(adapter_config, f)
    lora_config = LoRAConfig(max_lora_rank=16, max_cpu_loras=3, max_loras=2)
    # Test loading the adapter
    with pytest.raises(ValueError, match=expected_error):
        PEFTHelper.from_local_dir(
98
99
            test_dir, max_position_embeddings=4096
        ).validate_legal(lora_config)