v0.3.1 — no silently wrong results
v0.3.1 — no silently wrong results
A hardening release: every confirmed path where the library could keep running in an
inconsistent state, or produce the wrong model without saying so, is closed and covered
by tests. No new features. Behavior changes users should know about, in order of impact:
Behavior changes
dfine export --precision fp16now produces the v0.3 production tier (opset-19 base +
convert_fp16_surgical.py --slim, written asdfine_<size>_slim.onnx). Before v0.3.1 the CLI
silently produced the v0.2 decoder-FP32 tier (~11% below the README numbers at batch 8).
If you exported a custom model through the CLI, re-export it to pick up the production
recipe. The old tier remains available as--precision fp16-legacy(opset 16).- Checkpoint loading is strict by default. A checkpoint whose learned tensors do not
exactly fill the model (wrong--model-name, missing--num-classes) now stops the export
with the offending tensors and a hint, instead of exporting randomly initialized weights.
Size-derived geometry buffers (decoder.anchors/valid_mask) are the one exception: at the
training size the checkpoint's copies load as before (keeping exports byte-reproducible with
the gated v0.3.0 assets), and at a retargeted--img-sizethe freshly generated geometry is
used instead of failing. Research escape hatch:--allow-partial-checkpoint(recorded in the
sidecar).dfine exportgains--num-classes/--class-names. - CLI output contracts.
predict --jsonkeeps stdout pure JSON in every mode (all
diagnostics, including the--outconfirmation and engine-build chatter, go to stderr);
info/benchdrop their--onnxflag (it was parsed and never read). Engine cache entries
use a new content-fingerprinted naming scheme — old cache entries keep working as a warned
fallback; rebuild to bind them.
Runtime: errors are now safe
- TensorRT shape transitions are transactional. Two paths previously left the session
inconsistent behind a catchable exception: a frozen detector receiving a larger batch left the
TRT context reconfigured while the shape cache said otherwise (the next call silently ran
batch-2 shapes against batch-1 buffers — device OOB); an allocation failure mid-grow left the
context holding a freed buffer address. Now a failed transition either leaves the previous
state fully intact (frozen violations are rejected before the context is touched) or the
session refuses to run until repaired/recreated. Covered by fault-injection tests
(tests/test_shape_transitions.cpp) and a public-API recovery suite
(tests/test_detector_recovery.cpp); memcheck-clean under compute-sanitizer. - Image geometry is validated at every entry point (C++ and C ABI share one validator):
stride < width*channels— the pixels-vs-bytes mixup — was accepted by the C++ path and
produced sheared images plus an out-of-bounds read.
Artifacts: identity and honesty
- The engine cache is bound to artifact identity. The filename embeds a fingerprint of
the ONNX bytes + its sidecar; the batch profile stays in the name but is not identity — an
engine built with a serving profile is still found bypredict(largest max-batch wins,
numerically). An explicit--onnxcan never lose to a cache entry built from something
else — previously a stale COCO engine could silently serve a freshly exported custom model.
Provenance-less fallbacks warn and never win silently among several candidates. - Precision metadata is written by whoever set the compute types. Strongly-typed FP16
engines no longer get stamped"precision": "fp32"by the builder; the converter's
precision/precision_modepass through, and the builder appends its own facts
(network_typing,trt_version, batch profile,onnx_sha256). - Sidecar values are validated at load (zero/non-finite std, unknown resize mode, inverted
batch ranges, class-name/count mismatch, unsupported schema version), and a present sidecar
is cross-checked against the engine bindings — a stale file cannot mislabel detections. - Exports run a mandatory dynamic-batch postcondition (the graph is executed at N=1 and
N=2 via onnxruntime): a--trace-batch 1-style baked extent passes every static check and is
only caught by running — now it cannot leave the export step.--trace-batch < 2is rejected
outright; the exporter default opset is 19. - Interrupted writes are far harder to weaponize. Every artifact producer (exporter,
fp16/fp16-legacy/int8 converters, engine builder) stages BOTH the graph and its sidecar in
temp files before either goes live, then publishes them with two adjacent atomic renames;
a failed export gate deletes its staging, and a producer whose source carries no sidecar
REMOVES a stale output sidecar instead of leaving the previous graph's metadata next to
the new file. Covered by tests against every producer's publish path. Remaining caveat,
stated plainly: the pair is two renames, not one transaction — a crash exactly between the
two syscalls can still pair a new graph with old metadata for that instant.
Tooling and packaging
dfine predict --jsonkeeps stdout pure JSON (all diagnostics and build chatter go to
stderr) — pipes intojqeven on a cold cache.coco_eval.py/profile.pyno longer crash on 1-class models at the default--topk.- CI packages the wheel through
python/build_wheel.shitself (the v0.3.0 CI wheel silently
lacked the bundledbuild_engine.py), audits the payload, strips and forbids RPATH in the
bundledlibdfine.so(a baked build-machine path is searched beforeLD_LIBRARY_PATH),
and smoke-installs outside the checkout through the CLI's real script-resolution path. dfine info/dfine benchdrop their--onnxflag (it was parsed and never read).
Artifacts
- Five opset-19 FP32 graphs and five surgical/slim FP16 graphs, each with its JSON sidecar:
dfine_{n,s,m,l,x}_{op19,slim}.{onnx,json}. The ONNX bytes are identical to the gated
v0.3.0 assets; the regenerated sidecars add strict checkpoint provenance. dfine-0.3.1-py3-none-linux_x86_64.whl(CUDA sm_89/PTX wheel, TensorRT/CUDA supplied by
the target machine).SHA256SUMS, covering all 21 payload files above.
Docs and attribution
NOTICE/README now credit rf-detr-cpp (Apache-2.0) as the origin of the runtime scaffolding,
with per-file derivation notices; CONTRIBUTING/ROADMAP/README were swept for statements that
contradicted the shipped v0.3 recipes (decoder-FP32 rule, INT8 scoping, WASM promise);
HANDOFF is explicitly the historical journal. New: docs/RELEASE_CHECKLIST.md — the executable
release gate this release was verified against.