Fix tapas scatter (#20149)

* First draft

* Remove scatter dependency

* Add require_torch

* update vectorized sum test, add clone call

* remove artifacts

* fix style

* fix style v2

* remove "scatter" mentions from the code base

* fix isort error

Co-authored-by: Niels Rogge <nielsrogge@Nielss-MacBook-Pro.local>
Co-authored-by: ydshieh <ydshieh@users.noreply.github.com>
This commit is contained in:
Bartosz Szmelczynski 2022-11-14 07:04:26 +01:00 committed by GitHub
parent f711d683b5
commit 78a471ff71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 77 additions and 194 deletions

View File

@ -41,9 +41,6 @@ RUN python3 -m pip uninstall -y flax jax
# TODO: remove this line once the conflict is resolved in these libraries.
RUN python3 -m pip install --no-cache-dir git+https://github.com/onnx/tensorflow-onnx.git@ddca3a5eb2d912f20fe7e0568dd1a3013aee9fa3
# Use installed torch version for `torch-scatter` to avid to deal with PYTORCH='pre'.
# If torch is nightly version, the link is likely to be invalid, but the installation falls back to the latest torch-scatter
RUN python3 -m pip install --no-cache-dir torch-scatter -f https://data.pyg.org/whl/torch-$(python3 -c "from torch import version; print(version.__version__.split('+')[0])")+$CUDA.html
RUN python3 -m pip install --no-cache-dir intel_extension_for_pytorch==$INTEL_TORCH_EXT+cpu -f https://software.intel.com/ipex-whl-stable
RUN python3 -m pip install --no-cache-dir git+https://github.com/facebookresearch/detectron2.git pytesseract

View File

@ -10,7 +10,6 @@ RUN apt-get -y update && apt-get install -y libsndfile1-dev && apt install -y te
# Torch needs to be installed before deepspeed
RUN python3 -m pip install --no-cache-dir ./transformers[deepspeed]
RUN python3 -m pip install --no-cache-dir torch-scatter -f https://data.pyg.org/whl/torch-$(python -c "from torch import version; print(version.__version__.split('+')[0])")+cpu.html
RUN python3 -m pip install --no-cache-dir torchvision git+https://github.com/facebookresearch/detectron2.git pytesseract
RUN python3 -m pip install --no-cache-dir pytorch-quantization --extra-index-url https://pypi.ngc.nvidia.com
RUN python3 -m pip install -U "itsdangerous<2.1.0"

View File

@ -34,10 +34,4 @@ RUN python3 ./transformers/utils/past_ci_versions.py --framework $FRAMEWORK --ve
RUN echo "INSTALL_CMD = $INSTALL_CMD"
RUN $INSTALL_CMD
# Having installation problems for torch-scatter with torch <= 1.6. Disable so we have the same set of tests.
# (This part will be removed once the logic of using `past_ci_versions.py` is used in other Dockerfile files.)
# # Use installed torch version for `torch-scatter`.
# # (The env. variable $CUDA is defined in `past_ci_versions.py`)
# RUN [ "$FRAMEWORK" = "pytorch" ] && python3 -m pip install --no-cache-dir torch-scatter -f https://data.pyg.org/whl/torch-$(python3 -c "from torch import version; print(version.__version__.split('+')[0])")+$CUDA.html || echo "torch-scatter not to be installed"
RUN python3 -m pip install -U "itsdangerous<2.1.0"

View File

@ -69,8 +69,7 @@ To summarize:
<frameworkcontent>
<pt>
Initializing a model with a pre-trained base and randomly initialized classification heads from the hub can be done as shown below. Be sure to have installed the
[torch-scatter](https://github.com/rusty1s/pytorch_scatter) dependency:
Initializing a model with a pre-trained base and randomly initialized classification heads from the hub can be done as shown below.
```py
>>> from transformers import TapasConfig, TapasForQuestionAnswering

View File

@ -32,7 +32,6 @@ from .utils import (
OptionalDependencyNotAvailable,
_LazyModule,
is_flax_available,
is_scatter_available,
is_sentencepiece_available,
is_speech_available,
is_tensorflow_text_available,
@ -784,28 +783,6 @@ else:
]
)
try:
if not is_scatter_available():
raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
from .utils import dummy_scatter_objects
_import_structure["utils.dummy_scatter_objects"] = [
name for name in dir(dummy_scatter_objects) if not name.startswith("_")
]
else:
_import_structure["models.tapas"].extend(
[
"TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST",
"TapasForMaskedLM",
"TapasForQuestionAnswering",
"TapasForSequenceClassification",
"TapasModel",
"TapasPreTrainedModel",
"load_tf_weights_in_tapas",
]
)
# PyTorch-backed objects
try:
@ -2027,6 +2004,17 @@ else:
"Swinv2PreTrainedModel",
]
)
_import_structure["models.tapas"].extend(
[
"TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST",
"TapasForMaskedLM",
"TapasForQuestionAnswering",
"TapasForSequenceClassification",
"TapasModel",
"TapasPreTrainedModel",
"load_tf_weights_in_tapas",
]
)
_import_structure["models.t5"].extend(
[
"T5_PRETRAINED_MODEL_ARCHIVE_LIST",
@ -3845,22 +3833,6 @@ if TYPE_CHECKING:
TableTransformerPreTrainedModel,
)
try:
if not is_scatter_available():
raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
from .utils.dummy_scatter_objects import *
else:
from .models.tapas import (
TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST,
TapasForMaskedLM,
TapasForQuestionAnswering,
TapasForSequenceClassification,
TapasModel,
TapasPreTrainedModel,
load_tf_weights_in_tapas,
)
try:
if not is_torch_available():
raise OptionalDependencyNotAvailable()
@ -4854,6 +4826,15 @@ if TYPE_CHECKING:
T5PreTrainedModel,
load_tf_weights_in_t5,
)
from .models.tapas import (
TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST,
TapasForMaskedLM,
TapasForQuestionAnswering,
TapasForSequenceClassification,
TapasModel,
TapasPreTrainedModel,
load_tf_weights_in_tapas,
)
from .models.time_series_transformer import (
TIME_SERIES_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST,
TimeSeriesTransformerForPrediction,

View File

@ -102,7 +102,6 @@ from .utils import (
is_rjieba_available,
is_sagemaker_dp_enabled,
is_sagemaker_mp_enabled,
is_scatter_available,
is_scipy_available,
is_sentencepiece_available,
is_sklearn_available,

View File

@ -34,27 +34,14 @@ from ...utils import (
ModelOutput,
add_start_docstrings,
add_start_docstrings_to_model_forward,
is_scatter_available,
logging,
replace_return_docstrings,
requires_backends,
)
from .configuration_tapas import TapasConfig
logger = logging.get_logger(__name__)
# soft dependency
if is_scatter_available():
try:
from torch_scatter import scatter
except OSError:
logger.error(
"TAPAS models are not usable since `torch_scatter` can't be loaded. "
"It seems you have `torch_scatter` installed with the wrong CUDA version. "
"Please try to reinstall it following the instructions here: https://github.com/rusty1s/pytorch_scatter."
)
_CONFIG_FOR_DOC = "TapasConfig"
_TOKENIZER_FOR_DOC = "TapasTokenizer"
_TOKENIZER_FOR_DOC = "google/tapas-base"
@ -862,7 +849,6 @@ class TapasModel(TapasPreTrainedModel):
"""
def __init__(self, config, add_pooling_layer=True):
requires_backends(self, "scatter")
super().__init__(config)
self.config = config
@ -1798,12 +1784,9 @@ def _segment_reduce(values, index, segment_reduce_fn, name):
# changed "view" by "reshape" in the following line
flat_values = values.reshape(flattened_shape.tolist())
segment_means = scatter(
src=flat_values,
index=flat_index.indices.long(),
dim=0,
dim_size=int(flat_index.num_segments),
reduce=segment_reduce_fn,
out = torch.zeros(int(flat_index.num_segments), dtype=flat_values.dtype)
segment_means = out.scatter_reduce(
dim=0, index=flat_index.indices.long(), src=flat_values, reduce=segment_reduce_fn, include_self=False
)
# Unflatten the values.
@ -1816,7 +1799,7 @@ def _segment_reduce(values, index, segment_reduce_fn, name):
dim=0,
)
output_values = segment_means.view(new_shape.tolist())
output_values = segment_means.clone().view(new_shape.tolist())
output_index = range_index_map(index.batch_shape(), index.num_segments)
return output_values, output_index
@ -1901,7 +1884,7 @@ def reduce_max(values, index, name="segmented_reduce_max"):
output_values (`torch.Tensor`of shape [B1, B2, ..., Bn, num_segments, V1, V2, ..]): Tensor containing the
output values. output_index (`IndexMap`): IndexMap with shape [B1, B2, ..., Bn, num_segments].
"""
return _segment_reduce(values, index, "max", name)
return _segment_reduce(values, index, "amax", name)
def reduce_min(values, index, name="segmented_reduce_min"):
@ -1928,7 +1911,7 @@ def reduce_min(values, index, name="segmented_reduce_min"):
output_values (`torch.Tensor`of shape [B1, B2, ..., Bn, num_segments, V1, V2, ..]): Tensor containing the
output values. output_index (`IndexMap`): IndexMap with shape [B1, B2, ..., Bn, num_segments].
"""
return _segment_reduce(values, index, "min", name)
return _segment_reduce(values, index, "amin", name)
# End of everything related to segmented tensors

View File

@ -65,7 +65,6 @@ from .utils import (
is_pytorch_quantization_available,
is_rjieba_available,
is_safetensors_available,
is_scatter_available,
is_scipy_available,
is_sentencepiece_available,
is_soundfile_availble,
@ -319,16 +318,6 @@ def require_intel_extension_for_pytorch(test_case):
)(test_case)
def require_torch_scatter(test_case):
"""
Decorator marking a test that requires PyTorch scatter.
These tests are skipped when PyTorch scatter isn't installed.
"""
return unittest.skipUnless(is_scatter_available(), "test requires PyTorch scatter")(test_case)
def require_tensorflow_probability(test_case):
"""
Decorator marking a test that requires TensorFlow probability.
@ -405,14 +394,6 @@ def require_pytesseract(test_case):
return unittest.skipUnless(is_pytesseract_available(), "test requires PyTesseract")(test_case)
def require_scatter(test_case):
"""
Decorator marking a test that requires PyTorch Scatter. These tests are skipped when PyTorch Scatter isn't
installed.
"""
return unittest.skipUnless(is_scatter_available(), "test requires PyTorch Scatter")(test_case)
def require_pytorch_quantization(test_case):
"""
Decorator marking a test that requires PyTorch Quantization Toolkit. These tests are skipped when PyTorch

View File

@ -127,7 +127,6 @@ from .import_utils import (
is_safetensors_available,
is_sagemaker_dp_enabled,
is_sagemaker_mp_enabled,
is_scatter_available,
is_scipy_available,
is_sentencepiece_available,
is_sklearn_available,

View File

@ -5099,6 +5099,48 @@ def load_tf_weights_in_t5(*args, **kwargs):
requires_backends(load_tf_weights_in_t5, ["torch"])
TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST = None
class TapasForMaskedLM(metaclass=DummyObject):
_backends = ["torch"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["torch"])
class TapasForQuestionAnswering(metaclass=DummyObject):
_backends = ["torch"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["torch"])
class TapasForSequenceClassification(metaclass=DummyObject):
_backends = ["torch"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["torch"])
class TapasModel(metaclass=DummyObject):
_backends = ["torch"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["torch"])
class TapasPreTrainedModel(metaclass=DummyObject):
_backends = ["torch"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["torch"])
def load_tf_weights_in_tapas(*args, **kwargs):
requires_backends(load_tf_weights_in_tapas, ["torch"])
TIME_SERIES_TRANSFORMER_PRETRAINED_MODEL_ARCHIVE_LIST = None

View File

@ -1,45 +0,0 @@
# This file is autogenerated by the command `make fix-copies`, do not edit.
# flake8: noqa
from ..utils import DummyObject, requires_backends
TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST = None
class TapasForMaskedLM(metaclass=DummyObject):
_backends = ["scatter"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["scatter"])
class TapasForQuestionAnswering(metaclass=DummyObject):
_backends = ["scatter"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["scatter"])
class TapasForSequenceClassification(metaclass=DummyObject):
_backends = ["scatter"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["scatter"])
class TapasModel(metaclass=DummyObject):
_backends = ["scatter"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["scatter"])
class TapasPreTrainedModel(metaclass=DummyObject):
_backends = ["scatter"]
def __init__(self, *args, **kwargs):
requires_backends(self, ["scatter"])
def load_tf_weights_in_tapas(*args, **kwargs):
requires_backends(load_tf_weights_in_tapas, ["scatter"])

View File

@ -145,6 +145,7 @@ except importlib_metadata.PackageNotFoundError:
except importlib_metadata.PackageNotFoundError:
_faiss_available = False
_ftfy_available = importlib.util.find_spec("ftfy") is not None
try:
_ftfy_version = importlib_metadata.version("ftfy")
@ -176,6 +177,7 @@ try:
except importlib_metadata.PackageNotFoundError:
_tf2onnx_available = False
_onnx_available = importlib.util.find_spec("onnxruntime") is not None
try:
_onxx_version = importlib_metadata.version("onnx")
@ -184,14 +186,6 @@ except importlib_metadata.PackageNotFoundError:
_onnx_available = False
_scatter_available = importlib.util.find_spec("torch_scatter") is not None
try:
_scatter_version = importlib_metadata.version("torch_scatter")
logger.debug(f"Successfully imported torch-scatter version {_scatter_version}")
except importlib_metadata.PackageNotFoundError:
_scatter_available = False
_pytorch_quantization_available = importlib.util.find_spec("pytorch_quantization") is not None
try:
_pytorch_quantization_version = importlib_metadata.version("pytorch_quantization")
@ -584,10 +578,6 @@ def is_in_notebook():
return False
def is_scatter_available():
return _scatter_available
def is_pytorch_quantization_available():
return _pytorch_quantization_available
@ -826,13 +816,6 @@ installation section: https://github.com/rspeer/python-ftfy/tree/master#installi
that match your environment. Please note that you may need to restart your runtime after installation.
"""
# docstyle-ignore
SCATTER_IMPORT_ERROR = """
{0} requires the torch-scatter library but it was not found in your environment. You can install it with pip as
explained here: https://github.com/rusty1s/pytorch_scatter. Please note that you may need to restart your runtime after installation.
"""
# docstyle-ignore
PYTORCH_QUANTIZATION_IMPORT_ERROR = """
{0} requires the pytorch-quantization library but it was not found in your environment. You can install it with pip:
@ -941,7 +924,6 @@ BACKENDS_MAPPING = OrderedDict(
("pyctcdecode", (is_pyctcdecode_available, PYCTCDECODE_IMPORT_ERROR)),
("pytesseract", (is_pytesseract_available, PYTESSERACT_IMPORT_ERROR)),
("sacremoses", (is_sacremoses_available, SACREMOSES_IMPORT_ERROR)),
("scatter", (is_scatter_available, SCATTER_IMPORT_ERROR)),
("pytorch_quantization", (is_pytorch_quantization_available, PYTORCH_QUANTIZATION_IMPORT_ERROR)),
("sentencepiece", (is_sentencepiece_available, SENTENCEPIECE_IMPORT_ERROR)),
("sklearn", (is_sklearn_available, SKLEARN_IMPORT_ERROR)),

View File

@ -130,8 +130,7 @@ SPEECH_TO_TEXT_TINY = "hf-internal-testing/tiny-random-speech_to_text"
# models with low usage, unstable API, things about to change - do nothing about the following until someone runs into a problem
TAPAS_TINY = "hf-internal-testing/tiny-random-tapas"
# additional notes on tapas
# 1. requires torch_scatter - skip if it's not installed?
# 2. "Table must be of type pd.DataFrame" failure
# 1. "Table must be of type pd.DataFrame" failure
# TODO: new models to add:

View File

@ -28,7 +28,6 @@ from transformers.testing_utils import (
DUMMY_UNKNOWN_IDENTIFIER,
SMALL_MODEL_IDENTIFIER,
RequestCounter,
require_scatter,
require_torch,
slow,
)
@ -197,7 +196,6 @@ class AutoModelTest(unittest.TestCase):
self.assertIsInstance(model, BertForQuestionAnswering)
@slow
@require_scatter
def test_table_question_answering_model_from_pretrained(self):
for model_name in TAPAS_PRETRAINED_MODEL_ARCHIVE_LIST[5:6]:
config = AutoConfig.from_pretrained(model_name)

View File

@ -32,7 +32,6 @@ from transformers.testing_utils import (
get_tests_dir,
is_pt_tf_cross_test,
require_pandas,
require_scatter,
require_sentencepiece,
require_tokenizers,
require_torch,
@ -1176,7 +1175,6 @@ class LayoutXLMTokenizationTest(TokenizerTesterMixin, unittest.TestCase):
@require_torch
@slow
@require_scatter
def test_torch_encode_plus_sent_to_model(self):
import torch

View File

@ -32,13 +32,7 @@ from transformers import (
is_torch_available,
)
from transformers.models.auto import get_values
from transformers.testing_utils import (
require_scatter,
require_tensorflow_probability,
require_torch,
slow,
torch_device,
)
from transformers.testing_utils import require_tensorflow_probability, require_torch, slow, torch_device
from transformers.utils import cached_property
from ...test_configuration_common import ConfigTester
@ -414,7 +408,6 @@ class TapasModelTester:
@require_torch
@require_scatter
class TapasModelTest(ModelTesterMixin, unittest.TestCase):
all_model_classes = (
@ -553,7 +546,6 @@ def prepare_tapas_batch_inputs_for_training():
@require_torch
@require_scatter
class TapasModelIntegrationTest(unittest.TestCase):
@cached_property
def default_tokenizer(self):
@ -907,7 +899,7 @@ class TapasModelIntegrationTest(unittest.TestCase):
# Below: tests for Tapas utilities which are defined in modeling_tapas.py.
# These are based on segmented_tensor_test.py of the original implementation.
# URL: https://github.com/google-research/tapas/blob/master/tapas/models/segmented_tensor_test.py
@require_scatter
@require_torch
class TapasUtilitiesTest(unittest.TestCase):
def _prepare_tables(self):
"""Prepares two tables, both with three distinct rows.
@ -1064,11 +1056,11 @@ class TapasUtilitiesTest(unittest.TestCase):
def test_reduce_sum_vectorized(self):
values = torch.as_tensor([[1.0, 2.0, 3.0], [2.0, 3.0, 4.0], [3.0, 4.0, 5.0]])
index = IndexMap(indices=torch.as_tensor([0, 0, 1]), num_segments=2, batch_dims=0)
index = IndexMap(indices=torch.as_tensor([[0, 0, 1]]), num_segments=2, batch_dims=0)
sums, new_index = reduce_sum(values, index)
# We use np.testing.assert_allclose rather than Tensorflow's assertAllClose
np.testing.assert_allclose(sums.numpy(), [[3.0, 5.0, 7.0], [3.0, 4.0, 5.0]])
np.testing.assert_allclose(sums.numpy(), [3.0, 3.0])
# We use np.testing.assert_array_equal rather than Tensorflow's assertAllEqual
np.testing.assert_array_equal(new_index.indices.numpy(), [0, 1])
np.testing.assert_array_equal(new_index.num_segments.numpy(), 2)

View File

@ -35,7 +35,6 @@ from transformers.models.tapas.tokenization_tapas import (
from transformers.testing_utils import (
is_pt_tf_cross_test,
require_pandas,
require_scatter,
require_tensorflow_probability,
require_tokenizers,
require_torch,
@ -1031,7 +1030,6 @@ class TapasTokenizationTest(TokenizerTesterMixin, unittest.TestCase):
@require_torch
@slow
@require_scatter
def test_torch_encode_plus_sent_to_model(self):
import torch

View File

@ -50,7 +50,6 @@ from transformers.testing_utils import (
RequestCounter,
is_staging_test,
nested_simplify,
require_scatter,
require_tensorflow_probability,
require_tf,
require_torch,
@ -749,7 +748,6 @@ class PipelineUtilsTest(unittest.TestCase):
@slow
@require_torch
@require_scatter
def test_load_default_pipelines_pt_table_qa(self):
import torch

View File

@ -22,14 +22,7 @@ from transformers import (
TFAutoModelForTableQuestionAnswering,
pipeline,
)
from transformers.testing_utils import (
require_pandas,
require_tensorflow_probability,
require_tf,
require_torch,
require_torch_scatter,
slow,
)
from transformers.testing_utils import require_pandas, require_tensorflow_probability, require_tf, require_torch, slow
from .test_pipelines_common import PipelineTestCaseMeta
@ -145,7 +138,6 @@ class TQAPipelineTests(unittest.TestCase, metaclass=PipelineTestCaseMeta):
)
@require_torch
@require_torch_scatter
def test_small_model_pt(self):
model_id = "lysandre/tiny-tapas-random-wtq"
model = AutoModelForTableQuestionAnswering.from_pretrained(model_id)
@ -248,7 +240,6 @@ class TQAPipelineTests(unittest.TestCase, metaclass=PipelineTestCaseMeta):
)
@require_torch
@require_torch_scatter
def test_slow_tokenizer_sqa_pt(self):
model_id = "lysandre/tiny-tapas-random-sqa"
model = AutoModelForTableQuestionAnswering.from_pretrained(model_id)
@ -490,7 +481,6 @@ class TQAPipelineTests(unittest.TestCase, metaclass=PipelineTestCaseMeta):
)
@slow
@require_torch_scatter
def test_integration_wtq_pt(self):
table_querier = pipeline("table-question-answering")
@ -584,7 +574,6 @@ class TQAPipelineTests(unittest.TestCase, metaclass=PipelineTestCaseMeta):
self.assertListEqual(results, expected_results)
@slow
@require_torch_scatter
def test_integration_sqa_pt(self):
table_querier = pipeline(
"table-question-answering",