{"id":13738346,"url":"https://github.com/frgfm/torch-scan","last_synced_at":"2025-05-16T05:03:53.431Z","repository":{"id":37860181,"uuid":"247824251","full_name":"frgfm/torch-scan","owner":"frgfm","description":"Seamless analysis of your PyTorch models (RAM usage, FLOPs, MACs, receptive field, etc.)","archived":false,"fork":false,"pushed_at":"2025-03-24T05:30:12.000Z","size":7732,"stargazers_count":218,"open_issues_count":12,"forks_count":22,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-11T06:46:43.018Z","etag":null,"topics":["benchmark","deep-learning","deep-neural-networks","flops","flops-counter","keras","python","pytorch","pytorch-utils","receptive-field","summary"],"latest_commit_sha":null,"homepage":"https://frgfm.github.io/torch-scan/latest","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/frgfm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"frgfm","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-03-16T21:57:33.000Z","updated_at":"2025-03-09T11:47:10.000Z","dependencies_parsed_at":"2024-12-08T07:04:31.439Z","dependency_job_id":"d62bb3d0-fa44-42eb-b760-8afdd1112ca1","html_url":"https://github.com/frgfm/torch-scan","commit_stats":{"total_commits":66,"total_committers":2,"mean_commits":33.0,"dds":"0.015151515151515138","last_synced_commit":"9bda263ad024c90da283d38410a5b2a5e6dd97c9"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frgfm%2Ftorch-scan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frgfm%2Ftorch-scan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frgfm%2Ftorch-scan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frgfm%2Ftorch-scan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frgfm","download_url":"https://codeload.github.com/frgfm/torch-scan/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254471062,"owners_count":22076585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["benchmark","deep-learning","deep-neural-networks","flops","flops-counter","keras","python","pytorch","pytorch-utils","receptive-field","summary"],"created_at":"2024-08-03T03:02:19.482Z","updated_at":"2025-05-16T05:03:53.413Z","avatar_url":"https://github.com/frgfm.png","language":"Python","funding_links":["https://github.com/sponsors/frgfm"],"categories":["Python"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/frgfm/torch-scan/releases/download/v0.1.1/logo_text.png\" width=\"30%\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/frgfm/torch-scan/actions/workflows/builds.yml\"\u003e\n    \u003cimg alt=\"CI Status\" src=\"https://img.shields.io/github/actions/workflow/status/frgfm/torch-scan/builds.yml?branch=main\u0026label=CI\u0026logo=github\u0026style=flat-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/astral-sh/ruff\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Linter-Ruff-FCC21B?style=flat-square\u0026logo=ruff\u0026logoColor=white\" alt=\"ruff\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/astral-sh/ruff\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Formatter-Ruff-FCC21B?style=flat-square\u0026logo=Python\u0026logoColor=white\" alt=\"ruff\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.codacy.com/gh/frgfm/torch-scan/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=frgfm/torch-scan\u0026amp;utm_campaign=Badge_Grade\"\u003e\u003cimg src=\"https://app.codacy.com/project/badge/Grade/9dc68e8bfce34d9dbc8b44a350e9adc7\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/frgfm/torch-scan\"\u003e\n    \u003cimg src=\"https://img.shields.io/codecov/c/github/frgfm/torch-scan.svg?logo=codecov\u0026style=flat-square\u0026label=Coverage\" alt=\"Test coverage percentage\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pypi.org/project/torchscan/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/torchscan.svg?logo=PyPI\u0026logoColor=fff\u0026style=flat-square\u0026label=PyPI\" alt=\"PyPi Version\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://anaconda.org/frgfm/torchscan\"\u003e\n    \u003cimg src=\"https://img.shields.io/conda/v/frgfm/torchscan.svg?logo=anaconda\u0026label=Conda\u0026logoColor=fff\u0026style=flat-square\" alt=\"Conda Version\"\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/pypi/pyversions/torchscan.svg?logo=Python\u0026label=Python\u0026logoColor=fff\u0026style=flat-square\" alt=\"pyversions\"\u003e\n  \u003ca href=\"https://github.com/frgfm/torch-scan/blob/main/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/frgfm/torch-scan.svg?label=License\u0026logoColor=fff\u0026style=flat-square\" alt=\"License\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://frgfm.github.io/torch-scan\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/frgfm/torch-scan/docs.yml?branch=main\u0026label=Documentation\u0026logo=read-the-docs\u0026logoColor=white\u0026style=flat-square\" alt=\"Documentation Status\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\nThe very useful [summary](https://www.tensorflow.org/api_docs/python/tf/keras/Model#summary) method of `tf.keras.Model` but for PyTorch, with more useful information.\n\n\n## Quick Tour\n\n### Inspecting your PyTorch architecture\n\nSimilarly to the `torchsummary` implementation, `torchscan` brings useful module information into readable format. For nested complex architectures, you can use a maximum depth of display as follows:\n\n```python\nfrom torchvision.models import densenet121\nfrom torchscan import summary\n\nmodel = densenet121().eval().cuda()\nsummary(model, (3, 224, 224), max_depth=2)\n```\n\nwhich would yield\n\n```shell\n__________________________________________________________________________________________\nLayer                        Type                  Output Shape              Param #\n==========================================================================================\ndensenet                     DenseNet              (-1, 1000)                0\n├─features                   Sequential            (-1, 1024, 7, 7)          0\n|    └─conv0                 Conv2d                (-1, 64, 112, 112)        9,408\n|    └─norm0                 BatchNorm2d           (-1, 64, 112, 112)        257\n|    └─relu0                 ReLU                  (-1, 64, 112, 112)        0\n|    └─pool0                 MaxPool2d             (-1, 64, 56, 56)          0\n|    └─denseblock1           _DenseBlock           (-1, 256, 56, 56)         338,316\n|    └─transition1           _Transition           (-1, 128, 28, 28)         33,793\n|    └─denseblock2           _DenseBlock           (-1, 512, 28, 28)         930,072\n|    └─transition2           _Transition           (-1, 256, 14, 14)         133,121\n|    └─denseblock3           _DenseBlock           (-1, 1024, 14, 14)        2,873,904\n|    └─transition3           _Transition           (-1, 512, 7, 7)           528,385\n|    └─denseblock4           _DenseBlock           (-1, 1024, 7, 7)          2,186,272\n|    └─norm5                 BatchNorm2d           (-1, 1024, 7, 7)          4,097\n├─classifier                 Linear                (-1, 1000)                1,025,000\n==========================================================================================\nTrainable params: 7,978,856\nNon-trainable params: 0\nTotal params: 7,978,856\n------------------------------------------------------------------------------------------\nModel size (params + buffers): 30.76 Mb\nFramework \u0026 CUDA overhead: 423.57 Mb\nTotal RAM usage: 454.32 Mb\n------------------------------------------------------------------------------------------\nFloating Point Operations on forward: 5.74 GFLOPs\nMultiply-Accumulations on forward: 2.87 GMACs\nDirect memory accesses on forward: 2.90 GDMAs\n__________________________________________________________________________________________\n```\n\nResults are aggregated to the selected depth for improved readability.\n\nFor reference, here are explanations of a few acronyms:\n\n- **FLOPs**: floating-point operations (not to be confused with FLOPS which is FLOPs per second)\n- **MACs**: mutiply-accumulate operations (cf. [wikipedia](https://en.wikipedia.org/wiki/Multiply%E2%80%93accumulate_operation))\n- **DMAs**: direct memory accesses (many argue that it is more relevant than FLOPs or MACs to compare model inference speeds cf. [wikipedia](https://en.wikipedia.org/wiki/Direct_memory_access))\n\n\n\nAdditionally, for highway nets (models without multiple branches / skip connections), `torchscan` supports receptive field estimation.\n\n```python\nfrom torchvision.models import vgg16\nfrom torchscan import summary\n\nmodel = vgg16().eval().cuda()\nsummary(model, (3, 224, 224), receptive_field=True, max_depth=0)\n```\n\nwhich will add the layer's receptive field (relatively to the last convolutional layer) to the summary.\n\n\n## Setup\n\nPython 3.8 (or newer) and [pip](https://pip.pypa.io/en/stable/)/[conda](https://docs.conda.io/en/latest/miniconda.html) are required to install Torchscan.\n\n### Stable release\n\nYou can install the last stable release of the package using [pypi](https://pypi.org/project/torch-scan/) as follows:\n\n```shell\npip install torchscan\n```\n\nor using [conda](https://anaconda.org/frgfm/torchscan):\n\n```shell\nconda install -c frgfm torchscan\n```\n\n### Developer installation\n\nAlternatively, if you wish to use the latest features of the project that haven't made their way to a release yet, you can install the package from source:\n\n```shell\ngit clone https://github.com/frgfm/torch-scan.git\npip install -e torch-scan/.\n```\n\n\n## Benchmark\n\nBelow are the results for classification models supported by `torchvision` for a single image with 3 color channels of size `224x224` (apart from  `inception_v3`   which uses `299x299`).\n\n| Model              | Params (M) | FLOPs (G) | MACs (G) | DMAs (G) | RF   |\n| ------------------ | ---------- | --------- | -------- | -------- | ---- |\n| alexnet            | 61.1       | 1.43      | 0.71     | 0.72     | 195  |\n| googlenet          | 6.62       | 3.01      | 1.51     | 1.53     | --   |\n| vgg11              | 132.86     | 15.23     | 7.61     | 7.64     | 150  |\n| vgg11_bn           | 132.87     | 15.26     | 7.63     | 7.66     | 150  |\n| vgg13              | 133.05     | 22.63     | 11.31    | 11.35    | 156  |\n| vgg13_bn           | 133.05     | 22.68     | 11.33    | 11.37    | 156  |\n| vgg16              | 138.36     | 30.96     | 15.47    | 15.52    | 212  |\n| vgg16_bn           | 138.37     | 31.01     | 15.5     | 15.55    | 212  |\n| vgg19              | 143.67     | 39.28     | 19.63    | 19.69    | 268  |\n| vgg19_bn           | 143.68     | 39.34     | 19.66    | 19.72    | 268  |\n| resnet18           | 11.69      | 3.64      | 1.82     | 1.84     | --   |\n| resnet34           | 21.8       | 7.34      | 3.67     | 3.7      | --   |\n| resnet50           | 25.56      | 8.21      | 4.11     | 4.15     | --   |\n| resnet101          | 44.55      | 15.66     | 7.83     | 7.9      | --   |\n| resnet152          | 60.19      | 23.1      | 11.56    | 11.65    | --   |\n| inception_v3       | 27.16      | 11.45     | 5.73     | 5.76     | --   |\n| squeezenet1_0      | 1.25       | 1.64      | 0.82     | 0.83     | --   |\n| squeezenet1_1      | 1.24       | 0.7       | 0.35     | 0.36     | --   |\n| wide_resnet50_2    | 68.88      | 22.84     | 11.43    | 11.51    | --   |\n| wide_resnet101_2   | 126.89     | 45.58     | 22.8     | 22.95    | --   |\n| densenet121        | 7.98       | 5.74      | 2.87     | 2.9      | --   |\n| densenet161        | 28.68      | 15.59     | 7.79     | 7.86     | --   |\n| densenet169        | 14.15      | 6.81      | 3.4      | 3.44     | --   |\n| densenet201        | 20.01      | 8.7       | 4.34     | 4.39     | --   |\n| resnext50_32x4d    | 25.03      | 8.51      | 4.26     | 4.3      | --   |\n| resnext101_32x8d   | 88.79      | 32.93     | 16.48    | 16.61    | --   |\n| mobilenet_v2       | 3.5        | 0.63      | 0.31     | 0.32     | --   |\n| shufflenet_v2_x0_5 | 1.37       | 0.09      | 0.04     | 0.05     | --   |\n| shufflenet_v2_x1_0 | 2.28       | 0.3       | 0.15     | 0.15     | --   |\n| shufflenet_v2_x1_5 | 3.5        | 0.6       | 0.3      | 0.31     | --   |\n| shufflenet_v2_x2_0 | 7.39       | 1.18      | 0.59     | 0.6      | --   |\n| mnasnet0_5         | 2.22       | 0.22      | 0.11     | 0.12     | --   |\n| mnasnet0_75        | 3.17       | 0.45      | 0.23     | 0.24     | --   |\n| mnasnet1_0         | 4.38       | 0.65      | 0.33     | 0.34     | --   |\n| mnasnet1_3         | 6.28       | 1.08      | 0.54     | 0.56     | --   |\n\nThe above results were produced using the `scripts/benchmark.py` script.\n\n*Note: receptive field computation is currently only valid for highway nets.*\n\n\n\n## What else\n\n### Documentation\n\nThe full package documentation is available [here](https://frgfm.github.io/torch-scan/) for detailed specifications.\n\n\n### Example script\n\nAn example script is provided for you to benchmark torchvision models using the library:\n\n```shell\npython scripts/benchmark.py\n```\n\n\n## Credits\n\nThis project is developed and maintained by the repo owner, but the implementation was inspired or helped by the following contributions:\n\n- [Pytorch summary](https://github.com/sksq96/pytorch-summary): existing PyTorch porting of `tf.keras.Model.summary`\n- [Torchstat](https://github.com/Swall0w/torchstat): another module inspection tool\n- [Flops counter Pytorch](https://github.com/sovrasov/flops-counter.pytorch): operation counter tool\n- [THOP](https://github.com/Lyken17/pytorch-OpCounter): PyTorch Op counter\n- Number of operations and memory estimation articles by [Matthijs Hollemans](https://machinethink.net/blog/how-fast-is-my-model/), and [Sicara](https://www.sicara.ai/blog/2019-28-10-deep-learning-memory-usage-and-pytorch-optimization-tricks)\n- [Pruning Convolutional Neural Networks for Resource Efficient Inference](https://arxiv.org/abs/1611.06440)\n\n\n## Citation\n\nIf you wish to cite this project, feel free to use this [BibTeX](http://www.bibtex.org/) reference:\n\n```bibtex\n@misc{torchscan2020,\n    title={Torchscan: meaningful module insights},\n    author={François-Guillaume Fernandez},\n    year={2020},\n    month={March},\n    publisher = {GitHub},\n    howpublished = {\\url{https://github.com/frgfm/torch-scan}}\n}\n```\n\n\n## Contributing\n\nAny sort of contribution is greatly appreciated!\n\nYou can find a short guide in [`CONTRIBUTING`](CONTRIBUTING.md) to help grow this project!\n\n\n\n## License\n\nDistributed under the Apache 2.0 License. See [`LICENSE`](LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrgfm%2Ftorch-scan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrgfm%2Ftorch-scan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrgfm%2Ftorch-scan/lists"}