Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate PEFT LoRA with HuggingFaceModel #2829

Merged
merged 76 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
81cdd0e
add peft config
dakinggg Dec 19, 2023
3d06ed9
fix
dakinggg Dec 22, 2023
27cee1d
fix
dakinggg Dec 22, 2023
9fe230f
wip
dakinggg Jan 8, 2024
91a9962
tests and fixes
dakinggg Jan 9, 2024
af8a887
fix
dakinggg Jan 9, 2024
9a51ded
fix
dakinggg Jan 9, 2024
1b4ee1c
Merge branch 'dev' into composer_lora
dakinggg Jan 9, 2024
d43bd0c
precommit
dakinggg Jan 9, 2024
a8cc52f
fsdp test
dakinggg Jan 9, 2024
a7fe00c
bump version, add mistral fixtures, fix various tests
dakinggg Jan 9, 2024
48808b0
precommit
dakinggg Jan 9, 2024
0c21573
fix
dakinggg Jan 9, 2024
a4031f1
no peft
dakinggg Jan 9, 2024
44f8a89
rank0 path
dakinggg Jan 9, 2024
1ac4337
rank0 path
dakinggg Jan 9, 2024
538a54f
rank0 path
dakinggg Jan 9, 2024
b81506a
rank0 path
dakinggg Jan 9, 2024
0fda300
rank0 path
dakinggg Jan 9, 2024
57bf7df
rank0 path
dakinggg Jan 9, 2024
e4792f8
rank0 path
dakinggg Jan 9, 2024
d01e79f
rank0 path
dakinggg Jan 9, 2024
aa552f2
rank0 path
dakinggg Jan 9, 2024
49c10ac
sd filter
dakinggg Jan 9, 2024
4b7e472
filter sd
dakinggg Jan 9, 2024
09346e7
precommit
dakinggg Jan 9, 2024
dd47afe
more complete test
dakinggg Jan 16, 2024
ca494c5
gate
dakinggg Jan 16, 2024
b345d85
fix
dakinggg Jan 16, 2024
c400ab0
debug
dakinggg Jan 17, 2024
f276664
fix inspect for peft
dakinggg Jan 17, 2024
4da1d94
merge
dakinggg Jan 18, 2024
e9d4c4c
precommit
dakinggg Jan 18, 2024
794fc7c
Merge branch 'dev' into composer_lora
dakinggg Jan 18, 2024
eca54b1
update
dakinggg Jan 18, 2024
f019e1b
fix imports
dakinggg Jan 18, 2024
d8258aa
precommit
dakinggg Jan 18, 2024
7042185
round 1
dakinggg Jan 18, 2024
651faa0
remove more
dakinggg Jan 18, 2024
1c869d6
tests back
dakinggg Jan 18, 2024
c923125
add more back
dakinggg Jan 18, 2024
06bc6b6
add back
dakinggg Jan 18, 2024
e6ace25
add upper
dakinggg Jan 18, 2024
2396174
also task type
dakinggg Jan 18, 2024
87941a4
remove import
dakinggg Jan 18, 2024
db9d6c0
add quant and error
dakinggg Jan 18, 2024
8071285
precommit
dakinggg Jan 18, 2024
a82a57d
clean up
dakinggg Jan 19, 2024
1ba8f40
adjust
dakinggg Jan 20, 2024
4598e00
Merge branch 'dev' into composer_lora
dakinggg Jan 20, 2024
c26287d
Merge branch 'dev' into composer_lora
dakinggg Jan 22, 2024
a0e217f
simplify attempt
dakinggg Jan 23, 2024
090a026
precommit
dakinggg Jan 23, 2024
284c74b
Merge branch 'dev' into composer_lora
dakinggg Jan 23, 2024
144340e
fix tests
dakinggg Jan 23, 2024
f78d580
export peft installed
dakinggg Jan 25, 2024
176fdbe
first part of pr comments
dakinggg Jan 25, 2024
320ff55
clean up config usage
dakinggg Jan 25, 2024
67e3cb2
refactor underlying model get
dakinggg Jan 26, 2024
4f2fb19
`erge branch 'dev' into composer_lora
dakinggg Jan 26, 2024
a438f0a
fix
dakinggg Jan 26, 2024
090b736
finish cleaning up init
dakinggg Jan 26, 2024
d608099
adapter name cleanup
dakinggg Jan 26, 2024
d982d40
fix args
dakinggg Jan 26, 2024
ccfd004
rename
dakinggg Jan 26, 2024
d48be10
merge
dakinggg Jan 26, 2024
59b8106
Update tests/models/test_hf_model.py
dakinggg Jan 26, 2024
fdbdc0c
Update tests/models/test_hf_model.py
dakinggg Jan 26, 2024
0cb1587
fix rename
dakinggg Jan 26, 2024
d7cf361
precommit
dakinggg Jan 26, 2024
0a78471
Merge branch 'dev' into composer_lora
dakinggg Jan 26, 2024
840ee10
Merge branch 'dev' into composer_lora
dakinggg Jan 26, 2024
54c041f
nit
dakinggg Jan 29, 2024
e9c4d4a
rename
dakinggg Jan 29, 2024
f8f458b
Merge branch 'dev' into composer_lora
dakinggg Jan 29, 2024
e01c76f
Merge branch 'dev' into composer_lora
dakinggg Jan 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer/datasets/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def __init__(
self.stop_sequence_id_len = len(self.stop_sequence_ids) + 2
self.tokenizer = tokenizer

def __call__(self, input_ids: torch.Tensor, scores: Optional[torch.FloatTensor] = None, **kwargs) -> bool:
def __call__(self, input_ids: torch.LongTensor, scores: Optional[torch.FloatTensor] = None, **kwargs) -> bool:
dakinggg marked this conversation as resolved.
Show resolved Hide resolved
# For efficiency, we compare the last n tokens where n is the number of tokens in the stop_sequence
lookback_ids_batch = input_ids[:, :][:, -self.stop_sequence_id_len:]

Expand Down
271 changes: 234 additions & 37 deletions composer/models/huggingface.py

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ def package_files(prefix: str, directory: str, extension: str):
'datasets>=2.4,<3',
]

extra_deps['peft'] = [
'peft>=0.7.0,<0.8',
]

extra_deps['sentencepiece'] = [
'protobuf<3.21',
'sentencepiece==0.1.99',
Expand Down
102 changes: 80 additions & 22 deletions tests/common/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""Contains commonly used models that are shared across the test suite."""
import copy
from functools import partial
from typing import Any, Dict, Optional, Tuple, Union
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union

import pytest
import torch
Expand All @@ -14,6 +14,9 @@
from composer.metrics.nlp import LanguageCrossEntropy, MaskedAccuracy
from composer.models import ComposerClassifier, HuggingFaceModel

if TYPE_CHECKING:
from transformers import PretrainedConfig, PreTrainedModel, PreTrainedTokenizer, PreTrainedTokenizerFast


class EmptyModel(ComposerClassifier):
"""Always predict 0 with no parameters."""
Expand Down Expand Up @@ -443,105 +446,160 @@ def forward(self, batch: Tuple[torch.Tensor, Any]) -> torch.Tensor:
# As a workaround, we inject objects into the PyTest namespace. Tests should not directly
# use pytest.{var}, but instead should import and use these helper copy methods so the
# objects in the PyTest namespace do not change.
def configure_tiny_bert_model():
def configure_tiny_bert_model() -> 'PreTrainedModel':
try:
from transformers import PreTrainedModel
assert isinstance(pytest.tiny_bert_model, PreTrainedModel)
return copy.deepcopy(pytest.tiny_bert_model)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_bert_tokenizer():
def configure_tiny_bert_tokenizer() -> Union['PreTrainedTokenizer', 'PreTrainedTokenizerFast']:
try:
from transformers import PreTrainedTokenizer, PreTrainedTokenizerFast
assert isinstance(pytest.tiny_bert_tokenizer, (PreTrainedTokenizer, PreTrainedTokenizerFast))
return copy.deepcopy(pytest.tiny_bert_tokenizer)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_bert_config():
def configure_tiny_bert_config() -> 'PretrainedConfig':
try:
from transformers import PretrainedConfig
assert isinstance(pytest.tiny_bert_config, PretrainedConfig)
return copy.deepcopy(pytest.tiny_bert_config)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_bert_hf_model(use_logits=True):
return HuggingFaceModel(configure_tiny_bert_model(), configure_tiny_bert_tokenizer(), use_logits) # type: ignore
def configure_tiny_bert_hf_model(use_logits: bool = True) -> HuggingFaceModel:
return HuggingFaceModel(configure_tiny_bert_model(), configure_tiny_bert_tokenizer(), use_logits)


def configure_tiny_deberta_model():
def configure_tiny_deberta_model() -> 'PreTrainedModel':
try:
from transformers import PreTrainedModel
assert isinstance(pytest.tiny_deberta_model, PreTrainedModel)
return copy.deepcopy(pytest.tiny_deberta_model)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_deberta_tokenizer():
def configure_tiny_deberta_tokenizer() -> Union['PreTrainedTokenizer', 'PreTrainedTokenizerFast']:
try:
from transformers import PreTrainedTokenizer, PreTrainedTokenizerFast
assert isinstance(pytest.tiny_deberta_tokenizer, (PreTrainedTokenizer, PreTrainedTokenizerFast))
return copy.deepcopy(pytest.tiny_deberta_tokenizer)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_deberta_config():
def configure_tiny_deberta_config() -> 'PretrainedConfig':
try:
from transformers import PretrainedConfig
assert isinstance(pytest.tiny_deberta_config, PretrainedConfig)
return copy.deepcopy(pytest.tiny_deberta_config)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_deberta_hf_model(use_logits=True):
def configure_tiny_deberta_hf_model(use_logits: bool = True) -> HuggingFaceModel:
return HuggingFaceModel(
configure_tiny_deberta_model(), # type: ignore
configure_tiny_deberta_tokenizer(), # type: ignore
configure_tiny_deberta_model(),
configure_tiny_deberta_tokenizer(),
use_logits,
)


def configure_tiny_gpt2_model():
def configure_tiny_gpt2_model() -> 'PreTrainedModel':
try:
from transformers import PreTrainedModel
assert isinstance(pytest.tiny_gpt2_model, PreTrainedModel)
return copy.deepcopy(pytest.tiny_gpt2_model)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_gpt2_tokenizer():
def configure_tiny_gpt2_tokenizer() -> Union['PreTrainedTokenizer', 'PreTrainedTokenizerFast']:
try:
from transformers import PreTrainedTokenizer, PreTrainedTokenizerFast
assert isinstance(pytest.tiny_gpt2_tokenizer, (PreTrainedTokenizer, PreTrainedTokenizerFast))
return copy.deepcopy(pytest.tiny_gpt2_tokenizer)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_gpt2_config():
def configure_tiny_gpt2_config() -> 'PretrainedConfig':
try:
from transformers import PretrainedConfig
assert isinstance(pytest.tiny_gpt2_config, PretrainedConfig)
return copy.deepcopy(pytest.tiny_gpt2_config)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_gpt2_hf_model(use_logits=True):
return HuggingFaceModel(configure_tiny_gpt2_model(), configure_tiny_gpt2_tokenizer(), use_logits) # type: ignore
def configure_tiny_gpt2_hf_model(use_logits: bool = True) -> HuggingFaceModel:
return HuggingFaceModel(configure_tiny_gpt2_model(), configure_tiny_gpt2_tokenizer(), use_logits)


def configure_tiny_t5_model():
def configure_tiny_t5_model() -> 'PreTrainedModel':
try:
from transformers import PreTrainedModel
assert isinstance(pytest.tiny_t5_model, PreTrainedModel)
return copy.deepcopy(pytest.tiny_t5_model)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_t5_tokenizer():
def configure_tiny_t5_tokenizer() -> Union['PreTrainedTokenizer', 'PreTrainedTokenizerFast']:
try:
from transformers import PreTrainedTokenizer, PreTrainedTokenizerFast
assert isinstance(pytest.tiny_t5_tokenizer, (PreTrainedTokenizer, PreTrainedTokenizerFast))
return copy.deepcopy(pytest.tiny_t5_tokenizer)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_t5_config():
def configure_tiny_t5_config() -> 'PretrainedConfig':
try:
from transformers import PretrainedConfig
assert isinstance(pytest.tiny_t5_config, PretrainedConfig)
return copy.deepcopy(pytest.tiny_t5_config)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_t5_hf_model(use_logits=True):
return HuggingFaceModel(configure_tiny_t5_model(), configure_tiny_t5_tokenizer(), use_logits) # type: ignore
def configure_tiny_t5_hf_model(use_logits: bool = True) -> HuggingFaceModel:
return HuggingFaceModel(configure_tiny_t5_model(), configure_tiny_t5_tokenizer(), use_logits)


def configure_tiny_mistral_model() -> 'PreTrainedModel':
try:
from transformers import PreTrainedModel
assert isinstance(pytest.tiny_mistral_model, PreTrainedModel)
return copy.deepcopy(pytest.tiny_mistral_model)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_mistral_tokenizer() -> Union['PreTrainedTokenizer', 'PreTrainedTokenizerFast']:
try:
from transformers import PreTrainedTokenizer, PreTrainedTokenizerFast
assert isinstance(pytest.tiny_mistral_tokenizer, (PreTrainedTokenizer, PreTrainedTokenizerFast))
return copy.deepcopy(pytest.tiny_mistral_tokenizer)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_mistral_config() -> 'PretrainedConfig':
try:
from transformers import PretrainedConfig
assert isinstance(pytest.tiny_mistral_config, PretrainedConfig)
return copy.deepcopy(pytest.tiny_mistral_config)
except AttributeError:
pytest.skip('Composer installed without NLP support')


def configure_tiny_mistral_hf_model(use_logits: bool = True) -> HuggingFaceModel:
return HuggingFaceModel(configure_tiny_mistral_model(), configure_tiny_mistral_tokenizer(), use_logits)
7 changes: 6 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ def pytest_configure():
if TRANSFORMERS_INSTALLED:
from tests.fixtures.fixtures import (tiny_bert_config_helper, tiny_bert_model_helper,
tiny_bert_tokenizer_helper, tiny_gpt2_config_helper,
tiny_gpt2_model_helper, tiny_gpt2_tokenizer_helper, tiny_opt_config_helper,
tiny_gpt2_model_helper, tiny_gpt2_tokenizer_helper,
tiny_mistral_config_helper, tiny_mistral_model_helper,
tiny_mistral_tokenizer_helper, tiny_opt_config_helper,
tiny_opt_model_helper, tiny_opt_tokenizer_helper, tiny_t5_config_helper,
tiny_t5_model_helper, tiny_t5_tokenizer_helper)
pytest.tiny_bert_config = tiny_bert_config_helper() # type: ignore
Expand All @@ -126,6 +128,9 @@ def pytest_configure():
pytest.tiny_t5_config = tiny_t5_config_helper() # type: ignore
pytest.tiny_t5_model = tiny_t5_model_helper(pytest.tiny_t5_config) # type: ignore
pytest.tiny_t5_tokenizer = tiny_t5_tokenizer_helper() # type: ignore
pytest.tiny_mistral_config = tiny_mistral_config_helper() # type: ignore
pytest.tiny_mistral_model = tiny_mistral_model_helper(pytest.tiny_mistral_config) # type: ignore
pytest.tiny_mistral_tokenizer = tiny_mistral_tokenizer_helper() # type: ignore


def pytest_sessionfinish(session: pytest.Session, exitstatus: int):
Expand Down
56 changes: 56 additions & 0 deletions tests/fixtures/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,47 @@ def _session_tiny_t5_model(_session_tiny_t5_config): # type: ignore
return tiny_t5_model_helper(_session_tiny_t5_config)


def tiny_mistral_config_helper():
transformers = pytest.importorskip('transformers')

tiny_overrides = {
'hidden_size': 128,
'intermediate_size': 256,
'num_attention_heads': 8,
'num_hidden_layers': 2,
'num_kv_heads': 4
}
return transformers.AutoConfig.from_pretrained('mistralai/Mistral-7B-v0.1', **tiny_overrides)


@pytest.fixture(scope='session')
def _session_tiny_mistral_config(): # type: ignore
return tiny_mistral_config_helper()


def tiny_mistral_tokenizer_helper():
transformers = pytest.importorskip('transformers')

hf_tokenizer = transformers.AutoTokenizer.from_pretrained('mistralai/Mistral-7B-v0.1', model_max_length=512)
return hf_tokenizer


@pytest.fixture(scope='session')
def _session_tiny_mistral_tokenizer(): # type: ignore
return tiny_mistral_tokenizer_helper()


def tiny_mistral_model_helper(config):
transformers = pytest.importorskip('transformers')

return transformers.AutoModelForCausalLM.from_config(config)


@pytest.fixture(scope='session')
def _session_tiny_t5_model(_session_tiny_t5_config): # type: ignore
return tiny_t5_model_helper(_session_tiny_t5_config)


@pytest.fixture
def tiny_bert_model(_session_tiny_bert_model):
return copy.deepcopy(_session_tiny_bert_model)
Expand Down Expand Up @@ -393,3 +434,18 @@ def tiny_t5_tokenizer(_session_tiny_t5_tokenizer):
@pytest.fixture
def tiny_t5_model(_session_tiny_t5_model):
return copy.deepcopy(_session_tiny_t5_model)


@pytest.fixture
def tiny_mistral_config(_session_tiny_mistral_config):
return copy.deepcopy(_session_tiny_mistral_config)


@pytest.fixture
def tiny_mistral_tokenizer(_session_tiny_mistral_tokenizer):
return copy.deepcopy(_session_tiny_mistral_tokenizer)


@pytest.fixture
def tiny_mistral_model(_session_tiny_mistral_model):
return copy.deepcopy(_session_tiny_mistral_model)
Loading
Loading