{"id":14958653,"url":"https://github.com/tyleryep/torchinfo","last_synced_at":"2025-05-11T11:13:46.673Z","repository":{"id":37535557,"uuid":"247821912","full_name":"TylerYep/torchinfo","owner":"TylerYep","description":"View model summaries in PyTorch!","archived":false,"fork":false,"pushed_at":"2025-05-05T18:44:36.000Z","size":834,"stargazers_count":2779,"open_issues_count":56,"forks_count":127,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-05-11T11:13:34.180Z","etag":null,"topics":["keras","python","pytorch","torch","torch-summary","torchinfo","torchsummary","torchvision","visualization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TylerYep.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-03-16T21:41:29.000Z","updated_at":"2025-05-09T09:40:06.000Z","dependencies_parsed_at":"2024-01-27T20:26:32.801Z","dependency_job_id":"5c131082-6221-4123-9bd6-c739beca4feb","html_url":"https://github.com/TylerYep/torchinfo","commit_stats":{"total_commits":382,"total_committers":23,"mean_commits":"16.608695652173914","dds":0.7303664921465969,"last_synced_commit":"c229b2718f122bafa4eb75a6013fe65e66c6fa91"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TylerYep%2Ftorchinfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TylerYep%2Ftorchinfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TylerYep%2Ftorchinfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TylerYep%2Ftorchinfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TylerYep","download_url":"https://codeload.github.com/TylerYep/torchinfo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253554120,"owners_count":21926615,"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":["keras","python","pytorch","torch","torch-summary","torchinfo","torchsummary","torchvision","visualization"],"created_at":"2024-09-24T13:17:44.500Z","updated_at":"2025-05-11T11:13:46.654Z","avatar_url":"https://github.com/TylerYep.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# torchinfo\n\n[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/release/python-380/)\n[![PyPI version](https://badge.fury.io/py/torchinfo.svg)](https://badge.fury.io/py/torchinfo)\n[![Conda version](https://img.shields.io/conda/vn/conda-forge/torchinfo)](https://anaconda.org/conda-forge/torchinfo)\n[![Build Status](https://github.com/TylerYep/torchinfo/actions/workflows/test.yml/badge.svg)](https://github.com/TylerYep/torchinfo/actions/workflows/test.yml)\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/TylerYep/torchinfo/main.svg)](https://results.pre-commit.ci/latest/github/TylerYep/torchinfo/main)\n[![GitHub license](https://img.shields.io/github/license/TylerYep/torchinfo)](https://github.com/TylerYep/torchinfo/blob/main/LICENSE)\n[![codecov](https://codecov.io/gh/TylerYep/torchinfo/branch/main/graph/badge.svg)](https://codecov.io/gh/TylerYep/torchinfo)\n[![Downloads](https://pepy.tech/badge/torchinfo)](https://pepy.tech/project/torchinfo)\n\n(formerly torch-summary)\n\nTorchinfo provides information complementary to what is provided by `print(your_model)` in PyTorch, similar to Tensorflow's `model.summary()` API to view the visualization of the model, which is helpful while debugging your network. In this project, we implement a similar functionality in PyTorch and create a clean, simple interface to use in your projects.\n\nThis is a completely rewritten version of the original torchsummary and torchsummaryX projects by @sksq96 and @nmhkahn. This project addresses all of the issues and pull requests left on the original projects by introducing a completely new API.\n\nSupports PyTorch versions 1.4.0+.\n\n# Usage\n\n```\npip install torchinfo\n```\n\nAlternatively, via conda:\n\n```\nconda install -c conda-forge torchinfo\n```\n\n# How To Use\n\n```python\nfrom torchinfo import summary\n\nmodel = ConvNet()\nbatch_size = 16\nsummary(model, input_size=(batch_size, 1, 28, 28))\n```\n\n```\n================================================================================================================\nLayer (type:depth-idx)          Input Shape          Output Shape         Param #            Mult-Adds\n================================================================================================================\nSingleInputNet                  [7, 1, 28, 28]       [7, 10]              --                 --\n├─Conv2d: 1-1                   [7, 1, 28, 28]       [7, 10, 24, 24]      260                1,048,320\n├─Conv2d: 1-2                   [7, 10, 12, 12]      [7, 20, 8, 8]        5,020              2,248,960\n├─Dropout2d: 1-3                [7, 20, 8, 8]        [7, 20, 8, 8]        --                 --\n├─Linear: 1-4                   [7, 320]             [7, 50]              16,050             112,350\n├─Linear: 1-5                   [7, 50]              [7, 10]              510                3,570\n================================================================================================================\nTotal params: 21,840\nTrainable params: 21,840\nNon-trainable params: 0\nTotal mult-adds (M): 3.41\n================================================================================================================\nInput size (MB): 0.02\nForward/backward pass size (MB): 0.40\nParams size (MB): 0.09\nEstimated Total Size (MB): 0.51\n================================================================================================================\n```\n\n\u003c!-- single_input_all_cols.out --\u003e\n\nNote: if you are using a Jupyter Notebook or Google Colab, `summary(model, ...)` must be the returned value of the cell.\nIf it is not, you should wrap the summary in a print(), e.g. `print(summary(model, ...))`.\nSee `tests/jupyter_test.ipynb` for examples.\n\n**This version now supports:**\n\n- RNNs, LSTMs, and other recursive layers\n- Branching output used to explore model layers using specified depths\n- Returns ModelStatistics object containing all summary data fields\n- Configurable rows/columns\n- Jupyter Notebook / Google Colab\n\n**Other new features:**\n\n- Verbose mode to show weights and bias layers\n- Accepts either input data or simply the input shape!\n- Customizable line widths and batch dimension\n- Comprehensive unit/output testing, linting, and code coverage testing\n\n**Community Contributions:**\n\n- Sequentials \u0026 ModuleLists (thanks to @roym899)\n- Improved Mult-Add calculations (thanks to @TE-StefanUhlich, @zmzhang2000)\n- Dict/Misc input data (thanks to @e-dorigatti)\n- Pruned layer support (thanks to @MajorCarrot)\n\n# Documentation\n\n```python\ndef summary(\n    model: nn.Module,\n    input_size: Optional[INPUT_SIZE_TYPE] = None,\n    input_data: Optional[INPUT_DATA_TYPE] = None,\n    batch_dim: Optional[int] = None,\n    cache_forward_pass: Optional[bool] = None,\n    col_names: Optional[Iterable[str]] = None,\n    col_width: int = 25,\n    depth: int = 3,\n    device: Optional[torch.device] = None,\n    dtypes: Optional[List[torch.dtype]] = None,\n    mode: str = \"same\",\n    row_settings: Optional[Iterable[str]] = None,\n    verbose: int = 1,\n    **kwargs: Any,\n) -\u003e ModelStatistics:\n\"\"\"\nSummarize the given PyTorch model. Summarized information includes:\n    1) Layer names,\n    2) input/output shapes,\n    3) kernel shape,\n    4) # of parameters,\n    5) # of operations (Mult-Adds),\n    6) whether layer is trainable\n\nNOTE: If neither input_data or input_size are provided, no forward pass through the\nnetwork is performed, and the provided model information is limited to layer names.\n\nArgs:\n    model (nn.Module):\n            PyTorch model to summarize. The model should be fully in either train()\n            or eval() mode. If layers are not all in the same mode, running summary\n            may have side effects on batchnorm or dropout statistics. If you\n            encounter an issue with this, please open a GitHub issue.\n\n    input_size (Sequence of Sizes):\n            Shape of input data as a List/Tuple/torch.Size\n            (dtypes must match model input, default is FloatTensors).\n            You should include batch size in the tuple.\n            Default: None\n\n    input_data (Sequence of Tensors):\n            Arguments for the model's forward pass (dtypes inferred).\n            If the forward() function takes several parameters, pass in a list of\n            args or a dict of kwargs (if your forward() function takes in a dict\n            as its only argument, wrap it in a list).\n            Default: None\n\n    batch_dim (int):\n            Batch_dimension of input data. If batch_dim is None, assume\n            input_data / input_size contains the batch dimension, which is used\n            in all calculations. Else, expand all tensors to contain the batch_dim.\n            Specifying batch_dim can be an runtime optimization, since if batch_dim\n            is specified, torchinfo uses a batch size of 1 for the forward pass.\n            Default: None\n\n    cache_forward_pass (bool):\n            If True, cache the run of the forward() function using the model\n            class name as the key. If the forward pass is an expensive operation,\n            this can make it easier to modify the formatting of your model\n            summary, e.g. changing the depth or enabled column types, especially\n            in Jupyter Notebooks.\n            WARNING: Modifying the model architecture or input data/input size when\n            this feature is enabled does not invalidate the cache or re-run the\n            forward pass, and can cause incorrect summaries as a result.\n            Default: False\n\n    col_names (Iterable[str]):\n            Specify which columns to show in the output. Currently supported: (\n                \"input_size\",\n                \"output_size\",\n                \"num_params\",\n                \"params_percent\",\n                \"kernel_size\",\n                \"groups\",\n                \"mult_adds\",\n                \"trainable\",\n            )\n            Default: (\"output_size\", \"num_params\")\n            If input_data / input_size are not provided, only \"num_params\" is used.\n\n    col_width (int):\n            Width of each column.\n            Default: 25\n\n    depth (int):\n            Depth of nested layers to display (e.g. Sequentials).\n            Nested layers below this depth will not be displayed in the summary.\n            Default: 3\n\n    device (torch.Device):\n            Uses this torch device for model and input_data.\n            If not specified, uses the dtype of input_data if given, or the\n            parameters of the model. Otherwise, uses the result of\n            torch.cuda.is_available().\n            Default: None\n\n    dtypes (List[torch.dtype]):\n            If you use input_size, torchinfo assumes your input uses FloatTensors.\n            If your model use a different data type, specify that dtype.\n            For multiple inputs, specify the size of both inputs, and\n            also specify the types of each parameter here.\n            Default: None\n\n    mode (str)\n            Either \"train\", \"eval\" or \"same\", which determines whether we call\n            model.train() or model.eval() before calling summary(). In any case,\n            original model mode is restored at the end.\n            Default: \"same\".\n\n    row_settings (Iterable[str]):\n            Specify which features to show in a row. Currently supported: (\n                \"ascii_only\",\n                \"depth\",\n                \"var_names\",\n            )\n            Default: (\"depth\",)\n\n    verbose (int):\n            0 (quiet): No output\n            1 (default): Print model summary\n            2 (verbose): Show weight and bias layers in full detail\n            Default: 1\n            If using a Juypter Notebook or Google Colab, the default is 0.\n\n    **kwargs:\n            Other arguments used in `model.forward` function. Passing *args is no\n            longer supported.\n\nReturn:\n    ModelStatistics object\n            See torchinfo/model_statistics.py for more information.\n\"\"\"\n```\n\n# Examples\n\n## Get Model Summary as String\n\n```python\nfrom torchinfo import summary\n\nmodel_stats = summary(your_model, (1, 3, 28, 28), verbose=0)\nsummary_str = str(model_stats)\n# summary_str contains the string representation of the summary!\n```\n\n## Explore Different Configurations\n\n```python\nclass LSTMNet(nn.Module):\n    def __init__(self, vocab_size=20, embed_dim=300, hidden_dim=512, num_layers=2):\n        super().__init__()\n        self.hidden_dim = hidden_dim\n        self.embedding = nn.Embedding(vocab_size, embed_dim)\n        self.encoder = nn.LSTM(embed_dim, hidden_dim, num_layers=num_layers, batch_first=True)\n        self.decoder = nn.Linear(hidden_dim, vocab_size)\n\n    def forward(self, x):\n        embed = self.embedding(x)\n        out, hidden = self.encoder(embed)\n        out = self.decoder(out)\n        out = out.view(-1, out.size(2))\n        return out, hidden\n\nsummary(\n    LSTMNet(),\n    (1, 100),\n    dtypes=[torch.long],\n    verbose=2,\n    col_width=16,\n    col_names=[\"kernel_size\", \"output_size\", \"num_params\", \"mult_adds\"],\n    row_settings=[\"var_names\"],\n)\n```\n\n```\n========================================================================================================================\nLayer (type (var_name))                  Kernel Shape         Output Shape         Param #              Mult-Adds\n========================================================================================================================\nLSTMNet (LSTMNet)                        --                   [100, 20]            --                   --\n├─Embedding (embedding)                  --                   [1, 100, 300]        6,000                6,000\n│    └─weight                            [300, 20]                                 └─6,000\n├─LSTM (encoder)                         --                   [1, 100, 512]        3,768,320            376,832,000\n│    └─weight_ih_l0                      [2048, 300]                               ├─614,400\n│    └─weight_hh_l0                      [2048, 512]                               ├─1,048,576\n│    └─bias_ih_l0                        [2048]                                    ├─2,048\n│    └─bias_hh_l0                        [2048]                                    ├─2,048\n│    └─weight_ih_l1                      [2048, 512]                               ├─1,048,576\n│    └─weight_hh_l1                      [2048, 512]                               ├─1,048,576\n│    └─bias_ih_l1                        [2048]                                    ├─2,048\n│    └─bias_hh_l1                        [2048]                                    └─2,048\n├─Linear (decoder)                       --                   [1, 100, 20]         10,260               10,260\n│    └─weight                            [512, 20]                                 ├─10,240\n│    └─bias                              [20]                                      └─20\n========================================================================================================================\nTotal params: 3,784,580\nTrainable params: 3,784,580\nNon-trainable params: 0\nTotal mult-adds (M): 376.85\n========================================================================================================================\nInput size (MB): 0.00\nForward/backward pass size (MB): 0.67\nParams size (MB): 15.14\nEstimated Total Size (MB): 15.80\n========================================================================================================================\n\n```\n\n\u003c!-- lstm.out --\u003e\n\n## ResNet\n\n```python\nimport torchvision\n\nmodel = torchvision.models.resnet152()\nsummary(model, (1, 3, 224, 224), depth=3)\n```\n\n```\n==========================================================================================\nLayer (type:depth-idx)                   Output Shape              Param #\n==========================================================================================\nResNet                                   [1, 1000]                 --\n├─Conv2d: 1-1                            [1, 64, 112, 112]         9,408\n├─BatchNorm2d: 1-2                       [1, 64, 112, 112]         128\n├─ReLU: 1-3                              [1, 64, 112, 112]         --\n├─MaxPool2d: 1-4                         [1, 64, 56, 56]           --\n├─Sequential: 1-5                        [1, 256, 56, 56]          --\n│    └─Bottleneck: 2-1                   [1, 256, 56, 56]          --\n│    │    └─Conv2d: 3-1                  [1, 64, 56, 56]           4,096\n│    │    └─BatchNorm2d: 3-2             [1, 64, 56, 56]           128\n│    │    └─ReLU: 3-3                    [1, 64, 56, 56]           --\n│    │    └─Conv2d: 3-4                  [1, 64, 56, 56]           36,864\n│    │    └─BatchNorm2d: 3-5             [1, 64, 56, 56]           128\n│    │    └─ReLU: 3-6                    [1, 64, 56, 56]           --\n│    │    └─Conv2d: 3-7                  [1, 256, 56, 56]          16,384\n│    │    └─BatchNorm2d: 3-8             [1, 256, 56, 56]          512\n│    │    └─Sequential: 3-9              [1, 256, 56, 56]          16,896\n│    │    └─ReLU: 3-10                   [1, 256, 56, 56]          --\n│    └─Bottleneck: 2-2                   [1, 256, 56, 56]          --\n\n  ...\n  ...\n  ...\n\n├─AdaptiveAvgPool2d: 1-9                 [1, 2048, 1, 1]           --\n├─Linear: 1-10                           [1, 1000]                 2,049,000\n==========================================================================================\nTotal params: 60,192,808\nTrainable params: 60,192,808\nNon-trainable params: 0\nTotal mult-adds (G): 11.51\n==========================================================================================\nInput size (MB): 0.60\nForward/backward pass size (MB): 360.87\nParams size (MB): 240.77\nEstimated Total Size (MB): 602.25\n==========================================================================================\n```\n\n\u003c!-- resnet152.out --\u003e\n\n## Multiple Inputs w/ Different Data Types\n\n```python\nclass MultipleInputNetDifferentDtypes(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.fc1a = nn.Linear(300, 50)\n        self.fc1b = nn.Linear(50, 10)\n\n        self.fc2a = nn.Linear(300, 50)\n        self.fc2b = nn.Linear(50, 10)\n\n    def forward(self, x1, x2):\n        x1 = F.relu(self.fc1a(x1))\n        x1 = self.fc1b(x1)\n        x2 = x2.type(torch.float)\n        x2 = F.relu(self.fc2a(x2))\n        x2 = self.fc2b(x2)\n        x = torch.cat((x1, x2), 0)\n        return F.log_softmax(x, dim=1)\n\nsummary(model, [(1, 300), (1, 300)], dtypes=[torch.float, torch.long])\n```\n\nAlternatively, you can also pass in the input_data itself, and\ntorchinfo will automatically infer the data types.\n\n```python\ninput_data = torch.randn(1, 300)\nother_input_data = torch.randn(1, 300).long()\nmodel = MultipleInputNetDifferentDtypes()\n\nsummary(model, input_data=[input_data, other_input_data, ...])\n```\n\n## Sequentials \u0026 ModuleLists\n\n```python\nclass ContainerModule(nn.Module):\n\n    def __init__(self):\n        super().__init__()\n        self._layers = nn.ModuleList()\n        self._layers.append(nn.Linear(5, 5))\n        self._layers.append(ContainerChildModule())\n        self._layers.append(nn.Linear(5, 5))\n\n    def forward(self, x):\n        for layer in self._layers:\n            x = layer(x)\n        return x\n\n\nclass ContainerChildModule(nn.Module):\n\n    def __init__(self):\n        super().__init__()\n        self._sequential = nn.Sequential(nn.Linear(5, 5), nn.Linear(5, 5))\n        self._between = nn.Linear(5, 5)\n\n    def forward(self, x):\n        out = self._sequential(x)\n        out = self._between(out)\n        for l in self._sequential:\n            out = l(out)\n\n        out = self._sequential(x)\n        for l in self._sequential:\n            out = l(out)\n        return out\n\nsummary(ContainerModule(), (1, 5))\n```\n\n```\n==========================================================================================\nLayer (type:depth-idx)                   Output Shape              Param #\n==========================================================================================\nContainerModule                          [1, 5]                    --\n├─ModuleList: 1-1                        --                        --\n│    └─Linear: 2-1                       [1, 5]                    30\n│    └─ContainerChildModule: 2-2         [1, 5]                    --\n│    │    └─Sequential: 3-1              [1, 5]                    --\n│    │    │    └─Linear: 4-1             [1, 5]                    30\n│    │    │    └─Linear: 4-2             [1, 5]                    30\n│    │    └─Linear: 3-2                  [1, 5]                    30\n│    │    └─Sequential: 3-3              --                        (recursive)\n│    │    │    └─Linear: 4-3             [1, 5]                    (recursive)\n│    │    │    └─Linear: 4-4             [1, 5]                    (recursive)\n│    │    └─Sequential: 3-4              [1, 5]                    (recursive)\n│    │    │    └─Linear: 4-5             [1, 5]                    (recursive)\n│    │    │    └─Linear: 4-6             [1, 5]                    (recursive)\n│    │    │    └─Linear: 4-7             [1, 5]                    (recursive)\n│    │    │    └─Linear: 4-8             [1, 5]                    (recursive)\n│    └─Linear: 2-3                       [1, 5]                    30\n==========================================================================================\nTotal params: 150\nTrainable params: 150\nNon-trainable params: 0\nTotal mult-adds (M): 0.00\n==========================================================================================\nInput size (MB): 0.00\nForward/backward pass size (MB): 0.00\nParams size (MB): 0.00\nEstimated Total Size (MB): 0.00\n==========================================================================================\n```\n\n\u003c!-- container.out --\u003e\n\n# Contributing\n\nAll issues and pull requests are much appreciated! If you are wondering how to build the project:\n\n- torchinfo is actively developed using the lastest version of Python.\n  - Changes should be backward compatible to Python 3.8, and will follow Python's End-of-Life guidance for old versions.\n  - Run `pip install -r requirements-dev.txt`. We use the latest versions of all dev packages.\n  - Run `pre-commit install`.\n  - To use auto-formatting tools, use `pre-commit run -a`.\n  - To run unit tests, run `pytest`.\n  - To update the expected output files, run `pytest --overwrite`.\n  - To skip output file tests, use `pytest --no-output`\n\n# References\n\n- Thanks to @sksq96, @nmhkahn, and @sangyx for providing the inspiration for this project.\n- For Model Size Estimation @jacobkimmel ([details here](https://github.com/sksq96/pytorch-summary/pull/21))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftyleryep%2Ftorchinfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftyleryep%2Ftorchinfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftyleryep%2Ftorchinfo/lists"}