# What changed in ultralytics-thop

> 51 changes in ultralytics-thop 2 from its official release notes, upgrade guides and advisories: 2 breaking, 1 deprecations, 3 new APIs and options. Each one cited. Sources checked 2026-10-19. HTML: https://unstale.sh/pypi/ultralytics-thop/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## ultralytics-thop 2

### Breaking changes

- Rejects modules that already use total_ops for parameters, child modules, or class-level properties, preventing profiling from silently corrupting module structure or reported totals. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- The broken, unused fx_profile implementation was removed; code that depends on it must migrate to the standard profile API. (2.1.0) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.0)

### Deprecations

- Embedding layers using max_norm emit a warning because their data-dependent renormalization is not counted. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)

### New APIs and options

- Adds the min_cells argument to start proxy measurements at a larger size, which can help when model costs change behavior below a certain input size. (2.2.0) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.2.0)
- Custom counting rules can be callable objects or functools.partial instances and receive arguments from keyword, positional, or mixed module calls. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Adds an optional stride argument for image models, enabling smaller stride-aligned inputs and more accurate estimates when fixed-cost layers are present. (2.1.1) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.1)

### Performance

- Explicitly registered as a zero-MAC operation, reducing missing-rule warnings and profiling overhead. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Explicitly registered as a zero-MAC operation, reducing missing-rule warnings and profiling overhead. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Explicitly registered as a zero-MAC operation, reducing missing-rule warnings and profiling overhead. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Profiling overhead is reduced by up to 2.4× while preserving bit-exact results; get_flops is approximately 1.31× faster overall across the tested Ultralytics model configurations. (2.1.0) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.0)

### Behavior and default changes

- THOP now counts two-operand einsum operations in FLOPs estimates; one-operand calls and calls with more than two operands remain uncounted by this rule. (2.2.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.2.2)
- On PyTorch 1.13 and later, profile() counts functional matrix products and scaled_dot_product_attention when available, without recounting products inside modules with their own counting rule. (2.2.0) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.2.0)
- For models that may have quadratic costs, profile() uses measurements at several smaller sizes, validates a quadratic estimate, and profiles at the target size if the measurements do not support it. (2.2.0) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.2.0)
- Adds support for ModuleList, ModuleDict, ParameterList, and ParameterDict containers during profiling. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- Stride-based shortcut estimation is disabled for models containing attention; they use exact target-size profiling instead. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- THOP counts projection layers, attention matrix operations, and softmax processing for batched and unbatched, cross-attention, and other supported calls. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Rules resolve through a module type’s inheritance hierarchy, allowing custom subclasses, parametrized layers, and many lazy modules to inherit the nearest supported rule. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)

### Tooling

- Publish runs are queued and failed PyPI uploads retried; workflows can recover partially completed releases, reuse existing tags, and replace incomplete SBOM files. (2.0.21) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.21)

### Fixes and other changes

- Adaptive max pools and nn.Bilinear are treated as fixed-size operations during extrapolation, preventing FLOPs from being overcounted for affected models. (2.2.1) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.2.1)
- Custom operations that may have nonlinear computational costs use direct profiling instead of inaccurate linear extrapolation. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- Embedding lookups are treated as data gathering rather than arithmetic computation. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- Profiling accounts for projection work and reduced recurrent width in LSTM layers with proj_size. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- Recognized as performing no arithmetic operations during profiling. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- Packed RNN, GRU, and LSTM inputs are counted using their actual processed sequence steps instead of the larger padded shape. (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- Applies custom profiling rules to composite modules, matching the behavior of profile(). (2.1.6) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.6)
- Attention profiling skips MAC counting when older PyTorch versions cannot expose hook keyword arguments, avoiding unsafe calls while preserving accurate counts on PyTorch 2.x. (2.1.5) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.5)
- THOP now counts operations for nn.Bilinear layers instead of treating them as free, improving FLOPs/MACs estimates. (2.1.4) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.4)
- Fixed and adaptive average-pooling counts account for window sizes, padding, boundary behavior, ceil_mode, and count_include_pad. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Now counted, including additional elementwise work and correct handling of empty normalization dimensions. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Now counted, including additional elementwise work and correct handling of empty normalization dimensions. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Now counted, including additional elementwise work and correct handling of empty normalization dimensions. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Explicitly registered as a zero-MAC operation, reducing missing-rule warnings and profiling overhead. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Both profiler entry points count the forward pass that actually executed, including when inference replaces or detaches submodules. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Existing total_ops attributes and buffers are preserved during profiling and restored afterward, preventing model state from being overwritten. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Convolution and RNN/GRU/LSTM profilers correctly interpret channel, batch, and sequence dimensions for batched and unbatched layouts. (2.1.3) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3)
- Counts follow the integer pooling windows PyTorch uses, improving MAC estimates when output sizes do not evenly divide the input. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- Exact powers of 1,000 and negative values receive the correct units. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- These module families are handled through shared base classes. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- LeakyReLU is explicitly treated as a zero-MAC operation. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- Nearest and nearest-exact upsampling are counted as requiring zero arithmetic operations. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- GroupNorm and RMSNorm use the existing normalization rule, and lazy normalization modules receive more reliable rule resolution. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- Parameter totals come from the model’s parameter tree rather than profiling hooks, correctly handling shared weights, unused branches, unsupported module types, and parent-owned parameters. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- ReLU is explicitly treated as a zero-MAC operation. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- Model training modes are restored more reliably after profiling. (2.1.2) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.3), [release notes](https://github.com/ultralytics/thop/releases/tag/v2.1.2)
- Profiling restores the model’s previous training or evaluation mode after profiling completes or fails. (2.0.22) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.22)
- Temporary hooks and operation-counting buffers are removed even when the model’s forward pass raises an error, preventing profiling state from remaining attached to the model. (2.0.22) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.22)
- The profiler avoids duplicate operation and parameter totals when the same module is reached through multiple paths. (2.0.22) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.22)
- Modules referenced by multiple parent layers are hooked only once, avoiding orphaned hook handles. (2.0.22) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.22)
- profile() removes temporary hooks and total_ops/total_params buffers from every module it touches, preventing profiling metadata from affecting state_dict() or shared modules while preserving results. (2.0.21) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.21)
- The package now declares Python 3.14 compatibility in its metadata, helping users and tools recognize support for that version. (2.0.20) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.20)
- Profiling now counts a module’s own parameters and avoids double-counting child parameters, improving totals for nested module structures. (2.0.19) — [release notes](https://github.com/ultralytics/thop/releases/tag/v2.0.19)
