| @@ -169,7 +169,7 @@ class OneflowTensorPadder(Padder): | |||||
| else: | else: | ||||
| max_shape = [len(batch_field)] + [max(*_) for _ in zip(*shapes)] | max_shape = [len(batch_field)] + [max(*_) for _ in zip(*shapes)] | ||||
| tensor = oneflow.full(max_shape, fill_value=pad_val, dtype=dtype, device=device) | |||||
| tensor = oneflow.full(max_shape, value=pad_val, dtype=dtype, device=device) | |||||
| for i, field in enumerate(batch_field): | for i, field in enumerate(batch_field): | ||||
| slices = (i, ) + tuple(slice(0, s) for s in shapes[i]) | slices = (i, ) + tuple(slice(0, s) for s in shapes[i]) | ||||
| tensor[slices] = field | tensor[slices] = field | ||||
| @@ -221,6 +221,6 @@ def get_padded_oneflow_tensor(batch_field, dtype=None, pad_val=0): | |||||
| :return: | :return: | ||||
| """ | """ | ||||
| shapes = get_shape(batch_field) | shapes = get_shape(batch_field) | ||||
| tensor = oneflow.full(shapes, dtype=dtype, fill_value=pad_val) | |||||
| tensor = oneflow.full(shapes, dtype=dtype, value=pad_val) | |||||
| tensor = fill_tensor(batch_field, tensor, dtype=dtype) | tensor = fill_tensor(batch_field, tensor, dtype=dtype) | ||||
| return tensor | return tensor | ||||
| @@ -1,7 +1,7 @@ | |||||
| from typing import Optional | from typing import Optional | ||||
| import numpy as np | import numpy as np | ||||
| from ...envs.imports import _NEED_IMPORT_JITTOR, _NEED_IMPORT_TORCH, _NEED_IMPORT_PADDLE | |||||
| from ...envs.imports import _NEED_IMPORT_JITTOR, _NEED_IMPORT_TORCH, _NEED_IMPORT_PADDLE, _NEED_IMPORT_ONEFLOW | |||||
| from .paddle_utils import paddle_to | from .paddle_utils import paddle_to | ||||
| @@ -14,6 +14,9 @@ if _NEED_IMPORT_PADDLE: | |||||
| if _NEED_IMPORT_JITTOR: | if _NEED_IMPORT_JITTOR: | ||||
| import jittor | import jittor | ||||
| if _NEED_IMPORT_ONEFLOW: | |||||
| import oneflow | |||||
| def seq_len_to_mask(seq_len, max_len: Optional[int]=None): | def seq_len_to_mask(seq_len, max_len: Optional[int]=None): | ||||
| r""" | r""" | ||||
| @@ -80,5 +83,15 @@ def seq_len_to_mask(seq_len, max_len: Optional[int]=None): | |||||
| except NameError as e: | except NameError as e: | ||||
| pass | pass | ||||
| try: | |||||
| if isinstance(seq_len, oneflow.Tensor): | |||||
| assert seq_len.ndim == 1, f"seq_len can only have one dimension, got {seq_len.ndim == 1}." | |||||
| batch_size = seq_len.shape[0] | |||||
| broad_cast_seq_len = oneflow.arange(max_len).expand(batch_size, -1).to(seq_len) | |||||
| mask = broad_cast_seq_len < seq_len.unsqueeze(1) | |||||
| return mask | |||||
| except NameError as e: | |||||
| pass | |||||
| raise TypeError("seq_len_to_mask function only supports numpy.ndarray, torch.Tensor, paddle.Tensor, " | raise TypeError("seq_len_to_mask function only supports numpy.ndarray, torch.Tensor, paddle.Tensor, " | ||||
| f"and jittor.Var, but got {type(seq_len)}") | f"and jittor.Var, but got {type(seq_len)}") | ||||
| @@ -80,7 +80,7 @@ def dataloader_with_randomsampler(dataset, batch_size, shuffle, drop_last, seed= | |||||
| # | # | ||||
| ############################################################################ | ############################################################################ | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| class TestDDPDriverFunction: | class TestDDPDriverFunction: | ||||
| """ | """ | ||||
| 测试 OneflowDDPDriver 一些简单函数的测试类,基本都是测试能否运行、是否存在 import 错误等问题 | 测试 OneflowDDPDriver 一些简单函数的测试类,基本都是测试能否运行、是否存在 import 错误等问题 | ||||
| @@ -159,7 +159,7 @@ class TestDDPDriverFunction: | |||||
| # | # | ||||
| ############################################################################ | ############################################################################ | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| class TestSetDistReproDataloader: | class TestSetDistReproDataloader: | ||||
| @classmethod | @classmethod | ||||
| @@ -510,7 +510,7 @@ class TestSetDistReproDataloader: | |||||
| # 测试 save 和 load 相关的功能 | # 测试 save 和 load 相关的功能 | ||||
| # | # | ||||
| ############################################################################ | ############################################################################ | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| class TestSaveLoad: | class TestSaveLoad: | ||||
| """ | """ | ||||
| 测试多卡情况下 save 和 load 相关函数的表现 | 测试多卡情况下 save 和 load 相关函数的表现 | ||||
| @@ -740,7 +740,7 @@ class TestSaveLoad: | |||||
| rank_zero_rm(path) | rank_zero_rm(path) | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| @pytest.mark.parametrize("shuffle", ([True, False])) | @pytest.mark.parametrize("shuffle", ([True, False])) | ||||
| @pytest.mark.parametrize("batch_size", ([1, 3, 16, 17])) | @pytest.mark.parametrize("batch_size", ([1, 3, 16, 17])) | ||||
| @pytest.mark.parametrize("drop_last", ([True, False])) | @pytest.mark.parametrize("drop_last", ([True, False])) | ||||
| @@ -790,7 +790,7 @@ def test_shuffle_dataloader(shuffle, batch_size, drop_last, reproducible=True): | |||||
| pass | pass | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| @pytest.mark.parametrize("shuffle", ([True, False])) | @pytest.mark.parametrize("shuffle", ([True, False])) | ||||
| @pytest.mark.parametrize("batch_size", ([1, 3, 16, 17])) | @pytest.mark.parametrize("batch_size", ([1, 3, 16, 17])) | ||||
| @pytest.mark.parametrize("drop_last", ([True, False])) | @pytest.mark.parametrize("drop_last", ([True, False])) | ||||
| @@ -845,7 +845,7 @@ def test_batch_sampler_dataloader(shuffle, batch_size, drop_last, reproducible=T | |||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| @recover_logger | @recover_logger | ||||
| @pytest.mark.parametrize("inherit", ([True, False])) | @pytest.mark.parametrize("inherit", ([True, False])) | ||||
| def test_customized_batch_sampler_dataloader(inherit): | def test_customized_batch_sampler_dataloader(inherit): | ||||
| @@ -897,7 +897,7 @@ def test_customized_batch_sampler_dataloader(inherit): | |||||
| pass | pass | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| @recover_logger | @recover_logger | ||||
| @pytest.mark.parametrize("inherit", ([True, False])) | @pytest.mark.parametrize("inherit", ([True, False])) | ||||
| def test_customized_sampler_dataloader(inherit): | def test_customized_sampler_dataloader(inherit): | ||||
| @@ -77,7 +77,7 @@ def test_tensor_object_transfer_tensor(device): | |||||
| assert res["int"] == oneflow_dict["int"] | assert res["int"] == oneflow_dict["int"] | ||||
| assert res["string"] == oneflow_dict["string"] | assert res["string"] == oneflow_dict["string"] | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| def test_fastnlp_oneflow_all_gather(): | def test_fastnlp_oneflow_all_gather(): | ||||
| local_rank = int(os.environ["LOCAL_RANK"]) | local_rank = int(os.environ["LOCAL_RANK"]) | ||||
| obj = { | obj = { | ||||
| @@ -113,7 +113,7 @@ def test_fastnlp_oneflow_all_gather(): | |||||
| assert len(data) == world_size | assert len(data) == world_size | ||||
| assert data[0] == data[1] | assert data[0] == data[1] | ||||
| @pytest.mark.oneflow | |||||
| @pytest.mark.oneflowdist | |||||
| def test_fastnlp_oneflow_broadcast_object(): | def test_fastnlp_oneflow_broadcast_object(): | ||||
| local_rank = int(os.environ["LOCAL_RANK"]) | local_rank = int(os.environ["LOCAL_RANK"]) | ||||
| if os.environ["LOCAL_RANK"] == "0": | if os.environ["LOCAL_RANK"] == "0": | ||||
| @@ -557,7 +557,7 @@ def test_save_and_load_model(only_state_dict): | |||||
| res1 = driver1.model.evaluate_step(**batch) | res1 = driver1.model.evaluate_step(**batch) | ||||
| res2 = driver2.model.evaluate_step(**batch) | res2 = driver2.model.evaluate_step(**batch) | ||||
| assert oneflow.all(res1["preds"] == res2["preds"]) | |||||
| assert oneflow.all(res1["pred"] == res2["pred"]) | |||||
| finally: | finally: | ||||
| rank_zero_rm(path) | rank_zero_rm(path) | ||||
| @@ -623,7 +623,7 @@ def test_save_and_load_with_randombatchsampler(only_state_dict, fp16): | |||||
| left_y_batches.update(batch["y"].reshape(-1, ).tolist()) | left_y_batches.update(batch["y"].reshape(-1, ).tolist()) | ||||
| res1 = driver1.model.evaluate_step(**batch) | res1 = driver1.model.evaluate_step(**batch) | ||||
| res2 = driver2.model.evaluate_step(**batch) | res2 = driver2.model.evaluate_step(**batch) | ||||
| assert oneflow.all(res1["preds"] == res2["preds"]) | |||||
| assert oneflow.all(res1["pred"] == res2["pred"]) | |||||
| assert len(left_x_batches) + len(already_seen_x_set) == len(dataset) | assert len(left_x_batches) + len(already_seen_x_set) == len(dataset) | ||||
| assert len(left_x_batches | already_seen_x_set) == len(dataset) | assert len(left_x_batches | already_seen_x_set) == len(dataset) | ||||
| @@ -698,7 +698,7 @@ def test_save_and_load_with_randomsampler(only_state_dict, fp16): | |||||
| left_y_batches.update(batch["y"].reshape(-1, ).tolist()) | left_y_batches.update(batch["y"].reshape(-1, ).tolist()) | ||||
| res1 = driver1.model.evaluate_step(**batch) | res1 = driver1.model.evaluate_step(**batch) | ||||
| res2 = driver2.model.evaluate_step(**batch) | res2 = driver2.model.evaluate_step(**batch) | ||||
| assert oneflow.all(res1["preds"] == res2["preds"]) | |||||
| assert oneflow.all(res1["pred"] == res2["pred"]) | |||||
| assert len(left_x_batches) + len(already_seen_x_set) == len(dataset) | assert len(left_x_batches) + len(already_seen_x_set) == len(dataset) | ||||
| assert len(left_x_batches | already_seen_x_set) == len(dataset) | assert len(left_x_batches | already_seen_x_set) == len(dataset) | ||||
| @@ -1,7 +1,7 @@ | |||||
| import pytest | import pytest | ||||
| import numpy as np | import numpy as np | ||||
| from fastNLP.core.utils.seq_len_to_mask import seq_len_to_mask | from fastNLP.core.utils.seq_len_to_mask import seq_len_to_mask | ||||
| from fastNLP.envs.imports import _NEED_IMPORT_JITTOR, _NEED_IMPORT_PADDLE, _NEED_IMPORT_TORCH | |||||
| from fastNLP.envs.imports import _NEED_IMPORT_JITTOR, _NEED_IMPORT_PADDLE, _NEED_IMPORT_TORCH, _NEED_IMPORT_ONEFLOW | |||||
| if _NEED_IMPORT_TORCH: | if _NEED_IMPORT_TORCH: | ||||
| import torch | import torch | ||||
| @@ -11,6 +11,9 @@ if _NEED_IMPORT_PADDLE: | |||||
| if _NEED_IMPORT_JITTOR: | if _NEED_IMPORT_JITTOR: | ||||
| import jittor | import jittor | ||||
| if _NEED_IMPORT_ONEFLOW: | |||||
| import oneflow | |||||
| class TestSeqLenToMask: | class TestSeqLenToMask: | ||||
| @@ -20,7 +23,7 @@ class TestSeqLenToMask: | |||||
| length = seq_len[i] | length = seq_len[i] | ||||
| mask_i = mask[i] | mask_i = mask[i] | ||||
| for j in range(max_len): | for j in range(max_len): | ||||
| assert mask_i[j] == (j<length), (i, j, length) | |||||
| assert mask_i[j].item() == (j<length), (i, j, length) | |||||
| def test_numpy_seq_len(self): | def test_numpy_seq_len(self): | ||||
| # 测试能否转换numpy类型的seq_len | # 测试能否转换numpy类型的seq_len | ||||
| @@ -100,3 +103,22 @@ class TestSeqLenToMask: | |||||
| seq_len = jittor.randint(1, 10, shape=(10,)) | seq_len = jittor.randint(1, 10, shape=(10,)) | ||||
| mask = seq_len_to_mask(seq_len, 100) | mask = seq_len_to_mask(seq_len, 100) | ||||
| assert 100 == mask.shape[1] | assert 100 == mask.shape[1] | ||||
| @pytest.mark.oneflow | |||||
| def test_pytorch_seq_len(self): | |||||
| # 1. 随机测试 | |||||
| seq_len = oneflow.randint(1, 10, size=(10, )) | |||||
| max_len = seq_len.max() | |||||
| mask = seq_len_to_mask(seq_len) | |||||
| assert max_len == mask.shape[1] | |||||
| self.evaluate_mask_seq_len(seq_len.tolist(), mask) | |||||
| # 2. 异常检测 | |||||
| seq_len = oneflow.randn(3, 4) | |||||
| with pytest.raises(AssertionError): | |||||
| mask = seq_len_to_mask(seq_len) | |||||
| # 3. pad到指定长度 | |||||
| seq_len = oneflow.randint(1, 10, size=(10, )) | |||||
| mask = seq_len_to_mask(seq_len, 100) | |||||
| assert 100 == mask.size(1) | |||||
| @@ -9,3 +9,4 @@ markers = | |||||
| torchjittor | torchjittor | ||||
| deepspeed | deepspeed | ||||
| torchoneflow | torchoneflow | ||||
| oneflowdist | |||||