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

Tests Refactoring #740

Open
wants to merge 51 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
93bee1a
Make generation tests generic
TimoImhof Sep 16, 2024
f51cfdb
Merge remote-tracking branch 'origin/main' into dev/test-refactoring
TimoImhof Oct 16, 2024
7e65e82
Draft Refactoring AdapterTestBase
TimoImhof Oct 28, 2024
793cbe5
Merge branch 'adapter-hub:main' into dev/test-refactoring
TimoImhof Oct 30, 2024
65c3fb7
Replace import class names
TimoImhof Oct 30, 2024
afdcfdd
Merge branch 'dev/test-refactoring' of https://github.com/TimoImhof/a…
TimoImhof Oct 30, 2024
ee6166c
Base refactoring:
TimoImhof Nov 1, 2024
630b722
remove redundant imports
TimoImhof Nov 1, 2024
0d3577f
Add pytest markers and respective pytest commands
TimoImhof Nov 1, 2024
1300856
Add draft of README
TimoImhof Nov 1, 2024
78387db
Refactoring:
TimoImhof Nov 5, 2024
83d3b32
Fix make quality
TimoImhof Nov 5, 2024
5e8e1b8
Add gpt2 tests
TimoImhof Nov 5, 2024
53eb0b9
Fix config union and head tests
TimoImhof Nov 7, 2024
1dbd412
Fix paths and imports
TimoImhof Nov 7, 2024
cf4f6a7
remove accidently added prompt tuning from gpt2 and make style
TimoImhof Nov 7, 2024
b390d61
Revert PromptTuning changes
TimoImhof Nov 7, 2024
2193aee
Revert "Revert PromptTuning changes"
TimoImhof Nov 7, 2024
f555484
Re-add missing adapter model tests
TimoImhof Nov 7, 2024
8dccda2
Refactoring:
TimoImhof Nov 7, 2024
c665948
Introduce generic test creator function
TimoImhof Nov 8, 2024
fb425b6
Re-add beit adapter method tests
TimoImhof Nov 8, 2024
225439c
Refactor & Re-add bertgeneration and bert
TimoImhof Nov 9, 2024
09f9cdc
Re-add clip tests
TimoImhof Nov 11, 2024
7934350
Re-add:
TimoImhof Nov 11, 2024
5f55935
Add more models
TimoImhof Nov 21, 2024
147c8af
Re-add whisper
TimoImhof Nov 27, 2024
b2979ce
Changes:
TimoImhof Dec 16, 2024
ffd21a9
Add debug statements and only execute failing test
TimoImhof Dec 18, 2024
0dba87c
Add verbose information
TimoImhof Dec 18, 2024
c333467
check package versions
TimoImhof Dec 18, 2024
aac4038
More debugging statements
TimoImhof Dec 18, 2024
0f4c9b6
Merge branch 'adapter-hub:main' into dev/test-refactoring
TimoImhof Dec 22, 2024
9ac515c
Merge branch 'adapter-hub:main' into dev/test-refactoring
TimoImhof Dec 23, 2024
4af10df
Fix failing test:
TimoImhof Dec 23, 2024
dbd4965
Update README
TimoImhof Dec 24, 2024
d1a4a09
Merge branch 'main' of https://github.com/TimoImhof/adapters into dev…
TimoImhof Dec 27, 2024
c516464
Fix hf version and clip tests
TimoImhof Dec 27, 2024
87c0998
Merge branch 'adapter-hub:main' into dev/test-refactoring
TimoImhof Jan 8, 2025
2c80a5c
Polish:
TimoImhof Jan 8, 2025
be69f0a
Merge branch 'main' into dev/test-refactoring
TimoImhof Jan 8, 2025
f1b1136
Merge branch 'main' into dev/test-refactoring
TimoImhof Jan 8, 2025
88f6230
Integrate CLIP into refactored test structure
TimoImhof Jan 16, 2025
4a0c2f7
Remove conversion method
TimoImhof Jan 19, 2025
91f9036
Details:
TimoImhof Jan 19, 2025
cdd81f9
Transfer test class creation into if-statement
TimoImhof Jan 19, 2025
3738ada
Introduce new parameter to differentiate between redundant and not su…
TimoImhof Jan 19, 2025
843c968
Save config union debug process
TimoImhof Jan 22, 2025
e2a082e
Revert to standard import structure
TimoImhof Jan 23, 2025
3f33159
Revert config union debugging and test structure changes
TimoImhof Jan 23, 2025
0a35074
Remove initial fix:
TimoImhof Jan 23, 2025
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
19 changes: 15 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,29 @@ style:
isort $(check_dirs)
${MAKE} extra_style_checks

# Run tests for the library
# Library Tests

# run all tests in the library
test:
python -m pytest -n auto --dist=loadfile -s -v ./tests/
python -c "import transformers; print(transformers.__version__)"

# run all tests for the adapter methods for all adapter models
test-adapter-methods:
python -m pytest --ignore ./tests/models -n auto --dist=loadfile -s -v ./tests/
python -m pytest -n auto --dist=loadfile -s -v ./tests/test_methods/

# run a subset of the adapter method tests for all adapter models
# list of all subsets: [core, heads, embeddings, composition, prefix_tuning, prompt_tuning, reft, unipelt, compacter, bottleneck, ia3, lora, config_union]
subset ?=
test-adapter-method-subset:
@echo "Running subset $(subset)"
python -m pytest -n auto --dist=loadfile -s -v ./tests/test_methods/ -m $(subset)


# run the hugginface test suite for all adapter models
test-adapter-models:
python -m pytest -n auto --dist=loadfile -s -v ./tests/models
python -m pytest -n auto --dist=loadfile -s -v ./tests/test_models/

# Run tests for examples

test-examples:
python -m pytest -n auto --dist=loadfile -s -v ./examples/pytorch/
5 changes: 5 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,8 @@ def check_output(self, want, got, optionflags):


doctest.OutputChecker = CustomOutputChecker


def pytest_collection_modifyitems(items):
# Exclude the 'test_class' group from the test collection since it's not a real test class and byproduct of the generic test class generation.
items[:] = [item for item in items if 'test_class' not in item.nodeid]
2 changes: 1 addition & 1 deletion examples/pytorch/language-modeling/run_clm.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def main():
else:
model = AutoModelForCausalLM.from_config(config, trust_remote_code=model_args.trust_remote_code)
n_params = sum({p.data_ptr(): p.numel() for p in model.parameters()}.values())
logger.info(f"Training new model from scratch - Total size={n_params/2**20:.2f}M params")
logger.info(f"Training new model from scratch - Total size={n_params / 2**20:.2f}M params")

# Convert the model into an adapter model
adapters.init(model)
Expand Down
15 changes: 13 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
[tool.black]
line-length = 119
target-version = ['py38', 'py39', 'py310']

# copied from HF for testing
[tool.pytest.ini_options]
markers = [
"core: marks tests as core adapter test",
"composition: marks tests as composition adapter test",
"heads: marks tests as heads adapter test",
"embeddings: marks tests as embeddings adapter test",
"class_conversion: marks tests as class conversion adapter test",
"prefix_tuning: marks tests as prefix tuning adapter test",
"prompt_tuning: marks tests as prompt tuning adapter test",
"reft: marks tests as reft adapter test",
"unipelt: marks tests as unipelt adapter test",
"compacter: marks tests as compacter adapter test",
"bottleneck: marks tests as bottleneck adapter test",
"ia3: marks tests as ia3 adapter test",
"lora: marks tests as lora adapter test",
"flash_attn_test: marks tests related to flash attention (deselect with '-m \"not flash_attn_test\"')",
"bitsandbytes: select (or deselect with `not`) bitsandbytes integration tests",
"generate: marks tests that use the GenerationTesterMixin"
Expand Down
150 changes: 150 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Testing the Adapters Library

This README provides a comprehensive overview of the test directory organization and explains how to execute different types of tests within the adapters library.

## Test Directory Structure Overview

```
tests/
├── __init__.py
├── fixtures/ # Datasets, test samples, ...
| └── ...
├── test_methods/ # Dynamic adapter method tests (all models)
│ ├── __init__.py
│ ├── method_test_impl/ # Implementation of tests
│ │ ├── __init__.py
│ │ ├── core/
│ │ ├── composition/
│ │ └── ...
│ ├── base.py # Base from which model test bases inherit
│ ├── generator.py # Testcase generation and registration
│ ├── test_on_albert.py # Example model test base for testing adapter methods on albert adapter model
│ ├── test_on_beit.py
│ └── ...
├── test_misc/ # Miscellaneous adapter method tests (single model)
│ ├── test_adapter_config.py
│ └── ...
├── test_models/ # Adapter model tests with Hugging Face test suite
│ └── __init__.py
│ │ ├── base.py
│ │ ├── test_albert_model.py
│ │ └── ...
```

## Test Categories

The testing framework encompasses three distinct categories of tests:

1. Dynamic Adapter Method Tests: These tests cover core functionalities of the adapters library, including individual adapter methods (such as LoRA and prompt tuning) and head functionalities. These tests are executed across all supported models.

2. Miscellaneous Adapter Method Tests: These supplementary tests cover scenarios not included in the dynamic tests. To optimize resources, they are executed on a single model, as repeated execution across multiple models would not provide additional value.

3. Adapter Model Tests: These tests verify the implementation of the adapter models themselves using the Hugging Face model test suite.

## Test Generator and Pytest Markers

The test_methods directory contains the central component `generator.py`, which generates appropriate sets of adapter method tests. Each model test base registers these tests using the following pattern:

```python
method_tests = generate_method_tests(AlbertAdapterTestBase)

for test_class_name, test_class in method_tests.items():
globals()[test_class_name] = test_class
```

Each generated test class is decorated with a specific marker type. For example:

```python
@require_torch
@pytest.mark.lora
class LoRA(
AlbertAdapterTestBase,
LoRATestMixin,
unittest.TestCase,
):
pass
```

These markers enable the execution of specific test types across all models. You can run these tests using either of these methods:

1. Using the make command:
```bash
make test-adapter-method-subset subset=lora
```

2. Directly executing from the test directory:
```bash
cd tests/test_methods
pytest -m lora
```

Both approaches will execute all LoRA tests across every model in the adapters library.

## Adding a New Adapter Method to the Test Suite

The modular design of the test base simplifies the process of adding tests for new adapter methods. To add tests for a new adapter method "X", follow these steps:

1. Create the Test Implementation:
Create a new file `tests/test_methods/method_test_impl/peft/test_X.py` and implement the test mixin class:

```python
@require_torch
class XTestMixin(AdapterMethodBaseTestMixin):

default_config = XConfig()

def test_add_X(self):
model = self.get_model()
self.run_add_test(model, self.default_config, ["adapters.{name}."])

def ...
```

2. Register the Test Mixin:
Add the new test mixin class to `tests/test_methods/generator.py`:

```python
from tests.test_methods.method_test_impl.peft.test_X import XTestMixin

def generate_method_tests(model_test_base, ...):
""" Generate method tests for the given model test base """
test_classes = {}

@require_torch
@pytest.mark.core
class Core(
model_test_base,
CompabilityTestMixin,
AdapterFusionModelTestMixin,
unittest.TestCase,
):
pass

if "Core" not in excluded_tests:
test_classes["Core"] = Core

@require_torch
@pytest.mark.X
class X(
model_test_base,
XTestMixin,
unittest.TestCase,
):
pass

if "X" not in excluded_tests:
test_classes["X"] = X
```

The pytest marker enables execution of the new method's tests across all adapter models using:
```bash
make test-adapter-method-subset subset=X
```

If the new method is incompatible with specific adapter models, you can exclude the tests in the respective `test_on_xyz.py` file:

```python
method_tests = generate_method_tests(BartAdapterTestBase, excluded_tests=["PromptTuning", "X"])
```

Note: It is recommended to design new methods to work with the complete library whenever possible. Only exclude tests when there are unavoidable compatibility issues and make them clear in the documenation.
File renamed without changes.
42 changes: 0 additions & 42 deletions tests/methods/__init__.py

This file was deleted.

Loading
Loading