`with_format("numpy")` silently downcasts float64 to float32 features
COLLABORATOR
Hi! This behavior stems from these lines:

https://github.com/huggingface/datasets/blob/b065547654efa0ec633cf373ac1512884c68b2e1/src/datasets/formatting/np_formatter.py#L45-L46

I agree we should preserve the original type whenever possible and downcast explicitly with a warning.

@lhoestq Do you remember why we need this "default dtype" logic in our formatters?
2023-02-09T15:04:52Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1424335336
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5U5aHo
https://api.github.com/repos/huggingface/datasets/issues/comments/1424335336/reactions
2023-02-09T15:04:52Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1424335336
https://avatars.githubusercontent.com/u/47462742?v=4
https://api.github.com/users/mariosasko/events{/privacy}
https://api.github.com/users/mariosasko/followers
https://api.github.com/users/mariosasko/following{/other_user}
https://api.github.com/users/mariosasko/gists{/gist_id}
https://github.com/mariosasko
mariosasko
MDQ6VXNlcjQ3NDYyNzQy
https://api.github.com/users/mariosasko/orgs
https://api.github.com/users/mariosasko/received_events
https://api.github.com/users/mariosasko/repos
https://api.github.com/users/mariosasko/starred{/owner}{/repo}
https://api.github.com/users/mariosasko/subscriptions
User
https://api.github.com/users/mariosasko
public
NONE
I was also wondering why the default type logic is needed. Me just deleting it is probably too naive of a solution.
2023-02-09T15:06:29Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1424338437
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5U5a4F
https://api.github.com/repos/huggingface/datasets/issues/comments/1424338437/reactions
2023-02-09T15:06:38Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1424338437
https://avatars.githubusercontent.com/u/1250234?v=4
https://api.github.com/users/ernestum/events{/privacy}
https://api.github.com/users/ernestum/followers
https://api.github.com/users/ernestum/following{/other_user}
https://api.github.com/users/ernestum/gists{/gist_id}
https://github.com/ernestum
ernestum
MDQ6VXNlcjEyNTAyMzQ=
https://api.github.com/users/ernestum/orgs
https://api.github.com/users/ernestum/received_events
https://api.github.com/users/ernestum/repos
https://api.github.com/users/ernestum/starred{/owner}{/repo}
https://api.github.com/users/ernestum/subscriptions
User
https://api.github.com/users/ernestum
public
MEMBER
Hmm I think the idea was to end up with the usual default precision for deep learning models - no matter how the data was stored or where it comes from.

For example in NLP we store tokens using an optimized low precision to save disk space, but when we set the format to `torch` we actually need to get `int64`. Although the need for a default for integers also comes from numpy not returning the same integer precision depending on your machine. Finally I guess we added a default for floats as well for consistency.

I'm a bit embarrassed by this though, as a user I'd have expected to get the same precision indeed as well and get a zero copy view.
2023-02-09T15:44:10Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1424404260
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5U5q8k
https://api.github.com/repos/huggingface/datasets/issues/comments/1424404260/reactions
2023-02-09T15:44:10Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1424404260
https://avatars.githubusercontent.com/u/42851186?v=4
https://api.github.com/users/lhoestq/events{/privacy}
https://api.github.com/users/lhoestq/followers
https://api.github.com/users/lhoestq/following{/other_user}
https://api.github.com/users/lhoestq/gists{/gist_id}
https://github.com/lhoestq
lhoestq
MDQ6VXNlcjQyODUxMTg2
https://api.github.com/users/lhoestq/orgs
https://api.github.com/users/lhoestq/received_events
https://api.github.com/users/lhoestq/repos
https://api.github.com/users/lhoestq/starred{/owner}{/repo}
https://api.github.com/users/lhoestq/subscriptions
User
https://api.github.com/users/lhoestq
public
NONE
Will you fix this or should I open a PR?
2023-02-09T16:01:58Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1424430609
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5U5xYR
https://api.github.com/repos/huggingface/datasets/issues/comments/1424430609/reactions
2023-02-09T16:01:58Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1424430609
https://avatars.githubusercontent.com/u/1250234?v=4
https://api.github.com/users/ernestum/events{/privacy}
https://api.github.com/users/ernestum/followers
https://api.github.com/users/ernestum/following{/other_user}
https://api.github.com/users/ernestum/gists{/gist_id}
https://github.com/ernestum
ernestum
MDQ6VXNlcjEyNTAyMzQ=
https://api.github.com/users/ernestum/orgs
https://api.github.com/users/ernestum/received_events
https://api.github.com/users/ernestum/repos
https://api.github.com/users/ernestum/starred{/owner}{/repo}
https://api.github.com/users/ernestum/subscriptions
User
https://api.github.com/users/ernestum
public
MEMBER
Unfortunately removing it for integers is a breaking change for most `transformers` + `datasets` users for NLP (which is a common case). Removing it for floats is a breaking change for `transformers` + `datasets` for ASR as well. And it also is a breaking change for the other users relying on this behavior.

Therefore I think that the only short term solution is for the user to provide `dtype=` manually and document better this behavior. We could also extend `dtype` to accept a value that means "return the same dtype as the underlying storage" and make it easier to do zero copy.
2023-02-09T16:24:09Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1424463700
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5U55dU
https://api.github.com/repos/huggingface/datasets/issues/comments/1424463700/reactions
2023-02-09T16:24:09Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1424463700
https://avatars.githubusercontent.com/u/42851186?v=4
https://api.github.com/users/lhoestq/events{/privacy}
https://api.github.com/users/lhoestq/followers
https://api.github.com/users/lhoestq/following{/other_user}
https://api.github.com/users/lhoestq/gists{/gist_id}
https://github.com/lhoestq
lhoestq
MDQ6VXNlcjQyODUxMTg2
https://api.github.com/users/lhoestq/orgs
https://api.github.com/users/lhoestq/received_events
https://api.github.com/users/lhoestq/repos
https://api.github.com/users/lhoestq/starred{/owner}{/repo}
https://api.github.com/users/lhoestq/subscriptions
User
https://api.github.com/users/lhoestq
public
COLLABORATOR
@lhoestq It should be fine to remove this conversion in Datasets 3.0, no? For now, we can warn the user (with a log message) about the future change when the default type is changed.
2023-02-09T16:46:10Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1424495324
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5U6BLc
https://api.github.com/repos/huggingface/datasets/issues/comments/1424495324/reactions
2023-02-09T16:46:10Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1424495324
https://avatars.githubusercontent.com/u/47462742?v=4
https://api.github.com/users/mariosasko/events{/privacy}
https://api.github.com/users/mariosasko/followers
https://api.github.com/users/mariosasko/following{/other_user}
https://api.github.com/users/mariosasko/gists{/gist_id}
https://github.com/mariosasko
mariosasko
MDQ6VXNlcjQ3NDYyNzQy
https://api.github.com/users/mariosasko/orgs
https://api.github.com/users/mariosasko/received_events
https://api.github.com/users/mariosasko/repos
https://api.github.com/users/mariosasko/starred{/owner}{/repo}
https://api.github.com/users/mariosasko/subscriptions
User
https://api.github.com/users/mariosasko
public
MEMBER
Let's see with the transformers team if it sounds reasonable ? We'd have to fix multiple example scripts though.

If it's not ok we can also explore keeping this behavior only for tokens and audio data.
2023-02-10T14:05:44Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1425858073
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5U_N4Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1425858073/reactions
2023-02-10T14:05:44Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1425858073
https://avatars.githubusercontent.com/u/42851186?v=4
https://api.github.com/users/lhoestq/events{/privacy}
https://api.github.com/users/lhoestq/followers
https://api.github.com/users/lhoestq/following{/other_user}
https://api.github.com/users/lhoestq/gists{/gist_id}
https://github.com/lhoestq
lhoestq
MDQ6VXNlcjQyODUxMTg2
https://api.github.com/users/lhoestq/orgs
https://api.github.com/users/lhoestq/received_events
https://api.github.com/users/lhoestq/repos
https://api.github.com/users/lhoestq/starred{/owner}{/repo}
https://api.github.com/users/lhoestq/subscriptions
User
https://api.github.com/users/lhoestq
public
COLLABORATOR
IMO being coupled with Transformers can lead to unexpected behavior when one tries to use our lib without pairing it with Transformers, so I think it's still important to "fix" this, even if it means we will need to update Transformers' example scripts afterward.

2023-02-13T16:22:06Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1428234780
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5VISIc
https://api.github.com/repos/huggingface/datasets/issues/comments/1428234780/reactions
2023-02-13T16:22:06Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1428234780
https://avatars.githubusercontent.com/u/47462742?v=4
https://api.github.com/users/mariosasko/events{/privacy}
https://api.github.com/users/mariosasko/followers
https://api.github.com/users/mariosasko/following{/other_user}
https://api.github.com/users/mariosasko/gists{/gist_id}
https://github.com/mariosasko
mariosasko
MDQ6VXNlcjQ3NDYyNzQy
https://api.github.com/users/mariosasko/orgs
https://api.github.com/users/mariosasko/received_events
https://api.github.com/users/mariosasko/repos
https://api.github.com/users/mariosasko/starred{/owner}{/repo}
https://api.github.com/users/mariosasko/subscriptions
User
https://api.github.com/users/mariosasko
public
MEMBER
Ideally let's update the `transformers` example scripts before the change :P
2023-02-13T18:01:19Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1428410134
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5VI88W
https://api.github.com/repos/huggingface/datasets/issues/comments/1428410134/reactions
2023-02-13T18:01:19Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1428410134
https://avatars.githubusercontent.com/u/42851186?v=4
https://api.github.com/users/lhoestq/events{/privacy}
https://api.github.com/users/lhoestq/followers
https://api.github.com/users/lhoestq/following{/other_user}
https://api.github.com/users/lhoestq/gists{/gist_id}
https://github.com/lhoestq
lhoestq
MDQ6VXNlcjQyODUxMTg2
https://api.github.com/users/lhoestq/orgs
https://api.github.com/users/lhoestq/received_events
https://api.github.com/users/lhoestq/repos
https://api.github.com/users/lhoestq/starred{/owner}{/repo}
https://api.github.com/users/lhoestq/subscriptions
User
https://api.github.com/users/lhoestq
public
NONE
For others that run into the same issue: A temporary workaround for me is this:
```python
def numpy_transform(batch):
    return {key: np.asarray(val) for key, val in batch.items()}

dataset = dataset.with_transform(numpy_transform)
```
2023-02-14T15:38:54Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1429950390
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5VO0-2
https://api.github.com/repos/huggingface/datasets/issues/comments/1429950390/reactions
2023-02-14T15:38:54Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1429950390
https://avatars.githubusercontent.com/u/1250234?v=4
https://api.github.com/users/ernestum/events{/privacy}
https://api.github.com/users/ernestum/followers
https://api.github.com/users/ernestum/following{/other_user}
https://api.github.com/users/ernestum/gists{/gist_id}
https://github.com/ernestum
ernestum
MDQ6VXNlcjEyNTAyMzQ=
https://api.github.com/users/ernestum/orgs
https://api.github.com/users/ernestum/received_events
https://api.github.com/users/ernestum/repos
https://api.github.com/users/ernestum/starred{/owner}{/repo}
https://api.github.com/users/ernestum/subscriptions
User
https://api.github.com/users/ernestum
public
COLLABORATOR
This behavior (silent upcast from `int32` to `int64`) is also unexpected for the user in https://discuss.huggingface.co/t/standard-getitem-returns-wrong-data-type-for-arrays/62470/2
2023-11-16T15:52:25Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1814734376
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5sKqYo
https://api.github.com/repos/huggingface/datasets/issues/comments/1814734376/reactions
2023-11-16T15:52:25Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1814734376
https://avatars.githubusercontent.com/u/47462742?v=4
https://api.github.com/users/mariosasko/events{/privacy}
https://api.github.com/users/mariosasko/followers
https://api.github.com/users/mariosasko/following{/other_user}
https://api.github.com/users/mariosasko/gists{/gist_id}
https://github.com/mariosasko
mariosasko
MDQ6VXNlcjQ3NDYyNzQy
https://api.github.com/users/mariosasko/orgs
https://api.github.com/users/mariosasko/received_events
https://api.github.com/users/mariosasko/repos
https://api.github.com/users/mariosasko/starred{/owner}{/repo}
https://api.github.com/users/mariosasko/subscriptions
User
https://api.github.com/users/mariosasko
public
NONE
Hi, I stumbled on a variation that upcasts uint8 to int64. I would expect the dtype to be the same as it was when I generated the dataset.

```
import numpy as np
import datasets as ds

foo = np.random.randint(0, 256, size=(5, 10, 10), dtype=np.uint8)

features = ds.Features({"foo": ds.Array2D((10, 10), "uint8")})
dataset = ds.Dataset.from_dict({"foo": foo}, features=features)
dataset.set_format("torch")
print("feature dtype:", dataset.features["foo"].dtype)
print("array dtype:", dataset["foo"].dtype)

# feature dtype: uint8
# array dtype: torch.int64
```

2024-01-18T08:04:56Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1897984308
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5xIPE0
https://api.github.com/repos/huggingface/datasets/issues/comments/1897984308/reactions
2024-01-18T08:04:56Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1897984308
https://avatars.githubusercontent.com/u/48992179?v=4
https://api.github.com/users/jarnoseppanen-sc/events{/privacy}
https://api.github.com/users/jarnoseppanen-sc/followers
https://api.github.com/users/jarnoseppanen-sc/following{/other_user}
https://api.github.com/users/jarnoseppanen-sc/gists{/gist_id}
https://github.com/jarnoseppanen-sc
jarnoseppanen-sc
MDQ6VXNlcjQ4OTkyMTc5
https://api.github.com/users/jarnoseppanen-sc/orgs
https://api.github.com/users/jarnoseppanen-sc/received_events
https://api.github.com/users/jarnoseppanen-sc/repos
https://api.github.com/users/jarnoseppanen-sc/starred{/owner}{/repo}
https://api.github.com/users/jarnoseppanen-sc/subscriptions
User
https://api.github.com/users/jarnoseppanen-sc
public
NONE
workaround to remove torch upcasting

```
import datasets as ds
import torch

class FixedTorchFormatter(ds.formatting.TorchFormatter):
    def _tensorize(self, value):
        return torch.from_numpy(value)


ds.formatting._register_formatter(FixedTorchFormatter, "torch")
```
2024-01-18T08:42:16Z
https://github.com/huggingface/datasets/issues/5517#issuecomment-1898032892
https://api.github.com/repos/huggingface/datasets/issues/5517
IC_kwDODunzps5xIa78
https://api.github.com/repos/huggingface/datasets/issues/comments/1898032892/reactions
2024-01-18T08:42:16Z
https://api.github.com/repos/huggingface/datasets/issues/comments/1898032892
https://avatars.githubusercontent.com/u/48992179?v=4
https://api.github.com/users/jarnoseppanen-sc/events{/privacy}
https://api.github.com/users/jarnoseppanen-sc/followers
https://api.github.com/users/jarnoseppanen-sc/following{/other_user}
https://api.github.com/users/jarnoseppanen-sc/gists{/gist_id}
https://github.com/jarnoseppanen-sc
jarnoseppanen-sc
MDQ6VXNlcjQ4OTkyMTc5
https://api.github.com/users/jarnoseppanen-sc/orgs
https://api.github.com/users/jarnoseppanen-sc/received_events
https://api.github.com/users/jarnoseppanen-sc/repos
https://api.github.com/users/jarnoseppanen-sc/starred{/owner}{/repo}
https://api.github.com/users/jarnoseppanen-sc/subscriptions
User
https://api.github.com/users/jarnoseppanen-sc
public
### Describe the bug

When I create a dataset with a `float64` feature, then apply numpy formatting the returned numpy arrays are silently downcasted to `float32`.

### Steps to reproduce the bug

```python
import datasets
dataset = datasets.Dataset.from_dict({'a': [1.0, 2.0, 3.0]}).with_format("numpy")
print("feature dtype:", dataset.features['a'].dtype)
print("array dtype:", dataset['a'].dtype)
```
output:
```
feature dtype: float64
array dtype: float32
```

### Expected behavior

```
feature dtype: float64
array dtype: float64
```

### Environment info

- `datasets` version: 2.8.0
- Platform: Linux-5.4.0-135-generic-x86_64-with-glibc2.29
- Python version: 3.8.10
- PyArrow version: 10.0.1
- Pandas version: 1.4.4

### Suggested Fix

Changing [the `_tensorize` function of the numpy formatter](https://github.com/huggingface/datasets/blob/b065547654efa0ec633cf373ac1512884c68b2e1/src/datasets/formatting/np_formatter.py#L32) to 
```python
    def _tensorize(self, value):

        if isinstance(value, (str, bytes, type(None))):
            return value
        elif isinstance(value, (np.character, np.ndarray)) and np.issubdtype(value.dtype, np.character):
            return value
        elif isinstance(value, np.number):
            return value

        return np.asarray(value, **self.np_array_kwargs)
```
fixes this particular issue for me. Not sure if this would break other tests. This should also avoid unnecessary copying of the array.
