main
py 108 lines 3.52 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import os
4
5 import pytest
6 from huggingface_hub.constants import HF_HUB_CACHE
7
8 from vllm.plugins.lora_resolvers.hf_hub_resolver import HfHubResolver
9
10 LORA_LIB_MODEL_NAME = "ibm-granite/granite-3.3-8b-instruct"
11 # Repo with multiple LoRAs contained in it
12 LORA_LIB = "ibm-granite/granite-3.3-8b-rag-agent-lib"
13 LORA_NAME = "ibm-granite/granite-3.3-8b-rag-agent-lib/answerability_prediction_lora" # noqa: E501
14 NON_LORA_SUBPATH = "ibm-granite/granite-3.3-8b-rag-agent-lib/README.md"
15 LIB_DOWNLOAD_DIR = os.path.join(
16 HF_HUB_CACHE, "models--ibm-granite--granite-3.3-8b-rag-agent-lib"
17 )
18 INVALID_REPO_NAME = "thisrepodoesnotexist"
19
20 # Repo with only one LoRA in the root dir
21 LORA_REPO_MODEL_NAME = "meta-llama/Llama-2-7b-hf"
22 LORA_REPO = "yard1/llama-2-7b-sql-lora-test"
23 REPO_DOWNLOAD_DIR = os.path.join(
24 HF_HUB_CACHE, "models--yard1--llama-2-7b-sql-lora-test"
25 )
26
27
28 @pytest.mark.asyncio
29 async def test_hf_resolver_with_direct_path():
30 hf_resolver = HfHubResolver([LORA_REPO])
31 assert hf_resolver is not None
32
33 lora_request = await hf_resolver.resolve_lora(LORA_REPO_MODEL_NAME, LORA_REPO)
34 assert lora_request is not None
35 assert lora_request.lora_name == LORA_REPO
36 assert REPO_DOWNLOAD_DIR in lora_request.lora_path
37 assert "adapter_config.json" in os.listdir(lora_request.lora_path)
38
39
40 @pytest.mark.asyncio
41 async def test_hf_resolver_with_nested_paths():
42 hf_resolver = HfHubResolver([LORA_LIB])
43 assert hf_resolver is not None
44
45 lora_request = await hf_resolver.resolve_lora(LORA_LIB_MODEL_NAME, LORA_NAME)
46 assert lora_request is not None
47 assert lora_request.lora_name == LORA_NAME
48 assert LIB_DOWNLOAD_DIR in lora_request.lora_path
49 assert "adapter_config.json" in os.listdir(lora_request.lora_path)
50
51
52 @pytest.mark.asyncio
53 async def test_hf_resolver_with_multiple_repos():
54 hf_resolver = HfHubResolver([LORA_LIB, LORA_REPO])
55 assert hf_resolver is not None
56
57 lora_request = await hf_resolver.resolve_lora(LORA_LIB_MODEL_NAME, LORA_NAME)
58 assert lora_request is not None
59 assert lora_request.lora_name == LORA_NAME
60 assert LIB_DOWNLOAD_DIR in lora_request.lora_path
61 assert "adapter_config.json" in os.listdir(lora_request.lora_path)
62
63
64 @pytest.mark.asyncio
65 async def test_missing_adapter():
66 hf_resolver = HfHubResolver([LORA_LIB])
67 assert hf_resolver is not None
68
69 missing_lora_request = await hf_resolver.resolve_lora(LORA_LIB_MODEL_NAME, "foobar")
70 assert missing_lora_request is None
71
72
73 @pytest.mark.asyncio
74 async def test_nonlora_adapter():
75 hf_resolver = HfHubResolver([LORA_LIB])
76 assert hf_resolver is not None
77
78 readme_request = await hf_resolver.resolve_lora(
79 LORA_LIB_MODEL_NAME, NON_LORA_SUBPATH
80 )
81 assert readme_request is None
82
83
84 @pytest.mark.asyncio
85 async def test_invalid_repo():
86 hf_resolver = HfHubResolver([LORA_LIB])
87 assert hf_resolver is not None
88
89 invalid_repo_req = await hf_resolver.resolve_lora(
90 INVALID_REPO_NAME,
91 f"{INVALID_REPO_NAME}/foo",
92 )
93 assert invalid_repo_req is None
94
95
96 @pytest.mark.asyncio
97 async def test_trailing_slash():
98 hf_resolver = HfHubResolver([LORA_LIB])
99 assert hf_resolver is not None
100
101 lora_request = await hf_resolver.resolve_lora(
102 LORA_LIB_MODEL_NAME,
103 f"{LORA_NAME}/",
104 )
105 assert lora_request is not None
106 assert lora_request.lora_name == f"{LORA_NAME}/"
107 assert LIB_DOWNLOAD_DIR in lora_request.lora_path
108 assert "adapter_config.json" in os.listdir(lora_request.lora_path)