Skip to content

v0.3.1 — no silently wrong results

Choose a tag to compare

@PogChamper PogChamper released this 10 Jul 11:31

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 fp16 now produces the v0.3 production tier (opset-19 base +
    convert_fp16_surgical.py --slim, written as dfine_<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-size the freshly generated geometry is
    used instead of failing. Research escape hatch: --allow-partial-checkpoint (recorded in the
    sidecar). dfine export gains --num-classes / --class-names.
  • CLI output contracts. predict --json keeps stdout pure JSON in every mode (all
    diagnostics, including the --out confirmation and engine-build chatter, go to stderr);
    info/bench drop their --onnx flag (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 by predict (largest max-batch wins,
    numerically). An explicit --onnx can 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_mode pass 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 < 2 is 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 --json keeps stdout pure JSON (all diagnostics and build chatter go to
    stderr) — pipes into jq even on a cold cache.
  • coco_eval.py/profile.py no longer crash on 1-class models at the default --topk.
  • CI packages the wheel through python/build_wheel.sh itself (the v0.3.0 CI wheel silently
    lacked the bundled build_engine.py), audits the payload, strips and forbids RPATH in the
    bundled libdfine.so (a baked build-machine path is searched before LD_LIBRARY_PATH),
    and smoke-installs outside the checkout through the CLI's real script-resolution path.
  • dfine info/dfine bench drop their --onnx flag (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.