chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import lightning.pytorch as pl
|
||||
import torch
|
||||
from torch.utils.data import DataLoader, Dataset
|
||||
|
||||
from ray import tune
|
||||
from ray.air.constants import TRAINING_ITERATION
|
||||
from ray.tune import CheckpointConfig
|
||||
from ray.tune.integration.pytorch_lightning import TuneReportCheckpointCallback
|
||||
|
||||
|
||||
class _MockDataset(Dataset):
|
||||
def __init__(self, values):
|
||||
self.values = values
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.values[index]
|
||||
|
||||
def __len__(self):
|
||||
return len(self.values)
|
||||
|
||||
|
||||
class _MockModule(pl.LightningModule):
|
||||
def __init__(self, loss, acc):
|
||||
super().__init__()
|
||||
|
||||
self._dummy = torch.nn.Parameter(torch.zeros(1))
|
||||
self.loss_val = loss
|
||||
self.acc_val = acc
|
||||
|
||||
def forward(self, *args, **kwargs):
|
||||
return self._dummy
|
||||
|
||||
def training_step(self, train_batch, batch_idx):
|
||||
loss = self._dummy.sum() * 0 + self.loss_val
|
||||
self.log("loss", loss)
|
||||
self.log("acc", torch.tensor(self.acc_val))
|
||||
return loss
|
||||
|
||||
def validation_step(self, val_batch, batch_idx):
|
||||
self.log("avg_val_loss", torch.tensor(self.loss_val * 1.1))
|
||||
self.log("avg_val_acc", torch.tensor(self.acc_val * 0.9))
|
||||
|
||||
def configure_optimizers(self):
|
||||
return torch.optim.SGD([self._dummy], lr=0.001)
|
||||
|
||||
def train_dataloader(self):
|
||||
return DataLoader(_MockDataset(list(range(10))), batch_size=1)
|
||||
|
||||
def val_dataloader(self):
|
||||
return DataLoader(_MockDataset(list(range(10))), batch_size=1)
|
||||
|
||||
|
||||
class PyTorchLightningIntegrationTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def testReportCallbackUnnamed(self):
|
||||
def train_fn(config):
|
||||
module = _MockModule(10.0, 20.0)
|
||||
trainer = pl.Trainer(
|
||||
max_epochs=1,
|
||||
callbacks=[
|
||||
TuneReportCheckpointCallback(
|
||||
on="validation_end", save_checkpoints=False
|
||||
)
|
||||
],
|
||||
)
|
||||
trainer.fit(module)
|
||||
|
||||
analysis = tune.run(train_fn, stop={TRAINING_ITERATION: 1})
|
||||
|
||||
self.assertEqual(analysis.trials[0].last_result["avg_val_loss"], 10.0 * 1.1)
|
||||
|
||||
def testReportCallbackNamed(self):
|
||||
def train_fn(config):
|
||||
module = _MockModule(10.0, 20.0)
|
||||
trainer = pl.Trainer(
|
||||
max_epochs=1,
|
||||
callbacks=[
|
||||
TuneReportCheckpointCallback(
|
||||
metrics={"tune_loss": "avg_val_loss"},
|
||||
on="validation_end",
|
||||
save_checkpoints=False,
|
||||
)
|
||||
],
|
||||
)
|
||||
trainer.fit(module)
|
||||
|
||||
analysis = tune.run(train_fn, stop={TRAINING_ITERATION: 1})
|
||||
|
||||
self.assertEqual(analysis.trials[0].last_result["tune_loss"], 10.0 * 1.1)
|
||||
|
||||
def testCheckpointCallback(self):
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
self.addCleanup(lambda: shutil.rmtree(tmpdir))
|
||||
|
||||
def train_fn(config):
|
||||
module = _MockModule(10.0, 20.0)
|
||||
trainer = pl.Trainer(
|
||||
max_epochs=10,
|
||||
callbacks=[
|
||||
TuneReportCheckpointCallback(
|
||||
filename="trainer.ckpt", on=["train_epoch_end"]
|
||||
)
|
||||
],
|
||||
)
|
||||
trainer.fit(module)
|
||||
|
||||
checkpoint_config = CheckpointConfig(num_to_keep=100)
|
||||
tuner = tune.Tuner(
|
||||
train_fn,
|
||||
run_config=tune.RunConfig(
|
||||
stop={TRAINING_ITERATION: 10},
|
||||
storage_path=tmpdir,
|
||||
checkpoint_config=checkpoint_config,
|
||||
),
|
||||
)
|
||||
results = tuner.fit()
|
||||
|
||||
# 1 checkpoint per epoch
|
||||
self.assertEqual(len(results[0].best_checkpoints), 10)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
sys.exit(pytest.main(sys.argv[1:] + ["-v", __file__]))
|
||||
Reference in New Issue
Block a user