Flake8 plugin to prohibit calling .forward() on objects (use obj(inputs) instead so DDP backward hooks run)
Project description
flake8-no-model-forward-call
A flake8 plugin that forbids calling .forward() directly on PyTorch nn.Module objects.
Why?
Calling model.forward(inputs) bypasses nn.Module.__call__, which means PyTorch hooks are silently skipped — including the backward hooks that DistributedDataParallel (DDP) relies on for gradient synchronization.
# Bad — DDP backward hooks won't run, gradients won't sync
loss = model.forward(inputs)
# Good — goes through __call__, all hooks fire correctly
loss = model(inputs)
This bug is easy to introduce, hard to notice (training may appear to work), and can silently corrupt distributed training runs.
Installation
pip install flake8-no-model-forward-call
For development / editable install:
git clone https://github.com/mrsndmn/flake8-no-model-forward-call.git
cd flake8-no-model-forward-call
pip install -e .
Usage
Run flake8 with the check enabled:
flake8 --extend-select=NMF001 .
Or add it to your flake8 config so it runs automatically:
.flake8 / setup.cfg:
[flake8]
extend-select = NMF001
max-line-length = 128
pyproject.toml:
[tool.flake8]
extend-select = ["NMF001"]
max-line-length = 128
Error codes
| Code | Message |
|---|---|
| NMF001 | Do not call .forward() directly; use model(inputs) instead so DDP backward hooks run |
Example
import torch.nn as nn
class MyModel(nn.Module):
def forward(self, x):
return x * 2
model = MyModel()
model.forward(x) # NMF001 — flagged
model(x) # OK
Running flake8:
example.py:10:1: NMF001 Do not call .forward() directly; use model(inputs) instead so DDP backward hooks run
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b my-feature - Install dev dependencies:
pip install -e ".[dev]" - Run tests:
pytest - Open a pull request
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
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 flake8_no_module_forward_call-0.1.0.tar.gz.
File metadata
- Download URL: flake8_no_module_forward_call-0.1.0.tar.gz
- Upload date:
- Size: 3.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63160f1db8968ae2441ebd7aefcb91a5e8cd3b47545ee21c784349ccb9ef4609
|
|
| MD5 |
59758970fd43fb313f4cfc67aa8faeb2
|
|
| BLAKE2b-256 |
8678426719d8c0340a3b8e152b299a790fea422eb56bede304dc4056bb081580
|
File details
Details for the file flake8_no_module_forward_call-0.1.0-py3-none-any.whl.
File metadata
- Download URL: flake8_no_module_forward_call-0.1.0-py3-none-any.whl
- Upload date:
- Size: 3.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2093d3725b5a01c93f970e31f7e5a8a138caaebbab618be30dbae931cb822ee6
|
|
| MD5 |
8e78596d954c5c55ab89b6d4495ce64a
|
|
| BLAKE2b-256 |
a81accaf7a2b1a430d64cd06f2b9c956657fc21ce847752601bf9afa88218214
|