make torch.load a bit safer
Author: julien-c
Pull request: yes


Comments:
The docs for this PR live [here](https://moon-ci-docs.huggingface.co/docs/transformers/pr_27282). All of your documentation changes will be reflected on that endpoint.

This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the [contributing guidelines](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md) are likely to be ignored.

cc @LysandreJik is this stale or has it been done elsewhere since?

Thank you! :)

yay 1 more commit on the GOAT of codebases!!! happy:)

Hi @julien-c, thanks for your work!

I was building from `main` to use some features not distributed, but I found that `from_pretrained` no longer worked, and it might have something to do with this pr.

The code is as simple as this:
```
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
```
And it raises
```
Traceback (most recent call last):
  File "***/lib/python3.9/site-packages/transformers/modeling_utils.py", line 520, in load_state_dict
    return torch.load(checkpoint_file, map_location=map_location, weights_only=True)
  File "***/lib/python3.9/site-packages/torch/serialization.py", line 607, in load
    return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
  File "***/lib/python3.9/site-packages/torch/serialization.py", line 880, in _load
    unpickler = UnpicklerWrapper(data_file, **pickle_load_args)
TypeError: 'weights_only' is an invalid keyword argument for Unpickler()

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "***/lib/python3.9/site-packages/transformers/modeling_utils.py", line 524, in load_state_dict
    if f.read(7) == "version":
  File "***/lib/python3.9/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 64: invalid start byte

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ***, line 3, in <module>
    model = AutoModelForCausalLM.from_pretrained(
  File "***/lib/python3.9/site-packages/transformers/models/auto/auto_factory.py", line 566, in from_pretrained
    return model_class.from_pretrained(
  File "***/lib/python3.9/site-packages/transformers/modeling_utils.py", line 3430, in from_pretrained
    state_dict = load_state_dict(resolved_archive_file)
  File "***/lib/python3.9/site-packages/transformers/modeling_utils.py", line 536, in load_state_dict
    raise OSError(
OSError: Unable to load weights from pytorch checkpoint file for '/home/***/.cache/huggingface/hub/models--facebook--opt-125m/snapshots/27dcfa74d334bc871f3234de431e71c6eeba5dd6/pytorch_model.bin' at '/home/***/.cache/huggingface/hub/models--facebook--opt-125m/snapshots/27dcfa74d334bc871f3234de431e71c6eeba5dd6/pytorch_model.bin'. If you tried to load a PyTorch model from a TF 2.0 checkpoint, please set from_tf=True.
```

The `TypeError` seems to be related to incompatible `pytorch`. I'm using `1.10.1+cu111`. I wonder maybe it's better to fallback to the original implementation in case of error and emit a one-time warning? 

~~As for `UnicodeDecodeError`, I don't really know where it comes from. It might be related to `codec` or `pickle`, but I'm not sure. I'm using `Python 3.9.18`. I also tried deleting the cache and download again, but it still didn't work.~~

~~I also checked `from_tf=True` in the error, but it seems that `tensorflow` is required (which I don't have), so I think this shouldn't be the problem. After all, everything worked fine with `transformers 4.36.2` previously.~~

Fixing the `TypeError` shall eliminate the other errors.

Thank you for your time! If you need any help from me, feel free to ask.

torch 1.10 is quite old, is there any way you'd be able to upgrade to a more recent torch?

Sure, but the point is, `transformers` claims to support torch 1.10 [in its deps](https://github.com/huggingface/transformers/blob/932ad8af7a333875a36a9a2007d2601510b1f601/setup.py#L178C5-L178C28), but `weights_only` wasn't added to `torch.load` until 1.13 (see [here](https://pytorch.org/docs/1.12/generated/torch.load.html)). It might be better if either the deps are updated, or backward support is added?

yep! cc @LysandreJik 

#28207 will fix this 🤗 

>  but `weights_only` wasn't added to `torch.load` until 1.13 (see [here](https://pytorch.org/docs/1.12/generated/torch.load.html))

https://github.com/huggingface/transformers/pull/28207 only removes 1.10, but for torch 1.11 and torch 1.12, secure pickling should still be buggy. You can take a moment to compare https://pytorch.org/docs/1.12/generated/torch.load.html and https://pytorch.org/docs/1.13/generated/torch.load.html.

You're correct @hjenryin, we're taking a look at fixing this before the next release. Thanks for the report