Breaking change on `torch_required`.
Author: xkszltl
Pull request: no

`torch_required` was replaced by `requires_backends` in the following PR:
- https://github.com/huggingface/transformers/pull/20715#issuecomment-1704069322

This breaks the existing code using `torch_required`, and it is an unnecessary breaking change because `torch_required` can simply be reimplemented based on `requires_backends`.
We run into this issue and had to say transformers<4.26 in our own requirements.txt as mitigation.

Comments:
Hi @xkszltl, thanks for raising this issue. 

So that we can best help, could you: 
* Provide an minimal code snippet to reproduce this issue
* Give some more information about the error that occurs - the full error traceback if possible? 
* Share the the running environment: run `transformers-cli env` in the terminal and copy-paste the output

This is not related to any repro or error log, it's simply an existing func (decorator) got removed unnecessarily in the PR mentioned, so whatever code using that func will not work anymore.

`@torch_required` are used by people in various places before `requires_backends` exists, and we still want those code to work with a newer version of transformers.

A simple search on github found 700 calls to torch_required and all of them would be broken for no good reason.
![image](https://github.com/huggingface/transformers/assets/5203025/a9a5046d-050e-42de-8cc9-9907b6eae2c4)


Hi @xkszltl, 

The functions `torch_required` and `tf_required` were never part of our documented API and so we don't guaranteed backward compatibility or maintenance of these functions. They have been removed for some time now and this is the first issue raised, so it's not something we've seen have a large negative impact on the community. 

We understand it can be frustrating if there's something you're used to using gets modified or changed. The great thing about open source is you can use and modify the code as you wish (license permitting). For example, for the `torch_required` method, you can copy the deleted function and add it wherever is suitable in your codebase. 

```python
def torch_required(func):
    # Chose a different decorator name than in tests so it's clear they are not the same.
    @wraps(func)
    def wrapper(*args, **kwargs):
        if is_torch_available():
            return func(*args, **kwargs)
        else:
            raise ImportError(f"Method `{func.__name__}` requires PyTorch.")

    return wrapper
```




Thanks @amyeroberts 

> were never part of our documented API

That's a good point.
I think there's a difference between what's verbally on the API and what's practically used as API.
For example, as you can see in the screenshot, there're code copying `training_args.py` to build its own project, and `training_args.py` uses `torch_required` (this is also where we initially noticed the issue).
File like this may be internal to transformers, but in reality a lot of research projects would simply made changes on top.
I'm not saying it's a good practice, we can safely say they were relying on UB, but it did happen and the question would be: Do we have to break their use of UB?

> They have been removed for some time now and this is the first issue raised

(Here's just my experience in work, not necessarily represent the everyone's statistics)

I tend to find people hesitate to raise this kind of issues back, because it's time consuming, with fixes not readily available until the next release and unlikely to benefit their short-term exploration.
In most cases it's much easier to do exactly as what you describe (paste the old code back) and move on, without thinking if it's a good engineering practice.

> We understand it can be frustrating if there's something you're used to using gets modified or changed. The great thing about open source is you can use and modify the code as you wish (license permitting).

We usually consider that's bad because:
- Modifying/forking lib code (on transformers side) would break its integrity and also make it hard to upgrade in the future.
- Modifying downstream app code is doable but it's still a "fix", and it's a fix that has to be applied to all versions in history.
    - This also pushes people to do stricter version pinning, which is bad for security, upgradability and maintenance.

These are high-level thoughts and backgrounds about why we think it's not a good idea.

There're many technical ways to mitigate the error, but that's not the most important thing we want to raise through this issue.

Thanks for raising the issue @xkszltl! We could put back `torch_required` with a deprecation warning redirecting to the more complete and up-to-date `require_backends`, this would prevent your code from breaking.

Would you like to open a PR yourself to add it? If not, let me see what we can do internally to have a working workaround.

Would be great if you can help adding that in.
I don't have much experience with this part of code, just happen to come across this in our code base when trying to upgrade to the latest of transformer.

cc @ydshieh @Rocketknight1 in case you have some bandwidth available 

Just a matter of reverting the change relative to `import_utils` and init in https://github.com/huggingface/transformers/pull/20715/

![image](https://github.com/huggingface/transformers/assets/30755778/8868d12b-0b2f-46bc-9a5d-2676a688ec7c)


I can put it back, but the question would be when we could remove it. It's already a lot of deprecation in our codebase, and we don't have plan for a major release.

If we decide to have a deprecation cycle for a few minor releases for this specific change, that's fine to me. But at the end, @xkszltl (and other potential users) still needs to rework their codebase.

@xkszltl The above PR will bring them back. But please considering your codebase too, as we would not keep eveything deprecated forever 🙏 . 

Thanks @ydshieh 

> But at the end, @xkszltl

We're already working on that part

> (and other potential users) still needs to rework their codebase.

That's the point I'm trying to emphasize.
Not every code piece are actively maintained, and not everyone have the intention to do that.
It's simply impossible to tell everyone in the world "you have to work on something", breaking change breaks things.

> It's already a lot of deprecation in our codebase, and we don't have plan for a major release.

If there's a strong need of deprecation, e.g. to enable new functionality or major redesign that's incompatible with before, that would be a good reason to break backward compatibility.
If it's for the cleanness of code, I would say it's a much weaker reason.

In this case I would suggest to have a legacy dir for things no longer wanted but don't have the be broken, and import back to where it originally was in one line to keep that clean.

Also, without release of major version, it's better to just keep those deprecated things, or it's basically saying "all minor version can be incompatible with each other", which kind of defeat the purpose of major-minor versioning.

Hello @xkszltl
 
The plan is to remove these 2 functions, see #28220. Is it ready on your side before we merge that PR.