From 7089b0f9257c1edbdb5feefd98a61fcaf09a8ad3 Mon Sep 17 00:00:00 2001 From: Prashant Gupta Date: Tue, 1 Oct 2024 12:01:33 -0700 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9E=95=20add=20a=20bunch=20of=20supporte?= =?UTF-8?q?d=20lora=20modules=20for=20mixtral=20(they=20are=20part=20of=20?= =?UTF-8?q?the=20all-linear=20option)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Prashant Gupta --- vllm/model_executor/models/mixtral.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vllm/model_executor/models/mixtral.py b/vllm/model_executor/models/mixtral.py index 10cbfcf6432b..2997c52b72ab 100644 --- a/vllm/model_executor/models/mixtral.py +++ b/vllm/model_executor/models/mixtral.py @@ -319,10 +319,8 @@ class MixtralForCausalLM(nn.Module, SupportsLoRA): # LoRA specific attributes supported_lora_modules = [ - "qkv_proj", - "o_proj", - "embed_tokens", - "lm_head", + "qkv_proj", "o_proj", "embed_tokens", "lm_head", "w1", "w2", "w3", + "gate" ] embedding_modules = { "embed_tokens": "input_embeddings", From 56ac3a6394ad0ad05c17df893dcd5b01f1dacb84 Mon Sep 17 00:00:00 2001 From: Prashant Gupta Date: Wed, 2 Oct 2024 13:03:12 -0700 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=85=20add=20unit=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the mixtral lora model to dyang415/mixtral-lora-v0 which has all supported linear layers for mixtral Signed-off-by: Prashant Gupta --- tests/lora/conftest.py | 4 +--- tests/lora/test_mixtral.py | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/tests/lora/conftest.py b/tests/lora/conftest.py index 7f6f60f38b5d..e6bf2d95fb30 100644 --- a/tests/lora/conftest.py +++ b/tests/lora/conftest.py @@ -168,9 +168,7 @@ def sql_lora_files(sql_lora_huggingface_id): @pytest.fixture(scope="session") def mixtral_lora_files(): - # Note: this module has incorrect adapter_config.json to test - # https://github.com/vllm-project/vllm/pull/5909/files. - return snapshot_download(repo_id="SangBinCho/mixtral-lora") + return snapshot_download(repo_id="dyang415/mixtral-lora-v0") @pytest.fixture(scope="session") diff --git a/tests/lora/test_mixtral.py b/tests/lora/test_mixtral.py index b5b4a79eb956..1c0412149f0a 100644 --- a/tests/lora/test_mixtral.py +++ b/tests/lora/test_mixtral.py @@ -11,9 +11,9 @@ def do_sample(llm: vllm.LLM, lora_path: str, lora_id: int) -> List[str]: prompts = [ - "[system] Given a target sentence construct the underlying meaning representation\nof the input sentence as a single function with attributes and attribute\nvalues. This function should describe the target string accurately and the\nfunction must be one of the following ['inform', 'request', 'give_opinion',\n'confirm', 'verify_attribute', 'suggest', 'request_explanation',\n'recommend', 'request_attribute'].\n\nThe attributes must be one of the following:\n['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating',\n'genres', 'player_perspective', 'has_multiplayer', 'platforms',\n'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier'] [/system] [user] Here is the target sentence:\nSpellForce 3 is a pretty bad game. The developer Grimlore Games is clearly a bunch of no-talent hacks, and 2017 was a terrible year for games anyway. [/user] [assistant]", # noqa: E501 - "[system] Given a target sentence construct the underlying meaning representation\nof the input sentence as a single function with attributes and attribute\nvalues. This function should describe the target string accurately and the\nfunction must be one of the following ['inform', 'request', 'give_opinion',\n'confirm', 'verify_attribute', 'suggest', 'request_explanation',\n'recommend', 'request_attribute'].\n\nThe attributes must be one of the following:\n['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating',\n'genres', 'player_perspective', 'has_multiplayer', 'platforms',\n'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier'] [/system] [user] Here is the target sentence:\nI wanted to like Grimlore Games' 2017 entry, but in SpellForce 3 they just didn't get anything right. [/user] [assistant]", # noqa: E501 - "[system] Given a target sentence construct the underlying meaning representation\nof the input sentence as a single function with attributes and attribute\nvalues. This function should describe the target string accurately and the\nfunction must be one of the following ['inform', 'request', 'give_opinion',\n'confirm', 'verify_attribute', 'suggest', 'request_explanation',\n'recommend', 'request_attribute'].\n\nThe attributes must be one of the following:\n['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating',\n'genres', 'player_perspective', 'has_multiplayer', 'platforms',\n'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier'] [/system] [user] Here is the target sentence:\nBioShock is a good role-playing, action-adventure, shooter that released for PlayStation, Xbox, and PC in 2007. It is available on Steam, and it has a Mac release but not a Linux release. [/user] [assistant]", # noqa: E501 + "Question: What happens if you touch the eyes of a blind man?\nChoices:\nB: The man's sight will be restored.\nA: Nothing happens if you touch the eyes of a blind man.\nC: The man will get his eyesight back.\nD: The man will no longer be blind.\nAnswer:", # noqa: E501 + "Question: Which will increase the energy of motion of water molecules?\nChoices:\nA: add heat\nB: add ice\nC: remove some of the water\nD: place the water in the freezer\nAnswer:", # noqa: E501 + "Since Craig threw aluminum cans in the trash and Benjamin recycled, _ was environmentally irresponsible.\nChoices:\n1: Craig\n2: Benjamin\nAnswer:", # noqa: E501 ] sampling_params = vllm.SamplingParams(temperature=0, max_tokens=256) outputs = llm.generate( @@ -36,18 +36,22 @@ def test_mixtral_lora(mixtral_lora_files, tp_size): if torch.cuda.device_count() < tp_size: pytest.skip(f"Not enough GPUs for tensor parallelism {tp_size}") - llm = vllm.LLM(MODEL_PATH, - enable_lora=True, - max_num_seqs=16, - max_loras=4, - distributed_executor_backend="ray", - tensor_parallel_size=tp_size) + llm = vllm.LLM( + MODEL_PATH, + enable_lora=True, + max_num_seqs=16, + max_loras=4, + distributed_executor_backend="ray", + tensor_parallel_size=tp_size, + max_lora_rank=32, + ) expected_lora_output = [ - "give_opinion(name[SpellForce 3], release_year[2017], developer[Grimlore Games], rating[poor])", # noqa: E501 - "give_opinion(name[SpellForce 3], developer[Grimlore Games], release_year[2017], rating[poor])", # noqa: E501 - "inform(name[BioShock], release_year[2007], rating[good], genres[action-adventure, role-playing, shooter], platforms[PlayStation, Xbox, PC], available_on_steam[yes], has_linux_release[no], has_mac_release[yes])", # noqa: E501 + "A: Nothing happens if you touch the eyes of a blind man.", + "A: add heat", + "1: Craig", ] + assert do_sample(llm, mixtral_lora_files, lora_id=1) == expected_lora_output assert do_sample(llm, mixtral_lora_files, From 1048ebeb762bc1d3cc307c1f68fb199bfd9e8eb7 Mon Sep 17 00:00:00 2001 From: Prashant Gupta Date: Thu, 3 Oct 2024 09:45:54 -0700 Subject: [PATCH 3/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor=20tests=20as?= =?UTF-8?q?=20per=20review=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Prashant Gupta --- tests/lora/conftest.py | 7 +++++ tests/lora/test_mixtral.py | 62 ++++++++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/tests/lora/conftest.py b/tests/lora/conftest.py index e6bf2d95fb30..da98fac99cf2 100644 --- a/tests/lora/conftest.py +++ b/tests/lora/conftest.py @@ -168,6 +168,13 @@ def sql_lora_files(sql_lora_huggingface_id): @pytest.fixture(scope="session") def mixtral_lora_files(): + # Note: this module has incorrect adapter_config.json to test + # https://github.com/vllm-project/vllm/pull/5909/files. + return snapshot_download(repo_id="SangBinCho/mixtral-lora") + + +@pytest.fixture(scope="session") +def mixtral_lora_files_all_target_modules(): return snapshot_download(repo_id="dyang415/mixtral-lora-v0") diff --git a/tests/lora/test_mixtral.py b/tests/lora/test_mixtral.py index 1c0412149f0a..dddc299da446 100644 --- a/tests/lora/test_mixtral.py +++ b/tests/lora/test_mixtral.py @@ -9,12 +9,9 @@ MODEL_PATH = "mistralai/Mixtral-8x7B-Instruct-v0.1" -def do_sample(llm: vllm.LLM, lora_path: str, lora_id: int) -> List[str]: - prompts = [ - "Question: What happens if you touch the eyes of a blind man?\nChoices:\nB: The man's sight will be restored.\nA: Nothing happens if you touch the eyes of a blind man.\nC: The man will get his eyesight back.\nD: The man will no longer be blind.\nAnswer:", # noqa: E501 - "Question: Which will increase the energy of motion of water molecules?\nChoices:\nA: add heat\nB: add ice\nC: remove some of the water\nD: place the water in the freezer\nAnswer:", # noqa: E501 - "Since Craig threw aluminum cans in the trash and Benjamin recycled, _ was environmentally irresponsible.\nChoices:\n1: Craig\n2: Benjamin\nAnswer:", # noqa: E501 - ] +def do_sample(llm: vllm.LLM, lora_path: str, lora_id: int, + prompts: List[str]) -> List[str]: + sampling_params = vllm.SamplingParams(temperature=0, max_tokens=256) outputs = llm.generate( prompts, @@ -33,9 +30,50 @@ def do_sample(llm: vllm.LLM, lora_path: str, lora_id: int) -> List[str]: @pytest.mark.parametrize("tp_size", [4]) def test_mixtral_lora(mixtral_lora_files, tp_size): + """Original test, the LoRA model has the common target modules, not all""" if torch.cuda.device_count() < tp_size: pytest.skip(f"Not enough GPUs for tensor parallelism {tp_size}") + prompts = [ + "[system] Given a target sentence construct the underlying meaning representation\nof the input sentence as a single function with attributes and attribute\nvalues. This function should describe the target string accurately and the\nfunction must be one of the following ['inform', 'request', 'give_opinion',\n'confirm', 'verify_attribute', 'suggest', 'request_explanation',\n'recommend', 'request_attribute'].\n\nThe attributes must be one of the following:\n['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating',\n'genres', 'player_perspective', 'has_multiplayer', 'platforms',\n'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier'] [/system] [user] Here is the target sentence:\nSpellForce 3 is a pretty bad game. The developer Grimlore Games is clearly a bunch of no-talent hacks, and 2017 was a terrible year for games anyway. [/user] [assistant]", # noqa: E501 + "[system] Given a target sentence construct the underlying meaning representation\nof the input sentence as a single function with attributes and attribute\nvalues. This function should describe the target string accurately and the\nfunction must be one of the following ['inform', 'request', 'give_opinion',\n'confirm', 'verify_attribute', 'suggest', 'request_explanation',\n'recommend', 'request_attribute'].\n\nThe attributes must be one of the following:\n['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating',\n'genres', 'player_perspective', 'has_multiplayer', 'platforms',\n'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier'] [/system] [user] Here is the target sentence:\nI wanted to like Grimlore Games' 2017 entry, but in SpellForce 3 they just didn't get anything right. [/user] [assistant]", # noqa: E501 + "[system] Given a target sentence construct the underlying meaning representation\nof the input sentence as a single function with attributes and attribute\nvalues. This function should describe the target string accurately and the\nfunction must be one of the following ['inform', 'request', 'give_opinion',\n'confirm', 'verify_attribute', 'suggest', 'request_explanation',\n'recommend', 'request_attribute'].\n\nThe attributes must be one of the following:\n['name', 'exp_release_date', 'release_year', 'developer', 'esrb', 'rating',\n'genres', 'player_perspective', 'has_multiplayer', 'platforms',\n'available_on_steam', 'has_linux_release', 'has_mac_release', 'specifier'] [/system] [user] Here is the target sentence:\nBioShock is a good role-playing, action-adventure, shooter that released for PlayStation, Xbox, and PC in 2007. It is available on Steam, and it has a Mac release but not a Linux release. [/user] [assistant]", # noqa: E501 + ] + + llm = vllm.LLM( + MODEL_PATH, + enable_lora=True, + max_num_seqs=16, + max_loras=4, + distributed_executor_backend="ray", + tensor_parallel_size=tp_size, + ) + + expected_lora_output = [ + "give_opinion(name[SpellForce 3], release_year[2017], developer[Grimlore Games], rating[poor])", # noqa: E501 + "give_opinion(name[SpellForce 3], developer[Grimlore Games], release_year[2017], rating[poor])", # noqa: E501 + "inform(name[BioShock], release_year[2007], rating[good], genres[action-adventure, role-playing, shooter], platforms[PlayStation, Xbox, PC], available_on_steam[yes], has_linux_release[no], has_mac_release[yes])", # noqa: E501 + ] + assert do_sample(llm, mixtral_lora_files, lora_id=1, + prompts=prompts) == expected_lora_output + assert do_sample(llm, mixtral_lora_files, lora_id=2, + prompts=prompts) == expected_lora_output + + +@pytest.mark.parametrize("tp_size", [4]) +def test_mixtral_lora_all_target_modules(mixtral_lora_files_all_target_modules, + tp_size): + """This LoRA model has all supported Mixtral target modules""" + + if torch.cuda.device_count() < tp_size: + pytest.skip(f"Not enough GPUs for tensor parallelism {tp_size}") + + prompts = [ + "Question: What happens if you touch the eyes of a blind man?\nChoices:\nB: The man's sight will be restored.\nA: Nothing happens if you touch the eyes of a blind man.\nC: The man will get his eyesight back.\nD: The man will no longer be blind.\nAnswer:", # noqa: E501 + "Question: Which will increase the energy of motion of water molecules?\nChoices:\nA: add heat\nB: add ice\nC: remove some of the water\nD: place the water in the freezer\nAnswer:", # noqa: E501 + "Since Craig threw aluminum cans in the trash and Benjamin recycled, _ was environmentally irresponsible.\nChoices:\n1: Craig\n2: Benjamin\nAnswer:", # noqa: E501 + ] + llm = vllm.LLM( MODEL_PATH, enable_lora=True, @@ -52,7 +90,11 @@ def test_mixtral_lora(mixtral_lora_files, tp_size): "1: Craig", ] - assert do_sample(llm, mixtral_lora_files, - lora_id=1) == expected_lora_output - assert do_sample(llm, mixtral_lora_files, - lora_id=2) == expected_lora_output + assert do_sample(llm, + mixtral_lora_files_all_target_modules, + lora_id=1, + prompts=prompts) == expected_lora_output + assert do_sample(llm, + mixtral_lora_files_all_target_modules, + lora_id=2, + prompts=prompts) == expected_lora_output