🚀 THOP: PyTorch-OpCounter
THOP profiles PyTorch models by counting Multiply-Accumulate Operations (MACs) and parameters. It is lightweight, easy to extend, and maintained by Ultralytics.
📄 Description
THOP measures a model with one forward pass, making it useful for comparing architecture complexity before training or deployment. It includes counting rules for common convolutional, normalization, pooling, activation, linear, and recurrent layers, with support for custom rules.
📦 Installation
pip install ultralytics-thop
To install the latest development version:
pip install --upgrade git+https://github.com/ultralytics/thop.git
🛠️ How to Use
Basic Usage
Pass the model and a tuple of example inputs to profile():
import torch
from torchvision.models import resnet50
from thop import profile
model = resnet50()
inputs = (torch.randn(1, 3, 224, 224),)
macs, params = profile(model, inputs=inputs)
print(f"MACs: {macs}, Parameters: {params}")
# Expected output: MACs: 4133742592.0, Parameters: 25557032.0
For image models, pass the target-size input and the model stride to estimate MACs from smaller stride-aligned
profiles. profile() retains a single-profile fast path for spatial-only models, fits two points when size-independent
operations may be present, and falls back to the target input when the smaller inputs are unsuitable:
inputs = (torch.randn(1, 3, 640, 640),)
macs, params = profile(model, inputs=inputs, stride=32)
Calls that omit stride retain the exact profiling behavior shown in the basic example.
Define Custom Rules for Third-Party Modules
Map an unsupported module type to a forward-hook function. The hook receives the module, its inputs, and its output, then adds the operation count to module.total_ops.
import torch
from torch import nn
from thop import profile
def count_silu(module, inputs, output):
"""Count one operation per output element as a simple example."""
module.total_ops += output.numel()
model = nn.Sequential(nn.Conv2d(3, 64, 3, padding=1), nn.SiLU())
inputs = (torch.randn(1, 3, 224, 224),)
macs, params = profile(model, inputs=inputs, custom_ops={nn.SiLU: count_silu})
print(f"Custom MACs: {macs}, Parameters: {params}")
# Expected output: Custom MACs: 89915392.0, Parameters: 1792.0
Improve Output Readability
Use clever_format() to convert raw counts into human-readable values:
import torch
from torchvision.models import resnet50
from thop import clever_format, profile
model = resnet50()
inputs = (torch.randn(1, 3, 224, 224),)
macs, params = profile(model, inputs=inputs)
macs_readable, params_readable = clever_format([macs, params], "%.3f")
print(f"Formatted MACs: {macs_readable}, Formatted Parameters: {params_readable}")
# Expected output: Formatted MACs: 4.134G, Formatted Parameters: 25.557M
📊 Results of Recent Models
The following detection models were profiled at 640 × 640 from their fused architecture definitions using ultralytics==8.4.106. Install that version, then run python benchmark/evaluate_famous_models.py to reproduce the table without downloading model weights. FLOPs are often approximated as twice the MAC count.
| Model | size (pixels) |
params (M) |
MACs (B) |
|---|---|---|---|
| YOLOv8n | 640 | 3.15 | 4.37 |
| YOLOv8s | 640 | 11.16 | 14.30 |
| YOLOv8m | 640 | 25.89 | 39.47 |
| YOLOv8l | 640 | 43.67 | 82.58 |
| YOLOv8x | 640 | 68.20 | 128.91 |
| YOLO11n | 640 | 2.62 | 3.24 |
| YOLO11s | 640 | 9.44 | 10.74 |
| YOLO11m | 640 | 20.09 | 33.99 |
| YOLO11l | 640 | 25.34 | 43.46 |
| YOLO11x | 640 | 56.92 | 97.46 |
| YOLO26n | 640 | 2.41 | 2.68 |
| YOLO26s | 640 | 9.50 | 10.35 |
| YOLO26m | 640 | 20.41 | 34.09 |
| YOLO26l | 640 | 24.81 | 43.22 |
| YOLO26x | 640 | 55.73 | 96.94 |
🤝 Contribute
We thrive on community collaboration! THOP wouldn't be the tool it is without contributions from developers like you. Please see our Contributing Guide to get started. We also welcome your feedback—share your experience by completing our Survey. A huge Thank You 🙏 to everyone who contributes!
We look forward to your contributions to help make the Ultralytics ecosystem even better!
📜 License
Ultralytics offers two licensing options to suit different needs:
- AGPL-3.0 License: This OSI-approved open-source license is perfect for students, researchers, and enthusiasts. It encourages open collaboration and knowledge sharing. See the LICENSE file for full details.
- Ultralytics Enterprise License: For development and production use, this license enables seamless integration of Ultralytics software and AI models into business products and services, including internal tools, automated workflows, and production deployments, bypassing the open-source requirements of AGPL-3.0. To get started, please contact us via Ultralytics Licensing.
📞 Contact
For bug reports and feature requests related to THOP, please visit GitHub Issues. For questions, discussions, and community support, join our active communities on Discord, Reddit, and the Ultralytics Community Forums. We're here to help with all things Ultralytics!
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ultralytics_thop-2.1.1.tar.gz.
File metadata
- Download URL: ultralytics_thop-2.1.1.tar.gz
- Upload date:
- Size: 31.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae54d59adda9ebedf2202daa85bb5424b4b0ad4836647f83ae36d569e51d9567
|
|
| MD5 |
8a49e276669d688541cc9241475743c4
|
|
| BLAKE2b-256 |
d1bdc49ab753255d89a375723390ced8e46e01d3c41b863557b8ea2bbc9d497c
|
Provenance
The following attestation bundles were made for ultralytics_thop-2.1.1.tar.gz:
Publisher:
publish.yml on ultralytics/thop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ultralytics_thop-2.1.1.tar.gz -
Subject digest:
ae54d59adda9ebedf2202daa85bb5424b4b0ad4836647f83ae36d569e51d9567 - Sigstore transparency entry: 2273200479
- Sigstore integration time:
-
Permalink:
ultralytics/thop@163c0855572b5435da0b134ec3ac0f7e76000e1c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ultralytics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@163c0855572b5435da0b134ec3ac0f7e76000e1c -
Trigger Event:
push
-
Statement type:
File details
Details for the file ultralytics_thop-2.1.1-py3-none-any.whl.
File metadata
- Download URL: ultralytics_thop-2.1.1-py3-none-any.whl
- Upload date:
- Size: 25.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcc7cc361aea32bfb629fa46f1a4909605625999b7a77c43d2c8745d0216e4a6
|
|
| MD5 |
31c0cf4a79e74345fbd54542dc2d5b45
|
|
| BLAKE2b-256 |
bef78ef373ddc7821862c669d4897670fec0897c5df55eda72841e2ce9ef6c91
|
Provenance
The following attestation bundles were made for ultralytics_thop-2.1.1-py3-none-any.whl:
Publisher:
publish.yml on ultralytics/thop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ultralytics_thop-2.1.1-py3-none-any.whl -
Subject digest:
bcc7cc361aea32bfb629fa46f1a4909605625999b7a77c43d2c8745d0216e4a6 - Sigstore transparency entry: 2273200547
- Sigstore integration time:
-
Permalink:
ultralytics/thop@163c0855572b5435da0b134ec3ac0f7e76000e1c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ultralytics
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@163c0855572b5435da0b134ec3ac0f7e76000e1c -
Trigger Event:
push
-
Statement type: