From 5d307e08381f38ee57af66d615125de8afa2e9d8 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 21:22:18 +0200 Subject: [PATCH 01/24] use tox * update Travis * add Appveyor --- .travis.yml | 53 +++++++++++++++++++++++++++++++++--------- appveyor.yml | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tox.ini | 50 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 11 deletions(-) create mode 100644 appveyor.yml create mode 100644 tox.ini diff --git a/.travis.yml b/.travis.yml index d80b291f..51b99f89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,48 @@ +# vim ft=yaml + +# After changing this file, check it on: +# http://yaml-online-parser.appspot.com/ + +# See doc/travis_notes.txt for some guidelines + +# this file is *not* meant to cover or endorse the use of travis, but rather to +# help confirm pull requests to this project. + +dist: xenial # Ubuntu 16.04 + +env: + global: + - DISPLAY="" + language: python -python: - - "3.7" -# command to install dependencies + +matrix: + include: + - python: 3.5 + env: TOXENV=py35 + - python: 3.6 + env: TOXENV=py36 + - python: 3.7 + env: TOXENV=py37 + +# See http://docs.travis-ci.com/user/caching/#pip-cache cache: pip + install: - - pip install -e . + - sudo apt-get install python-opencv openslide-tools - pip install -r requirements.txt - - pip install -r tests/requirements.txt - - pip install -U numpy + - pip install -r ./tests/requirements.txt + - pip install tox + - pip --version ; pip list -# keep build from timing out -dist: xenial - -# command to run tests script: - - py.test -v # or py.test for Python versions 3.5 and below \ No newline at end of file + # integration + - tox --sitepackages + - python setup.py install --user --dry-run + +after_success: + - coverage report + - codecov + +notifications: + email: false diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..8e5e1414 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,65 @@ +# https://www.appveyor.com/docs/appveyor-yml/ +environment: + + # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the + # /E:ON and /V:ON options are not enabled in the batch script interpreter + # See: http://stackoverflow.com/a/13751649/163740 + CMD_IN_ENV: "cmd /E:ON /V:ON /C obvci_appveyor_python_build_env.cmd" + + matrix: + # Pre-installed Python versions, which Appveyor may upgrade to + # a later point release. + # See: http://www.appveyor.com/docs/installed-software#python + + + - PYTHON: "C:\\Python35-x64" + PYTHON_VERSION: "3.5.x" + PYTHON_ARCH: "64" + TOXENV: "py35" + + - PYTHON: "C:\\Python36-x64" + PYTHON_VERSION: "3.6.x" + PYTHON_ARCH: "64" + TOXENV: "py36" + + - PYTHON: "C:\\Python37-x64" + PYTHON_VERSION: "3.7.x" + PYTHON_ARCH: "64" + TOXENV: "py37" + +build: off + +# https://www.appveyor.com/docs/build-cache/ +cache: + - C:\ProgramData\chocolatey\bin -> appveyor.yml + - C:\ProgramData\chocolatey\lib -> appveyor.yml + - '%LOCALAPPDATA%\pip\Cache -> appveyor.yml' + +# scripts that run after cloning repository +install: + # If there is a newer build queued for the same PR, cancel this one. + # The AppVeyor 'rollout builds' option is supposed to serve the same + # purpose but it is problematic because it tends to cancel builds pushed + # directly to master instead of just PR builds (or the converse). + - choco upgrade chocolatey + - choco install -y opencv + - SET PATH=%PYTHON%;%PYTHON%\\Scripts;%path% + - pip install -U --user pip + - pip install -r requirements.txt + - pip install -r ./tests/requirements.txt + - pip install tox + +# scripts to run before tests (working directory and environment changes are persisted from the previous steps such as "before_build") +before_test: + - python --version + - pip --version + - pip list + - dir + +# to run your custom scripts instead of automatic tests +test_script: + - tox --sitepackages --parallel auto + +on_success: + - coverage report + - codecov diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..1c886cf8 --- /dev/null +++ b/tox.ini @@ -0,0 +1,50 @@ +# this file is *not* meant to cover or endorse the use of tox or pytest or testing in general, +# +# It's meant to show the use of: +# +# - check-manifest +# confirm items checked into vcs are in your segdist +# - python setup.py check +# confirm required package meta-data in setup.py +# - readme_renderer (when using a ReStructuredText README) +# confirms your long_description will render correctly on PyPI. +# +# and also to help confirm pull requests to this project. + +[tox] +envlist = py{35,36,37} + +[pytest] +log_cli = 0 +log_cli_level = CRITICAL +log_cli_format = %(message)s +log_file = pytest.log +log_file_level = DEBUG +log_file_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s) +log_file_date_format=%Y-%m-%d %H:%M:%S + +[testenv] +basepython = + py35: python3.5 + py36: python3.6 + py37: python3.7 +deps = + -r requirements.txt + -r ./tests/requirements.txt +commands = + check-manifest --ignore tox.ini + python setup.py check -m -s + coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules + flake8 . + +[flake8] +exclude = .tox,*.egg,build,temp +select = E,W,F +doctests = True +verbose = 2 +# https://pep8.readthedocs.io/en/latest/intro.html#error-codes +ignore = + E402 + E501 +format = pylint +max-line-length = 100 From 627ac0be32d37eca8de661ab3b9c292b5f113a54 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 22:01:45 +0200 Subject: [PATCH 02/24] fix tests req. --- tests/requirements.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/requirements.txt b/tests/requirements.txt index c16efc2a..dc667a09 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,2 +1,7 @@ -coverage==4.5.3 -pytest==5.0.1 +nose>=1.3.7 +coverage +codecov +pytest>=3.0.5 +pytest-cov +flake8 +check-manifest \ No newline at end of file From b4a17869240c2ddc2fb3207bd6f0bfc6db7725d2 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 22:02:05 +0200 Subject: [PATCH 03/24] add Codecov --- .codecov.yml | 42 ++++++++++++++++++++++++++++++++++++++++++ coverage.svg | 21 --------------------- 2 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 .codecov.yml delete mode 100644 coverage.svg diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 00000000..4870d144 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,42 @@ +#see https://github.com/codecov/support/wiki/Codecov-Yaml +codecov: + notify: + require_ci_to_pass: yes + +coverage: + precision: 0 # 2 = xx.xx%, 0 = xx% + round: nearest # how coverage is rounded: down/up/nearest + range: 40...100 # custom range of coverage colors from red -> yellow -> green + status: + # https://codecov.readme.io/v1.0/docs/commit-status + project: + default: + against: auto + target: 90% # specify the target coverage for each commit status + threshold: 20% # allow this little decrease on project + # https://github.com/codecov/support/wiki/Filtering-Branches + # branches: master + if_ci_failed: error + # https://github.com/codecov/support/wiki/Patch-Status + patch: + default: + against: auto + target: 40% # specify the target "X%" coverage to hit + # threshold: 50% # allow this much decrease on patch + changes: false + +parsers: + gcov: + branch_detection: + conditional: true + loop: true + macro: false + method: false + javascript: + enable_partials: false + +comment: + layout: header, diff + require_changes: false + behavior: default # update if exists else create new + # branches: * \ No newline at end of file diff --git a/coverage.svg b/coverage.svg deleted file mode 100644 index 6bfc8faf..00000000 --- a/coverage.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - coverage - coverage - 99% - 99% - - From 7bf7af5b43df7aac38fc352e5bfbfcec80754e4b Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 22:02:21 +0200 Subject: [PATCH 04/24] rename LICENSE --- LICENSE | 201 -------------------------------------------------------- 1 file changed, 201 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. From 34f0044bc584a6836166e20b606ae43252f5f326 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 22:02:48 +0200 Subject: [PATCH 05/24] update README use stick MD syntax --- README.md | 54 ++++++------------ docs/source/_static/lightning_logo_medium.png | Bin 0 -> 8543 bytes docs/source/_static/lightning_logo_small.png | Bin 0 -> 2643 bytes 3 files changed, 19 insertions(+), 35 deletions(-) create mode 100644 docs/source/_static/lightning_logo_medium.png create mode 100644 docs/source/_static/lightning_logo_small.png diff --git a/README.md b/README.md index 7542eeef..ca0ba4b0 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,21 @@ -

- - - -

-

- PyTorch Lightning -

-

- The PyTorch Keras for ML researchers. More control. Less boilerplate. -

+![Logo](./docs/source/_static/lightning_logo_medium.png) -

- PyPI version - PyPI version - Supported Python Version - - - - -

+# PyTorch Lightning +**The PyTorch Keras for ML researchers. More control. Less boilerplate.** + + +[![PyPI Status](https://badge.fury.io/py/pytorch-lightning.svg)](https://badge.fury.io/py/pytorch-lightning) +[![PyPI Status](https://pepy.tech/badge/pytorch-lightning)](https://pepy.tech/project/pytorch-lightning) +[![Build Status](https://travis-ci.org/williamFalcon/pytorch-lightning.svg?branch=master)](https://travis-ci.org/williamFalcon/pytorch-lightning) +[![Build status](https://ci.appveyor.com/api/projects/status/rum89d7hq8l1kfye?svg=true)](https://ci.appveyor.com/project/Borda/pytorch-lightning) +[![codecov](https://codecov.io/gh/Borda/pytorch-lightning/branch/master/graph/badge.svg)](https://codecov.io/gh/Borda/pytorch-lightning) +[![CodeFactor](https://www.codefactor.io/repository/github/borda/pytorch-lightning/badge)](https://www.codefactor.io/repository/github/borda/pytorch-lightning) +[![ReadTheDocs](https://readthedocs.org/projects/pytorch-lightning/badge/?version=latest)](https://pytorch-lightning.readthedocs.io/en/latest) +[![license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/williamFalcon/pytorch-lightning/blob/master/LICENSE) + + +Simple installation from PyPI ```bash pip install pytorch-lightning ``` @@ -137,11 +133,7 @@ print('and going to http://localhost:6006 on your browser') Everything in gray! You define the blue parts using the LightningModule interface: -

- - - -

+![Ouverview](./docs/source/_static/overview_flat.jpg) ```{.python} # what to do in the training loop @@ -223,19 +215,11 @@ def validation_end(self, outputs): ## Tensorboard Lightning is fully integrated with tensorboard. -

- - - -

+![tensorboard-support](./docs/source/_static/tf_loss.png) Lightning also adds a text column with all the hyperparameters for this experiment. -

- - - -

+![tensorboard-support](./docs/source/_static/tf_tags.png) Simply note the path you set for the Experiment ``` {.python} diff --git a/docs/source/_static/lightning_logo_medium.png b/docs/source/_static/lightning_logo_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..a28606b541632d4dbc96213d9e731d3c4636778c GIT binary patch literal 8543 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 aFaRP+5wK*-7wE%LfU2U_t6BxCu>S!pn_y`G literal 0 HcmV?d00001 diff --git a/docs/source/_static/lightning_logo_small.png b/docs/source/_static/lightning_logo_small.png new file mode 100644 index 0000000000000000000000000000000000000000..17d0aa92bce2bc4668dd455642253cfd1a2bf363 GIT binary patch literal 2643 zcmV-Z3as^sP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+MQNek|ZY#{pS=u0@@H9M`DTa4Sak*vZ_2i9pedy z$nJSXFn%2v>`#;JHtM~)B7CKROPMmxyobpb;K-3oBSBlOTRxqyB7BUzsi3-c+R{K(Jg3s z(GS1)(!!8ZL0)0PF@0!#!O2fTQ2q6|2(yS+*ZgN-MsH` zf=N&ZgV~5hxsZ~hG(^d`iBqTe_!o~)@=n-a52%J>y7Wu!uOITDSEhXYl5d{XFM;cI zsoI@{j2acE+ByoAgfwW7U3>r*aw-YAO{Kdq;o5zRtRczRoVF;A;2a;`D@C_QBH+TMEr!rpM|*w_sv;tff; zcW4NE^nQRZLG9|fr_G$LuUI3NYXjIpi^N($x6FAsPLA8uS~ov|HZ}(#>#d&!6phaU zJtlI5d};6=gNMPReT)!PqfFllWTrdC%puTu1kO_H>?a#T4KEzD5$S6z-WIcJu9aRu zm*<#cFI1%pr|PnC;Oy*e+w`NdmH|;8)Ma*{48!Ew$G+}5ZA2GEa>tTPpy{keavIG6 zUNy(s@PF+Vwt!>w+gvxG_iRhT5O1Bdfy1O(8hAdqnshzL)D2q-+AhP{aiV9FjO}zXgZCtN4@Ow(U=R22V71cuvx*{szFE(=vTBnG!5#z)#Jd+ zIZtZM;`JDtfv;RnKn=%E9vSL+Gp6ghVOk7q<821V6^R&q7&4M*Z{6snTpCp12YYAR zP%Soi^@VrIQKTARZumOb?x!wg&E~OAknE^|bn9TLS>L23EM(7Z4IIQ^cRMg1E)BVr zy9cH@^6a5=8R!|O`OdH@2)L2LcUX*aCS2i)EaU{TEL)h7!YCq>jVv^s&LFF=bJO7- zZ&LxWNZ;xk&{1Ej@a}NmV$Za71}&ebogG^Ry?Ti4)LTY*;23JGqRe7(+Zq)_rQvPv z3Xc-aaw-7Hc6ij4Q)qgk9BRM~!5Npw2o-bXoq9NOQ3hNprjmHpb_ynKtnDZJgh zK5L2@5acBSKH9?fQBV@2)EX=`ydNgg%Lh8`V(<7iL5+d^+6`S?@ZUn^MK?naYx5F@ zFNYjuqXb8lc2L+j#>CbLd7G$gQ3vVUyP;W z000DYLP=Bz2nYy#2xN!=00iqvL_t(&-qo7TZCALy z-g{l#*Jh@jQJA^Y!YpSp@BRJGdG5LAo*BumJ@=Q0+GNlM5FU@05tJCC$5bqy$4ESY z7&IbklZqq1Ld!Z%1KOySio7VnXoHC3$F4}!1s3vUJl~^I)=o{Rc8ga^xIa@Qd!m~U zZ@$TfEg8zi2vKfa_-)fJ7Mt1W0!L5xk{#%wybysgPN7xpio6w{=jfR}4!^e-qYXcP zG0fdxrwCI4#!>B1?ZReuy1=nB{Tv?Xp;EHQ+_;#-7`GeQZx=Sl&h(KT=pm|TyuhO{ zS7PwX5fbST9hpZDA*sS%74A3%{cyjq5(5d4#G<&IX+DpP@XV%3BpA9Lek4(+}R zZO(uwp;V~w%+{xP{r$ZdV^E$f6Ss)Z{Sr4X=SVti9a=L0R7#rloon$!4-9qdx(FC; z2$Mdq9Dk8QzGOGOtg-=PAWZq(8Jc8vvVbUQSl2}f$`cNq=;nVuhdLn_4rihO--4RMuqHr}^gd zUpRNkl71SuIvDid9 zAlVVvyThX}mCzaj&!b$bfHX#1S2Uu8pRe9wV&ooS!e3p4mYx&+N4jFA%SG8qg<^Pc zf{%}1!4JKr3z1U;B0_ng!iLTaJ9?kB?|EvucwaFxIKk=t=b8OGPmu7M?pECzP(m?Z zX6L>wJh3hrPa*1yKehi;W+w|II$FEvJ4Z+ab{%-$!fzUjpPS5+>Il&l-O_r#Q+$dR zpPl_%Y`u^1sTF^oxyb^_j*zHD@opz`N+=ep@v+y)M%cIz-Z&U#O~#lTiHRp1cfnr>>oL|y6K|ho5uhE002ovPDHLkV1i6- B5zYVr literal 0 HcmV?d00001 From 79f0856bc8e386e9acd7e0b6912ad767c778b7f1 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 22:19:55 +0200 Subject: [PATCH 06/24] update setup --- pytorch_lightning/__init__.py | 12 +++++++- setup.py | 52 ++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/pytorch_lightning/__init__.py b/pytorch_lightning/__init__.py index 4b5961ac..235590f2 100644 --- a/pytorch_lightning/__init__.py +++ b/pytorch_lightning/__init__.py @@ -1,3 +1,13 @@ from .models.trainer import Trainer from .root_module.root_module import LightningModule -from .root_module.decorators import data_loader \ No newline at end of file +from .root_module.decorators import data_loader + +__version__ = '0.3.6.9' +__author__ = "William Falcon", +__author_email__ = "waf2107@columbia.edu" +__license__ = 'MIT' +__homepage__ = 'https://github.com/williamFalcon/pytorch-lightning', +__copyright__ = 'Copyright (c) 2018-2019, %s.' % __author__ +__doc__ = """ +The Keras for ML researchers using PyTorch +""" diff --git a/setup.py b/setup.py index e680ef43..5f076a36 100755 --- a/setup.py +++ b/setup.py @@ -1,19 +1,28 @@ #!/usr/bin/env python -from setuptools import setup, find_packages +from setuptools import setup + +import pytorch_lightning # https://packaging.python.org/guides/single-sourcing-package-version/ # http://blog.ionelmc.ro/2014/05/25/python-packaging/ setup( name="pytorch-lightning", - version='0.3.6.9', - description="The Keras for ML researchers using PyTorch", - author="William Falcon", - author_email="waf2107@columbia.edu", - url="https://github.com/williamFalcon/pytorch-lightning", - download_url="https://github.com/williamFalcon/pytorch-lightning", - license="MIT", + version=pytorch_lightning.__version__, + description=pytorch_lightning.__doc__, + author=pytorch_lightning.__author__, + author_email=pytorch_lightning.__author_email__, + url=pytorch_lightning.__homepage__, + license=pytorch_lightning.__license__, + packages=['pytorch_lightning'], + + long_description=open("README.md", encoding="utf-8").read(), + long_description_content_type='text/markdown', + + include_package_data=True, + zip_safe=False, + keywords=["deep learning", "pytorch", "AI"], python_requires=">=3.5", install_requires=[ @@ -21,9 +30,26 @@ setup( "tqdm", "test-tube>=0.6.7.6", ], - packages=find_packages(), - long_description=open("README.md", encoding="utf-8").read(), - long_description_content_type='text/markdown', - include_package_data=True, - zip_safe=False, + + classifiers=[ + 'Environment :: Console', + 'Natural Language :: English', + # How mature is this project? Common values are + # 3 - Alpha, 4 - Beta, 5 - Production/Stable + 'Development Status :: 4 - Beta', + # Indicate who your project is intended for + 'Intended Audience :: Developers', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Scientific/Engineering :: Image Recognition', + 'Topic :: Scientific/Engineering :: Information Analysis', + # Pick your license as you wish + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + # Specify the Python versions you support here. In particular, ensure + # that you indicate whether you support Python 2, Python 3 or both. + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + ], ) From 0bfc99ad7ab0208941b0fcae46dc5f18bfb3bcbc Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 22:31:29 +0200 Subject: [PATCH 07/24] fix MANIFEST --- MANIFEST.in | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 53c1b220..e39ffbad 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,9 +1,36 @@ -graft docs +# Manifest syntax https://docs.python.org/2/distutils/sourcedist.html +graft wheelhouse -include COPYING -include AUTHORS +recursive-include birl *.py +recursive-exclude __pycache__ *.py[cod] *.orig -recursive-include src/einsteinpy/tests *.py *.html +# Include the README +include *.md -prune docs/source/examples/.ipynb_checkpoints -global-exclude *.py[cod] __pycache__ *.so *.dylib +# Include the license file +include LICENSE + +exclude *.sh +exclude *.toml +recursive-include examples *.py +recursive-include pytorch_lightning *.py + +# exclude tests from package +recursive-exclude tests * +exclude tests + +# Exclude the documentation files +recursive-exclude docs * +exclude docs + +# Include the Requirements +include requirements.txt + +# Exclude build configs +exclude *.yml + +prune .git +prune .github +prune notebook* +prune temp* +prune test* \ No newline at end of file From 50cca25d6f3378277ec7444397b9af85efd3b4cb Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 22:41:31 +0200 Subject: [PATCH 08/24] add missing req. --- .travis.yml | 1 - appveyor.yml | 2 -- requirements.txt | 1 + tests/requirements.txt | 3 ++- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 51b99f89..fdfa31be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,6 @@ matrix: cache: pip install: - - sudo apt-get install python-opencv openslide-tools - pip install -r requirements.txt - pip install -r ./tests/requirements.txt - pip install tox diff --git a/appveyor.yml b/appveyor.yml index 8e5e1414..ce284651 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -41,8 +41,6 @@ install: # The AppVeyor 'rollout builds' option is supposed to serve the same # purpose but it is problematic because it tends to cancel builds pushed # directly to master instead of just PR builds (or the converse). - - choco upgrade chocolatey - - choco install -y opencv - SET PATH=%PYTHON%;%PYTHON%\\Scripts;%path% - pip install -U --user pip - pip install -r requirements.txt diff --git a/requirements.txt b/requirements.txt index aba573c0..83e49f4a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ twine==1.13.0 numpy==1.16.4 torch>=1.1.0 torchvision==0.3.0 +pandas \ No newline at end of file diff --git a/tests/requirements.txt b/tests/requirements.txt index dc667a09..54c540cb 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -4,4 +4,5 @@ codecov pytest>=3.0.5 pytest-cov flake8 -check-manifest \ No newline at end of file +check-manifest +test_tube \ No newline at end of file From eacd93e2f05066c5ff7a89709ab9ec51bafbc607 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 23:28:04 +0200 Subject: [PATCH 09/24] fix rltv imports --- pytorch_lightning/models/__init__.py | 0 pytorch_lightning/models/trainer.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 pytorch_lightning/models/__init__.py diff --git a/pytorch_lightning/models/__init__.py b/pytorch_lightning/models/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pytorch_lightning/models/trainer.py b/pytorch_lightning/models/trainer.py index 2655809c..2a73d867 100644 --- a/pytorch_lightning/models/trainer.py +++ b/pytorch_lightning/models/trainer.py @@ -23,7 +23,7 @@ from ..utilities.debugging import MisconfigurationException try: from apex import amp APEX_AVAILABLE = True -except Exception: +except ImportError: APEX_AVAILABLE = False From c44966a8bf7c7baf401fb5214432bcf023d91590 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Mon, 5 Aug 2019 23:57:39 +0200 Subject: [PATCH 10/24] apply PEP8 --- examples/__init__.py | 6 ++- .../lightning_module_template.py | 13 +++--- .../trainer_cpu_template.py | 2 +- pytorch_lightning/__init__.py | 6 +++ pytorch_lightning/callbacks/__init__.py | 7 +++- pytorch_lightning/callbacks/pt_callbacks.py | 13 +++--- pytorch_lightning/models/trainer.py | 40 +++++++++---------- .../pt_overrides/override_data_parallel.py | 1 - pytorch_lightning/root_module/grads.py | 4 +- pytorch_lightning/root_module/hooks.py | 1 - pytorch_lightning/root_module/memory.py | 12 +++--- pytorch_lightning/root_module/root_module.py | 3 -- pytorch_lightning/testing/lm_test_module.py | 11 ++--- pytorch_lightning/utilities/arg_parse.py | 8 ++-- tests/debug.py | 4 +- tests/test_models.py | 9 ++--- 16 files changed, 74 insertions(+), 66 deletions(-) diff --git a/examples/__init__.py b/examples/__init__.py index 6743d7f9..0d456dac 100644 --- a/examples/__init__.py +++ b/examples/__init__.py @@ -1 +1,5 @@ -from .new_project_templates.lightning_module_template import LightningTemplateModel \ No newline at end of file +from .new_project_templates.lightning_module_template import LightningTemplateModel + +__all__ = [ + 'LightningTemplateModel' +] diff --git a/examples/new_project_templates/lightning_module_template.py b/examples/new_project_templates/lightning_module_template.py index 483a4e3a..a6550035 100644 --- a/examples/new_project_templates/lightning_module_template.py +++ b/examples/new_project_templates/lightning_module_template.py @@ -182,7 +182,7 @@ class LightningTemplateModel(LightningModule): 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: + except Exception: pass should_shuffle = train_sampler is None @@ -211,7 +211,7 @@ class LightningTemplateModel(LightningModule): return self.__dataloader(train=False) @staticmethod - def add_model_specific_args(parent_parser, root_dir): # pragma: no cover + def add_model_specific_args(parent_parser, root_dir): # pragma: no cover """ Parameters you define here will be available to your model through self.hparams :param parent_parser: @@ -224,20 +224,21 @@ class LightningTemplateModel(LightningModule): # parser.set_defaults(gradient_clip=5.0) # network params - parser.add_argument('--in_features', default=28*28, type=int) + 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 + # use 500 for CPU, 50000 for GPU to see speed difference + parser.add_argument('--hidden_dim', default=50000, type=int) parser.opt_list('--drop_prob', default=0.2, options=[0.2, 0.5], type=float, tunable=False) # 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*8, 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('--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, + 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 diff --git a/examples/new_project_templates/trainer_cpu_template.py b/examples/new_project_templates/trainer_cpu_template.py index de6ba7c4..21d705c6 100644 --- a/examples/new_project_templates/trainer_cpu_template.py +++ b/examples/new_project_templates/trainer_cpu_template.py @@ -67,7 +67,7 @@ if __name__ == '__main__': add_default_args(parent_parser, root_dir) # allow model to overwrite or extend args - parser = ExampleModel.add_model_specific_args(parent_parser) + parser = LightningTemplateModel.add_model_specific_args(parent_parser) hyperparams = parser.parse_args() # train model diff --git a/pytorch_lightning/__init__.py b/pytorch_lightning/__init__.py index 235590f2..145d3bd0 100644 --- a/pytorch_lightning/__init__.py +++ b/pytorch_lightning/__init__.py @@ -11,3 +11,9 @@ __copyright__ = 'Copyright (c) 2018-2019, %s.' % __author__ __doc__ = """ The Keras for ML researchers using PyTorch """ + +__all__ = [ + 'Trainer', + 'LightningModule', + 'data_loader', +] diff --git a/pytorch_lightning/callbacks/__init__.py b/pytorch_lightning/callbacks/__init__.py index f180c254..035deb06 100644 --- a/pytorch_lightning/callbacks/__init__.py +++ b/pytorch_lightning/callbacks/__init__.py @@ -1 +1,6 @@ -from .pt_callbacks import EarlyStopping, ModelCheckpoint \ No newline at end of file +from .pt_callbacks import EarlyStopping, ModelCheckpoint + +__all__ = [ + 'EarlyStopping', + 'ModelCheckpoint', +] diff --git a/pytorch_lightning/callbacks/pt_callbacks.py b/pytorch_lightning/callbacks/pt_callbacks.py index 89c8f6b2..f07c6a28 100644 --- a/pytorch_lightning/callbacks/pt_callbacks.py +++ b/pytorch_lightning/callbacks/pt_callbacks.py @@ -122,9 +122,9 @@ class EarlyStopping(Callback): current = logs.get(self.monitor) stop_training = False if current is None: - print('Early stopping conditioned on metric `%s` ''which is not available. Available metrics are: %s' % - (self.monitor, ','.join(list(logs.keys()))), RuntimeWarning - ) + print('Early stopping conditioned on metric `%s` ' + 'which is not available. Available metrics are: %s' % + (self.monitor, ','.join(list(logs.keys()))), RuntimeWarning) exit(-1) if self.monitor_op(current - self.min_delta, self.best): @@ -188,8 +188,7 @@ class ModelCheckpoint(Callback): if mode not in ['auto', 'min', 'max']: print('ModelCheckpoint mode %s is unknown, ' - 'fallback to auto mode.' % (mode), - RuntimeWarning) + 'fallback to auto mode.' % (mode), RuntimeWarning) mode = 'auto' if mode == 'min': @@ -233,8 +232,8 @@ class ModelCheckpoint(Callback): if self.save_best_only: current = logs.get(self.monitor) if current is None: - print('Can save best model only with %s available, ' - 'skipping.' % (self.monitor), RuntimeWarning) + print('Can save best model only with %s available,' + ' skipping.' % (self.monitor), RuntimeWarning) else: if self.monitor_op(current, self.best): if self.verbose > 0: diff --git a/pytorch_lightning/models/trainer.py b/pytorch_lightning/models/trainer.py index 2a73d867..c0f67d7a 100644 --- a/pytorch_lightning/models/trainer.py +++ b/pytorch_lightning/models/trainer.py @@ -1,12 +1,10 @@ """ The trainer handles all the logic for running a val loop, training loop, distributing, etc... """ -import subprocess -import traceback -import warnings + import os -import pdb import re +import warnings import numpy as np import tqdm @@ -201,7 +199,7 @@ class Trainer(TrainerIO): try: self.nb_slurm_tasks = int(os.environ['SLURM_NTASKS']) self.is_slurm_managing_tasks = self.nb_slurm_tasks == self.nb_requested_gpus - except Exception as e: + except Exception: # likely not on slurm, so set the slurm managed flag to false self.is_slurm_managing_tasks = False @@ -235,13 +233,13 @@ class Trainer(TrainerIO): print('using 16bit precision') if use_amp and not APEX_AVAILABLE: # pragma: no cover - msg = ''' + msg = """ You set use_amp=True but do not have apex installed. - Install apex first using this guide and rerun with use_amp=True: + 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 - ''' + """ raise ModuleNotFoundError(msg) @property @@ -275,7 +273,7 @@ class Trainer(TrainerIO): 'tng_loss': '{0:.3f}'.format(self.avg_loss), 'v_nb': '{}'.format(self.experiment.version), 'epoch': '{}'.format(self.current_epoch), - 'batch_nb':'{}'.format(self.batch_nb), + 'batch_nb': '{}'.format(self.batch_nb), } tqdm_dic.update(self.tqdm_metrics) @@ -389,18 +387,18 @@ class Trainer(TrainerIO): self.val_dataloader = model.val_dataloader if self.use_ddp and not isinstance(self.tng_dataloader.sampler, DistributedSampler): - msg = ''' + 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 MisconfigurationException(msg) # ----------------------------- @@ -418,8 +416,8 @@ class Trainer(TrainerIO): self.ddp_train(task, model) else: msg = f""" - You requested {self.nb_requested_gpus} GPUs but launched {self.nb_slurm_tasks} slurm tasks. - We will launch {self.nb_requested_gpus} processes for you. + You requested {self.nb_requested_gpus} GPUs but launched {self.nb_slurm_tasks} slurm tasks. + We will launch {self.nb_requested_gpus} processes for you. We recommend you let slurm manage the processes by setting: --ntasks-per-node={self.nb_requested_gpus} If you're not using SLURM, ignore this message! """ @@ -484,7 +482,7 @@ class Trainer(TrainerIO): try: node_id = os.environ['SLURM_NODEID'] self.node_rank = int(node_id) - except Exception as e: + except Exception: self.node_rank = 0 # recover original exp before went into process @@ -543,14 +541,14 @@ class Trainer(TrainerIO): # sets the appropriate port try: port = os.environ['MASTER_PORT'] - except Exception as e: + except Exception: port = 12910 os.environ['MASTER_PORT'] = f'{port}' # figure out the root node addr try: root_node = os.environ['SLURM_NODELIST'].split(' ')[0] - except Exception as e: + except Exception: root_node = '127.0.0.2' root_node = self.resolve_root_node_address(root_node) @@ -773,14 +771,14 @@ class Trainer(TrainerIO): try: model_specific_tqdm_metrics_dic = output['prog'] - except Exception as e: + except Exception: 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: + except Exception: if type(output) is torch.Tensor: loss = output diff --git a/pytorch_lightning/pt_overrides/override_data_parallel.py b/pytorch_lightning/pt_overrides/override_data_parallel.py index f06f8030..ab88d286 100644 --- a/pytorch_lightning/pt_overrides/override_data_parallel.py +++ b/pytorch_lightning/pt_overrides/override_data_parallel.py @@ -63,7 +63,6 @@ class LightningDataParallel(DataParallel): 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)]) diff --git a/pytorch_lightning/root_module/grads.py b/pytorch_lightning/root_module/grads.py index d50fa450..b28cf21c 100644 --- a/pytorch_lightning/root_module/grads.py +++ b/pytorch_lightning/root_module/grads.py @@ -4,6 +4,7 @@ Module to describe gradients from torch import nn + class GradInformation(nn.Module): def grad_norm(self, norm_type): @@ -17,11 +18,10 @@ class GradInformation(nn.Module): norm = param_norm ** (1 / norm_type) results['grad_{}_norm_{}'.format(norm_type, i)] = round(norm.data.cpu().numpy().flatten()[0], 3) - except Exception as e: + except Exception: # this param had no grad pass total_norm = total_norm ** (1. / norm_type) results['grad_{}_norm_total'.format(norm_type)] = round(total_norm.data.cpu().numpy().flatten()[0], 3) return results - diff --git a/pytorch_lightning/root_module/hooks.py b/pytorch_lightning/root_module/hooks.py index 849826a8..00ece234 100644 --- a/pytorch_lightning/root_module/hooks.py +++ b/pytorch_lightning/root_module/hooks.py @@ -43,4 +43,3 @@ class ModelHooks(torch.nn.Module): :return: """ pass - diff --git a/pytorch_lightning/root_module/memory.py b/pytorch_lightning/root_module/memory.py index 128fb16f..a0ec9aa0 100644 --- a/pytorch_lightning/root_module/memory.py +++ b/pytorch_lightning/root_module/memory.py @@ -94,7 +94,7 @@ class ModelSummary(object): mods = list(self.model.modules()) sizes = [] - for i in range(1,len(mods)): + for i in range(1, len(mods)): m = mods[i] p = list(m.parameters()) modsz = [] @@ -127,7 +127,7 @@ class ModelSummary(object): if self.model.example_input_array is not None: cols.extend(['In_sizes', 'Out_sizes']) - df = pd.DataFrame(np.zeros( (len(self.layer_names), len(cols)))) + df = pd.DataFrame(np.zeros((len(self.layer_names), len(cols)))) df.columns = cols df['Name'] = self.layer_names @@ -152,16 +152,16 @@ class ModelSummary(object): self.make_summary() -def print_mem_stack(): # pragma: no cover +def print_mem_stack(): # pragma: no cover for obj in gc.get_objects(): try: if torch.is_tensor(obj) or (hasattr(obj, 'data') and torch.is_tensor(obj.data)): print(type(obj), obj.size()) - except Exception as e: + except Exception: pass -def count_mem_items(): # pragma: no cover +def count_mem_items(): # pragma: no cover nb_params = 0 nb_tensors = 0 for obj in gc.get_objects(): @@ -172,7 +172,7 @@ def count_mem_items(): # pragma: no cover nb_params += 1 else: nb_tensors += 1 - except Exception as e: + except Exception: pass return nb_params, nb_tensors diff --git a/pytorch_lightning/root_module/root_module.py b/pytorch_lightning/root_module/root_module.py index 1421a72d..96dbfdcd 100644 --- a/pytorch_lightning/root_module/root_module.py +++ b/pytorch_lightning/root_module/root_module.py @@ -129,6 +129,3 @@ class LightningModule(GradInformation, ModelIO, ModelHooks): def unfreeze(self): for param in self.parameters(): param.requires_grad = True - - - diff --git a/pytorch_lightning/testing/lm_test_module.py b/pytorch_lightning/testing/lm_test_module.py index 9861810e..24995c7f 100644 --- a/pytorch_lightning/testing/lm_test_module.py +++ b/pytorch_lightning/testing/lm_test_module.py @@ -202,7 +202,7 @@ class LightningTestModel(LightningModule): if self.on_gpu and not self.force_remove_distributed_sampler: train_sampler = DistributedSampler(dataset, rank=self.trainer.proc_rank) batch_size = batch_size // self.trainer.world_size # scale batch size - except Exception as e: + except Exception: pass should_shuffle = train_sampler is None @@ -242,19 +242,20 @@ class LightningTestModel(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, type=int) + 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 + # use 500 for CPU, 50000 for GPU to see speed difference + parser.add_argument('--hidden_dim', default=50000, type=int) # 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*8, 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('--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, + 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 diff --git a/pytorch_lightning/utilities/arg_parse.py b/pytorch_lightning/utilities/arg_parse.py index f274e751..44399c39 100644 --- a/pytorch_lightning/utilities/arg_parse.py +++ b/pytorch_lightning/utilities/arg_parse.py @@ -3,6 +3,9 @@ List of default args which mught be useful for all the available flags Might need to update with the new flags """ +import os + + def add_default_args(parser, root_dir, rand_seed=None, possible_model_names=None): # tng, test, val check intervals @@ -44,7 +47,7 @@ def add_default_args(parser, root_dir, rand_seed=None, possible_model_names=None # test_tube settings 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('--tt_save_path', default=os.path.join(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) parser.add_argument('--log_stdout', dest='log_stdout', action='store_true') @@ -55,8 +58,7 @@ def add_default_args(parser, root_dir, rand_seed=None, possible_model_names=None parser.add_argument('--default_tensor_type', default='torch.cuda.FloatTensor', type=str) parser.add_argument('--use_amp', dest='use_amp', action='store_true') parser.add_argument('--check_grad_nans', dest='check_grad_nans', action='store_true') - parser.add_argument('--amp_level', default='O2',type=str) - + parser.add_argument('--amp_level', default='O2', type=str) # run on hpc parser.add_argument('--on_cluster', dest='on_cluster', action='store_true') diff --git a/tests/debug.py b/tests/debug.py index 09e9186b..fb0109a0 100644 --- a/tests/debug.py +++ b/tests/debug.py @@ -61,8 +61,8 @@ def get_model(): root_dir = os.path.dirname(os.path.realpath(__file__)) hparams = Namespace(**{'drop_prob': 0.2, 'batch_size': 32, - 'in_features': 28*28, - 'learning_rate': 0.001*8, + 'in_features': 28 * 28, + 'learning_rate': 0.001 * 8, 'optimizer_name': 'adam', 'data_root': os.path.join(root_dir, 'mnist'), 'out_features': 10, diff --git a/tests/test_models.py b/tests/test_models.py index 73ba2e43..fbf36442 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -136,11 +136,9 @@ def test_cpu_slurm_save_load(): def test_loading_meta_tags(): hparams = get_hparams() - save_dir = init_save_dir() - # save tags exp = get_exp(False) - exp.tag({'some_str':'a_str', 'an_int': 1, 'a_float': 2.0}) + exp.tag({'some_str': 'a_str', 'an_int': 1, 'a_float': 2.0}) exp.argparse(hparams) exp.save() @@ -502,7 +500,6 @@ def test_multi_gpu_model_ddp(): run_gpu_model_test(trainer_options, model, hparams) - def test_ddp_sampler_error(): """ Make sure DDP + AMP work @@ -587,8 +584,8 @@ def get_hparams(continue_training=False, hpc_exp_number=0): args = { 'drop_prob': 0.2, 'batch_size': 32, - 'in_features': 28*28, - 'learning_rate': 0.001*8, + 'in_features': 28 * 28, + 'learning_rate': 0.001 * 8, 'optimizer_name': 'adam', 'data_root': os.path.join(root_dir, 'mnist'), 'out_features': 10, From 778149735c1c36869f8b3efe2050edf1b19ccd0e Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Tue, 6 Aug 2019 00:12:19 +0200 Subject: [PATCH 11/24] fix tests --- .travis.yml | 2 +- pytorch_lightning/models/trainer.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index fdfa31be..3382c5d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,7 @@ install: script: # integration - tox --sitepackages - - python setup.py install --user --dry-run + - python setup.py install --dry-run after_success: - coverage report diff --git a/pytorch_lightning/models/trainer.py b/pytorch_lightning/models/trainer.py index c0f67d7a..b07b1808 100644 --- a/pytorch_lightning/models/trainer.py +++ b/pytorch_lightning/models/trainer.py @@ -172,7 +172,7 @@ class Trainer(TrainerIO): # 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"]}') + print('VISIBLE GPUS: %r' % os.environ["CUDA_VISIBLE_DEVICES"]) # make DP and DDP mutually exclusive # single GPU will also use DP with devices=[0] @@ -415,12 +415,12 @@ class Trainer(TrainerIO): task = int(os.environ['SLURM_LOCALID']) self.ddp_train(task, model) else: - msg = f""" - You requested {self.nb_requested_gpus} GPUs but launched {self.nb_slurm_tasks} slurm tasks. - We will launch {self.nb_requested_gpus} processes for you. - We recommend you let slurm manage the processes by setting: --ntasks-per-node={self.nb_requested_gpus} + msg = """ + You requested %(nb_gpus)s GPUs but launched %(nb_tasks)s slurm tasks. + We will launch %(nb_gpus)s processes for you. + We recommend you let slurm manage the processes by setting: --ntasks-per-node=%(nb_gpus)s If you're not using SLURM, ignore this message! - """ + """ % {'nb_gpus': self.nb_requested_gpus, 'nb_tasks': self.nb_slurm_tasks} warnings.warn(msg) mp.spawn(self.ddp_train, nprocs=len(self.data_parallel_device_ids), args=(model, )) From a8f07adfe96521a24cc862f1f1b5d2e747211926 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Mon, 5 Aug 2019 16:08:08 -0400 Subject: [PATCH 12/24] MIT -> apache 2 license --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 632d07b4906468fe574a5fbe8a7e832f50c74a74 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Tue, 6 Aug 2019 00:47:39 +0200 Subject: [PATCH 13/24] fix prints for py3.5 --- README.md | 4 ++-- docs/Trainer/Distributed training.md | 2 +- examples/new_project_templates/single_cpu_template.py | 2 +- .../single_gpu_node_16bit_template.py | 2 +- .../single_gpu_node_ddp_template.py | 2 +- .../single_gpu_node_dp_template.py | 2 +- pytorch_lightning/models/trainer.py | 10 ++++++---- pytorch_lightning/root_module/memory.py | 2 +- tests/debug.py | 2 +- tests/test_models.py | 4 ++-- 10 files changed, 17 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ca0ba4b0..2d1914ff 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Logo](./docs/source/_static/lightning_logo_medium.png) +![Logo](./docs/source/_static/lightning_logo_small.png) # PyTorch Lightning @@ -123,7 +123,7 @@ trainer = Trainer(experiment=exp, max_nb_epochs=1, train_percent_check=0.1) trainer.fit(model) # view tensorflow logs -print(f'View tensorboard logs by running\ntensorboard --logdir {os.getcwd()}') +print('View tensorboard logs by running\ntensorboard --logdir %s' % os.getcwd()) print('and going to http://localhost:6006 on your browser') ``` diff --git a/docs/Trainer/Distributed training.md b/docs/Trainer/Distributed training.md index aedbd20e..cafc719d 100644 --- a/docs/Trainer/Distributed training.md +++ b/docs/Trainer/Distributed training.md @@ -94,7 +94,7 @@ cluster.add_command('export NCCL_SOCKET_IFNAME=^docker0,lo') cluster.add_command('export NCCL_DEBUG=INFO') # setting a master port here is a good idea. -cluster.add_command(f'export MASTER_PORT={PORT}') +cluster.add_command('export MASTER_PORT=%r' % PORT) # good to load the latest NCCL version cluster.load_modules(['NCCL/2.4.7-1-cuda.10.0']) diff --git a/examples/new_project_templates/single_cpu_template.py b/examples/new_project_templates/single_cpu_template.py index 29c25598..c9ad4435 100644 --- a/examples/new_project_templates/single_cpu_template.py +++ b/examples/new_project_templates/single_cpu_template.py @@ -102,5 +102,5 @@ if __name__ == '__main__': # RUN TRAINING # --------------------- # run on HPC cluster - print(f'RUNNING ON CPU') + print('RUNNING ON CPU') main(hyperparams) diff --git a/examples/new_project_templates/single_gpu_node_16bit_template.py b/examples/new_project_templates/single_gpu_node_16bit_template.py index 14db484e..c2bf6674 100644 --- a/examples/new_project_templates/single_gpu_node_16bit_template.py +++ b/examples/new_project_templates/single_gpu_node_16bit_template.py @@ -105,5 +105,5 @@ if __name__ == '__main__': # RUN TRAINING # --------------------- # run on HPC cluster - print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {hyperparams.gpus}') + print('RUNNING INTERACTIVE MODE ON GPUS. gpu ids: %i' % hyperparams.gpus) main(hyperparams) diff --git a/examples/new_project_templates/single_gpu_node_ddp_template.py b/examples/new_project_templates/single_gpu_node_ddp_template.py index 56e301b2..358b8c94 100644 --- a/examples/new_project_templates/single_gpu_node_ddp_template.py +++ b/examples/new_project_templates/single_gpu_node_ddp_template.py @@ -105,5 +105,5 @@ if __name__ == '__main__': # RUN TRAINING # --------------------- # run on HPC cluster - print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {hyperparams.gpus}') + print('RUNNING INTERACTIVE MODE ON GPUS. gpu ids: %i' % hyperparams.gpus) main(hyperparams) diff --git a/examples/new_project_templates/single_gpu_node_dp_template.py b/examples/new_project_templates/single_gpu_node_dp_template.py index 9d699253..65692441 100644 --- a/examples/new_project_templates/single_gpu_node_dp_template.py +++ b/examples/new_project_templates/single_gpu_node_dp_template.py @@ -104,5 +104,5 @@ if __name__ == '__main__': # RUN TRAINING # --------------------- # run on HPC cluster - print(f'RUNNING INTERACTIVE MODE ON GPUS. gpu ids: {hyperparams.gpus}') + print('RUNNING INTERACTIVE MODE ON GPUS. gpu ids: %i' % hyperparams.gpus) main(hyperparams) diff --git a/pytorch_lightning/models/trainer.py b/pytorch_lightning/models/trainer.py index b07b1808..7d2a925c 100644 --- a/pytorch_lightning/models/trainer.py +++ b/pytorch_lightning/models/trainer.py @@ -460,9 +460,11 @@ class Trainer(TrainerIO): # check for this bug (amp + dp + !01 doesn't work) # https://github.com/NVIDIA/apex/issues/227 if self.use_dp and self.use_amp: - m = f'amp level {self.amp_level} with DataParallel is not supported. ' \ - f'See this note from NVIDIA for more info: https://github.com/NVIDIA/apex/issues/227. ' \ - f'We recommend you switch to ddp if you want to use amp' + m = """ + Amp level %r with DataParallel is not supported. + See this note from NVIDIA for more info: https://github.com/NVIDIA/apex/issues/227. + We recommend you switch to ddp if you want to use amp + """ % self.amp_level raise MisconfigurationException(m) model = LightningDataParallel(model, device_ids=self.data_parallel_device_ids) @@ -543,7 +545,7 @@ class Trainer(TrainerIO): port = os.environ['MASTER_PORT'] except Exception: port = 12910 - os.environ['MASTER_PORT'] = f'{port}' + os.environ['MASTER_PORT'] = str(port) # figure out the root node addr try: diff --git a/pytorch_lightning/root_module/memory.py b/pytorch_lightning/root_module/memory.py index a0ec9aa0..3a636b04 100644 --- a/pytorch_lightning/root_module/memory.py +++ b/pytorch_lightning/root_module/memory.py @@ -196,6 +196,6 @@ def get_gpu_memory_map(): gpu_memory = [int(x) for x in result.strip().split('\n')] gpu_memory_map = {} for k, v in zip(range(len(gpu_memory)), gpu_memory): - k = f'gpu_{k}' + k = 'gpu_%i' % k gpu_memory_map[k] = v return gpu_memory_map diff --git a/tests/debug.py b/tests/debug.py index fb0109a0..d068e63e 100644 --- a/tests/debug.py +++ b/tests/debug.py @@ -132,7 +132,7 @@ def run_prediction(dataloader, trained_model): print(val_acc) - assert val_acc > 0.70, f'this model is expected to get > 0.7 in test set (it got {val_acc})' + assert val_acc > 0.70, 'this model is expected to get > 0.7 in test set (it got %f)' % val_acc def main(): diff --git a/tests/test_models.py b/tests/test_models.py index fbf36442..59c4577a 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -670,13 +670,13 @@ def run_prediction(dataloader, trained_model): print(val_acc) - assert val_acc > 0.50, f'this model is expected to get > 0.50 in test set (it got {val_acc})' + assert val_acc > 0.50, 'this model is expected to get > 0.50 in test set (it got %f)' % val_acc def assert_ok_acc(trainer): # this model should get 0.80+ acc acc = trainer.tng_tqdm_dic['val_acc'] - assert acc > 0.50, f'model failed to get expected 0.50 validation accuracy. Got: {acc}' + assert acc > 0.50, 'model failed to get expected 0.50 validation accuracy. Got: %f' % acc if __name__ == '__main__': From 4e0b9c50e71bc06c57c14d7c952782fe5b7a2710 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Tue, 6 Aug 2019 10:46:14 +0200 Subject: [PATCH 14/24] add CircleCI --- .circleci/config.yml | 60 ++++++++++++++++++++++++++++++++++++++++++ .travis.yml | 1 - MANIFEST.in | 2 ++ appveyor.yml | 1 - tests/requirements.txt | 2 +- tox.ini | 3 --- update.sh | 3 --- 7 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..87555253 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,60 @@ +version: 2.0 + +references: + + install_pips: &install_pips + run: + name: Install PyPI dependences + command: | + pip install -r requirements.txt --user + sudo pip install -r ./tests/requirements.txt + python --version ; pwd ; ls -l + pip --version ; pip list + + test_coverage: &test_coverage + run: + name: Testing and Formating + command: | + check-manifest --ignore tox.ini + python setup.py check -m -s + coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules + flake8 . --max-line-length=100 + codecov + +jobs: + + Py3.6: + docker: + - image: circleci/python:3.6 + steps: &steps + - checkout + # INSTALLATION + - *install_pips + # TESTING + - *test_coverage + # DOCUMENTATION + + # PASSING + - run: + name: Finalise + command: | + python setup.py install --user + coverage report && coverage xml -o test-reports/coverage.xml + # RESULTS + - store_test_results: + path: test-reports + - store_artifacts: + path: test-reports + + Py3.7: + docker: + - image: circleci/python:3.7 + steps: *steps + + +workflows: + version: 2 + build: + jobs: + - Py3.6 + - Py3.7 diff --git a/.travis.yml b/.travis.yml index 3382c5d6..d601362e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,6 @@ cache: pip install: - pip install -r requirements.txt - pip install -r ./tests/requirements.txt - - pip install tox - pip --version ; pip list script: diff --git a/MANIFEST.in b/MANIFEST.in index e39ffbad..b16540b8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -27,10 +27,12 @@ exclude docs include requirements.txt # Exclude build configs +recursive-exclude .circleci * exclude *.yml prune .git prune .github +prune .circleci prune notebook* prune temp* prune test* \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index ce284651..40379cc5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -45,7 +45,6 @@ install: - pip install -U --user pip - pip install -r requirements.txt - pip install -r ./tests/requirements.txt - - pip install tox # scripts to run before tests (working directory and environment changes are persisted from the previous steps such as "before_build") before_test: diff --git a/tests/requirements.txt b/tests/requirements.txt index 54c540cb..076bfd65 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,4 +1,4 @@ -nose>=1.3.7 +tox coverage codecov pytest>=3.0.5 diff --git a/tox.ini b/tox.ini index 1c886cf8..a91ac5ef 100644 --- a/tox.ini +++ b/tox.ini @@ -43,8 +43,5 @@ select = E,W,F doctests = True verbose = 2 # https://pep8.readthedocs.io/en/latest/intro.html#error-codes -ignore = - E402 - E501 format = pylint max-line-length = 100 diff --git a/update.sh b/update.sh index 4eaf1149..40fcc22d 100644 --- a/update.sh +++ b/update.sh @@ -11,10 +11,7 @@ rm -rf ./dist/* python3 setup.py sdist twine upload dist/* - - # to update docs # cd to root dir # mkdocs gh-deploy - From d9bfe964f9ab10e6f4cf94c918426ee79cbfe2a9 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Tue, 6 Aug 2019 12:08:31 +0200 Subject: [PATCH 15/24] update by flake8 --- .circleci/config.yml | 2 +- README.md | 1 + .../lightning_module_template.py | 26 +++-- .../multi_node_cluster_template.py | 34 ++++--- .../single_cpu_template.py | 13 ++- .../single_gpu_node_16bit_template.py | 17 ++-- .../single_gpu_node_ddp_template.py | 17 ++-- .../single_gpu_node_dp_template.py | 17 ++-- pytorch_lightning/models/trainer.py | 95 +++++++++++-------- pytorch_lightning/root_module/grads.py | 6 +- pytorch_lightning/root_module/model_saving.py | 6 +- pytorch_lightning/testing/lm_test_module.py | 26 +++-- pytorch_lightning/utilities/arg_parse.py | 54 +++++++---- tests/debug.py | 3 +- tests/test_models.py | 39 +++++--- 15 files changed, 226 insertions(+), 130 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 87555253..71d3c14c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ references: check-manifest --ignore tox.ini python setup.py check -m -s coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules - flake8 . --max-line-length=100 + flake8 . --max-line-length=120 codecov jobs: diff --git a/README.md b/README.md index 2d1914ff..bbe110ba 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ [![PyPI Status](https://badge.fury.io/py/pytorch-lightning.svg)](https://badge.fury.io/py/pytorch-lightning) [![PyPI Status](https://pepy.tech/badge/pytorch-lightning)](https://pepy.tech/project/pytorch-lightning) [![Build Status](https://travis-ci.org/williamFalcon/pytorch-lightning.svg?branch=master)](https://travis-ci.org/williamFalcon/pytorch-lightning) +[![CircleCI](https://circleci.com/gh/Borda/pytorch-lightning.svg?style=svg)](https://circleci.com/gh/Borda/pytorch-lightning) [![Build status](https://ci.appveyor.com/api/projects/status/rum89d7hq8l1kfye?svg=true)](https://ci.appveyor.com/project/Borda/pytorch-lightning) [![codecov](https://codecov.io/gh/Borda/pytorch-lightning/branch/master/graph/badge.svg)](https://codecov.io/gh/Borda/pytorch-lightning) [![CodeFactor](https://www.codefactor.io/repository/github/borda/pytorch-lightning/badge)](https://www.codefactor.io/repository/github/borda/pytorch-lightning) diff --git a/examples/new_project_templates/lightning_module_template.py b/examples/new_project_templates/lightning_module_template.py index a6550035..d6bdd130 100644 --- a/examples/new_project_templates/lightning_module_template.py +++ b/examples/new_project_templates/lightning_module_template.py @@ -47,11 +47,13 @@ class LightningTemplateModel(LightningModule): Layout model :return: """ - self.c_d1 = nn.Linear(in_features=self.hparams.in_features, out_features=self.hparams.hidden_dim) + self.c_d1 = nn.Linear(in_features=self.hparams.in_features, + out_features=self.hparams.hidden_dim) self.c_d1_bn = nn.BatchNorm1d(self.hparams.hidden_dim) self.c_d1_drop = nn.Dropout(self.hparams.drop_prob) - self.c_d2 = nn.Linear(in_features=self.hparams.hidden_dim, out_features=self.hparams.out_features) + self.c_d2 = nn.Linear(in_features=self.hparams.hidden_dim, + out_features=self.hparams.out_features) # --------------------- # TRAINING @@ -171,8 +173,10 @@ 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) + transform = transforms.Compose([transforms.ToTensor(), + transforms.Normalize((0.5,), (1.0,))]) + dataset = MNIST(root=self.hparams.data_root, train=train, + transform=transform, download=True) # when using multi-node we need to add the datasampler train_sampler = None @@ -234,11 +238,15 @@ class LightningTemplateModel(LightningModule): 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 * 8, 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('--optimizer_name', default='adam', type=str, options=['adam'], 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') + # 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 gpus being used across all nodes') return parser diff --git a/examples/new_project_templates/multi_node_cluster_template.py b/examples/new_project_templates/multi_node_cluster_template.py index 5f6914d1..cdbda003 100644 --- a/examples/new_project_templates/multi_node_cluster_template.py +++ b/examples/new_project_templates/multi_node_cluster_template.py @@ -10,12 +10,12 @@ from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint +from .lightning_module_template import LightningTemplateModel + SEED = 2334 torch.manual_seed(SEED) np.random.seed(SEED) -from .lightning_module_template import LightningTemplateModel - def main_local(hparams): main(hparams, None, None) @@ -112,8 +112,10 @@ def optimize_on_cluster(hyperparams): 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') + 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 @@ -140,15 +142,23 @@ if __name__ == '__main__': 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('--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') + 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) diff --git a/examples/new_project_templates/single_cpu_template.py b/examples/new_project_templates/single_cpu_template.py index c9ad4435..9822f216 100644 --- a/examples/new_project_templates/single_cpu_template.py +++ b/examples/new_project_templates/single_cpu_template.py @@ -9,12 +9,12 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint +from .lightning_module_template import LightningTemplateModel + SEED = 2334 torch.manual_seed(SEED) np.random.seed(SEED) -from .lightning_module_template import LightningTemplateModel - def main(hparams): """ @@ -90,9 +90,12 @@ if __name__ == '__main__': 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') + 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) diff --git a/examples/new_project_templates/single_gpu_node_16bit_template.py b/examples/new_project_templates/single_gpu_node_16bit_template.py index c2bf6674..137f0e48 100644 --- a/examples/new_project_templates/single_gpu_node_16bit_template.py +++ b/examples/new_project_templates/single_gpu_node_16bit_template.py @@ -9,12 +9,12 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint +from .lightning_module_template import LightningTemplateModel + SEED = 2334 torch.manual_seed(SEED) np.random.seed(SEED) -from .lightning_module_template import LightningTemplateModel - def main(hparams): """ @@ -92,10 +92,15 @@ if __name__ == '__main__': 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') + parent_parser.add_argument('--gpus', type=str, default='-1', + help='how many gpus to use in the node.' + 'value -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) diff --git a/examples/new_project_templates/single_gpu_node_ddp_template.py b/examples/new_project_templates/single_gpu_node_ddp_template.py index 358b8c94..e8f46012 100644 --- a/examples/new_project_templates/single_gpu_node_ddp_template.py +++ b/examples/new_project_templates/single_gpu_node_ddp_template.py @@ -9,12 +9,12 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint +from .lightning_module_template import LightningTemplateModel + SEED = 2334 torch.manual_seed(SEED) np.random.seed(SEED) -from .lightning_module_template import LightningTemplateModel - def main(hparams): """ @@ -92,10 +92,15 @@ if __name__ == '__main__': 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') + parent_parser.add_argument('--gpus', type=str, default='-1', + help='how many gpus to use in the node.' + ' value -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) diff --git a/examples/new_project_templates/single_gpu_node_dp_template.py b/examples/new_project_templates/single_gpu_node_dp_template.py index 65692441..f48df5ca 100644 --- a/examples/new_project_templates/single_gpu_node_dp_template.py +++ b/examples/new_project_templates/single_gpu_node_dp_template.py @@ -9,12 +9,12 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint +from .lightning_module_template import LightningTemplateModel + SEED = 2334 torch.manual_seed(SEED) np.random.seed(SEED) -from .lightning_module_template import LightningTemplateModel - def main(hparams): """ @@ -91,10 +91,15 @@ if __name__ == '__main__': 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') + parent_parser.add_argument('--gpus', type=str, default='-1', + help='how many gpus to use in the node.' + ' value -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) diff --git a/pytorch_lightning/models/trainer.py b/pytorch_lightning/models/trainer.py index 7d2a925c..e23dfa0b 100644 --- a/pytorch_lightning/models/trainer.py +++ b/pytorch_lightning/models/trainer.py @@ -15,7 +15,8 @@ import torch.distributed as dist from ..root_module.memory import get_gpu_memory_map from ..root_module.model_saving import TrainerIO -from ..pt_overrides.override_data_parallel import LightningDistributedDataParallel, LightningDataParallel +from ..pt_overrides.override_data_parallel import ( + LightningDistributedDataParallel, LightningDataParallel) from ..utilities.debugging import MisconfigurationException try: @@ -64,17 +65,20 @@ class Trainer(TrainerIO): check_val_every_n_epoch=1, fast_dev_run=False, accumulate_grad_batches=1, - max_nb_epochs=1000, min_nb_epochs=1, - train_percent_check=1.0, val_percent_check=1.0, test_percent_check=1.0, + 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, + log_save_interval=100, + add_log_row_interval=10, 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 @@ -100,16 +104,15 @@ class Trainer(TrainerIO): :param val_check_interval: :param log_save_interval: :param add_log_row_interval: - :param distributed_backend: 'np' to use DistributedParallel, 'ddp' to use DistributedDataParallel + :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 @@ -171,13 +174,13 @@ class Trainer(TrainerIO): # 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]) + os.environ["CUDA_VISIBLE_DEVICES"] = ','.join([str(x) for x in + self.data_parallel_device_ids]) print('VISIBLE GPUS: %r' % 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: + if self.data_parallel_device_ids: self.use_dp = distributed_backend == 'dp' self.use_ddp = distributed_backend == 'ddp' @@ -224,7 +227,8 @@ class Trainer(TrainerIO): self.val_dataloader = None # how much of the data to use - self.__determine_data_use_amount(train_percent_check, val_percent_check, test_percent_check, overfit_pct) + 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)) # 16 bit mixed precision training using apex @@ -246,7 +250,8 @@ class Trainer(TrainerIO): 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): + def __determine_data_use_amount(self, train_percent_check, val_percent_check, + test_percent_check, overfit_pct): """ Use less data for debugging purposes """ @@ -388,17 +393,18 @@ class Trainer(TrainerIO): 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). +when using multiple gpus and multiple nodes you must pass + a DistributedSampler to DataLoader(sampler). - ie: this: - dataset = myDataset() - dataloader = Dataloader(dataset) +ie: this: +dataset = myDataset() +dataloader = Dataloader(dataset) - becomes: - dataset = myDataset() - dist_sampler = torch.utils.data.distributed.DistributedSampler(dataset) - dataloader = Dataloader(dataset, sampler=dist_sampler) - """ +becomes: +dataset = myDataset() +dist_sampler = torch.utils.data.distributed.DistributedSampler(dataset) +dataloader = Dataloader(dataset, sampler=dist_sampler) +""" raise MisconfigurationException(msg) # ----------------------------- @@ -408,7 +414,8 @@ class Trainer(TrainerIO): # 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 + # 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() if self.is_slurm_managing_tasks: @@ -416,11 +423,11 @@ class Trainer(TrainerIO): self.ddp_train(task, model) else: msg = """ - You requested %(nb_gpus)s GPUs but launched %(nb_tasks)s slurm tasks. - We will launch %(nb_gpus)s processes for you. - We recommend you let slurm manage the processes by setting: --ntasks-per-node=%(nb_gpus)s - If you're not using SLURM, ignore this message! - """ % {'nb_gpus': self.nb_requested_gpus, 'nb_tasks': self.nb_slurm_tasks} +You requested %(nb_gpus)s GPUs but launched %(nb_tasks)s slurm tasks. +We will launch %(nb_gpus)s processes for you. +We recommend you let slurm manage the processes by setting: --ntasks-per-node=%(nb_gpus)s +If you're not using SLURM, ignore this message! +""" % {'nb_gpus': self.nb_requested_gpus, 'nb_tasks': self.nb_slurm_tasks} warnings.warn(msg) mp.spawn(self.ddp_train, nprocs=len(self.data_parallel_device_ids), args=(model, )) @@ -433,7 +440,8 @@ class Trainer(TrainerIO): else: # run through amp wrapper if self.use_amp: - raise MisconfigurationException('amp + cpu is not supported. Please use a GPU option') + raise MisconfigurationException('amp + cpu is not supported.' + ' Please use a GPU option') # CHOOSE OPTIMIZER # allow for lr schedulers as well @@ -461,10 +469,10 @@ class Trainer(TrainerIO): # https://github.com/NVIDIA/apex/issues/227 if self.use_dp and self.use_amp: m = """ - Amp level %r with DataParallel is not supported. - See this note from NVIDIA for more info: https://github.com/NVIDIA/apex/issues/227. - We recommend you switch to ddp if you want to use amp - """ % self.amp_level +Amp level %r with DataParallel is not supported. +See this note from NVIDIA for more info: https://github.com/NVIDIA/apex/issues/227. +We recommend you switch to ddp if you want to use amp +""" % self.amp_level raise MisconfigurationException(m) model = LightningDataParallel(model, device_ids=self.data_parallel_device_ids) @@ -527,7 +535,8 @@ class Trainer(TrainerIO): ) self.optimizers = optimizers - model = LightningDistributedDataParallel(model, device_ids=[gpu_nb], find_unused_parameters=True) + model = LightningDistributedDataParallel(model, device_ids=[gpu_nb], + find_unused_parameters=True) # continue training routine self.__run_pretrain_routine(model) @@ -642,7 +651,8 @@ class Trainer(TrainerIO): # init progbar when requested if self.progress_bar: - self.prog_bar = tqdm.tqdm(range(self.total_batches), position=self.process_position) + self.prog_bar = tqdm.tqdm(range(self.total_batches), + position=self.process_position) for batch_nb, data_batch in enumerate(self.tng_dataloader): self.batch_nb = batch_nb @@ -651,7 +661,8 @@ class Trainer(TrainerIO): 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 + # stop when the flag is changed or we've gone past the amount + # requested in the batches self.total_batch_nb += 1 met_batch_limit = batch_nb > self.nb_tng_batches if met_batch_limit: @@ -698,7 +709,8 @@ class Trainer(TrainerIO): model.on_tng_metrics(metrics) # log metrics - scalar_metrics = self.__metrics_to_scalars(metrics, blacklist=self.__log_vals_blacklist()) + 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() @@ -720,7 +732,8 @@ class Trainer(TrainerIO): # early stopping 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) + should_stop = self.early_stop_callback.on_epoch_end(epoch=epoch_nb, + logs=self.__tng_tqdm_dic) # stop training stop = should_stop and met_min_epochs @@ -828,7 +841,8 @@ class Trainer(TrainerIO): # clear gradients optimizer.zero_grad() - # queuing loss across batches blows it up proportionally... divide out the number accumulated + # queuing loss across batches blows it up proportionally... + # divide out the number accumulated self.batch_loss_value = self.batch_loss_value / self.accumulate_grad_batches # track loss @@ -885,4 +899,5 @@ class Trainer(TrainerIO): # model checkpointing if self.proc_rank == 0 and self.checkpoint_callback is not None: print('save callback...') - self.checkpoint_callback.on_epoch_end(epoch=self.current_epoch, logs=self.__tng_tqdm_dic) + self.checkpoint_callback.on_epoch_end(epoch=self.current_epoch, + logs=self.__tng_tqdm_dic) diff --git a/pytorch_lightning/root_module/grads.py b/pytorch_lightning/root_module/grads.py index b28cf21c..7bdc8572 100644 --- a/pytorch_lightning/root_module/grads.py +++ b/pytorch_lightning/root_module/grads.py @@ -17,11 +17,13 @@ class GradInformation(nn.Module): total_norm += param_norm ** norm_type norm = param_norm ** (1 / norm_type) - results['grad_{}_norm_{}'.format(norm_type, i)] = round(norm.data.cpu().numpy().flatten()[0], 3) + grad = round(norm.data.cpu().numpy().flatten()[0], 3) + results['grad_{}_norm_{}'.format(norm_type, i)] = grad except Exception: # this param had no grad pass total_norm = total_norm ** (1. / norm_type) - results['grad_{}_norm_total'.format(norm_type)] = round(total_norm.data.cpu().numpy().flatten()[0], 3) + grad = round(total_norm.data.cpu().numpy().flatten()[0], 3) + results['grad_{}_norm_total'.format(norm_type)] = grad return results diff --git a/pytorch_lightning/root_module/model_saving.py b/pytorch_lightning/root_module/model_saving.py index 0bde0943..0765142c 100644 --- a/pytorch_lightning/root_module/model_saving.py +++ b/pytorch_lightning/root_module/model_saving.py @@ -3,7 +3,8 @@ import re import torch -from ..pt_overrides.override_data_parallel import LightningDistributedDataParallel, LightningDataParallel +from ..pt_overrides.override_data_parallel import ( + LightningDistributedDataParallel, LightningDataParallel) class ModelIO(object): @@ -45,7 +46,8 @@ class ModelIO(object): class TrainerIO(object): def __get_model(self): - is_dp_module = type(self.model) is LightningDistributedDataParallel or type(self.model) is LightningDataParallel + is_dp_module = isinstance(self.model, (LightningDistributedDataParallel, + LightningDataParallel)) model = self.model.module if is_dp_module else self.model return model diff --git a/pytorch_lightning/testing/lm_test_module.py b/pytorch_lightning/testing/lm_test_module.py index 24995c7f..61ecf874 100644 --- a/pytorch_lightning/testing/lm_test_module.py +++ b/pytorch_lightning/testing/lm_test_module.py @@ -48,11 +48,13 @@ class LightningTestModel(LightningModule): Layout model :return: """ - self.c_d1 = nn.Linear(in_features=self.hparams.in_features, out_features=self.hparams.hidden_dim) + self.c_d1 = nn.Linear(in_features=self.hparams.in_features, + out_features=self.hparams.hidden_dim) self.c_d1_bn = nn.BatchNorm1d(self.hparams.hidden_dim) self.c_d1_drop = nn.Dropout(self.hparams.drop_prob) - self.c_d2 = nn.Linear(in_features=self.hparams.hidden_dim, out_features=self.hparams.out_features) + self.c_d2 = nn.Linear(in_features=self.hparams.hidden_dim, + out_features=self.hparams.out_features) # --------------------- # TRAINING @@ -191,8 +193,10 @@ class LightningTestModel(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) + transform = transforms.Compose([transforms.ToTensor(), + transforms.Normalize((0.5,), (1.0,))]) + dataset = MNIST(root=self.hparams.data_root, train=train, + transform=transform, download=True) # when using multi-node we need to add the datasampler train_sampler = None @@ -251,11 +255,15 @@ class LightningTestModel(LightningModule): 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 * 8, 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('--optimizer_name', default='adam', type=str, options=['adam'], 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') + # 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 gpus being used across all nodes') return parser diff --git a/pytorch_lightning/utilities/arg_parse.py b/pytorch_lightning/utilities/arg_parse.py index 44399c39..39d4ec81 100644 --- a/pytorch_lightning/utilities/arg_parse.py +++ b/pytorch_lightning/utilities/arg_parse.py @@ -9,29 +9,40 @@ import os def add_default_args(parser, root_dir, rand_seed=None, possible_model_names=None): # tng, test, val check intervals - parser.add_argument('--eval_test_set', dest='eval_test_set', action='store_true', help='true = run test set also') - parser.add_argument('--check_val_every_n_epoch', default=1, type=int, help='check val every n epochs') + parser.add_argument('--eval_test_set', dest='eval_test_set', action='store_true', + help='true = run test set also') + parser.add_argument('--check_val_every_n_epoch', default=1, type=int, + help='check val every n epochs') parser.opt_list('--accumulate_grad_batches', default=1, type=int, tunable=False, - help='accumulates gradients k times before applying update. Simulates huge batch size') + help='accumulates gradients k times before applying update.' + ' Simulates huge batch size') parser.add_argument('--max_nb_epochs', default=200, type=int, help='cap epochs') parser.add_argument('--min_nb_epochs', default=2, type=int, help='min epochs') - parser.add_argument('--train_percent_check', default=1.0, type=float, help='how much of tng set to check') - parser.add_argument('--val_percent_check', default=1.0, type=float, help='how much of val set to check') - parser.add_argument('--test_percent_check', default=1.0, type=float, help='how much of test set to check') + parser.add_argument('--train_percent_check', default=1.0, type=float, + help='how much of tng set to check') + parser.add_argument('--val_percent_check', default=1.0, type=float, + help='how much of val set to check') + parser.add_argument('--test_percent_check', default=1.0, type=float, + help='how much of test set to check') - parser.add_argument('--val_check_interval', default=0.95, type=float, help='how much within 1 epoch to check val') - parser.add_argument('--log_save_interval', default=100, type=int, help='how many batches between log saves') - parser.add_argument('--add_log_row_interval', default=100, type=int, help='add log every k batches') + parser.add_argument('--val_check_interval', default=0.95, type=float, + help='how much within 1 epoch to check val') + parser.add_argument('--log_save_interval', default=100, type=int, + help='how many batches between log saves') + parser.add_argument('--add_log_row_interval', default=100, type=int, + help='add log every k batches') # early stopping parser.add_argument('--disable_early_stop', dest='enable_early_stop', action='store_false') parser.add_argument('--early_stop_metric', default='val_acc', type=str) parser.add_argument('--early_stop_mode', default='min', type=str) - parser.add_argument('--early_stop_patience', default=3, type=int, help='number of epochs until stop') + parser.add_argument('--early_stop_patience', default=3, type=int, + help='number of epochs until stop') # gradient handling parser.add_argument('--gradient_clip', default=-1, type=int) - parser.add_argument('--track_grad_norm', default=-1, type=int, help='if > 0, will track this grad norm') + parser.add_argument('--track_grad_norm', default=-1, type=int, + help='if > 0, will track this grad norm') # model saving parser.add_argument('--model_save_path', default=root_dir + '/model_weights') @@ -47,7 +58,8 @@ def add_default_args(parser, root_dir, rand_seed=None, possible_model_names=None # test_tube settings 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=os.path.join(root_dir, 'test_tube_logs'), help='logging dir') + parser.add_argument('--tt_save_path', default=os.path.join(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) parser.add_argument('--log_stdout', dest='log_stdout', action='store_true') @@ -65,17 +77,23 @@ def add_default_args(parser, root_dir, rand_seed=None, possible_model_names=None # FAST training # use these settings to make sure network has no bugs without running a full dataset - parser.add_argument('--fast_dev_run', dest='fast_dev_run', default=False, action='store_true', help='runs validation after 1 tng step') - parser.add_argument('--enable_tqdm', dest='enable_tqdm', default=False, action='store_true', help='false removes the prog bar') - parser.add_argument('--overfit', default=-1, type=float, help='% of dataset to use with this option. float, or -1 for none') + parser.add_argument('--fast_dev_run', dest='fast_dev_run', default=False, action='store_true', + help='runs validation after 1 tng step') + parser.add_argument('--enable_tqdm', dest='enable_tqdm', default=False, action='store_true', + help='false removes the prog bar') + parser.add_argument('--overfit', default=-1, type=float, + help='% of dataset to use with this option. float, or -1 for none') # debug args if rand_seed is not None: parser.add_argument('--random_seed', default=rand_seed, type=int) - parser.add_argument('--interactive', dest='interactive', action='store_true', help='runs on gpu without cluster') - parser.add_argument('--debug', dest='debug', action='store_true', help='enables/disables test tube') - parser.add_argument('--local', dest='local', action='store_true', help='enables local tng') + parser.add_argument('--interactive', dest='interactive', action='store_true', + help='runs on gpu without cluster') + parser.add_argument('--debug', dest='debug', action='store_true', + help='enables/disables test tube') + parser.add_argument('--local', dest='local', action='store_true', + help='enables local tng') # optimizer parser.add_argument('--lr_scheduler_milestones', default=None, type=str) diff --git a/tests/debug.py b/tests/debug.py index d068e63e..6a5efbec 100644 --- a/tests/debug.py +++ b/tests/debug.py @@ -107,7 +107,8 @@ def load_model(exp, save_dir): checkpoints = [x for x in os.listdir(save_dir) if '.ckpt' in x] weights_dir = os.path.join(save_dir, checkpoints[0]) - trained_model = LightningTemplateModel.load_from_metrics(weights_path=weights_dir, tags_csv=tags_path, on_gpu=True) + trained_model = LightningTemplateModel.load_from_metrics(weights_path=weights_dir, + tags_csv=tags_path, on_gpu=True) assert trained_model is not None, 'loading model failed' diff --git a/tests/test_models.py b/tests/test_models.py index 59c4577a..044f2391 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -30,10 +30,12 @@ def test_amp_gpu_ddp(): :return: """ if not torch.cuda.is_available(): - warnings.warn('test_amp_gpu_ddp cannot run. Rerun on a GPU node to run this test') + warnings.warn('test_amp_gpu_ddp cannot run.' + 'Rerun on a GPU node to run this test') return if not torch.cuda.device_count() > 1: - warnings.warn('test_amp_gpu_ddp cannot run. Rerun on a node with 2+ GPUs to run this test') + warnings.warn('test_amp_gpu_ddp cannot run.' + 'Rerun on a node with 2+ GPUs to run this test') return os.environ['MASTER_PORT'] = str(np.random.randint(12000, 19000, 1)[0]) @@ -105,7 +107,8 @@ def test_cpu_slurm_save_load(): # wipe-out trainer and model # retrain with not much data... this simulates picking training back up after slurm # we want to see if the weights come back correctly - continue_tng_hparams = get_hparams(continue_training=True, hpc_exp_number=cluster_a.hpc_exp_number) + continue_tng_hparams = get_hparams(continue_training=True, + hpc_exp_number=cluster_a.hpc_exp_number) trainer_options = dict( max_nb_epochs=1, cluster=SlurmCluster(continue_tng_hparams), @@ -219,7 +222,8 @@ def test_model_saving_loading(): # load new model tags_path = exp.get_data_path(exp.name, exp.version) tags_path = os.path.join(tags_path, 'meta_tags.csv') - model_2 = LightningTestModel.load_from_metrics(weights_path=new_weights_path, tags_csv=tags_path, on_gpu=False) + model_2 = LightningTestModel.load_from_metrics(weights_path=new_weights_path, + tags_csv=tags_path, on_gpu=False) model_2.eval() # make prediction @@ -244,10 +248,12 @@ def test_amp_gpu_ddp_slurm_managed(): :return: """ if not torch.cuda.is_available(): - warnings.warn('test_amp_gpu_ddp cannot run. Rerun on a GPU node to run this test') + warnings.warn('test_amp_gpu_ddp cannot run.' + ' Rerun on a GPU node to run this test') return if not torch.cuda.device_count() > 1: - warnings.warn('test_amp_gpu_ddp cannot run. Rerun on a node with 2+ GPUs to run this test') + warnings.warn('test_amp_gpu_ddp cannot run.' + ' Rerun on a node with 2+ GPUs to run this test') return # simulate setting slurm flags @@ -411,7 +417,8 @@ def test_single_gpu_model(): :return: """ if not torch.cuda.is_available(): - warnings.warn('test_single_gpu_model cannot run. Rerun on a GPU node to run this test') + warnings.warn('test_single_gpu_model cannot run.' + ' Rerun on a GPU node to run this test') return model, hparams = get_model() @@ -432,10 +439,12 @@ def test_multi_gpu_model_dp(): :return: """ if not torch.cuda.is_available(): - warnings.warn('test_multi_gpu_model_dp cannot run. Rerun on a GPU node to run this test') + warnings.warn('test_multi_gpu_model_dp cannot run.' + ' Rerun on a GPU node to run this test') return if not torch.cuda.device_count() > 1: - warnings.warn('test_multi_gpu_model_dp cannot run. Rerun on a node with 2+ GPUs to run this test') + warnings.warn('test_multi_gpu_model_dp cannot run.' + ' Rerun on a node with 2+ GPUs to run this test') return model, hparams = get_model() trainer_options = dict( @@ -458,10 +467,12 @@ def test_amp_gpu_dp(): :return: """ if not torch.cuda.is_available(): - warnings.warn('test_amp_gpu_dp cannot run. Rerun on a GPU node to run this test') + warnings.warn('test_amp_gpu_dp cannot run.' + ' Rerun on a GPU node to run this test') return if not torch.cuda.device_count() > 1: - warnings.warn('test_amp_gpu_dp cannot run. Rerun on a node with 2+ GPUs to run this test') + warnings.warn('test_amp_gpu_dp cannot run.' + ' Rerun on a node with 2+ GPUs to run this test') return model, hparams = get_model() trainer_options = dict( @@ -480,10 +491,12 @@ def test_multi_gpu_model_ddp(): :return: """ if not torch.cuda.is_available(): - warnings.warn('test_multi_gpu_model_ddp cannot run. Rerun on a GPU node to run this test') + warnings.warn('test_multi_gpu_model_ddp cannot run.' + ' Rerun on a GPU node to run this test') return if not torch.cuda.device_count() > 1: - warnings.warn('test_multi_gpu_model_ddp cannot run. Rerun on a node with 2+ GPUs to run this test') + warnings.warn('test_multi_gpu_model_ddp cannot run.' + ' Rerun on a node with 2+ GPUs to run this test') return os.environ['MASTER_PORT'] = str(np.random.randint(12000, 19000, 1)[0]) From f8a79b308274f3d62d0cff7361dd1144445ebd62 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Tue, 6 Aug 2019 18:04:10 +0200 Subject: [PATCH 16/24] fix imports in examples --- examples/new_project_templates/multi_node_cluster_template.py | 2 +- examples/new_project_templates/single_cpu_template.py | 2 +- .../new_project_templates/single_gpu_node_16bit_template.py | 2 +- examples/new_project_templates/single_gpu_node_ddp_template.py | 2 +- examples/new_project_templates/single_gpu_node_dp_template.py | 2 +- examples/new_project_templates/trainer_cpu_template.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/new_project_templates/multi_node_cluster_template.py b/examples/new_project_templates/multi_node_cluster_template.py index cdbda003..c4af6d41 100644 --- a/examples/new_project_templates/multi_node_cluster_template.py +++ b/examples/new_project_templates/multi_node_cluster_template.py @@ -10,7 +10,7 @@ from test_tube import HyperOptArgumentParser, Experiment, SlurmCluster from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint -from .lightning_module_template import LightningTemplateModel +from examples.new_project_templates.lightning_module_template import LightningTemplateModel SEED = 2334 torch.manual_seed(SEED) diff --git a/examples/new_project_templates/single_cpu_template.py b/examples/new_project_templates/single_cpu_template.py index 9822f216..c0f4826f 100644 --- a/examples/new_project_templates/single_cpu_template.py +++ b/examples/new_project_templates/single_cpu_template.py @@ -9,7 +9,7 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint -from .lightning_module_template import LightningTemplateModel +from examples.new_project_templates.lightning_module_template import LightningTemplateModel SEED = 2334 torch.manual_seed(SEED) diff --git a/examples/new_project_templates/single_gpu_node_16bit_template.py b/examples/new_project_templates/single_gpu_node_16bit_template.py index 137f0e48..babf18e7 100644 --- a/examples/new_project_templates/single_gpu_node_16bit_template.py +++ b/examples/new_project_templates/single_gpu_node_16bit_template.py @@ -9,7 +9,7 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint -from .lightning_module_template import LightningTemplateModel +from examples.new_project_templates.lightning_module_template import LightningTemplateModel SEED = 2334 torch.manual_seed(SEED) diff --git a/examples/new_project_templates/single_gpu_node_ddp_template.py b/examples/new_project_templates/single_gpu_node_ddp_template.py index e8f46012..68a332ae 100644 --- a/examples/new_project_templates/single_gpu_node_ddp_template.py +++ b/examples/new_project_templates/single_gpu_node_ddp_template.py @@ -9,7 +9,7 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint -from .lightning_module_template import LightningTemplateModel +from examples.new_project_templates.lightning_module_template import LightningTemplateModel SEED = 2334 torch.manual_seed(SEED) diff --git a/examples/new_project_templates/single_gpu_node_dp_template.py b/examples/new_project_templates/single_gpu_node_dp_template.py index f48df5ca..d752713e 100644 --- a/examples/new_project_templates/single_gpu_node_dp_template.py +++ b/examples/new_project_templates/single_gpu_node_dp_template.py @@ -9,7 +9,7 @@ from test_tube import HyperOptArgumentParser, Experiment from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint -from .lightning_module_template import LightningTemplateModel +from examples.new_project_templates.lightning_module_template import LightningTemplateModel SEED = 2334 torch.manual_seed(SEED) diff --git a/examples/new_project_templates/trainer_cpu_template.py b/examples/new_project_templates/trainer_cpu_template.py index 21d705c6..84a29a9b 100644 --- a/examples/new_project_templates/trainer_cpu_template.py +++ b/examples/new_project_templates/trainer_cpu_template.py @@ -6,7 +6,7 @@ from pytorch_lightning.models.trainer import Trainer from pytorch_lightning.utilities.arg_parse import add_default_args from pytorch_lightning.callbacks.pt_callbacks import EarlyStopping, ModelCheckpoint -from .lightning_module_template import LightningTemplateModel +from examples.new_project_templates.lightning_module_template import LightningTemplateModel def main(hparams): From 715be66590d0d7247a66ee453fe14911388d5476 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Tue, 6 Aug 2019 21:59:12 +0200 Subject: [PATCH 17/24] drop CircleCI --- .circleci/config.yml | 60 -------------------------------------------- MANIFEST.in | 2 -- README.md | 1 - 3 files changed, 63 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 71d3c14c..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: 2.0 - -references: - - install_pips: &install_pips - run: - name: Install PyPI dependences - command: | - pip install -r requirements.txt --user - sudo pip install -r ./tests/requirements.txt - python --version ; pwd ; ls -l - pip --version ; pip list - - test_coverage: &test_coverage - run: - name: Testing and Formating - command: | - check-manifest --ignore tox.ini - python setup.py check -m -s - coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules - flake8 . --max-line-length=120 - codecov - -jobs: - - Py3.6: - docker: - - image: circleci/python:3.6 - steps: &steps - - checkout - # INSTALLATION - - *install_pips - # TESTING - - *test_coverage - # DOCUMENTATION - - # PASSING - - run: - name: Finalise - command: | - python setup.py install --user - coverage report && coverage xml -o test-reports/coverage.xml - # RESULTS - - store_test_results: - path: test-reports - - store_artifacts: - path: test-reports - - Py3.7: - docker: - - image: circleci/python:3.7 - steps: *steps - - -workflows: - version: 2 - build: - jobs: - - Py3.6 - - Py3.7 diff --git a/MANIFEST.in b/MANIFEST.in index b16540b8..e39ffbad 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -27,12 +27,10 @@ exclude docs include requirements.txt # Exclude build configs -recursive-exclude .circleci * exclude *.yml prune .git prune .github -prune .circleci prune notebook* prune temp* prune test* \ No newline at end of file diff --git a/README.md b/README.md index bbe110ba..2d1914ff 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ [![PyPI Status](https://badge.fury.io/py/pytorch-lightning.svg)](https://badge.fury.io/py/pytorch-lightning) [![PyPI Status](https://pepy.tech/badge/pytorch-lightning)](https://pepy.tech/project/pytorch-lightning) [![Build Status](https://travis-ci.org/williamFalcon/pytorch-lightning.svg?branch=master)](https://travis-ci.org/williamFalcon/pytorch-lightning) -[![CircleCI](https://circleci.com/gh/Borda/pytorch-lightning.svg?style=svg)](https://circleci.com/gh/Borda/pytorch-lightning) [![Build status](https://ci.appveyor.com/api/projects/status/rum89d7hq8l1kfye?svg=true)](https://ci.appveyor.com/project/Borda/pytorch-lightning) [![codecov](https://codecov.io/gh/Borda/pytorch-lightning/branch/master/graph/badge.svg)](https://codecov.io/gh/Borda/pytorch-lightning) [![CodeFactor](https://www.codefactor.io/repository/github/borda/pytorch-lightning/badge)](https://www.codefactor.io/repository/github/borda/pytorch-lightning) From a1bb6237a6ac391096b14dad2d8d0b08256c1ce1 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Tue, 6 Aug 2019 22:37:58 +0200 Subject: [PATCH 18/24] review changes #44 --- .codecov.yml | 2 +- .travis.yml | 2 -- README.md | 3 +++ pytorch_lightning/__init__.py | 2 +- pytorch_lightning/models/trainer.py | 2 +- setup.py | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 4870d144..b6fc9280 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -12,7 +12,7 @@ coverage: project: default: against: auto - target: 90% # specify the target coverage for each commit status + target: 100% # specify the target coverage for each commit status threshold: 20% # allow this little decrease on project # https://github.com/codecov/support/wiki/Filtering-Branches # branches: master diff --git a/.travis.yml b/.travis.yml index d601362e..ec7f80d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,6 @@ language: python matrix: include: - - python: 3.5 - env: TOXENV=py35 - python: 3.6 env: TOXENV=py36 - python: 3.7 diff --git a/README.md b/README.md index 2d1914ff..90040a3e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +
+ ![Logo](./docs/source/_static/lightning_logo_small.png) # PyTorch Lightning @@ -14,6 +16,7 @@ [![ReadTheDocs](https://readthedocs.org/projects/pytorch-lightning/badge/?version=latest)](https://pytorch-lightning.readthedocs.io/en/latest) [![license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/williamFalcon/pytorch-lightning/blob/master/LICENSE) +
Simple installation from PyPI ```bash diff --git a/pytorch_lightning/__init__.py b/pytorch_lightning/__init__.py index 145d3bd0..73067d63 100644 --- a/pytorch_lightning/__init__.py +++ b/pytorch_lightning/__init__.py @@ -5,7 +5,7 @@ from .root_module.decorators import data_loader __version__ = '0.3.6.9' __author__ = "William Falcon", __author_email__ = "waf2107@columbia.edu" -__license__ = 'MIT' +__license__ = 'Apache-2' __homepage__ = 'https://github.com/williamFalcon/pytorch-lightning', __copyright__ = 'Copyright (c) 2018-2019, %s.' % __author__ __doc__ = """ diff --git a/pytorch_lightning/models/trainer.py b/pytorch_lightning/models/trainer.py index e23dfa0b..6f07f925 100644 --- a/pytorch_lightning/models/trainer.py +++ b/pytorch_lightning/models/trainer.py @@ -105,7 +105,7 @@ class Trainer(TrainerIO): :param log_save_interval: :param add_log_row_interval: :param distributed_backend: - 'np' to use DistributedParallel, 'ddp' to use DistributedDataParallel + 'np' to use DistributedParallel, 'dp' to use DistributedDataParallel :param use_amp: :param print_nan_grads: :param print_weights_summary: diff --git a/setup.py b/setup.py index 5f076a36..a8f0d370 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ setup( zip_safe=False, keywords=["deep learning", "pytorch", "AI"], - python_requires=">=3.5", + python_requires=">=3.6", install_requires=[ "torch>=1.1.0", "tqdm", From b2d1a24999f23107d592d9a0adcffe108a6a20c3 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Tue, 6 Aug 2019 17:24:09 -0400 Subject: [PATCH 19/24] Update .codecov.yml --- .codecov.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index b6fc9280..f10c1873 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -12,7 +12,7 @@ coverage: project: default: against: auto - target: 100% # specify the target coverage for each commit status + target: 99% # specify the target coverage for each commit status threshold: 20% # allow this little decrease on project # https://github.com/codecov/support/wiki/Filtering-Branches # branches: master @@ -39,4 +39,4 @@ comment: layout: header, diff require_changes: false behavior: default # update if exists else create new - # branches: * \ No newline at end of file + # branches: * From 97a9a0f6c1d199bf4c7c502ed241350e65c11cfc Mon Sep 17 00:00:00 2001 From: William Falcon Date: Tue, 6 Aug 2019 18:02:22 -0400 Subject: [PATCH 20/24] Update trainer.py --- pytorch_lightning/models/trainer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pytorch_lightning/models/trainer.py b/pytorch_lightning/models/trainer.py index 6f07f925..574c8061 100644 --- a/pytorch_lightning/models/trainer.py +++ b/pytorch_lightning/models/trainer.py @@ -180,7 +180,8 @@ class Trainer(TrainerIO): # make DP and DDP mutually exclusive # single GPU will also use DP with devices=[0] - if self.data_parallel_device_ids: + requested_gpus = self.data_parallel_device_ids is not None + if requested_gpus and len(self.data_parallel_device_ids) > 0: self.use_dp = distributed_backend == 'dp' self.use_ddp = distributed_backend == 'ddp' From b75ee7fd8dc998dc62792f0fd00664f620f4400f Mon Sep 17 00:00:00 2001 From: William Falcon Date: Tue, 6 Aug 2019 21:26:01 -0400 Subject: [PATCH 21/24] Update tox.ini --- tox.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index a91ac5ef..111bae58 100644 --- a/tox.ini +++ b/tox.ini @@ -34,7 +34,9 @@ deps = commands = check-manifest --ignore tox.ini python setup.py check -m -s - coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules + # disable auto coverage bc it isn't accurate since it misses gpu code. + # to get coverage, run local and push results + # coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules flake8 . [flake8] From 421c4fab7dda431887026166ef767fab4f3174b0 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Wed, 7 Aug 2019 10:36:25 +0200 Subject: [PATCH 22/24] fix appveyor - install pytorch --- appveyor.yml | 12 ++++++++---- requirements.txt | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 40379cc5..57c6294d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,20 +12,22 @@ environment: # See: http://www.appveyor.com/docs/installed-software#python - - PYTHON: "C:\\Python35-x64" - PYTHON_VERSION: "3.5.x" - PYTHON_ARCH: "64" - TOXENV: "py35" + # - PYTHON: "C:\\Python35-x64" + # PYTHON_VERSION: "3.5.x" + # PYTHON_ARCH: "64" + # TOXENV: "py35" - PYTHON: "C:\\Python36-x64" PYTHON_VERSION: "3.6.x" PYTHON_ARCH: "64" TOXENV: "py36" + PIP_PYVER: "36" - PYTHON: "C:\\Python37-x64" PYTHON_VERSION: "3.7.x" PYTHON_ARCH: "64" TOXENV: "py37" + PIP_PYVER: "37" build: off @@ -43,6 +45,8 @@ install: # directly to master instead of just PR builds (or the converse). - SET PATH=%PYTHON%;%PYTHON%\\Scripts;%path% - pip install -U --user pip + - pip install "https://download.pytorch.org/whl/cu90/torch-1.1.0-cp%PIP_PYVER%-cp%PIP_PYVER%m-win_amd%PYTHON_ARCH%.whl" + pip install "https://download.pytorch.org/whl/cu90/torchvision-0.3.0-cp%PIP_PYVER%-cp%PIP_PYVER%m-win_amd%PYTHON_ARCH%.whl" - pip install -r requirements.txt - pip install -r ./tests/requirements.txt diff --git a/requirements.txt b/requirements.txt index 83e49f4a..86c02573 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,5 @@ tqdm==4.32.1 twine==1.13.0 numpy==1.16.4 torch>=1.1.0 -torchvision==0.3.0 +torchvision>=0.3.0 pandas \ No newline at end of file From a25429b05cb5b8a4525b9d781400f796bb6e02d7 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Wed, 7 Aug 2019 06:11:15 -0400 Subject: [PATCH 23/24] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 90040a3e..b2d286ec 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ [![PyPI Status](https://badge.fury.io/py/pytorch-lightning.svg)](https://badge.fury.io/py/pytorch-lightning) [![PyPI Status](https://pepy.tech/badge/pytorch-lightning)](https://pepy.tech/project/pytorch-lightning) [![Build Status](https://travis-ci.org/williamFalcon/pytorch-lightning.svg?branch=master)](https://travis-ci.org/williamFalcon/pytorch-lightning) -[![Build status](https://ci.appveyor.com/api/projects/status/rum89d7hq8l1kfye?svg=true)](https://ci.appveyor.com/project/Borda/pytorch-lightning) + [![codecov](https://codecov.io/gh/Borda/pytorch-lightning/branch/master/graph/badge.svg)](https://codecov.io/gh/Borda/pytorch-lightning) [![CodeFactor](https://www.codefactor.io/repository/github/borda/pytorch-lightning/badge)](https://www.codefactor.io/repository/github/borda/pytorch-lightning) [![ReadTheDocs](https://readthedocs.org/projects/pytorch-lightning/badge/?version=latest)](https://pytorch-lightning.readthedocs.io/en/latest) From 86a90bfefda5138ccde4a64f80107dfd917d92f8 Mon Sep 17 00:00:00 2001 From: Jiri BOROVEC Date: Wed, 7 Aug 2019 14:32:32 +0200 Subject: [PATCH 24/24] update codecov --- .travis.yml | 4 +++- appveyor.yml | 2 +- tests/README.md | 10 +++++++--- tests/test_models.py | 10 ++++++---- tox.ini | 4 +--- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index ec7f80d2..fb1f8c95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,9 @@ script: after_success: - coverage report - - codecov + # disable auto coverage bc it isn't accurate since it misses gpu code. + # to get coverage, run local and push results + # - codecov notifications: email: false diff --git a/appveyor.yml b/appveyor.yml index 57c6294d..ad03a478 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -63,4 +63,4 @@ test_script: on_success: - coverage report - - codecov + # - codecov diff --git a/tests/README.md b/tests/README.md index a121ff14..032cf04f 100644 --- a/tests/README.md +++ b/tests/README.md @@ -17,7 +17,7 @@ pip install -e . pip install -r requirements.txt # run tests -py.test +py.test -v ``` To test models that require GPU make sure to run the above command on a GPU machine. @@ -50,10 +50,14 @@ cd pytorch-lightning # generate coverage pip install coverage -coverage run tests/test_models.py +coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules # print coverage stats -coverage report -m +coverage report -m + +# exporting resulys +coverage xml +codecov -t 17327163-8cca-4a5d-86c8-ca5f2ef700bc -v ``` diff --git a/tests/test_models.py b/tests/test_models.py index 044f2391..cd03d8b4 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,20 +1,22 @@ import os import shutil import warnings +from argparse import Namespace import pytest import numpy as np import torch -from pytorch_lightning import Trainer -from examples import LightningTemplateModel -from pytorch_lightning.testing.lm_test_module import LightningTestModel -from argparse import Namespace from test_tube import Experiment, SlurmCluster + +# sys.path += [os.path.abspath('..'), os.path.abspath('../..')] +from pytorch_lightning import Trainer +from pytorch_lightning.testing.lm_test_module import LightningTestModel from pytorch_lightning.callbacks import ModelCheckpoint, EarlyStopping from pytorch_lightning.utilities.debugging import MisconfigurationException from pytorch_lightning.root_module import memory from pytorch_lightning.models.trainer import reduce_distributed_output from pytorch_lightning.root_module import model_saving +from examples import LightningTemplateModel SEED = 2334 torch.manual_seed(SEED) diff --git a/tox.ini b/tox.ini index 111bae58..a91ac5ef 100644 --- a/tox.ini +++ b/tox.ini @@ -34,9 +34,7 @@ deps = commands = check-manifest --ignore tox.ini python setup.py check -m -s - # disable auto coverage bc it isn't accurate since it misses gpu code. - # to get coverage, run local and push results - # coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules + coverage run --source pytorch_lightning -m py.test pytorch_lightning tests examples -v --doctest-modules flake8 . [flake8]