Pytorch Lightning ์‹œ์ž‘ํ•˜๊ธฐ


๐Ÿ“Œย pytorch์— ๋Œ€ํ•œ high-level ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

GPU๋‚˜ TPU, 16bit precision, ๋ถ„์‚ฐํ•™์Šต ๋“ฑ ๋”์šฑ ๋ณต์žกํ•œ ์กฐ๊ฑด์—์„œ ์‹คํ—˜ํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง„๋‹ค.

pytorch lightning์˜ ๋ชฉ์ ์€ ์ฝ”๋“œ์˜ ์ถ”์ƒํ™”๋ฅผ ํ†ตํ•ด ์ข€ ๋” ์ •๋ˆ๋˜๊ณ  ๊ฐ„๊ฒฐํ™”๋œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ์— ์žˆ๋‹ค.

pytorch lightning์€ Lightning Model class ๋‚ด์— DataLoader, Model, optimizer, Training roof ๋“ฑ์„ ํ•œ๋ฒˆ์— ๊ตฌํ˜„ํ•˜๋„๋ก ๋˜์–ด ์žˆ๋‹ค. ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์žˆ๋Š” ํ•จ์ˆ˜๋ช…์€ ๋˜‘๊ฐ™์ด ์จ์•ผํ•˜๊ณ  ๊ทธ ๋ชฉ์ ์— ๋งž๊ฒŒ ์ฝ”๋”ฉํ•˜๋ฉด ๋œ๋‹ค

pytorch lightning์€ ํฌ๊ฒŒ Trainer์™€ Lightning Module๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.

Lightning Module์€ ๋ชจ๋ธ ๋‚ด๋ถ€์˜ ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•˜๋Š” research & science ํด๋ž˜์Šค๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋ธ์˜ ๊ตฌ์กฐ๋‚˜ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ, ์†์‹คํ•จ์ˆ˜ ๋“ฑ์˜ ์„ค์ •์„ ํ†ตํ•ด ๋ชจ๋ธ์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. ์‹ค์ œ๋กœ ์ฝ”๋“œ์—์„œ๋Š” pl.LightningModule ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ์ƒˆ๋กœ์šด LightningModule ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ๊ธฐ์กด PyTorch์˜ nn.Module๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์ด๋ผ๊ณ  ๋ณด๋ฉด๋œ๋‹ค.

Trainer๋Š” ๋ชจ๋ธ์˜ ํ•™์Šต์„ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋ธ์˜ ํ•™์Šต epoch์ด๋‚˜ batch ๋“ฑ์˜ ์ƒํƒœ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ชจ๋ธ์„ ์ €์žฅํ•ด ๋กœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ถ„๊นŒ์ง€ ๋‹ด๋‹นํ•œ๋‹ค. ์‹ค์ œ๋กœ ์ฝ”๋“œ์—์„œ๋Š” pl.Trainer()๋ผ๊ณ  ์ •์˜ํ•˜๋ฉด ๋์ด๋‹ค.

pytorch lightning์€ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํžˆ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค

pip install pytorch-lightning

pytorch lightning์„ ํ†ตํ•ด ๋”ฅ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ์ž‘์„ฑํ•˜๋Š” ์ˆœ์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. lightning module์—์„œ ์ƒ์†๋œ ์ƒˆ๋กœ์šด Lightning Module ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
  2. DataLoader๋ฅผ ํ†ตํ•ด ํ•™์Šตํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ค€๋น„ํ•œ๋‹ค.
  3. Trainer ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ Trainer์— ๋ฐ์ดํ„ฐ์™€ Lightning Module ํด๋ž˜์Šค๋ฅผ ์ฃผ์–ด ํ•™์Šตํ•œ๋‹ค.

Lightning Module Class

lightning module์€ trainer์™€ model์ด ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ตฌํ˜„์ฒด์ด๋‹ค.

๊ธฐ์กด pytorch์™€ ๋‹ฌ๋ฆฌ, DataLoader, Model, optimizer, Training loof ๋“ฑ์„ Lightning Module Class ์•ˆ์— ํ•œ๋ฒˆ์— ๊ตฌํ˜„ํ•˜๋„๋ก ๋˜์–ด์žˆ๋‹ค.

๋ชจ๋“ˆ ์ •์˜๋ฅผ ์œ„ํ•ด LightningModule ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ  ํ•™์Šต์— ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.

Lightning Module์€ ์•„๋ž˜ 6๊ฐ€์ง€๋กœ ๊ตฌ์„ฑ๋œ๋‹ค

  • Computations (__init__)

    • ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ
    • Lightning Module Calss์—์„œ ์‚ฌ์šฉํ•  ์‹ ๊ฒฝ๋ง์„ ์ •์˜ํ•œ๋‹ค
    • ์‹ ๊ฒฝ๋ง ๋ ˆ์ด์–ด๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด torch.nn.module ์—์„œ ๋ถˆ๋Ÿฌ์˜ค๊ฑฐ๋‚˜ ํ™•์žฅํ•ด์•ผํ•œ๋‹ค
  • Train loop (training_step)

    • ํ•™์Šต ๋ฃจํ”„์˜ body ๋ถ€๋ถ„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

    • nn.Module์˜ forward์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, ๋‹จ์ผ ๋ฐฐ์น˜์—์„œ์˜ loss๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผํ•˜๋ฉฐ, ์ด๋Š” train loop๋กœ ์ž๋™ ๋ฐ˜๋ณต๋œ๋‹ค

    • ์ด ๋ฉ”์†Œ๋“œ์—์„œ๋Š” argument๋กœ training dataloader๊ฐ€ ์ œ๊ณตํ•˜๋Š” batch์™€ ํ•ด๋‹น batch์˜ index๊ฐ€ ์ฃผ์–ด์ง€๊ณ , ํ•™์Šต loss๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    • lightning์—์„œ๋Š” batch์˜ tensor๋ฅผ cpu/gpu tensor๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋”ฐ๋กœ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์•„๋„ trainer์˜ ์„ค์ •์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ์ ์ ˆํ•œ ํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝํ•ด์ค€๋‹ค.

    • epoch level metric์„ ๊ณ„์‚ฐํ•˜๊ณ  log๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด .log ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. ๋งŒ์•ฝ, training_step์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฌด์—‡์ธ๊ฐ€ ํ•  ์ผ์ด ์žˆ์œผ๋ฉด training_epoch_end ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

      def training_step(self, batch, batch_idx):
          x, y = batch
          y_hat = self.model(x)
          loss = F.cross_entropy(y_hat, y)
          # logs metrics for each training_step,
          # and the average across the epoch, to the progress bar and logger
          self.log("train_loss", loss, on_step=True, on_epoch=True, prog_bar=True, logger=True)
          return loss
      
      def training_epoch_end(self, training_step_outputs):
          for pred in training_step_outputs:
              ...
  • Validation loop (validation_step)

    • loss ๋ฐ metric logging์„ ์œ„ํ•œ validation_step๋ฐ test_step์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • validation_step์€ ํ•™์Šต ์ค‘๊ฐ„์— ๋ชจ๋ธ์˜ ์„ฑ๋Šฅ์„ ์ฒดํฌํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

    • training_step๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ validation ๋ฐ์ดํ„ฐ๋กœ๋”์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฐฐ์น˜๋ฅผ ๊ฐ€์ง€๊ณ  ํ™•์ธํ•˜๊ณ ์ž ํ•˜๋Š” ํ†ต๊ณ„๋Ÿ‰์„ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ๋งŒ์•ฝ์— ๊ฐ validation_step์˜ ๊ฒฐ๊ณผ๋กœ ๋ฌด์—‡์ธ๊ฐ€ ํ•  ์ผ์ด ์žˆ์œผ๋ฉด validation_epoch_end ๋ฉ”์„œ๋“œ์— ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

      def validation_step(self, batch, batch_idx):
          x, y = batch
          y_hat = self.model(x)
          loss = F.cross_entropy(y_hat, y)
          self.log("val_loss", loss)
          pred = ...
          return pred
      
      def validation_epoch_end(self, validation_step_outputs):
          for pred in validation_step_outputs:
              ...
  • Test loop (test_step)

    • test_step์€ ์•ž์˜ ๋‘ ํ•จ์ˆ˜์™€ ๋น„์Šทํ•˜๊ฒŒ test ๋ฐ์ดํ„ฐ๋กœ๋”์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฐฐ์น˜๋ฅผ ๊ฐ€์ง€๊ณ  ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ํ†ต๊ณ„๋Ÿ‰์„ ๊ธฐ๋กํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    • test loop ์ฝ”๋“œ๋Š” validation loop ์ฝ”๋“œ์™€ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค.

    • ํ˜ธ์ถœํ•  ๋•Œ๋Š” test_step()๋ฉ”์„œ๋“œ ๋ฅผ ์žฌ์ •์˜ํ•ด์•ผํ•œ๋‹ค.

      # call after training
      trainer = Trainer()
      trainer.fit(model)
      
      # automatically auto-loads the best weights from the previous run
      trainer.test(dataloaders=test_dataloader)
  • Prediction loop (predict_step)

  • Optimizers (configure_optimizers)

์•„๋ž˜๋Š” ๋ผˆ๋Œ€ ์ฝ”๋“œ์ด๋‹ค

import pytorch_lightning as pl

class Classifier(pl.LightningModule):
	def __init__(self):
		super().__init__()
		self.model = nn.Sequential(
				...
		)

	def forward(self, x):
		pass

	def training_step(self, batch, batch_idx):
		pass

	def validation_step(self, batch, batch_idx):
		pass

	def test_step(self, batch, batch_idx):
		pass

	def configure_optimizers(self):
		pass

reference

https://wikidocs.net/156985