CoolFace
Apppublic

chendl/compositional_test

sourceHugging Faceupdated 3y agoView on Hugging Face
1likes
test_trainer_distributed.py160 linesDownload Raw Back to trainer
1# Copyright 2020 The HuggingFace Team. All rights reserved.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7#     http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14 15import sys16from typing import Dict17 18from transformers import EvalPrediction, HfArgumentParser, TrainingArguments, is_torch_available19from transformers.testing_utils import (20    TestCasePlus,21    execute_subprocess_async,22    get_torch_dist_unique_port,23    require_torch_multi_gpu,24    require_torch_neuroncore,25)26from transformers.utils import logging27 28 29logger = logging.get_logger(__name__)30 31 32if is_torch_available():33    import torch34    from torch import nn35    from torch.utils.data import Dataset36 37    from transformers import Trainer38 39    class DummyDataset(Dataset):40        def __init__(self, length: int = 101):41            self.length = length42 43        def __len__(self):44            return self.length45 46        def __getitem__(self, i) -> int:47            return i48 49    class DummyDataCollator:50        def __call__(self, features):51            return {"input_ids": torch.tensor(features), "labels": torch.tensor(features)}52 53    class DummyModel(nn.Module):54        def __init__(self):55            super().__init__()56            # Add some (unused) params otherwise DDP will complain.57            self.fc = nn.Linear(120, 80)58 59        def forward(self, input_ids, labels=None):60            if labels is not None:61                return torch.tensor(0.0, device=input_ids.device), input_ids62            else:63                return input_ids64 65 66class TestTrainerDistributedNeuronCore(TestCasePlus):67    @require_torch_neuroncore68    def test_trainer(self):69        distributed_args = f"""70            -m torch.distributed.run71            --nproc_per_node=272            --master_port={get_torch_dist_unique_port()}73            {self.test_file_dir}/test_trainer_distributed.py74        """.split()75        output_dir = self.get_auto_remove_tmp_dir()76        args = f"--output_dir {output_dir}".split()77        cmd = [sys.executable] + distributed_args + args78        execute_subprocess_async(cmd, env=self.get_env())79        # successful return here == success - any errors would have caused an error in the sub-call80 81 82class TestTrainerDistributed(TestCasePlus):83    @require_torch_multi_gpu84    def test_trainer(self):85        distributed_args = f"""86            -m torch.distributed.run87            --nproc_per_node={torch.cuda.device_count()}88            --master_port={get_torch_dist_unique_port()}89            {self.test_file_dir}/test_trainer_distributed.py90        """.split()91        output_dir = self.get_auto_remove_tmp_dir()92        args = f"--output_dir {output_dir}".split()93        cmd = [sys.executable] + distributed_args + args94        execute_subprocess_async(cmd, env=self.get_env())95        # successful return here == success - any errors would have caused an error in the sub-call96 97 98if __name__ == "__main__":99    # The script below is meant to be run under torch.distributed, on a machine with multiple GPUs:100    #101    # PYTHONPATH="src" python -m torch.distributed.run --nproc_per_node 2 --output_dir output_dir ./tests/test_trainer_distributed.py102 103    parser = HfArgumentParser((TrainingArguments,))104    training_args = parser.parse_args_into_dataclasses()[0]105 106    logger.warning(107        f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}, "108        f"distributed training: {training_args.local_rank != -1}"109    )110 111    # Essentially, what we want to verify in the distributed case is that we get all samples back,112    # in the right order. (this is crucial for prediction for instance)113    for dataset_length in [101, 40, 7]:114        dataset = DummyDataset(dataset_length)115 116        def compute_metrics(p: EvalPrediction) -> Dict:117            sequential = list(range(len(dataset)))118            success = p.predictions.tolist() == sequential and p.label_ids.tolist() == sequential119            if not success and training_args.local_rank == 0:120                logger.warning(121                    "Predictions and/or labels do not match expected results:\n  - predictions: "122                    f"{p.predictions.tolist()}\n  - labels: {p.label_ids.tolist()}\n  - expected: {sequential}"123                )124            return {"success": success}125 126        trainer = Trainer(127            model=DummyModel(),128            args=training_args,129            data_collator=DummyDataCollator(),130            eval_dataset=dataset,131            compute_metrics=compute_metrics,132        )133        metrics = trainer.evaluate()134        logger.info(metrics)135        if metrics["eval_success"] is not True:136            logger.error(metrics)137            exit(1)138 139        p = trainer.predict(dataset)140        logger.info(p.metrics)141        if p.metrics["test_success"] is not True:142            logger.error(p.metrics)143            exit(1)144 145        trainer.args.eval_accumulation_steps = 2146 147        metrics = trainer.evaluate()148        logger.info(metrics)149        if metrics["eval_success"] is not True:150            logger.error(metrics)151            exit(1)152 153        p = trainer.predict(dataset)154        logger.info(p.metrics)155        if p.metrics["test_success"] is not True:156            logger.error(p.metrics)157            exit(1)158 159        trainer.args.eval_accumulation_steps = None160