FastestDet: a 240K-parameter anchor-free detector for ARM CPUs
:zap: A newly designed ultra lightweight anchor free target detection algorithm, weight only 250K parameters, reduces the time consumption by 10% compared with yolo-fastest, and the post-processing is simpler
At a glance
- What is it?
- FastestDet is a single-scale, anchor-free object detector aimed at CPU-only edge boards. Its own benchmark table puts it marginally ahead of Yolo-FastestV2 at 352x352, but the same table shows a 13.0 percent mAP at IoU 0.50:0.95, which tells you where the ceiling sits.
- Who is it for?
- Adopt FastestDet when you are shipping a fixed-class detector onto an ARM CPU board and can accept roughly 25 percent mAP at IoU 0.50 with weak small-object recall. Do not adopt it for dense scenes, small objects, or anything needing a multi-scale head.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 126 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem FastestDet is built for: detection on a CPU with no accelerator
Most object detectors assume you have a GPU somewhere, either at training time or at inference. FastestDet assumes you do not. The benchmark table lists a Radxa Rock3A with an RK3568 Cortex-A55 running ncnn at 70.62ms single core and 23.51ms across four cores, both at a locked 2.0GHz. A Snapdragon 835 on Android lands at 32.34ms single core. These are the numbers the project is selling against, and they are the numbers that matter if you are putting a detector on a board that costs less than the camera attached to it.
The target user is someone who already tried Yolo-Fastest or Yolo-FastestV2 and wants either a smaller weight file or less post-processing code. The README states the weight is 0.24M parameters, against 0.25M for yolo-fastestv2 and 0.35M for yolo-fastestv1.1. That is not a dramatic reduction. The more interesting claim is the post-processing: the README says FastestDet has "simpler feature map post-processing than Yolo-fastest", which matters because decoding anchor boxes on a microcontroller-class CPU is often a larger share of latency than the network itself.
If your deployment target is a Jetson, a desktop, or a phone with a usable NPU, this project is solving a problem you do not have, and you are paying for it in accuracy.
What anchor-free and single-scale actually change in the architecture
The improvement list in the README is short and specific: anchor-free, single scale detector head, cross grid multiple candidate targets, and dynamic positive and negative sample allocation. Each of those removes work.
Anchor-free means the head predicts box geometry directly rather than offsets from a set of predefined anchor shapes. That removes the anchor-matching step at training time and the anchor-decoding step at inference. It also removes the anchor hyperparameters (scales, aspect ratios, IoU thresholds for assignment) that normally have to be retuned whenever you change dataset or input resolution.
Single scale means one feature map, not the three-level pyramid that yolov5s and most modern detectors use. This is the design decision that most directly explains the accuracy gap. A 352x352 input with one detection head gives you one stride, so small objects have very few spatial positions to land on. The COCO evaluation output pasted into the README shows the cost: AP at IoU 0.50:0.95 for small objects is 0.021, against 0.129 for medium objects and 0.130 overall. Small-object AP is roughly one sixth of the overall figure. That is the single most important number in the whole document.
Cross grid multiple candidate targets and dynamic sample allocation are the compensation mechanism. Instead of assigning each ground-truth box to one grid cell, the training procedure lets multiple candidates across grid boundaries compete, and the positive/negative assignment is decided dynamically rather than by a fixed rule. The README does not describe the assignment algorithm in detail, so anyone who needs to modify it will be reading the training code rather than the documentation.
The 2022.7.14 loss change and what it did to the reported AP
The first line of the README is a dated changelog entry: on 2022.7.14 the loss was changed to use IOU-aware weighting based on smooth L1, and the README states AP increased significantly by 0.7. The released checkpoint filename is weight_AP05:0.253207_280-epoch.pth, which encodes both the score and the epoch, so the 0.253 in the benchmark table is traceable to a specific artifact rather than a vague claim.
That is a useful level of traceability and it is also a warning. A 0.7 point AP gain from a loss reweighting, on a model whose headline AP at IoU 0.50 is 25.3 percent, is a large relative move. It suggests the model is sensitive to training configuration. If you fine-tune on your own data, expect the loss weighting to matter more than it would on a larger backbone where the head has more capacity to absorb a poorly shaped objective.
The README does not state whether the 280-epoch checkpoint was trained with the new loss or the old one. The date on the changelog is twelve days after the v1.0 release, and the filename carries no loss-version marker. Anyone reproducing the 0.253 number should verify this before treating it as a baseline.
Dataset layout follows Darknet Yolo, not COCO JSON
FastestDet does not read COCO JSON annotations. The README states the dataset is constructed the same way as Darknet Yolo: each image has a same-named .txt file in the same directory, with one line per object in the format "category cx cy wh", where cx and cy are normalized center coordinates and w and h are normalized width and height. The README gives this example:
11 0.344192634561 0.611 0.416430594901 0.262
On top of the per-image labels you need three more files. train.txt and val.txt are plain lists of absolute image paths, one per line. A .names file holds the class names, one per line, in index order. The README shows the final layout as a directory containing category.names, train/, train.txt, val/, and val.txt.
This is a real constraint, not a formality. If your annotations are in COCO JSON, Pascal VOC XML, or a database, you are writing a converter before you write any training code. The upside is that the format is simple enough that the converter is short, and it is the same format used by Yolo-Fastest and Yolo-FastestV2, so if you are migrating between those projects your data pipeline carries over unchanged.
Config keys, training and evaluation commands
Installation is a single requirements file: pip install -r requirements.txt. The README notes to check the PyTorch CUDA version selection, which is the only environment caveat it gives.
The model and training settings live in a YAML file modeled on configs/coco.yaml. The keys are grouped into three blocks. DATASET holds TRAIN and VAL (paths to the two path-list files) and NAMES (the .names file). MODEL holds NC for the number of classes, plus INPUT_WIDTH and INPUT_HEIGHT, both 352 in the shipped config. TRAIN holds LR at 0.001, WARMUP as a boolean, BATCH_SIZE at 64, END_EPOCH at 350, and MILESTIONES as a list of epoch numbers where the learning rate drops (150, 250, 300). Note the spelling: MILESTIONES, not MILESTONES. Getting that wrong will silently leave your learning rate schedule inert unless the code validates unknown keys, which the README does not say.
The TRAIN block also contains a THRESH key set to 0.25, annotated in the README with four question marks. That annotation is still there. It is an honest admission that the author himself does not consider the key documented, and it means you should read the training code before assuming THRESH does what you expect.
Three commands cover the workflow:
python3 test.py --yaml configs/coco.yaml --weight weights/weight_AP05:0.253207_280-epoch.pth --img data/3.jpg
python3 train.py --yaml configs/coco.yaml
python3 eval.py --yaml configs/coco.yaml --weight weights/weight_AP05:0.253207_280-epoch.pth
The test command takes a single image path via --img, so there is no batch inference entry point documented. If you need to run a directory of images you are writing that loop yourself.
Where FastestDet loses to its own alternatives
The benchmark table is the most useful part of the repository because it includes the models FastestDet is meant to replace. Against yolo-fastestv2 at 352x352, FastestDet reports 25.3 percent mAP at IoU 0.50 versus 24.10 percent, at 23.51ms versus 23.8ms on four cores and 70.62ms versus 68.9ms on one core. So the accuracy gain is 1.2 points and the single-core latency is slightly worse. The README's claim of being 10 percent faster than Yolo-Fastest is not visible in this table at 352x352; the four-core numbers are effectively tied.
The comparison the table does not make is against anything with a feature pyramid. yolox-nano at 416x416 reports 25.8 percent mAP at IoU 0.50:0.95 with 0.91M parameters, and nanodet_m at 320x320 reports 20.6 percent at 0.95M. Those are different metrics (0.50:0.95 rather than 0.50) so they cannot be read directly against FastestDet's 25.3 percent at 0.50, but FastestDet's own 13.0 percent at 0.50:0.95 is roughly half of yolox-nano's figure at a comparable input size. The parameter count is a quarter of yolox-nano's, so the trade is explicit: you buy 4x smaller weights and pay roughly half the localization quality.
The clearest case where FastestDet is the wrong tool is any scene with small objects. The 0.021 small-object AP is not a tuning problem, it is a consequence of a single-scale head at 352x352. Adding input resolution helps, but the README's benchmark is fixed at 352x352 and there is no table showing what happens at 640.
A second failure mode is class count. The shipped config is NC: 80 for COCO. The README gives no guidance on how the single-scale head behaves when you push toward hundreds of classes with limited data per class, and the dynamic sample allocation scheme is exactly the kind of thing that becomes unstable when some classes are rare.
Maintenance cost and the BSD-3-Clause terms
The repository has one release, v1.0 from 2022.7.02, and the last push is 2026.5.12. The README's most recent changelog entry is from 2022.7.14, so the documented feature set has been stable for years while the code has seen later commits. There is no changelog describing what changed after that date, and no migration notes. If you pin to a commit, pin to a specific SHA rather than to main, because there is no release cadence to anchor against.
The dependency surface is a requirements.txt plus PyTorch, and the README's only environment warning is about CUDA version selection. There is no lockfile and no stated Python version. On a long-lived deployment that means the first maintenance task is usually freezing the environment yourself.
The licence is BSD-3-Clause. That permits commercial use and modification, and it requires retaining the copyright notice and licence text in redistributed source and in binary distributions. It also contains the standard clause preventing use of the copyright holder's name to endorse derived products without permission. This is a permissive licence with no copyleft obligation on your own code, but it is not legal advice and the actual terms in the LICENSE file are what govern. One practical consequence worth checking: the released checkpoint is distributed through the repository, and the README does not state a separate licence for the weights, so confirm the weights fall under the same terms before shipping them in a product.
Editorial conclusion
Adopt FastestDet when you are shipping a fixed-class detector onto an ARM CPU board and can accept roughly 25 percent mAP at IoU 0.50 with weak small-object recall. Do not adopt it for dense scenes, small objects, or anything needing a multi-scale head. Before committing, run eval.py on your own val split rather than trusting the published 0.253, since that figure comes from a single released checkpoint whose filename encodes the score.
Community notes