Skip to content

Commit 31dcab1

Browse files
authored
add compat with hf-hub >1 (#176)
* add compat with hf-hub >1 * fix import order to ensure tests go through
1 parent 3bd8685 commit 31dcab1

9 files changed

Lines changed: 134 additions & 72 deletions

File tree

‎.gitignore‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
.venv
1+
.venv/
2+
.venv-*/
23
build
34
dist
45
wandb
@@ -23,5 +24,4 @@ data_subset/**
2324
*.txt
2425
*.log
2526
xlmr-*/**
26-
**/checkpoint-*/**
27-
.venv/
27+
**/checkpoint-*/**

‎setup.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
version="2.2.0",
66
packages=find_packages(),
77
description="Universal Robust, Efficient and Adaptable Sentence Segmentation",
8+
long_description=open("README.md", encoding="utf-8").read(),
9+
long_description_content_type="text/markdown",
810
author="Markus Frohmann, Igor Sterner, Benjamin Minixhofer",
911
author_email="markus.frohmann@gmail.com",
1012
python_requires=">=3.9",
1113
install_requires=[
1214
# "onnxruntime>=1.13.1", # can make conflicts between onnxruntime and onnxruntime-gpu
1315
"transformers>=4.22.2",
14-
"huggingface-hub<1.0", # v1.0 has breaking changes (HfFolder removed)
16+
"huggingface-hub",
1517
"numpy>=1.0",
1618
"scikit-learn>=1",
1719
"tqdm",

‎wtpsplit/__init__.py‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77
from pathlib import Path
88
from typing import Literal
99

10+
import numpy as np
11+
12+
# Import skops before transformers: skops enumerates trusted types at import time
13+
# and can otherwise trigger transformers' lazy vision submodules (torchvision), which
14+
# wtpsplit does not use for segmentation.
15+
import skops.io as sio
16+
1017
# avoid the "None of PyTorch, TensorFlow, etc. have been found" warning.
1118
with contextlib.redirect_stderr(open(os.devnull, "w")):
1219
import transformers # noqa
1320

14-
import numpy as np
15-
import skops.io as sio
16-
1721
from huggingface_hub import hf_hub_download
1822
from transformers import AutoConfig, AutoModelForTokenClassification, AutoTokenizer
1923
from transformers.utils.hub import cached_file

‎wtpsplit/train/adaptertrainer.py‎

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,56 @@
11
import os
2-
from typing import Dict
2+
import re
3+
from typing import Callable, Dict, List, Optional, Tuple, Union
34

45
import numpy as np
56
import torch
7+
from packaging import version
68
from torch import nn
9+
from torch.utils.data import Dataset
10+
11+
from transformers import PreTrainedModel, Trainer, __version__
12+
from transformers.configuration_utils import PretrainedConfig
13+
from transformers.data.data_collator import DataCollator
14+
from transformers.tokenization_utils_base import PreTrainedTokenizerBase
15+
from transformers.trainer_callback import (
16+
TrainerCallback,
17+
TrainerControl,
18+
TrainerState,
19+
)
20+
from transformers.trainer_utils import EvalPrediction
21+
from transformers.training_args import TrainingArguments
22+
from transformers.utils import (
23+
CONFIG_NAME,
24+
is_accelerate_available,
25+
is_apex_available,
26+
logging,
27+
)
728

8-
from transformers import PreTrainedModel
9-
from transformers.modeling_utils import unwrap_model
10-
from transformers.trainer import (
29+
from wtpsplit.train.hf_compat import is_torch_tpu_available
30+
from wtpsplit.train.transformers_trainer_imports import (
1131
ALL_LAYERNORM_LAYERS,
12-
WEIGHTS_NAME,
1332
DataLoader,
1433
EvalLoopOutput,
1534
IterableDatasetShard,
16-
List,
17-
Optional,
35+
WEIGHTS_NAME,
1836
deepspeed_init,
1937
denumpify_detensorize,
2038
find_batch_size,
2139
get_parameter_names,
2240
has_length,
2341
is_sagemaker_mp_enabled,
24-
is_torch_tpu_available,
2542
nested_concat,
2643
nested_numpify,
2744
nested_truncate,
45+
unwrap_model,
2846
)
29-
3047
from wtpsplit.train.utils import Model
3148

3249
if is_torch_tpu_available(check_device=False):
3350
import torch_xla.core.xla_model as xm # noqa: F401
3451
import torch_xla.debug.metrics as met # noqa: F401
3552
import torch_xla.distributed.parallel_loader as pl # noqa: F401
3653

37-
import re
38-
from typing import Callable, Tuple, Union
39-
40-
from packaging import version
41-
from torch.utils.data import Dataset
42-
from transformers import Trainer, __version__
43-
from transformers.configuration_utils import PretrainedConfig
44-
from transformers.data.data_collator import DataCollator
45-
from transformers.tokenization_utils_base import PreTrainedTokenizerBase
46-
from transformers.trainer_callback import (
47-
TrainerCallback,
48-
TrainerControl,
49-
TrainerState,
50-
)
51-
from transformers.trainer_utils import (
52-
EvalPrediction,
53-
)
54-
from transformers.training_args import TrainingArguments
55-
from transformers.utils import (
56-
CONFIG_NAME,
57-
is_accelerate_available,
58-
is_apex_available,
59-
is_torch_tpu_available,
60-
logging,
61-
)
62-
63-
from adapters.composition import AdapterCompositionBlock, Fuse
64-
6554
if is_apex_available():
6655
pass
6756

@@ -74,6 +63,7 @@
7463

7564
if version.parse(accelerate_version) >= version.parse("0.16"):
7665
pass
66+
7767
logger = logging.get_logger(__name__)
7868

7969
TRAINING_ARGS_NAME = "training_args.bin"
@@ -121,8 +111,12 @@ def __init__(
121111
model_frozen = getattr(self.model.backbone.base_model, "model_frozen", False)
122112
else:
123113
model_frozen = False
114+
# Default: same as pre-lazy-import behaviour when `model_frozen` is False (e.g. full finetune path).
115+
self.train_adapter_fusion = False
124116
if model_frozen and self.model.backbone.active_adapters:
125-
# Check if training AdapterFusion
117+
# Check if training AdapterFusion (requires optional `adapters` package)
118+
from adapters.composition import AdapterCompositionBlock, Fuse
119+
126120
self.train_adapter_fusion = (
127121
isinstance(self.model.backbone.active_adapters, Fuse)
128122
or isinstance(self.model.backbone.active_adapters, AdapterCompositionBlock)
@@ -304,9 +298,7 @@ def evaluation_loop(
304298
if args.deepspeed and not self.deepspeed:
305299
# XXX: eval doesn't have `resume_from_checkpoint` arg but we should be able to do eval
306300
# from the checkpoint eventually
307-
deepspeed_engine, _, _ = deepspeed_init(
308-
self, num_training_steps=0, resume_from_checkpoint=None, inference=True
309-
)
301+
deepspeed_engine, _, _ = deepspeed_init(self, num_training_steps=0, inference=True)
310302
self.model = deepspeed_engine.module
311303
self.model_wrapped = deepspeed_engine
312304
self.deepspeed = deepspeed_engine

‎wtpsplit/train/hf_compat.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""TPU / XLA checks compatible with **transformers 4.x and 5.x**.
2+
3+
v5 removed ``is_torch_tpu_available`` from ``transformers.trainer``; ``is_torch_xla_available``
4+
exists on both and matches the old behaviour.
5+
"""
6+
7+
from transformers.utils.import_utils import is_torch_xla_available
8+
9+
10+
def is_torch_tpu_available(check_device: bool = True) -> bool:
11+
"""Same idea as the old ``transformers.trainer.is_torch_tpu_available``.
12+
13+
- ``check_device=False``: ``torch_xla`` is importable (optional imports).
14+
- ``check_device=True`` (default): current process is on a TPU.
15+
"""
16+
if check_device:
17+
return is_torch_xla_available(check_is_tpu=True)
18+
return is_torch_xla_available()

‎wtpsplit/train/train.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
from torchinfo import summary
2424
from tqdm.auto import tqdm
2525
from transformers import AutoTokenizer, HfArgumentParser, TrainingArguments, set_seed
26-
from transformers.trainer import is_torch_tpu_available
26+
27+
from wtpsplit.train.hf_compat import is_torch_tpu_available
2728

2829
import wandb
2930
from wtpsplit.models import (

‎wtpsplit/train/trainer.py‎

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
11
import os
2-
from typing import Dict
2+
from typing import Dict, List, Optional
33

44
import numpy as np
55
import torch
66
import transformers
77
from torch import nn
88
from torch.optim.lr_scheduler import LambdaLR
99
from transformers import PreTrainedModel
10-
from transformers.trainer import (
10+
11+
from wtpsplit.train.hf_compat import is_torch_tpu_available
12+
from wtpsplit.train.transformers_trainer_imports import (
1113
ALL_LAYERNORM_LAYERS,
12-
TRAINING_ARGS_NAME,
13-
WEIGHTS_NAME,
1414
DataLoader,
1515
EvalLoopOutput,
1616
IterableDatasetShard,
17-
List,
18-
Optional,
19-
ShardedDDPOption,
17+
TRAINING_ARGS_NAME,
18+
WEIGHTS_NAME,
2019
deepspeed_init,
2120
denumpify_detensorize,
2221
find_batch_size,
2322
get_parameter_names,
2423
has_length,
2524
is_sagemaker_mp_enabled,
26-
is_torch_tpu_available,
2725
logger,
2826
nested_concat,
2927
nested_numpify,
3028
nested_truncate,
29+
unwrap_model,
3130
)
32-
from transformers.modeling_utils import unwrap_model
33-
3431
from wtpsplit.train.utils import Model
3532

3633
if is_torch_tpu_available(check_device=False):
@@ -108,19 +105,19 @@ def create_optimizer(self):
108105

109106
optimizer_cls, optimizer_kwargs = Trainer.get_optimizer_cls_and_kwargs(self.args)
110107

111-
if self.sharded_ddp == ShardedDDPOption.SIMPLE:
108+
_sharded = getattr(self, "sharded_ddp", None)
109+
if _sharded is not None and getattr(_sharded, "name", str(_sharded)) == "SIMPLE":
112110
raise NotImplementedError()
113-
else:
114-
self.optimizer = optimizer_cls(optimizer_grouped_parameters, **optimizer_kwargs)
115-
if optimizer_cls.__name__ == "Adam8bit":
116-
import bitsandbytes
111+
self.optimizer = optimizer_cls(optimizer_grouped_parameters, **optimizer_kwargs)
112+
if optimizer_cls.__name__ == "Adam8bit":
113+
import bitsandbytes
117114

118-
manager = bitsandbytes.optim.GlobalOptimManager.get_instance()
115+
manager = bitsandbytes.optim.GlobalOptimManager.get_instance()
119116

120-
for module in opt_model.modules():
121-
if isinstance(module, nn.Embedding):
122-
manager.register_module_override(module, "weight", {"optim_bits": 32})
123-
logger.debug(f"bitsandbytes: will optimize {module} in fp32")
117+
for module in opt_model.modules():
118+
if isinstance(module, nn.Embedding):
119+
manager.register_module_override(module, "weight", {"optim_bits": 32})
120+
logger.debug(f"bitsandbytes: will optimize {module} in fp32")
124121

125122
if is_sagemaker_mp_enabled():
126123
raise NotImplementedError()
@@ -226,9 +223,7 @@ def evaluation_loop(
226223
if args.deepspeed and not self.deepspeed:
227224
# XXX: eval doesn't have `resume_from_checkpoint` arg but we should be able to do eval
228225
# from the checkpoint eventually
229-
deepspeed_engine, _, _ = deepspeed_init(
230-
self, num_training_steps=0, resume_from_checkpoint=None, inference=True
231-
)
226+
deepspeed_engine, _, _ = deepspeed_init(self, num_training_steps=0, inference=True)
232227
self.model = deepspeed_engine.module
233228
self.model_wrapped = deepspeed_engine
234229
self.deepspeed = deepspeed_engine
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""Stable imports for custom ``Trainer`` subclasses on **transformers 4.x and 5.x**.
2+
3+
In v5, many symbols are no longer re-exported from ``transformers.trainer``; importing from the
4+
same public submodules used internally works on both versions (``integrations.deepspeed``,
5+
``pytorch_utils``, ``trainer_pt_utils``, etc.).
6+
"""
7+
8+
from transformers.integrations.deepspeed import deepspeed_init
9+
from transformers.modeling_utils import unwrap_model
10+
from transformers.pytorch_utils import ALL_LAYERNORM_LAYERS
11+
from transformers.trainer import (
12+
DataLoader,
13+
EvalLoopOutput,
14+
IterableDatasetShard,
15+
TRAINING_ARGS_NAME,
16+
WEIGHTS_NAME,
17+
logger,
18+
)
19+
from transformers.trainer_pt_utils import (
20+
find_batch_size,
21+
get_parameter_names,
22+
nested_concat,
23+
nested_numpify,
24+
nested_truncate,
25+
)
26+
from transformers.trainer_utils import denumpify_detensorize, has_length
27+
from transformers.utils import is_sagemaker_mp_enabled
28+
29+
__all__ = [
30+
"ALL_LAYERNORM_LAYERS",
31+
"DataLoader",
32+
"EvalLoopOutput",
33+
"IterableDatasetShard",
34+
"TRAINING_ARGS_NAME",
35+
"WEIGHTS_NAME",
36+
"deepspeed_init",
37+
"denumpify_detensorize",
38+
"find_batch_size",
39+
"get_parameter_names",
40+
"has_length",
41+
"is_sagemaker_mp_enabled",
42+
"logger",
43+
"nested_concat",
44+
"nested_numpify",
45+
"nested_truncate",
46+
"unwrap_model",
47+
]

‎wtpsplit/train/utils.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ def forward(
5050
else:
5151
reduced_attention_mask = (input_ids != 0).to(torch.long)
5252

53+
# Transformers 4.51+ Trainer may pass this; HF models ignore it, custom backbones must not receive it.
54+
kwargs.pop("num_items_in_batch", None)
55+
5356
output = dict(
5457
self.backbone.forward(
5558
input_ids=input_ids,

0 commit comments

Comments
 (0)