Compare commits

..
373 Commits
Author SHA1 Message Date
William Falcon d98b9f2f93 release v0.3.3 2019-07-21 18:16:12 -04:00
William Falcon f6416f737d added grad hook 2019-07-21 18:15:58 -04:00
William Falcon 3888825333 release v0.3.2 2019-07-21 12:21:21 -04:00
William Falcon 0479784e7b added analysis notebook 2019-07-21 12:20:01 -04:00
William Falcon 7e053fc731 added analysis notebook 2019-07-21 12:18:46 -04:00
William Falcon 7ac344e43a updated docs 2019-07-21 08:35:29 -04:00
William Falcon f6b98fe74f updated docs 2019-07-21 08:33:53 -04:00
William Falcon 25f5491ac7 updated docs 2019-07-21 08:32:17 -04:00
William Falcon df77f5042b updated docs 2019-07-21 08:30:17 -04:00
William Falcon d273271b4b updated docs 2019-07-21 08:29:12 -04:00
William Falcon babaa088d7 release v0.3.1 2019-07-21 08:20:21 -04:00
William Falcon 8217ebe029 updated auto ddp for > 1 node 2019-07-21 08:20:06 -04:00
William Falcon 9311812829 updated docs 2019-07-21 08:17:12 -04:00
William Falcon 2357815640 release v0.3 2019-07-21 08:08:21 -04:00
William Falcon ab87244884 release v0.2.6 2019-07-20 09:39:00 -04:00
William Falcon 2aa0b3be5c removed logging 2019-07-20 09:31:10 -04:00
William Falcon 0fdf290201 removed logging 2019-07-20 09:22:47 -04:00
William Falcon 1a39f703ad removed logging 2019-07-20 09:22:04 -04:00
William Falcon 955e9ea6d5 removed logging 2019-07-20 09:18:45 -04:00
William Falcon 10e031a843 removed logging 2019-07-20 09:17:20 -04:00
William Falcon 229d168c20 removed logging 2019-07-20 09:15:09 -04:00
William Falcon 468bd141f4 added slurm managed flag catch for non-slurm peeps 2019-07-20 09:08:24 -04:00
William Falcon 00678c6053 added slurm managed flag catch for non-slurm peeps 2019-07-20 08:53:36 -04:00
William Falcon bbb5001aac added slurm managed flag catch for non-slurm peeps 2019-07-20 08:53:24 -04:00
William Falcon a514674358 added slurm managed flag catch for non-slurm peeps 2019-07-20 08:38:17 -04:00
William Falcon 9757841e67 release v0.2.5.2 2019-07-18 17:59:39 -04:00
William Falcon 0ac7a8590b added slurm managed flag catch for non-slurm peeps 2019-07-18 17:59:16 -04:00
William Falcon 6e12431e6b added slurm managed flag catch for non-slurm peeps 2019-07-18 17:58:38 -04:00
William Falcon c2e2298586 release v0.2.5.1 2019-07-18 17:14:34 -04:00
William Falcon 319feb7da5 removed printing. added auto process gen if slurm tasks do not match 2019-07-18 17:13:57 -04:00
William Falcon 5195124d4e added slurm no process warning 2019-07-18 17:06:56 -04:00
William Falcon 4e67983f23 added slurm no process warning 2019-07-18 17:05:09 -04:00
William Falcon c02b6c4c88 added slurm no process warning 2019-07-18 17:03:27 -04:00
William Falcon ad44d9168b added slurm no process warning 2019-07-18 16:47:46 -04:00
William Falcon 53a1a6d462 removed print lines 2019-07-18 16:37:48 -04:00
William Falcon 59d60eaf18 testing single process ddp 2019-07-18 15:06:20 -04:00
William Falcon 112be99b19 testing single process ddp 2019-07-18 14:57:56 -04:00
William Falcon 0e67773d2e testing single process ddp 2019-07-18 14:53:01 -04:00
William Falcon 394cdeeb8b added epoch flag back 2019-07-18 13:32:36 -04:00
William Falcon d0a8292e02 release v0.2.5 2019-07-18 12:13:00 -04:00
William Falcon d7409afed9 added arg docs 2019-07-18 12:11:59 -04:00
William Falcon f01cb63234 added arg docs 2019-07-18 12:10:07 -04:00
William Falcon 8be7480f31 added arg docs 2019-07-18 12:09:25 -04:00
William Falcon 751bc7c695 added arg docs 2019-07-18 12:08:47 -04:00
William Falcon 3be26dbb95 added arg docs 2019-07-18 12:08:17 -04:00
William Falcon 2ca0864ce8 added arg docs 2019-07-18 12:07:11 -04:00
William Falcon b1041220ac added arg docs 2019-07-18 12:05:52 -04:00
William Falcon da842c0cd6 added arg docs 2019-07-18 12:04:45 -04:00
William Falcon c4971e8432 added arg docs 2019-07-18 12:04:19 -04:00
William Falcon e81dbce38c set dp as default backend 2019-07-18 11:59:14 -04:00
William Falcon 0d992689d5 set dp as default backend 2019-07-18 11:58:27 -04:00
William Falcon 4085b3fa69 set dp as default backend 2019-07-18 11:57:39 -04:00
William Falcon b684bb55c5 set dp as default backend 2019-07-18 11:56:48 -04:00
William Falcon f98f88ff08 set dp as default backend 2019-07-18 11:51:43 -04:00
William Falcon f0955df4f0 set dp as default backend 2019-07-18 11:50:23 -04:00
William Falcon 7744c7117d set dp as default backend 2019-07-18 11:49:42 -04:00
William Falcon 22f4d6e26e set dp as default backend 2019-07-18 11:49:28 -04:00
William Falcon d49a83dec0 set dp as default backend 2019-07-18 11:48:16 -04:00
William Falcon 6d1d5ef68e set dp as default backend 2019-07-18 11:45:55 -04:00
William Falcon 3a1525222d set dp as default backend 2019-07-18 11:42:47 -04:00
William Falcon f650253cae set dp as default backend 2019-07-18 11:40:10 -04:00
William Falcon c67c84b443 set dp as default backend 2019-07-18 11:40:00 -04:00
William Falcon 4db32984c6 set dp as default backend 2019-07-18 11:39:13 -04:00
William Falcon 81d39786d9 set dp as default backend 2019-07-18 11:39:06 -04:00
William Falcon 63de076765 set dp as default backend 2019-07-18 11:36:48 -04:00
William Falcon 256ca62a3c set dp as default backend 2019-07-18 11:36:31 -04:00
William Falcon 39d04eb795 set dp as default backend 2019-07-18 11:35:59 -04:00
William Falcon e02857fcce set dp as default backend 2019-07-18 11:33:51 -04:00
William Falcon c163caf8cb set dp as default backend 2019-07-18 11:31:45 -04:00
William Falcon 2096a0aa84 set dp as default backend 2019-07-18 11:29:38 -04:00
William Falcon c253f96c53 set dp as default backend 2019-07-18 11:29:21 -04:00
William Falcon 551daca047 set dp as default backend 2019-07-18 11:25:02 -04:00
William Falcon ded0abead7 set dp as default backend 2019-07-18 11:21:35 -04:00
William Falcon e86b191691 set dp as default backend 2019-07-18 11:20:11 -04:00
William Falcon 3321e8c541 set dp as default backend 2019-07-18 11:18:19 -04:00
William Falcon bc3a805202 set dp as default backend 2019-07-18 11:16:16 -04:00
William Falcon 162b9f4f27 set dp as default backend 2019-07-18 11:15:21 -04:00
William Falcon e5bc3ea5b4 added training router 2019-07-18 11:09:37 -04:00
William Falcon baa139f97a added training router 2019-07-18 11:09:00 -04:00
William Falcon 470f3e6d29 added training router 2019-07-18 11:08:48 -04:00
William Falcon c12a0b57da added dp and ddp flag 2019-07-18 11:03:16 -04:00
William Falcon e7ecfa15f8 added option and flag 2019-07-18 10:56:45 -04:00
William Falcon 9051eb0039 updated docs 2019-07-17 15:56:55 -04:00
William Falcon bb8dbfca09 release v0.2.4.1 2019-07-17 10:04:14 -04:00
William Falcon 0240c70780 updated required deps 2019-07-17 10:03:58 -04:00
William Falcon a41abad5b2 Update trainer.py 2019-07-16 17:02:21 -04:00
William Falcon a83588b14e Update trainer.py 2019-07-16 13:12:56 -04:00
William Falcon 80192752b7 Merge pull request #13 from cinjon/on_tng_metrics
add a hook for on_tng_metrics so that users get access to the grad_no…
2019-07-16 12:59:16 -04:00
Cinjon Resnick fbd3873a0f add a hook for on_tng_metrics so that users get access to the grad_norm and mem_map dicts. 2019-07-16 12:51:48 -04:00
William Falcon 28cfddbe65 accept dist sampler classes 2019-07-16 12:44:58 -04:00
William Falcon b4bdb283ce release v0.2.4 2019-07-16 10:05:14 -04:00
William Falcon 967e57f071 early stop starts counting once min epochs met 2019-07-16 10:00:03 -04:00
William Falcon d12f6b7dd8 added summary flag 2019-07-15 21:11:29 -04:00
William Falcon 182c025c88 removed validation call 2019-07-15 20:48:46 -04:00
William Falcon 58e6199ce8 removed validation call 2019-07-15 14:56:56 -04:00
William Falcon 6a33f0d483 made early stop checkpoint optional 2019-07-15 14:54:38 -04:00
William Falcon dd230a93e8 made early stop checkpoint optional 2019-07-15 14:53:37 -04:00
William Falcon 3aa9cfc18e made checkpoint callback optional 2019-07-15 13:18:56 -04:00
William Falcon e57f461323 made checkpoint callback optional 2019-07-15 13:17:38 -04:00
William Falcon ab00514ef6 fixed metrics request not forced anymore 2019-07-15 13:03:08 -04:00
William Falcon 1dd58b4687 Merge branch 'master' of https://github.com/williamFalcon/pytorch-lightning 2019-07-15 13:01:17 -04:00
William Falcon b4b8a3dfde fixed none bug 2019-07-15 13:01:08 -04:00
William Falcon d8782c7b90 Update README.md 2019-07-15 09:21:30 -04:00
William Falcon d5878e9a72 release v0.2.3 2019-07-14 18:15:15 -04:00
William Falcon ad24bef1c9 removed print statements 2019-07-14 18:12:41 -04:00
William Falcon 50246a5066 working on single gpu init speed 2019-07-14 17:33:48 -04:00
William Falcon 21914cb1c1 working on single gpu init speed 2019-07-14 17:15:20 -04:00
William Falcon 904935cf98 working on single gpu init speed 2019-07-14 17:11:52 -04:00
William Falcon 468e75c180 working on single gpu init speed 2019-07-14 17:10:13 -04:00
William Falcon 849f52b7a6 modified single gpu init 2019-07-14 17:01:18 -04:00
William Falcon e520297781 modified single gpu init 2019-07-14 16:57:15 -04:00
William Falcon cefc27112d ddp flag change 2019-07-13 22:28:08 -04:00
William Falcon 6876f60098 merge 2019-07-13 22:21:17 -04:00
William Falcon fc1653e337 Merge branch 'nccl' of https://github.com/williamFalcon/pytorch-lightning into nccl 2019-07-13 22:19:41 -04:00
William Falcon e9f5913dac enabling gpu size = 1 to run without data parallel 2019-07-13 22:16:10 -04:00
William Falcon 7da82c2560 added fallback local init 2019-07-13 22:16:10 -04:00
William Falcon a2639c6894 added fallback local init 2019-07-13 22:16:10 -04:00
William Falcon eb05fa316f added fallback local init 2019-07-13 22:16:10 -04:00
William Falcon 6d55adb0d8 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon cff0500a63 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon f3ca184fb6 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 3239c9fdf8 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 7e37f68a5b fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 960937ebe9 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon a87784b4c5 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 5812efcf24 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon e82014ec6c fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon dc87a4fc91 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 4f5eef2e78 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 6c02afefca fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 4696e12641 fixed nccl init 2019-07-13 22:16:10 -04:00
William Falcon 7c688fbf2e enabling gpu size = 1 to run without data parallel 2019-07-13 22:09:17 -04:00
William Falcon 9ccfc7bd33 added fallback local init 2019-07-13 22:03:36 -04:00
William Falcon 52a98d76d8 added fallback local init 2019-07-13 10:16:50 -04:00
William Falcon 8b0cda84e7 added fallback local init 2019-07-13 10:13:52 -04:00
William Falcon 9f41a9e8b7 fixed nccl init 2019-07-12 16:35:20 -04:00
William Falcon b7baa96186 fixed nccl init 2019-07-12 16:29:44 -04:00
William Falcon faa2d4fa8b fixed nccl init 2019-07-12 16:23:20 -04:00
William Falcon 4f5da45fae fixed nccl init 2019-07-12 16:17:50 -04:00
William Falcon 7e54ad3f7c fixed nccl init 2019-07-12 16:16:46 -04:00
William Falcon 3bf366bcd8 fixed nccl init 2019-07-12 16:08:23 -04:00
William Falcon 6219f24a03 fixed nccl init 2019-07-12 16:07:57 -04:00
William Falcon 0bd81db538 fixed nccl init 2019-07-12 16:05:46 -04:00
William Falcon c84700814d fixed nccl init 2019-07-12 16:03:17 -04:00
William Falcon c244599ae8 fixed nccl init 2019-07-12 15:59:33 -04:00
William Falcon d99b121379 fixed nccl init 2019-07-12 15:59:12 -04:00
William Falcon 91b869d043 fixed nccl init 2019-07-12 15:55:28 -04:00
William Falcon 08e1ab64b5 fixed nccl init 2019-07-12 15:53:45 -04:00
William Falcon c1b21fb1e4 Merge pull request #11 from cinjon/modulefix
trainer: module fix.
2019-07-12 15:28:48 -04:00
William Falcon 8451bb7745 fixed nccl init 2019-07-12 15:25:34 -04:00
William Falcon 1a1771cfd8 fixed nccl init 2019-07-12 15:24:42 -04:00
William Falcon 1952e9be49 fixed nccl init 2019-07-12 15:11:32 -04:00
William Falcon 19391b1df1 fixed nccl init 2019-07-12 15:04:20 -04:00
William Falcon 369174c4d3 fixed nccl init 2019-07-12 14:36:00 -04:00
William Falcon 5ba0a2ed48 fixed nccl init 2019-07-12 14:28:49 -04:00
William Falcon 88061b2284 Merge branch 'master' of https://github.com/williamFalcon/pytorch-lightning 2019-07-12 13:42:53 -04:00
William Falcon ba38037917 fixed nccl init 2019-07-12 13:39:58 -04:00
William Falcon a7bb731a1d testing env init 2019-07-12 13:19:10 -04:00
William Falcon 58531888e0 testing env init 2019-07-12 13:17:33 -04:00
William Falcon 56ac885f03 Merge pull request #12 from cinjon/commafix
root_module: fix comma splits.
2019-07-12 13:13:57 -04:00
William Falcon 5e033fd97a testing env init 2019-07-12 13:11:08 -04:00
William Falcon 5d14b97aa6 testing file init 2019-07-12 12:57:54 -04:00
William Falcon 0b0addbcbe testing file init 2019-07-12 12:56:44 -04:00
Cinjon Resnick 098d518398 trainer: module fix. 2019-07-12 12:54:35 -04:00
William Falcon ba111e681e testing file init 2019-07-12 12:41:54 -04:00
Cinjon Resnick 3de053c903 root_module: fix comma splits. 2019-07-12 12:38:39 -04:00
William Falcon ac1bd57b8b testing file init 2019-07-12 12:33:54 -04:00
William Falcon 3f0fab9160 reset master 2019-07-12 12:32:36 -04:00
William Falcon 24c13aadc0 testing file init 2019-07-12 12:06:19 -04:00
William Falcon 885bad3555 testing master_Addr flag 2019-07-12 11:55:14 -04:00
William Falcon 6dde1d7ae3 testing master_Addr flag 2019-07-12 11:43:05 -04:00
William Falcon c223960edb testing master_Addr flag 2019-07-12 11:30:57 -04:00
William Falcon 32646cf2ee release v0.2.2 2019-07-11 16:19:11 -04:00
William Falcon 415ee4903b simplify trainer output 2019-07-11 15:23:33 -04:00
William Falcon a21dc5a187 simplify trainer output 2019-07-11 15:15:22 -04:00
William Falcon 0929908229 simplify trainer output 2019-07-11 15:08:45 -04:00
William Falcon cc12a1c8fa added clarifying comments 2019-07-11 14:58:47 -04:00
William Falcon 91b3a0aac6 added clarifying comments 2019-07-11 14:57:26 -04:00
William Falcon ed35f4e076 updated amp use 2019-07-11 14:35:41 -04:00
William Falcon c4781cb415 Merge branch 'master' of https://github.com/williamFalcon/pytorch-lightning 2019-07-11 14:18:07 -04:00
William Falcon 730a06640b updated amp use 2019-07-11 14:17:43 -04:00
William Falcon 6eb25edb31 release v0.21 2019-07-09 19:56:11 -04:00
William Falcon da24d87ece release v0.2 2019-07-08 20:19:11 -04:00
William Falcon cc3905cdc5 removed from_lightning flag 2019-07-08 20:17:55 -04:00
William Falcon 611fbdea3e removed from_lightning flag 2019-07-08 20:14:56 -04:00
William Falcon f38f3827fd docs 2019-07-08 20:13:40 -04:00
William Falcon 12ee3c60dd docs 2019-07-08 20:12:27 -04:00
William Falcon 65f6cd4321 removed dead code 2019-07-08 20:11:43 -04:00
William Falcon 7ab1a837a9 adjusted imports 2019-07-08 20:11:20 -04:00
William Falcon 7123dfeaf5 scaled batch size 2019-07-08 20:06:45 -04:00
William Falcon 9ee8f93483 scaled batch size 2019-07-08 20:05:45 -04:00
William Falcon 4f3c9d019b scaled batch size 2019-07-08 20:04:44 -04:00
William Falcon 9bb7a30f39 scaled batch size 2019-07-08 20:03:31 -04:00
William Falcon a8f3b1b21f scaled batch size 2019-07-08 20:03:08 -04:00
William Falcon 51c55c938a scaled batch size 2019-07-08 20:02:06 -04:00
William Falcon 49ad7d6c28 scaled batch size 2019-07-08 20:00:43 -04:00
William Falcon 7285598e11 scaled batch size 2019-07-08 19:57:51 -04:00
William Falcon 9d35b5b4f7 scaled batch size 2019-07-08 19:57:06 -04:00
William Falcon 2b16c75499 scaled batch size 2019-07-08 19:56:52 -04:00
William Falcon 0bd9152e0a scaled batch size 2019-07-08 19:55:26 -04:00
William Falcon a87073bffd scaled batch size 2019-07-08 19:54:00 -04:00
William Falcon f95fad864d scaled batch size 2019-07-08 19:53:24 -04:00
William Falcon b644234d08 scaled batch size 2019-07-08 19:49:37 -04:00
William Falcon f2c1f0221e scaled batch size 2019-07-08 19:48:22 -04:00
William Falcon 25dbd7a936 scaled batch size 2019-07-08 19:45:52 -04:00
William Falcon 971a6c4184 scaled batch size 2019-07-08 19:44:23 -04:00
William Falcon f95cc6144c scaled batch size 2019-07-08 19:42:53 -04:00
William Falcon 3e2dde1680 added dist sampler exception 2019-07-08 19:39:59 -04:00
William Falcon 96314cbf46 updated dist sampler 2019-07-08 19:26:51 -04:00
William Falcon d596ff2039 moved sampler 2019-07-08 19:15:28 -04:00
William Falcon cc3fbff704 moved sampler 2019-07-08 19:11:53 -04:00
William Falcon 0bcc858cef moved sampler 2019-07-08 19:11:16 -04:00
William Falcon cf4b25e455 moved sampler 2019-07-08 18:59:16 -04:00
William Falcon 31d9062b3a moved sampler 2019-07-08 18:55:05 -04:00
William Falcon 3873850ad4 moved sampler 2019-07-08 18:33:29 -04:00
William Falcon 85dd78f3a4 moved sampler 2019-07-08 18:32:28 -04:00
William Falcon 493a98d591 moved sampler 2019-07-08 18:28:30 -04:00
William Falcon bd2d1ddc07 moved sampler 2019-07-08 18:02:41 -04:00
William Falcon 14d1329655 auto distribute datasets across nodes 2019-07-08 17:51:07 -04:00
William Falcon c494e6d305 added cpu example 2019-07-08 17:45:09 -04:00
William Falcon a311a62b48 added cpu example 2019-07-08 17:44:06 -04:00
William Falcon 7a354668ff added cpu example 2019-07-08 17:42:33 -04:00
William Falcon abd8b2ea4e moved dataloaders after amp and optimizers 2019-07-08 17:41:07 -04:00
William Falcon 726dd1f61a moved dataloaders after amp and optimizers 2019-07-08 17:40:23 -04:00
William Falcon 687a133145 amp now supports multiple optimizers 2019-07-08 17:38:57 -04:00
William Falcon 98b779ba42 added single node example 2019-07-08 17:33:20 -04:00
William Falcon c750015c80 added single node example 2019-07-08 17:31:47 -04:00
William Falcon bd43c4417f added single node example 2019-07-08 17:29:46 -04:00
William Falcon e32d355d26 testing new pretrain order 2019-07-08 17:15:26 -04:00
William Falcon 64bdd1c46d cleaning up demo file 2019-07-08 14:31:40 -04:00
William Falcon 5c56295421 updated demo name 2019-07-08 14:29:03 -04:00
William Falcon bba51dde8c updated parser help 2019-07-08 14:27:19 -04:00
William Falcon 7c0e3715dd using slurm flag to fine node nb 2019-07-08 14:22:09 -04:00
William Falcon d2a717d31e using slurm flag to fine node nb 2019-07-08 14:14:36 -04:00
William Falcon 553223334f using slurm flag to fine node nb 2019-07-08 14:11:48 -04:00
William Falcon 8552a911bf using slurm flag to fine node nb 2019-07-08 14:07:04 -04:00
William Falcon 94da5431cd using slurm flag to fine node nb 2019-07-08 14:01:59 -04:00
William Falcon 63c113d55b using slurm flag to fine node nb 2019-07-08 14:00:17 -04:00
William Falcon 2261eaac2e using slurm flag to fine node nb 2019-07-08 13:56:20 -04:00
William Falcon fac98e0846 using slurm flag to fine node nb 2019-07-08 13:51:04 -04:00
William Falcon 52a3c3137a using slurm flag to fine node nb 2019-07-08 13:48:59 -04:00
William Falcon e637e09788 added multi-node locked ip search 2019-07-08 13:41:02 -04:00
William Falcon 5c41838d55 added multi-node locked ip search 2019-07-08 13:37:21 -04:00
William Falcon 8faf15073d added multi-node locked ip search 2019-07-08 13:27:04 -04:00
William Falcon 4589f49820 added multi-node locked ip search 2019-07-08 13:26:00 -04:00
William Falcon bc63bfe34b added multi-node locked ip search 2019-07-08 13:25:02 -04:00
William Falcon e2c36e8714 added multi-node locked ip search 2019-07-08 13:17:15 -04:00
William Falcon 660b966a8f added multi-node locked ip search 2019-07-08 13:04:52 -04:00
William Falcon ae0b85f235 added multi-node locked ip search 2019-07-08 13:01:38 -04:00
William Falcon a83d00456b added multi-node locked ip search 2019-07-08 12:59:10 -04:00
William Falcon c0e3cb784a added multi-node locked ip search 2019-07-08 12:58:47 -04:00
William Falcon 615711131e added multi-node locked ip search 2019-07-08 12:54:20 -04:00
William Falcon c2987d3b40 added multi-node locked ip search 2019-07-08 12:51:07 -04:00
William Falcon f4ab46e1c9 added multi-node locked ip search 2019-07-08 12:45:20 -04:00
William Falcon 6462cab351 added multi-node locked ip search 2019-07-08 12:39:49 -04:00
William Falcon 1d8d1f72a9 added multi-node locked ip search 2019-07-08 12:34:33 -04:00
William Falcon 6a1199b797 added multi-node locked ip search 2019-07-08 12:32:48 -04:00
William Falcon 212eabf626 added multi-node locked ip search 2019-07-08 12:30:38 -04:00
William Falcon fd194ab843 added multi-node locked ip search 2019-07-08 12:27:53 -04:00
William Falcon b563cfe598 testing slurm ddp 2019-07-08 11:48:28 -04:00
William Falcon 5f697cb22e testing slurm ddp 2019-07-08 11:44:11 -04:00
William Falcon dbfcbbc004 testing slurm ddp 2019-07-08 11:36:45 -04:00
William Falcon 770aff5fc7 testing slurm ddp 2019-07-08 11:32:01 -04:00
William Falcon 1f3d011c58 testing slurm ddp 2019-07-08 11:24:17 -04:00
William Falcon a971ca515d testing slurm ddp 2019-07-08 11:21:41 -04:00
William Falcon 3c2b3ccc5d testing slurm ddp 2019-07-08 11:21:28 -04:00
William Falcon f11eda857d testing slurm ddp 2019-07-08 10:59:07 -04:00
William Falcon e325ba5f68 testing slurm ddp 2019-07-08 10:57:34 -04:00
William Falcon f907158c97 testing slurm ddp 2019-07-08 10:55:06 -04:00
William Falcon 06928f721f testing slurm ddp 2019-07-08 10:51:31 -04:00
William Falcon 01b9502847 testing slurm ddp 2019-07-08 10:45:35 -04:00
William Falcon ae0349d449 testing slurm ddp 2019-07-08 10:30:55 -04:00
William Falcon 861047672a testing slurm ddp 2019-07-08 10:24:29 -04:00
William Falcon 65a0c98c5b testing slurm ddp 2019-07-08 10:23:04 -04:00
William Falcon 0fc9550a24 testing slurm ddp 2019-07-08 10:18:57 -04:00
William Falcon 6029d8fb75 testing slurm ddp 2019-07-08 10:16:12 -04:00
William Falcon cdbbf9abe3 moved cuda flags inside trainer 2019-07-08 10:00:04 -04:00
William Falcon 79ca5f6265 moved cuda flags inside trainer 2019-07-08 09:58:43 -04:00
William Falcon 2172280d8d moved cuda flags inside trainer 2019-07-08 09:58:11 -04:00
William Falcon f5a87c5016 moved cuda flags inside trainer 2019-07-08 09:58:01 -04:00
William Falcon 523cc9f2be added multi-node proc 0 ip reading 2019-07-08 09:50:45 -04:00
William Falcon ef530af7b8 added multi-node proc 0 ip reading 2019-07-08 09:45:43 -04:00
William Falcon 77fb4441ab added multi-node proc 0 ip reading 2019-07-08 09:45:00 -04:00
William Falcon e1823e0d1a added multi-node proc 0 ip reading 2019-07-08 09:44:20 -04:00
William Falcon 3422f7610b added multi-node proc 0 ip reading 2019-07-08 09:42:13 -04:00
William Falcon 79d9adf004 added multi-node proc 0 ip reading 2019-07-08 09:36:27 -04:00
William Falcon f705f15c7a added multi-node proc 0 ip reading 2019-07-08 09:36:09 -04:00
William Falcon 5fbe00837e easy import for lightningModule 2019-07-08 09:33:58 -04:00
William Falcon 1e57a75ff9 easy import for lightningModule 2019-07-08 09:32:57 -04:00
William Falcon 7d08e52b5d easy import for lightningModule 2019-07-08 09:30:51 -04:00
William Falcon d540d476a0 easy import for lightningModule 2019-07-08 09:29:02 -04:00
William Falcon 4454b968f0 easy import for lightningModule 2019-07-08 09:27:16 -04:00
William Falcon ae81473464 easy import for lightningModule 2019-07-03 18:43:13 -04:00
William Falcon 153b95c01f checkpoint only on rank=0 now 2019-07-03 18:18:29 -04:00
William Falcon a9acae3ed0 checkpoint only on rank=0 now 2019-07-03 18:17:12 -04:00
William Falcon f101152650 checkpoint only on rank=0 now 2019-07-03 18:14:34 -04:00
William Falcon 75e32daad4 clean up dead code 2019-07-03 17:09:39 -04:00
William Falcon 522af58504 clean up dead code 2019-07-03 17:05:20 -04:00
William Falcon 3ed02e4ed6 clean up dead code 2019-07-03 17:03:10 -04:00
William Falcon 9ef70bffa9 clean up dead code 2019-07-03 17:02:30 -04:00
William Falcon 9340e0a091 clean up dead code 2019-07-03 16:51:32 -04:00
William Falcon 0bfe0a993a clean up dead code 2019-07-03 16:49:53 -04:00
William Falcon 4b31f3d4bf clean up dead code 2019-07-03 16:47:39 -04:00
William Falcon 5bdad8a7b8 clean up dead code 2019-07-03 16:46:14 -04:00
William Falcon cd0d294236 clean up dead code 2019-07-03 16:44:18 -04:00
William Falcon e8abbb1e75 clean up dead code 2019-07-03 16:43:05 -04:00
William Falcon c10121c6ff clean up dead code 2019-07-03 16:39:33 -04:00
William Falcon 8630df5880 clean up dead code 2019-07-03 16:39:25 -04:00
William Falcon 23137ea08a added single node distdataparallel 2019-07-03 16:38:03 -04:00
William Falcon 32eddf492e added single node distdataparallel 2019-07-03 16:34:49 -04:00
William Falcon 7010d16752 added single node distdataparallel 2019-07-03 16:31:43 -04:00
William Falcon 080c308bcc added single node distdataparallel 2019-07-03 16:29:10 -04:00
William Falcon 8ddee926dd added single node distdataparallel 2019-07-03 16:24:10 -04:00
William Falcon 7e874dfb43 added single node distdataparallel 2019-07-03 16:23:12 -04:00
William Falcon 55b69f9fc5 added single node distdataparallel 2019-07-03 16:22:43 -04:00
William Falcon 8d3090c843 added single node distdataparallel 2019-07-03 16:21:56 -04:00
William Falcon 62774ffacb added single node distdataparallel 2019-07-03 16:17:56 -04:00
William Falcon 98a0a23158 added single node distdataparallel 2019-07-03 15:31:37 -04:00
William Falcon d52c92e09d added single node distdataparallel 2019-07-03 15:26:19 -04:00
William Falcon 09ed6904c2 added single node distdataparallel 2019-07-03 15:25:56 -04:00
William Falcon 970d1609e1 added single node distdataparallel 2019-07-03 15:25:33 -04:00
William Falcon 5f57792131 added single node distdataparallel 2019-07-03 15:24:56 -04:00
William Falcon 6eb7674e18 added single node distdataparallel 2019-07-03 15:24:16 -04:00
William Falcon 5ff3a90a6f added single node distdataparallel 2019-07-03 15:23:47 -04:00
William Falcon 22becf3915 added single node distdataparallel 2019-07-03 15:23:39 -04:00
William Falcon 5797f812ad added single node distdataparallel 2019-07-03 15:22:57 -04:00
William Falcon 251c2e964f added single node distdataparallel 2019-07-03 15:22:31 -04:00
William Falcon d67e80bf16 added single node distdataparallel 2019-07-03 15:21:13 -04:00
William Falcon 98db51eb95 added single node distdataparallel 2019-07-03 15:20:33 -04:00
William Falcon 129dce0d18 added single node distdataparallel 2019-07-03 15:18:47 -04:00
William Falcon 7f3c653747 added single node distdataparallel 2019-07-03 15:18:16 -04:00
William Falcon f06c650fc1 added single node distdataparallel 2019-07-03 15:18:10 -04:00
William Falcon b9f581ab87 added single node distdataparallel 2019-07-03 15:17:02 -04:00
William Falcon ac57dac235 added single node distdataparallel 2019-07-03 15:16:09 -04:00
William Falcon 96ab78dc41 added single node distdataparallel 2019-07-03 15:11:35 -04:00
William Falcon 7ef6db49d3 added single node distdataparallel 2019-07-03 15:11:17 -04:00
William Falcon c4aca832ba added single node distdataparallel 2019-07-03 15:09:49 -04:00
William Falcon 30e2fc6c4b added on_hpc_load and on_hpc_save hooks 2019-07-02 09:36:48 -04:00
William Falcon 62e091f48d added on_hpc_load and on_hpc_save hooks 2019-07-02 09:36:33 -04:00
William Falcon f257c080c0 added on_hpc_load and on_hpc_save hooks 2019-07-02 09:35:15 -04:00
William Falcon cd11b7de98 remove default tensor 2019-07-02 09:23:47 -04:00
William Falcon 2eba85d02c release v0.122 2019-07-02 08:59:11 -04:00
William Falcon 49c27770da fix dataparallel 2019-07-01 18:38:07 -04:00
William Falcon 0f5a7c322e fix dataparallel 2019-07-01 18:33:24 -04:00
William Falcon 8fde5e444e release v0.121 2019-06-30 18:56:54 -04:00
William Falcon f338d39b92 release v0.12 2019-06-30 18:42:28 -04:00
William Falcon c13c6a9ec6 release vusing pytorch summarywriter now 2019-06-30 18:41:59 -04:00
William Falcon 1cb31cd210 Merge branch 'master' of https://github.com/williamFalcon/pytorch-lightning 2019-06-29 18:42:44 -04:00
William Falcon 1460987b40 added demo tfx images 2019-06-29 18:42:39 -04:00
William Falcon 56b6fedf18 Update requirements.txt 2019-06-29 18:41:05 -04:00
William Falcon e7d7004d92 Update requirements.txt 2019-06-29 18:40:25 -04:00
William Falcon 01e0027c5e Update README.md 2019-06-29 18:35:41 -04:00
William Falcon 773d677b3b Update README.md 2019-06-29 18:35:13 -04:00
William Falcon 0c5beb5ab1 Update README.md 2019-06-29 18:33:27 -04:00
William Falcon 0d3303a4ab Update README.md 2019-06-29 18:32:55 -04:00
William Falcon 2b55fa89b4 Update README.md 2019-06-29 18:29:37 -04:00
William Falcon ba763be4f9 Update README.md 2019-06-29 18:29:03 -04:00
William Falcon f39f8ed1a9 added demo tfx images 2019-06-29 18:28:11 -04:00
William Falcon 7997c4609b added demo tfx images 2019-06-29 18:26:13 -04:00
William Falcon 7fd2b0fa19 added module properties 2019-06-29 18:14:45 -04:00
William Falcon 04445504e5 Update README.md 2019-06-29 18:09:11 -04:00
William Falcon 5735a366cf Update README.md 2019-06-29 18:08:57 -04:00
William Falcon a36061ad2b Update README.md 2019-06-29 18:06:30 -04:00
William Falcon 614d84e560 Update README.md 2019-06-29 18:05:17 -04:00
William Falcon 3ab8120f27 Update README.md 2019-06-29 17:58:10 -04:00
William Falcon 306ca02813 Update README.md 2019-06-29 17:57:40 -04:00
William Falcon 8a6680937f 0.113 2019-06-29 17:51:15 -04:00
William Falcon d2608b4f6a release v0.113 2019-06-29 17:50:06 -04:00
William Falcon 6ffb6fb010 verified tfx support 2019-06-29 17:45:26 -04:00
William Falcon 0a03042bf7 fixed multiprocessing import 2019-06-29 17:33:10 -04:00
William Falcon f2134a4ddd integrated tensorboardx test-tube 2019-06-29 15:58:47 -04:00
William Falcon 38c9102d13 required tensorflow for tensorboardx install 2019-06-29 15:35:05 -04:00
William Falcon cb34270d31 added module properties docs 2019-06-28 19:02:51 -04:00
29 changed files with 1510 additions and 342 deletions
+1
View File
@@ -8,6 +8,7 @@ datasets/
model_weights/
app/models/
pip-wheel-metadata/
test_tube_exp/
# Byte-compiled / optimized / DLL files
__pycache__/
+71 -8
View File
@@ -36,9 +36,26 @@ To use lightning do 2 things:
2. [Define a LightningModel](https://github.com/williamFalcon/pytorch-lightning/blob/master/examples/new_project_templates/lightning_module_template.py).
## What does lightning control for me?
Everything! Except the following three things:
Everything!
Except for these 6 core functions which you define:
**What happens in the training loop**
```{.python}
# what to do in the training loop
def training_step(self, data_batch, batch_nb):
# what to do in the validation loop
def validation_step(self, data_batch, batch_nb):
# how to aggregate validation_step outputs
def validation_end(self, outputs):
# and your dataloaders
def tng_dataloader():
def val_dataloader():
def test_dataloader():
```
**Could be as complex as seq-2-seq + attention**
```python
# define what happens for training here
@@ -46,25 +63,39 @@ def training_step(self, data_batch, batch_nb):
x, y = data_batch
# define your own forward and loss calculation
out = self.forward(x)
loss = my_loss(out, y)
hidden_states = self.encoder(x)
# even as complex as a seq-2seq + attn model
# (this is just a toy, non-working example to illustrate)
start_token = '<SOS>'
last_hidden = torch.zeros(...)
loss = 0
for step in range(max_seq_len):
attn_context = self.attention_nn(hidden_states, start_token)
pred = self.decoder(start_token, attn_context, last_hidden)
last_hidden = pred
pred = self.predict_nn(pred)
loss += self.loss(last_hidden, y[step])
#toy example as well
loss = loss / max_seq_len
return {'loss': loss}
```
**What happens in the validation loop**
**Or as basic as CNN image classification**
```python
# define what happens for validation here
def validation_step(self, data_batch, batch_nb):
x, y = data_batch
# define your own forward and loss calculation
# or as basic as a CNN classification
out = self.forward(x)
loss = my_loss(out, y)
return {'loss': loss}
```
**And what to do with the output of all validation batches**
**And you also decide how to collate the output of all validation steps**
```python
def validation_end(self, outputs):
@@ -84,8 +115,40 @@ def validation_end(self, outputs):
tqdm_dic = {'val_loss': val_loss_mean.item(), 'val_acc': val_acc_mean.item()}
return tqdm_dic
```
## Tensorboard
Lightning is fully integrated with tensorboard.
## Lightning gives you options to control the following:
<p align="center">
<a href="https://williamfalcon.github.io/pytorch-lightning/">
<img alt="" src="https://github.com/williamFalcon/pytorch-lightning/blob/master/docs/source/_static/tf_loss.png" width="900px">
</a>
</p>
Lightning also adds a text column with all the hyperparameters for this experiment.
<p align="center">
<a href="https://williamfalcon.github.io/pytorch-lightning/">
<img alt="" src="https://github.com/williamFalcon/pytorch-lightning/blob/master/docs/source/_static/tf_tags.png" width="900px">
</a>
</p>
Simply note the path you set for the Experiment
``` {.python}
from test_tube import Experiment
from pytorch-lightning import Trainer
exp = Experiment(save_dir='/some/path')
trainer = Trainer(experiment=exp)
...
```
And run tensorboard from that dir
```bash
tensorboard --logdir /some/path
```
## Lightning automatically automates all of the following ([each is also configurable](https://williamfalcon.github.io/pytorch-lightning/Trainer/)):
###### Checkpointing
+18 -3
View File
@@ -8,12 +8,21 @@ The current epoch
#### dtype
Current dtype
---
#### experiment
An instance of test-tube Experiment which you can use to log anything for tensorboarX.
```{.python}
self.experiment.add_embedding(...)
self.experiment.log({'val_loss': 0.9})
self.experiment.add_scalars(...)
```
---
#### global_step
#### global_step
Total training batches seen across all epochs
---
#### gradient_clip
#### gradient_clip
The current gradient clip value
---
@@ -21,5 +30,11 @@ The current gradient clip value
True if your model is currently running on GPUs. Useful to set flags around the LightningModule for different CPU vs GPU behavior.
---
#### Trainer
#### trainer
Last resort access to any state the trainer has. Changing certain properties here could affect your training run.
```{.python}
self.trainer.optimizers
self.trainer.current_epoch
...
```
+78 -5
View File
@@ -3,6 +3,26 @@ Lightning makes multi-gpu training and 16 bit training trivial.
*Note:*
None of the flags below require changing anything about your lightningModel definition.
---
#### Choosing a backend
Lightning supports two backends. DataParallel and DistributedDataParallel. Both can be used for single-node multi-GPU training.
For multi-node training you must use DistributedDataParallel.
You can toggle between each mode by setting this flag.
``` {.python}
# DEFAULT uses DataParallel
trainer = Trainer(distributed_backend='dp')
# change to distributed data parallel
trainer = Trainer(distributed_backend='ddp')
```
If you request multiple nodes, the back-end will auto-switch to ddp.
We recommend you use DistributedDataparallel even for single-node multi-GPU training. It is MUCH faster than DP but *may*
have configuration issues depending on your cluster.
For a deeper understanding of what lightning is doing, feel free to read [this guide](https://medium.com/@_willfalcon/9-tips-for-training-lightning-fast-neural-networks-in-pytorch-8e63a502f565).
---
#### 16-bit mixed precision
16 bit precision can cut your memory footprint by half. If using volta architecture GPUs it can give a dramatic training speed-up as well.
@@ -37,16 +57,69 @@ Make sure you're on a GPU machine. You can set as many GPUs as you want.
In this setting, the model will run on all 8 GPUs at once using DataParallel under the hood.
```python
# set these flags
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1,2,3,4,5,6,7"
# lightning sets these flags for you automatically
# no need to set yourself
# os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
# os.environ["CUDA_VISIBLE_DEVICES"] = "0,1,2,3,4,5,6,7"
# DEFAULT
trainer = Trainer(gpus=[0,1,2,3,4,5,6,7])
# to use DataParallel (default)
trainer = Trainer(gpus=[0,1,2,3,4,5,6,7], distributed_backend='dp')
# RECOMMENDED use DistributedDataParallel
trainer = Trainer(gpus=[0,1,2,3,4,5,6,7], distributed_backend='ddp')
```
---
#### Multi-node
COMING SOON.
Multi-node training is easily done by specifying these flags.
```python
# train on 12*8 GPUs
trainer = Trainer(gpus=[0,1,2,3,4,5,6,7], nb_gpu_nodes=12)
```
In addition, make sure to set up your SLURM job correctly via the [SlurmClusterObject](https://williamfalcon.github.io/test-tube/hpc/SlurmCluster/). In particular, specify the number of tasks per node correctly.
```python
cluster = SlurmCluster(
hyperparam_optimizer=test_tube.HyperOptArgumentParser(),
log_path='/some/path/to/save',
)
# OPTIONAL FLAGS WHICH MAY BE CLUSTER DEPENDENT
# which interface your nodes use for communication
cluster.add_command('export NCCL_SOCKET_IFNAME=^docker0,lo')
# see output of the NCCL connection process
# NCCL is how the nodes talk to each other
cluster.add_command('export NCCL_DEBUG=INFO')
# setting a master port here is a good idea.
cluster.add_command(f'export MASTER_PORT={PORT}')
# good to load the latest NCCL version
cluster.load_modules(['NCCL/2.4.7-1-cuda.10.0'])
# configure cluster
cluster.per_experiment_nb_nodes = 12
cluster.per_experiment_nb_gpus = 8
cluster.add_slurm_cmd(cmd='ntasks-per-node', value=8, comment='1 task per gpu')
```
Finally, make sure to add a distributed sampler to your dataset. The distributed sampler copies a
portion of your dataset onto each GPU. (World_size = gpus_per_node * nb_nodes).
```python
# ie: this:
dataset = myDataset()
dataloader = Dataloader(dataset)
# becomes:
dataset = myDataset()
dist_sampler = torch.utils.data.distributed.DistributedSampler(dataset)
dataloader = Dataloader(dataset, sampler=dist_sampler)
```
---
#### Self-balancing architecture
+1 -1
View File
@@ -19,7 +19,7 @@ Cut the learning rate by 10 at every epoch listed in this list.
trainer = Trainer(lr_scheduler_milestones=None)
# cut LR by 10 at 100, 200, and 300 epochs
trainer = Trainer(lr_scheduler_milestones=[100, 200, 300])
trainer = Trainer(lr_scheduler_milestones='100, 200, 300')
```
---
-2
View File
@@ -1,5 +1,3 @@
# PYTORCH-LIGHTNING DOCUMENTATION
###### New project Quick Start
To start a new project define these two files.
Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

@@ -0,0 +1 @@
from .lightning_module_template import LightningTemplateModel
@@ -7,6 +7,8 @@ import torch
import torch.nn.functional as F
from test_tube import HyperOptArgumentParser
from torch import optim
from torch.utils.data import DataLoader
from torch.utils.data.distributed import DistributedSampler
from pytorch_lightning.root_module.root_module import LightningModule
@@ -82,9 +84,10 @@ class LightningTemplateModel(LightningModule):
loss_val = self.loss(y, y_hat)
output = OrderedDict({
'loss': loss_val,
'tqdm_metrics': {}
'loss': loss_val
})
# can also return just a scalar instead of a dict (return loss_val)
return output
def validation_step(self, data_batch, batch_i):
@@ -105,8 +108,10 @@ class LightningTemplateModel(LightningModule):
output = OrderedDict({
'val_loss': loss_val,
'val_acc': torch.tensor(val_acc),
'val_acc': torch.tensor(val_acc).cuda(loss_val.device.index),
})
# can also return just a scalar instead of a dict (return loss_val)
return output
def validation_end(self, outputs):
@@ -115,6 +120,10 @@ class LightningTemplateModel(LightningModule):
:param outputs: list of individual outputs of each validation step
:return:
"""
# if returned a scalar from validation_step, outputs is a list of tensor scalars
# we return just the average in this case (if we want)
# return torch.stack(outputs).mean()
val_loss_mean = 0
val_acc_mean = 0
for output in outputs:
@@ -154,13 +163,25 @@ class LightningTemplateModel(LightningModule):
def __dataloader(self, train):
# init data generators
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (1.0,))])
dataset = MNIST(root=self.hparams.data_root, train=train, transform=transform, download=True)
loader = torch.utils.data.DataLoader(
# when using multi-node we need to add the datasampler
train_sampler = None
batch_size = self.hparams.batch_size
try:
if self.on_gpu:
train_sampler = DistributedSampler(dataset, rank=self.trainer.proc_rank)
batch_size = batch_size // self.trainer.world_size # scale batch size
except Exception as e:
pass
should_shuffle = train_sampler is None
loader = DataLoader(
dataset=dataset,
batch_size=self.hparams.batch_size,
shuffle=True
batch_size=batch_size,
shuffle=should_shuffle,
sampler=train_sampler
)
return loader
@@ -210,16 +231,19 @@ class LightningTemplateModel(LightningModule):
# network params
parser.opt_list('--drop_prob', default=0.2, options=[0.2, 0.5], type=float, tunable=False)
parser.add_argument('--in_features', default=28*28)
parser.add_argument('--out_features', default=10)
parser.add_argument('--hidden_dim', default=50000) # use 500 for CPU, 50000 for GPU to see speed difference
parser.add_argument('--in_features', default=28*28, type=int)
parser.add_argument('--out_features', default=10, type=int)
parser.add_argument('--hidden_dim', default=50000, type=int) # use 500 for CPU, 50000 for GPU to see speed difference
# data
parser.add_argument('--data_root', default=os.path.join(root_dir, 'mnist'), type=str)
# training params (opt)
parser.opt_list('--learning_rate', default=0.001, type=float, options=[0.0001, 0.0005, 0.001, 0.005],
parser.opt_list('--learning_rate', default=0.001*8, type=float, options=[0.0001, 0.0005, 0.001, 0.005],
tunable=False)
parser.opt_list('--batch_size', default=256, type=int, options=[32, 64, 128, 256], tunable=False)
parser.opt_list('--optimizer_name', default='adam', type=str, options=['adam'], tunable=False)
# if using 2 nodes with 4 gpus each the batch size here (256) will be 256 / (2*8) = 16 per gpu
parser.opt_list('--batch_size', default=256*8, type=int, options=[32, 64, 128, 256], tunable=False,
help='batch size will be divided over all the gpus being used across all nodes')
return parser
@@ -0,0 +1,172 @@
import os
import sys
import numpy as np
from time import sleep
import torch
from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster
from pytorch_lightning.models.trainer import Trainer
from pytorch_lightning.utils.arg_parse import add_default_args
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
SEED = 2334
torch.manual_seed(SEED)
np.random.seed(SEED)
# ---------------------
# DEFINE MODEL HERE
# ---------------------
from lightning_module_template import LightningTemplateModel
# ---------------------
"""
Allows training by using command line arguments
Run by:
# TYPE YOUR RUN COMMAND HERE
"""
def main_local(hparams):
main(hparams, None, None)
def main(hparams, cluster, results_dict):
"""
Main training routine specific for this project
:param hparams:
:return:
"""
# ------------------------
# 1 INIT LIGHTNING MODEL
# ------------------------
print('loading model...')
model = LightningTemplateModel(hparams)
print('model built')
# ------------------------
# 2 INIT TEST TUBE EXP
# ------------------------
# when using grid search, it's possible for all models to start at once
# and use the same test tube experiment version
relative_node_id = int(os.environ['SLURM_NODEID'])
sleep(relative_node_id + 1)
# init experiment
exp = Experiment(
name=hyperparams.experiment_name,
save_dir=hyperparams.test_tube_save_path,
autosave=False,
description='test demo'
)
exp.argparse(hparams)
exp.save()
# ------------------------
# 3 DEFINE CALLBACKS
# ------------------------
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
early_stop = EarlyStopping(
monitor='val_acc',
patience=3,
verbose=True,
mode='max'
)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_best_only=True,
verbose=True,
monitor='val_loss',
mode='min'
)
# ------------------------
# 4 INIT TRAINER
# ------------------------
trainer = Trainer(
experiment=exp,
cluster=cluster,
checkpoint_callback=checkpoint,
early_stop_callback=early_stop,
gpus=hparams.gpus,
nb_gpu_nodes=hyperparams.nb_gpu_nodes
)
# ------------------------
# 5 START TRAINING
# ------------------------
trainer.fit(model)
def optimize_on_cluster(hyperparams):
# enable cluster training
# log all scripts to the test tube folder
cluster = SlurmCluster(
hyperparam_optimizer=hyperparams,
log_path=hyperparams.slurm_log_path,
)
# email for cluster coms
cluster.notify_job_status(email='add_email_here', on_done=True, on_fail=True)
# configure cluster
cluster.per_experiment_nb_gpus = hyperparams.per_experiment_nb_gpus
cluster.per_experiment_nb_nodes = hyperparams.nb_gpu_nodes
cluster.job_time = '2:00:00'
cluster.gpu_type = 'volta'
cluster.memory_mb_per_node = 0
# any modules for code to run in env
cluster.add_command('source activate lightning')
# run only on 32GB voltas
cluster.add_slurm_cmd(cmd='constraint', value='volta32gb', comment='use 32gb gpus')
cluster.add_slurm_cmd(cmd='partition', value=hyperparams.gpu_partition, comment='use 32gb gpus')
# run hopt
# creates and submits jobs to slurm
cluster.optimize_parallel_cluster_gpu(
main,
nb_trials=hyperparams.nb_hopt_trials,
job_name=hyperparams.experiment_name
)
if __name__ == '__main__':
# use default args
root_dir = os.path.dirname(os.path.realpath(__file__))
demo_log_dir = os.path.join(root_dir, 'pt_lightning_demo_logs')
checkpoint_dir = os.path.join(demo_log_dir, 'model_weights')
test_tube_dir = os.path.join(demo_log_dir, 'test_tube_data')
slurm_out_dir = os.path.join(demo_log_dir, 'slurm_scripts')
parent_parser = HyperOptArgumentParser(strategy='grid_search', add_help=False)
# cluster args not defined inside the model
parent_parser.add_argument('--gpu_partition', type=str, help='consult your cluster manual')
# TODO: make 1 param
parent_parser.add_argument('--per_experiment_nb_gpus', type=int, help='how many gpus to use in a node')
parent_parser.add_argument('--gpus', type=str, default='-1', help='how many gpus to use in the node')
parent_parser.add_argument('--nb_gpu_nodes', type=int, default=1, help='how many nodes to use in a cluster')
parent_parser.add_argument('--test_tube_save_path', type=str, default=test_tube_dir, help='where to save logs')
parent_parser.add_argument('--slurm_log_path', type=str, default=slurm_out_dir, help='where to save slurm meta')
parent_parser.add_argument('--model_save_path', type=str, default=checkpoint_dir, help='where to save model')
parent_parser.add_argument('--experiment_name', type=str, default='pt_lightning_exp_a', help='test tube exp name')
parent_parser.add_argument('--nb_hopt_trials', type=int, default=1, help='how many grid search trials to run')
# allow model to overwrite or extend args
parser = LightningTemplateModel.add_model_specific_args(parent_parser, root_dir)
hyperparams = parser.parse_args()
# ---------------------
# RUN TRAINING
# ---------------------
# run on HPC cluster
print('RUNNING ON SLURM CLUSTER')
optimize_on_cluster(hyperparams)
@@ -0,0 +1,110 @@
"""
Runs a model on a single node across N-gpus.
"""
import os
import sys
import numpy as np
from time import sleep
import torch
from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster
from pytorch_lightning.models.trainer import Trainer
from pytorch_lightning.utils.arg_parse import add_default_args
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
SEED = 2334
torch.manual_seed(SEED)
np.random.seed(SEED)
from lightning_module_template import LightningTemplateModel
def main(hparams):
"""
Main training routine specific for this project
:param hparams:
:return:
"""
# ------------------------
# 1 INIT LIGHTNING MODEL
# ------------------------
print('loading model...')
model = LightningTemplateModel(hparams)
print('model built')
# ------------------------
# 2 INIT TEST TUBE EXP
# ------------------------
# init experiment
exp = Experiment(
name=hyperparams.experiment_name,
save_dir=hyperparams.test_tube_save_path,
autosave=False,
description='test demo'
)
exp.argparse(hparams)
exp.save()
# ------------------------
# 3 DEFINE CALLBACKS
# ------------------------
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
early_stop = EarlyStopping(
monitor='val_acc',
patience=3,
verbose=True,
mode='max'
)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_best_only=True,
verbose=True,
monitor='val_loss',
mode='min'
)
# ------------------------
# 4 INIT TRAINER
# ------------------------
trainer = Trainer(
experiment=exp,
checkpoint_callback=checkpoint,
early_stop_callback=early_stop,
)
# ------------------------
# 5 START TRAINING
# ------------------------
trainer.fit(model)
if __name__ == '__main__':
# dirs
root_dir = os.path.dirname(os.path.realpath(__file__))
demo_log_dir = os.path.join(root_dir, 'pt_lightning_demo_logs')
checkpoint_dir = os.path.join(demo_log_dir, 'model_weights')
test_tube_dir = os.path.join(demo_log_dir, 'test_tube_data')
# although we user hyperOptParser, we are using it only as argparse right now
parent_parser = HyperOptArgumentParser(strategy='grid_search', add_help=False)
# gpu args
parent_parser.add_argument('--test_tube_save_path', type=str, default=test_tube_dir, help='where to save logs')
parent_parser.add_argument('--model_save_path', type=str, default=checkpoint_dir, help='where to save model')
parent_parser.add_argument('--experiment_name', type=str, default='pt_lightning_exp_a', help='test tube exp name')
# allow model to overwrite or extend args
parser = LightningTemplateModel.add_model_specific_args(parent_parser, root_dir)
hyperparams = parser.parse_args()
# ---------------------
# RUN TRAINING
# ---------------------
# run on HPC cluster
print(f'RUNNING ON CPU')
main(hyperparams)
@@ -0,0 +1,113 @@
"""
Runs a model on a single node across N-gpus.
"""
import os
import sys
import numpy as np
from time import sleep
import torch
from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster
from pytorch_lightning.models.trainer import Trainer
from pytorch_lightning.utils.arg_parse import add_default_args
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
SEED = 2334
torch.manual_seed(SEED)
np.random.seed(SEED)
from lightning_module_template import LightningTemplateModel
def main(hparams):
"""
Main training routine specific for this project
:param hparams:
:return:
"""
# ------------------------
# 1 INIT LIGHTNING MODEL
# ------------------------
print('loading model...')
model = LightningTemplateModel(hparams)
print('model built')
# ------------------------
# 2 INIT TEST TUBE EXP
# ------------------------
# init experiment
exp = Experiment(
name=hyperparams.experiment_name,
save_dir=hyperparams.test_tube_save_path,
autosave=False,
description='test demo'
)
exp.argparse(hparams)
exp.save()
# ------------------------
# 3 DEFINE CALLBACKS
# ------------------------
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
early_stop = EarlyStopping(
monitor='val_acc',
patience=3,
verbose=True,
mode='max'
)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_best_only=True,
verbose=True,
monitor='val_loss',
mode='min'
)
# ------------------------
# 4 INIT TRAINER
# ------------------------
trainer = Trainer(
experiment=exp,
checkpoint_callback=checkpoint,
early_stop_callback=early_stop,
gpus=hparams.gpus,
use_amp=True
)
# ------------------------
# 5 START TRAINING
# ------------------------
trainer.fit(model)
if __name__ == '__main__':
# dirs
root_dir = os.path.dirname(os.path.realpath(__file__))
demo_log_dir = os.path.join(root_dir, 'pt_lightning_demo_logs')
checkpoint_dir = os.path.join(demo_log_dir, 'model_weights')
test_tube_dir = os.path.join(demo_log_dir, 'test_tube_data')
# although we user hyperOptParser, we are using it only as argparse right now
parent_parser = HyperOptArgumentParser(strategy='grid_search', add_help=False)
# gpu args
parent_parser.add_argument('--gpus', type=str, default='-1', help='how many gpus to use in the node. -1 uses all the gpus on the node')
parent_parser.add_argument('--test_tube_save_path', type=str, default=test_tube_dir, help='where to save logs')
parent_parser.add_argument('--model_save_path', type=str, default=checkpoint_dir, help='where to save model')
parent_parser.add_argument('--experiment_name', type=str, default='pt_lightning_exp_a', help='test tube exp name')
# allow model to overwrite or extend args
parser = LightningTemplateModel.add_model_specific_args(parent_parser, root_dir)
hyperparams = parser.parse_args()
# ---------------------
# RUN TRAINING
# ---------------------
# run on HPC cluster
print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {hyperparams.gpus}')
main(hyperparams)
@@ -0,0 +1,112 @@
"""
Runs a model on a single node across N-gpus.
"""
import os
import sys
import numpy as np
from time import sleep
import torch
from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster
from pytorch_lightning.models.trainer import Trainer
from pytorch_lightning.utils.arg_parse import add_default_args
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
SEED = 2334
torch.manual_seed(SEED)
np.random.seed(SEED)
from lightning_module_template import LightningTemplateModel
def main(hparams):
"""
Main training routine specific for this project
:param hparams:
:return:
"""
# ------------------------
# 1 INIT LIGHTNING MODEL
# ------------------------
print('loading model...')
model = LightningTemplateModel(hparams)
print('model built')
# ------------------------
# 2 INIT TEST TUBE EXP
# ------------------------
# init experiment
exp = Experiment(
name=hyperparams.experiment_name,
save_dir=hyperparams.test_tube_save_path,
autosave=False,
description='test demo'
)
exp.argparse(hparams)
exp.save()
# ------------------------
# 3 DEFINE CALLBACKS
# ------------------------
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
early_stop = EarlyStopping(
monitor='val_acc',
patience=3,
verbose=True,
mode='max'
)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_best_only=True,
verbose=True,
monitor='val_loss',
mode='min'
)
# ------------------------
# 4 INIT TRAINER
# ------------------------
trainer = Trainer(
experiment=exp,
checkpoint_callback=checkpoint,
early_stop_callback=early_stop,
gpus=hparams.gpus,
)
# ------------------------
# 5 START TRAINING
# ------------------------
trainer.fit(model)
if __name__ == '__main__':
# dirs
root_dir = os.path.dirname(os.path.realpath(__file__))
demo_log_dir = os.path.join(root_dir, 'pt_lightning_demo_logs')
checkpoint_dir = os.path.join(demo_log_dir, 'model_weights')
test_tube_dir = os.path.join(demo_log_dir, 'test_tube_data')
# although we user hyperOptParser, we are using it only as argparse right now
parent_parser = HyperOptArgumentParser(strategy='grid_search', add_help=False)
# gpu args
parent_parser.add_argument('--gpus', type=str, default='-1', help='how many gpus to use in the node. -1 uses all the gpus on the node')
parent_parser.add_argument('--test_tube_save_path', type=str, default=test_tube_dir, help='where to save logs')
parent_parser.add_argument('--model_save_path', type=str, default=checkpoint_dir, help='where to save model')
parent_parser.add_argument('--experiment_name', type=str, default='pt_lightning_exp_a', help='test tube exp name')
# allow model to overwrite or extend args
parser = LightningTemplateModel.add_model_specific_args(parent_parser, root_dir)
hyperparams = parser.parse_args()
# ---------------------
# RUN TRAINING
# ---------------------
# run on HPC cluster
print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {hyperparams.gpus}')
main(hyperparams)
@@ -0,0 +1,112 @@
"""
Runs a model on a single node across N-gpus.
"""
import os
import sys
import numpy as np
from time import sleep
import torch
from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster
from pytorch_lightning.models.trainer import Trainer
from pytorch_lightning.utils.arg_parse import add_default_args
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
SEED = 2334
torch.manual_seed(SEED)
np.random.seed(SEED)
from lightning_module_template import LightningTemplateModel
def main(hparams):
"""
Main training routine specific for this project
:param hparams:
:return:
"""
# ------------------------
# 1 INIT LIGHTNING MODEL
# ------------------------
print('loading model...')
model = LightningTemplateModel(hparams)
print('model built')
# ------------------------
# 2 INIT TEST TUBE EXP
# ------------------------
# init experiment
exp = Experiment(
name=hyperparams.experiment_name,
save_dir=hyperparams.test_tube_save_path,
autosave=False,
description='test demo'
)
exp.argparse(hparams)
exp.save()
# ------------------------
# 3 DEFINE CALLBACKS
# ------------------------
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
early_stop = EarlyStopping(
monitor='val_acc',
patience=3,
verbose=True,
mode='max'
)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_best_only=True,
verbose=True,
monitor='val_loss',
mode='min'
)
# ------------------------
# 4 INIT TRAINER
# ------------------------
trainer = Trainer(
experiment=exp,
checkpoint_callback=checkpoint,
early_stop_callback=early_stop,
gpus=hparams.gpus,
)
# ------------------------
# 5 START TRAINING
# ------------------------
trainer.fit(model)
if __name__ == '__main__':
# dirs
root_dir = os.path.dirname(os.path.realpath(__file__))
demo_log_dir = os.path.join(root_dir, 'pt_lightning_demo_logs')
checkpoint_dir = os.path.join(demo_log_dir, 'model_weights')
test_tube_dir = os.path.join(demo_log_dir, 'test_tube_data')
# although we user hyperOptParser, we are using it only as argparse right now
parent_parser = HyperOptArgumentParser(strategy='grid_search', add_help=False)
# gpu args
parent_parser.add_argument('--gpus', type=str, default='-1', help='how many gpus to use in the node. -1 uses all the gpus on the node')
parent_parser.add_argument('--test_tube_save_path', type=str, default=test_tube_dir, help='where to save logs')
parent_parser.add_argument('--model_save_path', type=str, default=checkpoint_dir, help='where to save model')
parent_parser.add_argument('--experiment_name', type=str, default='pt_lightning_exp_a', help='test tube exp name')
# allow model to overwrite or extend args
parser = LightningTemplateModel.add_model_specific_args(parent_parser, root_dir)
hyperparams = parser.parse_args()
# ---------------------
# RUN TRAINING
# ---------------------
# run on HPC cluster
print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {hyperparams.gpus}')
main(hyperparams)
@@ -0,0 +1,112 @@
"""
Runs a model on a single node across N-gpus.
"""
import os
import sys
import numpy as np
from time import sleep
import torch
from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster
from pytorch_lightning.models.trainer import Trainer
from pytorch_lightning.utils.arg_parse import add_default_args
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
SEED = 2334
torch.manual_seed(SEED)
np.random.seed(SEED)
from lightning_module_template import LightningTemplateModel
def main(hparams):
"""
Main training routine specific for this project
:param hparams:
:return:
"""
# ------------------------
# 1 INIT LIGHTNING MODEL
# ------------------------
print('loading model...')
model = LightningTemplateModel(hparams)
print('model built')
# ------------------------
# 2 INIT TEST TUBE EXP
# ------------------------
# init experiment
exp = Experiment(
name=hyperparams.experiment_name,
save_dir=hyperparams.test_tube_save_path,
autosave=False,
description='test demo'
)
exp.argparse(hparams)
exp.save()
# ------------------------
# 3 DEFINE CALLBACKS
# ------------------------
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
early_stop = EarlyStopping(
monitor='val_acc',
patience=3,
verbose=True,
mode='max'
)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_best_only=True,
verbose=True,
monitor='val_loss',
mode='min'
)
# ------------------------
# 4 INIT TRAINER
# ------------------------
trainer = Trainer(
experiment=exp,
checkpoint_callback=checkpoint,
early_stop_callback=early_stop,
gpus=hparams.gpus,
)
# ------------------------
# 5 START TRAINING
# ------------------------
trainer.fit(model)
if __name__ == '__main__':
# dirs
root_dir = os.path.dirname(os.path.realpath(__file__))
demo_log_dir = os.path.join(root_dir, 'pt_lightning_demo_logs')
checkpoint_dir = os.path.join(demo_log_dir, 'model_weights')
test_tube_dir = os.path.join(demo_log_dir, 'test_tube_data')
# although we user hyperOptParser, we are using it only as argparse right now
parent_parser = HyperOptArgumentParser(strategy='grid_search', add_help=False)
# gpu args
parent_parser.add_argument('--gpus', type=str, default='0', help='how many gpus to use in the node. -1 uses all the gpus on the node')
parent_parser.add_argument('--test_tube_save_path', type=str, default=test_tube_dir, help='where to save logs')
parent_parser.add_argument('--model_save_path', type=str, default=checkpoint_dir, help='where to save model')
parent_parser.add_argument('--experiment_name', type=str, default='pt_lightning_exp_a', help='test tube exp name')
# allow model to overwrite or extend args
parser = LightningTemplateModel.add_model_specific_args(parent_parser, root_dir)
hyperparams = parser.parse_args()
# ---------------------
# RUN TRAINING
# ---------------------
# run on HPC cluster
print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {hyperparams.gpus}')
main(hyperparams)
@@ -41,7 +41,6 @@ def main(hparams):
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_function=None,
save_best_only=True,
verbose=True,
monitor='val_acc',
@@ -1,210 +0,0 @@
import os
import sys
import numpy as np
from time import sleep
import torch
from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster
from pytorch_lightning.models.trainer import Trainer
from pytorch_lightning.utils.arg_parse import add_default_args
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
SEED = 2334
torch.manual_seed(SEED)
np.random.seed(SEED)
# ---------------------
# DEFINE MODEL HERE
# ---------------------
from examples.new_project_templates.lightning_module_template import LightningTemplateModel
# ---------------------
AVAILABLE_MODELS = {
'model_template': LightningTemplateModel
}
"""
Allows training by using command line arguments
Run by:
# TYPE YOUR RUN COMMAND HERE
"""
def main_local(hparams):
main(hparams, None, None)
def main(hparams, cluster, results_dict):
"""
Main training routine specific for this project
:param hparams:
:return:
"""
on_gpu = hparams.gpus is not None and torch.cuda.is_available()
device = 'cuda' if on_gpu else 'cpu'
hparams.__setattr__('device', device)
hparams.__setattr__('on_gpu', on_gpu)
hparams.__setattr__('nb_gpus', torch.cuda.device_count())
hparams.__setattr__('inference_mode', hparams.model_load_weights_path is not None)
# delay each training start to not overwrite logs
process_position, current_gpu = TRAINING_MODEL.get_process_position(hparams.gpus)
sleep(process_position + 1)
# init experiment
log_dir = os.path.dirname(os.path.realpath(__file__))
exp = Experiment(
name='test_tube_exp',
debug=True,
save_dir=log_dir,
version=0,
autosave=False,
description='test demo'
)
exp.argparse(hparams)
exp.save()
# build model
print('loading model...')
model = TRAINING_MODEL(hparams)
print('model built')
# callbacks
early_stop = EarlyStopping(
monitor=hparams.early_stop_metric,
patience=hparams.early_stop_patience,
verbose=True,
mode=hparams.early_stop_mode
)
model_save_path = '{}/{}/{}'.format(hparams.model_save_path, exp.name, exp.version)
checkpoint = ModelCheckpoint(
filepath=model_save_path,
save_function=None,
save_best_only=True,
verbose=True,
monitor=hparams.model_save_monitor_value,
mode=hparams.model_save_monitor_mode
)
# gpus are ; separated for inside a node and , within nodes
gpu_list = None
if hparams.gpus is not None:
gpu_list = [int(x) for x in hparams.gpus.split(';')]
# configure trainer
trainer = Trainer(
experiment=exp,
cluster=cluster,
checkpoint_callback=checkpoint,
early_stop_callback=early_stop,
gpus=gpu_list
)
# train model
trainer.fit(model)
def get_default_parser(strategy, root_dir):
possible_model_names = list(AVAILABLE_MODELS.keys())
parser = HyperOptArgumentParser(strategy=strategy, add_help=False)
add_default_args(parser, root_dir, possible_model_names=possible_model_names, rand_seed=SEED)
return parser
def get_model_name(args):
for i, arg in enumerate(args):
if 'model_name' in arg:
return args[i+1]
def optimize_on_cluster(hyperparams):
# enable cluster training
cluster = SlurmCluster(
hyperparam_optimizer=hyperparams,
log_path=hyperparams.tt_save_path,
test_tube_exp_name=hyperparams.tt_name
)
# email for cluster coms
cluster.notify_job_status(email='add_email_here', on_done=True, on_fail=True)
# configure cluster
cluster.per_experiment_nb_gpus = hyperparams.per_experiment_nb_gpus
cluster.job_time = '48:00:00'
cluster.gpu_type = '1080ti'
cluster.memory_mb_per_node = 48000
# any modules for code to run in env
cluster.add_command('source activate pytorch_lightning')
# name of exp
job_display_name = hyperparams.tt_name.split('_')[0]
job_display_name = job_display_name[0:3]
# run hopt
print('submitting jobs...')
cluster.optimize_parallel_cluster_gpu(
main,
nb_trials=hyperparams.nb_hopt_trials,
job_name=job_display_name
)
if __name__ == '__main__':
model_name = get_model_name(sys.argv)
if model_name is None:
model_name = 'model_template'
# use default args
root_dir = os.path.dirname(os.path.realpath(__file__))
parent_parser = get_default_parser(strategy='random_search', root_dir=root_dir)
# allow model to overwrite or extend args
TRAINING_MODEL = AVAILABLE_MODELS[model_name]
parser = TRAINING_MODEL.add_model_specific_args(parent_parser, root_dir)
hyperparams = parser.parse_args()
# format GPU layout
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
# ---------------------
# RUN TRAINING
# ---------------------
# cluster and CPU
if hyperparams.on_cluster:
# run on HPC cluster
print('RUNNING ON SLURM CLUSTER')
gpu_ids = hyperparams.gpus.split(';')
os.environ["CUDA_VISIBLE_DEVICES"] = ','.join(gpu_ids)
optimize_on_cluster(hyperparams)
elif hyperparams.gpus is None:
# run on cpu
print('RUNNING ON CPU')
main(hyperparams, None, None)
# single or multiple GPUs on same machine
gpu_ids = hyperparams.gpus.split(';')
if hyperparams.interactive:
# run on 1 gpu
print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {gpu_ids}')
os.environ["CUDA_VISIBLE_DEVICES"] = ','.join(gpu_ids)
main(hyperparams, None, None)
else:
# multiple GPUs on same machine
print(f'RUNNING MULTI GPU. GPU ids: {gpu_ids}')
hyperparams.optimize_parallel_gpu(
main_local,
gpu_ids=gpu_ids,
nb_trials=hyperparams.nb_hopt_trials,
nb_workers=len(gpu_ids)
)
+2 -1
View File
@@ -1 +1,2 @@
from .models import Trainer
from .models import Trainer
from .root_module.root_module import LightningModule
+2 -2
View File
@@ -1,6 +1,6 @@
import numpy as np
import os, shutil
from pytorch_lightning.pt_overrides.override_data_parallel import LightningDataParallel
from pytorch_lightning.pt_overrides.override_data_parallel import LightningDistributedDataParallel
class Callback(object):
@@ -34,7 +34,7 @@ class Callback(object):
self.params = params
def set_model(self, model):
if type(model) is LightningDataParallel:
if type(model) is LightningDistributedDataParallel:
model = model.module
self.model = model
+419 -67
View File
@@ -1,12 +1,25 @@
import torch
import tqdm
import numpy as np
from pytorch_lightning.root_module.memory import get_gpu_memory_map
"""
The trainer handles all the logic for running a val loop, training loop, distributing, etc...
"""
import subprocess
import traceback
from pytorch_lightning.root_module.model_saving import TrainerIO
from torch.optim.lr_scheduler import MultiStepLR
from pytorch_lightning.pt_overrides.override_data_parallel import LightningDataParallel
import warnings
import os
import pdb
import re
import torch
from torch.utils.data.distributed import DistributedSampler
from torch.optim.lr_scheduler import MultiStepLR
import torch.multiprocessing as mp
import torch.distributed as dist
import numpy as np
import tqdm
from pytorch_lightning.root_module.memory import get_gpu_memory_map
from pytorch_lightning.root_module.model_saving import TrainerIO
from pytorch_lightning.pt_overrides.override_data_parallel import LightningDistributedDataParallel, LightningDataParallel
try:
from apex import amp
@@ -16,6 +29,14 @@ except ModuleNotFoundError:
def reduce_distributed_output(output, nb_gpus):
if nb_gpus <= 1:
return output
# when using DP, we get one output per gpu
# average outputs and return
if type(output) is torch.Tensor:
return output.mean()
for k, v in output.items():
# recurse on nested dics
if isinstance(output[k], dict):
@@ -32,11 +53,13 @@ class Trainer(TrainerIO):
def __init__(self,
experiment,
checkpoint_callback, early_stop_callback,
early_stop_callback=None,
checkpoint_callback=None,
gradient_clip=0,
cluster=None,
process_position=0,
current_gpu_name=0,
nb_gpu_nodes=1,
gpus=None,
progress_bar=True,
overfit_pct=0.0,
@@ -44,19 +67,57 @@ class Trainer(TrainerIO):
check_val_every_n_epoch=1,
fast_dev_run=False,
accumulate_grad_batches=1,
enable_early_stop=True, max_nb_epochs=1000, min_nb_epochs=1,
train_percent_check=1.0, val_percent_check=1.0, test_percent_check=1.0, val_check_interval=0.95,
max_nb_epochs=1000, min_nb_epochs=1,
train_percent_check=1.0, val_percent_check=1.0, test_percent_check=1.0,
val_check_interval=0.95,
log_save_interval=100, add_log_row_interval=10,
lr_scheduler_milestones=None,
distributed_backend='dp',
use_amp=False,
print_nan_grads=False,
print_weights_summary=True,
amp_level='O2',
nb_sanity_val_steps=5):
"""
:param experiment: Test-tube experiment
:param early_stop_callback: from pytorch_lightning import EarlyStopping
:param checkpoint_callback: from pytorch_lightning import Checkpoint
:param gradient_clip:
:param cluster:
:param process_position:
:param current_gpu_name:
:param nb_gpu_nodes:
:param gpus:
:param progress_bar:
:param overfit_pct:
:param track_grad_norm:
:param check_val_every_n_epoch:
:param fast_dev_run:
:param accumulate_grad_batches:
:param max_nb_epochs:
:param min_nb_epochs:
:param train_percent_check:
:param val_percent_check:
:param test_percent_check:
:param val_check_interval:
:param log_save_interval:
:param add_log_row_interval:
:param lr_scheduler_milestones:
:param distributed_backend: 'np' to use DistributedParallel, 'ddp' to use DistributedDataParallel
:param use_amp:
:param print_nan_grads:
:param print_weights_summary:
:param amp_level:
:param nb_sanity_val_steps:
"""
# Transfer params
self.nb_gpu_nodes = nb_gpu_nodes
self.gradient_clip = gradient_clip
self.check_val_every_n_epoch = check_val_every_n_epoch
self.enable_early_stop = enable_early_stop
self.enable_early_stop = early_stop_callback is not None
self.track_grad_norm = track_grad_norm
self.fast_dev_run = fast_dev_run
self.on_gpu = gpus is not None and torch.cuda.is_available()
@@ -66,8 +127,12 @@ class Trainer(TrainerIO):
self.cluster = cluster
self.process_position = process_position
self.current_gpu_name = current_gpu_name
self.print_weights_summary = print_weights_summary
self.checkpoint_callback = checkpoint_callback
self.checkpoint_callback.save_function = self.save_checkpoint
if self.checkpoint_callback is not None:
self.checkpoint_callback.save_function = self.save_checkpoint
self.early_stop = early_stop_callback
self.model = None
self.max_nb_epochs = max_nb_epochs
@@ -79,8 +144,50 @@ class Trainer(TrainerIO):
self.lr_schedulers = []
self.amp_level = amp_level
self.print_nan_grads = print_nan_grads
self.data_parallel_device_ids = gpus
self.data_parallel = gpus is not None and len(gpus) > 0
self.data_parallel_device_ids = None
self.world_size = 1
self.node_rank = 0
self.use_ddp = False
self.use_dp = False
# gpus come in as a string.
# if gpus = -1 then use all available devices
# otherwise, split the string using commas
if gpus is not None:
if type(gpus) is list:
self.data_parallel_device_ids = gpus
elif type(gpus) is str:
if gpus == '-1':
self.data_parallel_device_ids = list(range(0, torch.cuda.device_count()))
else:
self.data_parallel_device_ids = [int(x.strip()) for x in gpus.split(',')]
else:
raise Exception('gpus has to be a string or list of ids')
# set the correct cuda visible devices (using pci order)
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = ','.join([str(x) for x in self.data_parallel_device_ids])
print(f'VISIBLE GPUS: {os.environ["CUDA_VISIBLE_DEVICES"]}')
# make DP and DDP mutually exclusive
# single GPU will also use DP with devices=[0]
have_gpus = self.data_parallel_device_ids is not None and len(self.data_parallel_device_ids) > 0
if have_gpus:
self.use_dp = distributed_backend == 'dp'
self.use_ddp = distributed_backend == 'ddp'
# use ddp automatically if nb_gpu_nodes > 1
if nb_gpu_nodes > 1:
self.use_ddp = True
self.use_ddp = False
w = 'DataParallel does not support nb_gpu_nodes > 1. ' \
'Switching to DistributedDataParallel for you. ' \
'To silence this warning set distributed_backend=ddp'
warnings.warn(w)
# process info
self.proc_rank = 0
# training state
self.optimizers = None
@@ -103,11 +210,25 @@ class Trainer(TrainerIO):
self.__determine_data_use_amount(train_percent_check, val_percent_check, test_percent_check, overfit_pct)
print('gpu available: {}, used: {}'.format(torch.cuda.is_available(), self.on_gpu))
# apex test
# 16 bit mixed precision training using apex
self.use_amp = use_amp and APEX_AVAILABLE
if self.use_amp:
print('using 16bit precision')
if use_amp and not APEX_AVAILABLE:
msg = '''
You set use_amp=True but do not have apex installed.
Install apex first using this guide and rerun with use_amp=True:
https://github.com/NVIDIA/apex#linux
this run will NOT use 16 bit precision
'''
warnings.warn(msg)
@property
def data_parallel(self):
return self.use_dp or self.use_ddp
def __determine_data_use_amount(self, train_percent_check, val_percent_check, test_percent_check, overfit_pct):
"""
Use less data for debugging purposes
@@ -120,24 +241,30 @@ class Trainer(TrainerIO):
self.val_percent_check = overfit_pct
self.test_percent_check = overfit_pct
def __get_model(self):
return self.model.module if self.data_parallel else self.model
def __is_function_implemented(self, f_name):
f_op = getattr(self.model, f_name, None)
model = self.__get_model()
f_op = getattr(model, f_name, None)
return callable(f_op)
@property
def __tng_tqdm_dic(self):
tqdm_dic = {
'tng_loss': '{0:.3f}'.format(self.avg_loss),
'gpu': '{}'.format(self.current_gpu_name),
'v_nb': '{}'.format(self.experiment.version),
'epoch': '{}'.format(self.current_epoch),
'batch_nb':'{}'.format(self.batch_nb),
}
tqdm_dic.update(self.tqdm_metrics)
if self.on_gpu:
tqdm_dic['gpu'] = '{}'.format(self.current_gpu_name)
return tqdm_dic
def __layout_bookeeping(self, model):
def __layout_bookeeping(self):
# training bookeeping
self.total_batch_nb = 0
self.running_loss = []
@@ -146,17 +273,17 @@ class Trainer(TrainerIO):
self.tqdm_metrics = {}
# determine number of training batches
self.nb_tng_batches = model.nb_batches(self.tng_dataloader)
self.nb_tng_batches = len(self.tng_dataloader)
self.nb_tng_batches = int(self.nb_tng_batches * self.train_percent_check)
# determine number of validation batches
self.nb_val_batches = model.nb_batches(self.val_dataloader)
self.nb_val_batches = len(self.val_dataloader)
self.nb_val_batches = int(self.nb_val_batches * self.val_percent_check)
self.nb_val_batches = max(1, self.nb_val_batches)
self.nb_val_batches = self.nb_val_batches
# determine number of test batches
self.nb_test_batches = model.nb_batches(self.test_dataloader)
self.nb_test_batches = len(self.test_dataloader)
self.nb_test_batches = int(self.nb_test_batches * self.test_percent_check)
# determine when to check validation
@@ -177,12 +304,9 @@ class Trainer(TrainerIO):
:param max_batches: Scalar
:return:
"""
print('validating...')
# enable eval mode
model.zero_grad()
model.eval()
model.from_lightning = True
# disable gradients to save memory
torch.set_grad_enabled(False)
@@ -203,9 +327,12 @@ class Trainer(TrainerIO):
# -----------------
# RUN VALIDATION STEP
# -----------------
if self.data_parallel:
if self.use_ddp:
output = model(data_batch, batch_i)
elif self.use_dp:
output = model(data_batch, batch_i)
output = reduce_distributed_output(output, len(self.data_parallel_device_ids))
else:
output = model.validation_step(data_batch, batch_i)
@@ -239,30 +366,209 @@ class Trainer(TrainerIO):
self.test_dataloader = model.test_dataloader
self.val_dataloader = model.val_dataloader
if self.use_ddp and not isinstance(self.tng_dataloader.sampler, DistributedSampler):
msg = '''
when using multiple gpus and multiple nodes you must pass a DistributedSampler to DataLoader(sampler).
ie: this:
dataset = myDataset()
dataloader = Dataloader(dataset)
becomes:
dataset = myDataset()
dist_sampler = torch.utils.data.distributed.DistributedSampler(dataset)
dataloader = Dataloader(dataset, sampler=dist_sampler)
'''
raise Exception(msg)
# -----------------------------
# MODEL TRAINING
# -----------------------------
def fit(self, model):
model.trainer = self
# when using multi-node or DDP within a node start each module in a separate process
if self.use_ddp:
# must copy only the meta of the exp so it survives pickle/unpickle when going to new process
self.experiment = self.experiment.get_meta_copy()
# transfer data loaders from model
self.__get_dataloaders(model)
# whenever we have the correct number of tasks, we let slurm manage processes
# otherwise we launch the required number of processes
nb_requested_gpus = len(self.data_parallel_device_ids) * self.nb_gpu_nodes
nb_slurm_tasks = 0
try:
nb_slurm_tasks = int(os.environ['SLURM_NTASKS'])
is_slurm_managing_tasks = nb_slurm_tasks == nb_requested_gpus
except Exception as e:
# likely not on slurm, so set the slurm managed flag to false
is_slurm_managing_tasks = False
# init training constants
self.__layout_bookeeping(model)
if is_slurm_managing_tasks:
task = int(os.environ['SLURM_LOCALID'])
self.ddp_train(task, model)
else:
msg = f"""
You requested {nb_requested_gpus} GPUs but launched {nb_slurm_tasks} slurm tasks.
We will launch {nb_requested_gpus} processes for you.
We recommend you let slurm manage the processes by setting: --ntasks-per-node={nb_requested_gpus}
If you're not using SLURM, ignore this message!
"""
warnings.warn(msg)
mp.spawn(self.ddp_train, nprocs=len(self.data_parallel_device_ids), args=(model, ))
# 1 gpu or dp option triggers training using DP module
# easier to avoid NCCL issues
elif self.use_dp:
self.dp_train(model)
# ON CPU
else:
# CHOOSE OPTIMIZER
# filter out the weights that were done on gpu so we can load on good old cpus
self.optimizers = model.configure_optimizers()
# run through amp wrapper
if self.use_amp:
# An example
model, optimizers = amp.initialize(
model, self.optimizers, opt_level=self.amp_level,
)
self.optimizers = optimizers
self.__run_pretrain_routine(model)
def dp_train(self, model):
# CHOOSE OPTIMIZER
# filter out the weights that were done on gpu so we can load on good old cpus
self.optimizers = model.configure_optimizers()
model.cuda(self.data_parallel_device_ids[0])
model = LightningDataParallel(model, device_ids=self.data_parallel_device_ids)
# run through amp wrapper
if self.use_amp:
# An example
model, optimizer = amp.initialize(
model, self.optimizers[0], opt_level=self.amp_level,
model, optimizers = amp.initialize(
model, self.optimizers, opt_level=self.amp_level,
)
self.optimizers[0] = optimizer
model.trainer = self
self.optimizers = optimizers
self.__run_pretrain_routine(model)
def ddp_train(self, gpu_nb, model):
"""
Entry point into a DP thread
:param gpu_nb:
:param model:
:param cluster_obj:
:return:
"""
# node rank using relative slurm id
# otherwise default to node rank 0
try:
node_id = os.environ['SLURM_NODEID']
self.node_rank = int(node_id)
except Exception as e:
self.node_rank = 0
# recover original exp before went into process
# init in write mode only on proc 0
self.experiment.debug = self.proc_rank > 0
self.experiment = self.experiment.get_non_ddp_exp()
# show progbar only on prog_rank 0
self.prog_bar = self.prog_bar and self.node_rank == 0 and gpu_nb == 0
# determine which process we are and world size
self.proc_rank = self.node_rank * len(self.data_parallel_device_ids) + gpu_nb
self.world_size = self.nb_gpu_nodes * len(self.data_parallel_device_ids)
# set up server using proc 0's ip address
# try to init for 20 times at max in case ports are taken
# where to store ip_table
self.__init_tcp_connection()
# CHOOSE OPTIMIZER
# filter out the weights that were done on gpu so we can load on good old cpus
self.optimizers = model.configure_optimizers()
# MODEL
# copy model to each gpu
torch.cuda.set_device(gpu_nb)
model.cuda(gpu_nb)
# AMP
# run through amp wrapper before going to distributed DP
if self.use_amp:
# An example
model, optimizers = amp.initialize(
model, self.optimizers, opt_level=self.amp_level,
)
self.optimizers = optimizers
model = LightningDistributedDataParallel(model, device_ids=[gpu_nb])
# continue training routine
self.__run_pretrain_routine(model)
def __init_tcp_connection(self):
"""
Connect all procs in the world using the env:// init
Use the first node as the root address
:param port:
:param tries:
:return:
"""
try:
port = os.environ['MASTER_PORT']
except Exception as e:
port = 12910
os.environ['MASTER_PORT'] = f'{port}'
root_node = self.__resolve_root_node_address()
os.environ['MASTER_ADDR'] = root_node
dist.init_process_group("nccl", rank=self.proc_rank, world_size=self.world_size)
def __resolve_root_node_address(self):
try:
root_node = os.environ['SLURM_NODELIST'].split(' ')[0]
if '[' in root_node:
name = root_node.split('[')[0]
number = root_node.split(',')[0]
if '-' in number:
number = number.split('-')[0]
number = re.sub('[^0-9]', '', number)
root_node = name + number
except Exception as e:
root_node = '127.0.0.2'
return root_node
def __run_pretrain_routine(self, model):
"""
Sanity check a few things before starting actual training
:param model:
:return:
"""
ref_model = model
if self.data_parallel:
ref_model = model.module
ref_model.trainer = self
# set local properties on the model
ref_model.on_gpu = self.on_gpu
# transfer data loaders from model
self.__get_dataloaders(ref_model)
# init training constants
self.__layout_bookeeping()
# add lr schedulers
if self.lr_scheduler_milestones is not None:
@@ -271,17 +577,19 @@ class Trainer(TrainerIO):
self.lr_schedulers.append(scheduler)
# print model summary
model.summarize()
if self.proc_rank == 0 and self.print_weights_summary:
ref_model.summarize()
# put on gpu if needed
if self.on_gpu:
model = LightningDataParallel(model, device_ids=self.data_parallel_device_ids)
# give model convenience properties
ref_model.trainer = self
ref_model.experiment = self.experiment
# run tiny validation to make sure program won't crash during val
_ = self.validate(model, self.val_dataloader, max_batches=self.nb_sanity_val_steps)
# save exp to get started
self.experiment.save()
if self.proc_rank == 0:
self.experiment.save()
# enable cluster checkpointing
if self.cluster is not None:
@@ -300,12 +608,12 @@ class Trainer(TrainerIO):
for lr_scheduler in self.lr_schedulers:
lr_scheduler.step()
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
model.current_epoch = epoch_nb
# hook
if self.__is_function_implemented('on_epoch_start'):
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
model.on_epoch_start()
self.current_epoch = epoch_nb
@@ -320,7 +628,7 @@ class Trainer(TrainerIO):
self.batch_nb = batch_nb
self.global_step += 1
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
model.global_step = self.global_step
# stop when the flag is changed or we've gone past the amount requested in the batches
@@ -344,17 +652,16 @@ class Trainer(TrainerIO):
# when batch should be saved
if (batch_nb + 1) % self.log_save_interval == 0 or early_stop_epoch:
self.experiment.save()
if self.proc_rank == 0:
self.experiment.save()
# when metrics should be logged
if batch_nb % self.add_log_row_interval == 0 or early_stop_epoch:
# count items in memory
# nb_params, nb_tensors = count_mem_items()
if self.data_parallel:
metrics = self.model.module.update_tng_log_metrics(self.__tng_tqdm_dic)
else:
metrics = self.model.update_tng_log_metrics(self.__tng_tqdm_dic)
model = self.__get_model()
metrics = model.update_tng_log_metrics(self.__tng_tqdm_dic)
# add gpu memory
if self.on_gpu:
@@ -363,18 +670,22 @@ class Trainer(TrainerIO):
# add norms
if self.track_grad_norm > 0:
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
grad_norm_dic = model.grad_norm(self.track_grad_norm)
metrics.update(grad_norm_dic)
if self.__is_function_implemented('on_tng_metrics'):
model.on_tng_metrics(metrics)
# log metrics
self.experiment.log(metrics)
self.experiment.save()
scalar_metrics = self.__metrics_to_scalars(metrics, blacklist=self.__log_vals_blacklist())
if self.proc_rank == 0:
self.experiment.log(scalar_metrics, global_step=self.global_step)
self.experiment.save()
# hook
if self.__is_function_implemented('on_batch_end'):
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
model.on_batch_end()
# end epoch early
@@ -383,19 +694,37 @@ class Trainer(TrainerIO):
# hook
if self.__is_function_implemented('on_epoch_end'):
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
model.on_epoch_end()
# early stopping
if self.enable_early_stop:
met_min_epochs = epoch_nb > self.min_nb_epochs
if self.enable_early_stop and met_min_epochs:
should_stop = self.early_stop_callback.on_epoch_end(epoch=epoch_nb, logs=self.__tng_tqdm_dic)
met_min_epochs = epoch_nb > self.min_nb_epochs
# stop training
stop = should_stop and met_min_epochs
if stop:
return
def __metrics_to_scalars(self, metrics, blacklist=[]):
new_metrics = {}
for k, v in metrics.items():
if type(v) is torch.Tensor:
v = v.item()
if type(v) is dict:
v = self.__metrics_to_scalars(v)
if k not in blacklist:
new_metrics[k] = float(v)
return new_metrics
def __log_vals_blacklist(self):
"""avoid logging some vals lightning uses to maintain state"""
blacklist = {'batch_nb', 'v_nb', 'gpu'}
return blacklist
def __run_tng_batch(self, data_batch, batch_nb):
if data_batch is None:
@@ -403,8 +732,8 @@ class Trainer(TrainerIO):
# hook
if self.__is_function_implemented('on_batch_start'):
model = self.model.module if self.data_parallel else self.model
response = model.on_batch_start(data_batch)
model_ref = self.__get_model()
response = model_ref.on_batch_start(data_batch)
if response == -1:
return -1
@@ -414,19 +743,32 @@ class Trainer(TrainerIO):
# forward pass
# return a scalar value and a dic with tqdm metrics
if self.data_parallel:
if self.use_ddp:
output = self.model(data_batch, batch_nb)
elif self.use_dp:
output = self.model(data_batch, batch_nb)
output = reduce_distributed_output(output, len(self.data_parallel_device_ids))
else:
output = self.model.training_step(data_batch, batch_nb)
model_specific_tqdm_metrics_dic = output['tqdm_metrics']
loss = output['loss']
try:
model_specific_tqdm_metrics_dic = output['tqdm_metrics']
except Exception as e:
model_specific_tqdm_metrics_dic = {}
# if output dict doesn't have the keyword loss
# then assume the output=loss if scalar
try:
loss = output['loss']
except Exception as e:
if type(output) is torch.Tensor:
loss = output
self.__add_tqdm_metrics(model_specific_tqdm_metrics_dic)
# backward pass
if self.use_amp:
# scale loss when using amp
for optimizer in self.optimizers:
with amp.scale_loss(loss, optimizer) as scaled_loss:
scaled_loss.backward()
@@ -434,10 +776,11 @@ class Trainer(TrainerIO):
loss.backward()
if self.print_nan_grads:
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
for param in model.parameters():
print(param.grad.float().sum())
# avoid memory leaks
self.batch_loss_value += loss.item()
# gradient update with accumulated gradients
@@ -445,13 +788,18 @@ class Trainer(TrainerIO):
# clip gradients
if self.gradient_clip > 0:
model = self.model.module if self.data_parallel else self.model
model = self.__get_model()
torch.nn.utils.clip_grad_norm(model.parameters(), self.gradient_clip)
# update gradients across all optimizers
for optimizer in self.optimizers:
optimizer.step()
# insert after step hook
if self.__is_function_implemented('on_before_zero_grad'):
model_ref = self.__get_model()
response = model_ref.on_before_zero_grad(optimizer)
# clear gradients
optimizer.zero_grad()
@@ -471,7 +819,8 @@ class Trainer(TrainerIO):
# activate batch end hook
if self.__is_function_implemented('on_batch_end'):
self.model.on_batch_end()
model = self.__get_model()
model.on_batch_end()
return 0
@@ -486,7 +835,8 @@ class Trainer(TrainerIO):
try:
# hook
if self.__is_function_implemented('on_pre_performance_check'):
self.model.on_pre_performance_check()
model = self.__get_model()
model.on_pre_performance_check()
# use full val set on end of epoch
# use a small portion otherwise
@@ -500,7 +850,8 @@ class Trainer(TrainerIO):
# hook
if self.__is_function_implemented('on_post_performance_check'):
self.model.on_post_performance_check()
model = self.__get_model()
model.on_post_performance_check()
except Exception as e:
print(e)
@@ -512,5 +863,6 @@ class Trainer(TrainerIO):
self.prog_bar.set_postfix(**tqdm_metrics)
# model checkpointing
print('save callback...')
self.checkpoint_callback.on_epoch_end(epoch=self.current_epoch, logs=self.__tng_tqdm_dic)
if self.proc_rank == 0 and self.checkpoint_callback:
print('save callback...')
self.checkpoint_callback.on_epoch_end(epoch=self.current_epoch, logs=self.__tng_tqdm_dic)
@@ -1,4 +1,7 @@
from torch.nn import DataParallel
from torch.nn.parallel import DistributedDataParallel
import itertools
from itertools import chain
import threading
import torch
@@ -6,6 +9,20 @@ from torch.cuda._utils import _get_device_index
import pdb
def _find_tensors(obj):
r"""
Recursively find all tensors contained in the specified object.
"""
if isinstance(obj, torch.Tensor):
return [obj]
if isinstance(obj, (list, tuple)):
return itertools.chain(*map(_find_tensors, obj))
if isinstance(obj, dict):
return itertools.chain(*map(_find_tensors, obj.values()))
return []
def get_a_var(obj):
if isinstance(obj, torch.Tensor):
return obj
@@ -26,10 +43,76 @@ class LightningDataParallel(DataParallel):
Override the forward call in lightning so it goes to training and validation step respectively
"""
def forward(self, *inputs, **kwargs):
if not self.device_ids:
return self.module(*inputs, **kwargs)
for t in chain(self.module.parameters(), self.module.buffers()):
if t.device != self.src_device_obj:
raise RuntimeError("module must have its parameters and buffers "
"on device {} (device_ids[0]) but found one of "
"them on device: {}".format(self.src_device_obj, t.device))
inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids)
if len(self.device_ids) == 1:
# lightning
if self.module.training:
return self.module.training_step(*inputs[0], **kwargs[0])
else:
return self.module.validation_step(*inputs[0], **kwargs[0])
replicas = self.replicate(self.module, self.device_ids[:len(inputs)])
outputs = self.parallel_apply(replicas, inputs, kwargs)
return self.gather(outputs, self.output_device)
def parallel_apply(self, replicas, inputs, kwargs):
return parallel_apply(replicas, inputs, kwargs, self.device_ids[:len(replicas)])
class LightningDistributedDataParallel(DistributedDataParallel):
"""
Override the forward call in lightning so it goes to training and validation step respectively
"""
def parallel_apply(self, replicas, inputs, kwargs):
return parallel_apply(replicas, inputs, kwargs, self.device_ids[:len(replicas)])
def forward(self, *inputs, **kwargs):
self._sync_params()
if self.device_ids:
inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids)
if len(self.device_ids) == 1:
# --------------
# LIGHTNING MOD
# --------------
# normal
# output = self.module(*inputs[0], **kwargs[0])
# lightning
if self.module.training:
output = self.module.training_step(*inputs[0], **kwargs[0])
else:
output = self.module.validation_step(*inputs[0], **kwargs[0])
else:
outputs = self.parallel_apply(self._module_copies[:len(inputs)], inputs, kwargs)
output = self.gather(outputs, self.output_device)
else:
output = self.module(*inputs, **kwargs)
if torch.is_grad_enabled():
# We'll return the output object verbatim since it is a freeform
# object. We need to find any tensors in this object, though,
# because we need to figure out which parameters were used during
# this forward pass, to ensure we short circuit reduction for any
# unused parameters. Only if `find_unused_parameters` is set.
if self.find_unused_parameters:
self.reducer.prepare_for_backward(list(_find_tensors(output)))
else:
self.reducer.prepare_for_backward([])
return output
def parallel_apply(modules, inputs, kwargs_tup=None, devices=None):
r"""Applies each `module` in :attr:`modules` in parallel on arguments
contained in :attr:`inputs` (positional) and :attr:`kwargs_tup` (keyword)
@@ -102,4 +185,4 @@ def parallel_apply(modules, inputs, kwargs_tup=None, devices=None):
if isinstance(output, Exception):
raise output
outputs.append(output)
return outputs
return outputs
+17
View File
@@ -19,3 +19,20 @@ class ModelHooks(torch.nn.Module):
def on_post_performance_check(self):
pass
def on_tng_metrics(self, metrics):
pass
def on_before_zero_grad(self, optimizer):
"""
Called after optimizer.step() and before optimizer.zero_grad()
for optimizer in optimizers:
optimizer.step()
model.on_before_zero_grad(optimizer) # < ---- called here
optimizer.zero_grad
:param optimizer:
:return:
"""
pass
+29 -2
View File
@@ -2,7 +2,7 @@ import torch
import os
import re
import pdb
from pytorch_lightning.pt_overrides.override_data_parallel import LightningDataParallel
from pytorch_lightning.pt_overrides.override_data_parallel import LightningDistributedDataParallel, LightningDataParallel
class ModelIO(object):
@@ -21,6 +21,23 @@ class ModelIO(object):
"""
raise NotImplementedError
# -------------------------
# OPTIONAL HOOKS
# -------------------------
def on_hpc_save(self):
"""
Hook to do whatever you need right before Slurm manager saves the model
:return:
"""
pass
def on_hpc_load(self):
"""
Hook to do whatever you need right before Slurm manager loads the model
:return:
"""
pass
class TrainerIO(object):
@@ -49,7 +66,8 @@ class TrainerIO(object):
checkpoint['optimizer_states'] = optimizer_states
# request what to save from the model
model = self.model.module if type(self.model) is LightningDataParallel else self.model
is_dp_module = type(self.model) is LightningDistributedDataParallel or type(self.model) is LightningDataParallel
model = self.model.module if is_dp_module else self.model
checkpoint_dict = model.get_save_dict()
# merge trainer and model saving items
@@ -107,12 +125,18 @@ class TrainerIO(object):
# save exp to make sure we get all the metrics
experiment.save()
# close experiment to avoid issues
experiment.close()
ckpt_number = self.max_ckpt_in_folder(folderpath) + 1
if not os.path.exists(folderpath):
os.makedirs(folderpath, exist_ok=True)
filepath = '{}/hpc_ckpt_{}.ckpt'.format(folderpath, ckpt_number)
# give model a chance to do something on hpc_save
self.on_hpc_save()
# request what to save from the model
checkpoint_dict = self.dump_checkpoint()
@@ -134,6 +158,9 @@ class TrainerIO(object):
model = self.model.module if type(self.model) is LightningDataParallel else self.model
model.load_model_specific(checkpoint)
# call model hook
self.on_hpc_load()
def max_ckpt_in_folder(self, path):
files = os.listdir(path)
files = [x for x in files if 'ckpt_' in x]
+3 -18
View File
@@ -9,7 +9,6 @@ from pytorch_lightning.root_module.optimization import OptimizerConfig
from pytorch_lightning.root_module.hooks import ModelHooks
class LightningModule(GradInformation, ModelIO, OptimizerConfig, ModelHooks):
def __init__(self, hparams):
@@ -21,28 +20,17 @@ class LightningModule(GradInformation, ModelIO, OptimizerConfig, ModelHooks):
self.current_epoch = 0
self.global_step = 0
self.loaded_optimizer_states_dict = {}
self.fast_dev_run = hparams.fast_dev_run
self.overfit = hparams.overfit
self.gradient_clip = hparams.gradient_clip
self.trainer = None
self.from_lightning = True
self.experiment = None
# track if gpu was requested for checkpointing
self.on_gpu = False
try:
self.on_gpu = hparams.on_gpu
except Exception as e:
pass
# computed vars for the dataloaders
self._tng_dataloader = None
self._val_dataloader = None
self._test_dataloader = None
if self.on_gpu:
print('running on gpu...')
torch.set_default_tensor_type(hparams.default_tensor_type)
def forward(self, *args, **kwargs):
"""
Expand model in into whatever you need.
@@ -90,7 +78,7 @@ class LightningModule(GradInformation, ModelIO, OptimizerConfig, ModelHooks):
:param logs:
:return:
"""
raise NotImplementedError
return logs
def loss(self, *args, **kwargs):
"""
@@ -104,9 +92,6 @@ class LightningModule(GradInformation, ModelIO, OptimizerConfig, ModelHooks):
model_summary = ModelSummary(self)
print(model_summary)
def nb_batches(self, dataloader):
a = math.ceil(float(len(dataloader.dataset) / self.batch_size))
return int(a)
def freeze(self):
for param in self.parameters():
@@ -144,7 +129,7 @@ class LightningModule(GradInformation, ModelIO, OptimizerConfig, ModelHooks):
def get_process_position(gpus):
try:
current_gpu = os.environ["CUDA_VISIBLE_DEVICES"]
gpu_ids = gpus.split(';')
gpu_ids = gpus.split(',')
process_position = gpu_ids.index(current_gpu)
return process_position, current_gpu
except Exception as e:
+2 -2
View File
@@ -39,8 +39,8 @@ def add_default_args(parser, root_dir, rand_seed=None, possible_model_names=None
parser.add_argument('--model_name', default='', help=','.join(possible_model_names))
# test_tube settings
parser.add_argument('-en', '--tt_name', default='r_lib_')
parser.add_argument('-td', '--tt_description', default='test research lib')
parser.add_argument('-en', '--tt_name', default='pt_test')
parser.add_argument('-td', '--tt_description', default='pytorch lightning test')
parser.add_argument('--tt_save_path', default=root_dir + '/test_tube_logs', help='logging dir')
parser.add_argument('--enable_single_run', dest='single_run', action='store_true')
parser.add_argument('--nb_hopt_trials', default=1, type=int)
+1 -1
View File
@@ -1,4 +1,3 @@
from matplotlib import pyplot as plt
import numpy as np
np.seterr(divide='ignore', invalid='ignore')
@@ -13,6 +12,7 @@ def plot_confusion_matrix(cm,
This function prints and plots the confusion matrix.
Normalization can be applied by setting `normalize=True`.
"""
from matplotlib import pyplot as plt
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
print("Normalized confusion matrix")
+11 -3
View File
@@ -1,8 +1,8 @@
atomicwrites==1.2.1
attrs==18.2.0
certifi==2018.11.29
cffi==1.11.5
h5py==2.9.0
imageio==2.4.1
mkl-fft==1.0.6
mkl-random==1.0.2
@@ -21,7 +21,15 @@ scikit-learn==0.20.2
scipy==1.2.0
six==1.12.0
sklearn==0.0
test-tube==0.6282
tensorboard==1.14.0
tensorboardX==1.7
tensorflow==1.14.0
test-tube==0.643
torch==1.0.0
torchvision==0.2.1
tqdm==4.28.1
tqdm==4.32.1
twine==1.13.0
urllib3==1.25.3
webencodings==0.5.1
Werkzeug==0.15.4
wrapt==1.11.2
+3 -3
View File
@@ -7,7 +7,7 @@ from setuptools import setup, find_packages
# http://blog.ionelmc.ro/2014/05/25/python-packaging/
setup(
name="pytorch-lightning",
version='0.112',
version='0.3.3',
description="The Keras for ML researchers using PyTorch",
author="William Falcon",
author_email="waf2107@columbia.edu",
@@ -17,9 +17,9 @@ setup(
keywords=["deep learning", "pytorch", "AI"],
python_requires=">=3.5",
install_requires=[
"torch>=1.0.0",
"torch>=1.1.0",
"tqdm",
"test-tube",
"test-tube>=0.6.7.1",
],
packages=find_packages(),
long_description=open("README.md", encoding="utf-8").read(),