发布

  • v1021 6959a42312

    feat(cog-person-count): v0.0.1 scaffold + tests + fusion math + bench (ADR-103) (#694)

    frostbyte_neo 发布于 2026-05-21 22:46:57 +00:00

    First implementation PR for ADR-103. Same incremental shape that
    ADR-101 used: scaffold the cog crate, ship a stub-backend release
    that satisfies the runtime contract + 15 tests + measured cold-start,
    then follow up with the trained count_v1.safetensors in a separate PR.

    What ships:

    • v2/crates/cog-person-count/ — new workspace member.

      • Cargo.toml: candle-core/candle-nn 0.9 (cpu default, cuda feature
        opt-in), safetensors, ureq, sha2 — same dep shape as the pose cog
        but minus wifi-densepose-train (this cog has no training-side
        consumer, so the dep tree is materially smaller → 2.36 MB
        binary vs the pose cog's 4.5 MB).
      • src/inference.rs: CountNet (Conv1d 56→64→128→128 encoder + count
        head Linear(128→64→8)+softmax + confidence head
        Linear(128→32→1)+sigmoid). Stub backend returns
        {1-person, 0-confidence} honestly when no safetensors present.
      • src/fusion.rs: fuse_confidence_weighted() — Bayesian product of
        per-node distributions with confidence-weighted log-sum, plus
        fuse_with_mincut_clip() hook for the v0.2.0 Stoer-Wagner
        upper-bound (ruvector-mincut dep lands when min-cut graph
        builder is ready). Confidences floored at 1e-3 and probs floored
        at 1e-9 before logs — no NaN propagation.
      • src/publisher.rs: emits {count, confidence, count_p95_low,
        count_p95_high, n_nodes, probs} per ADR-103 §"Output".
      • src/main.rs: full ADR-100 four-verb CLI (version|manifest|health
        |run). The run subcommand explicitly returns "wiring pending
        v0.0.1" so the in-process library API is the v0.0.1-clean
        integration path.
      • tests/smoke.rs (8 tests) + fusion::tests (7 tests, in-lib) — 15
        total, all green. Cover stub-backend behaviour, wrong-shape
        rejection, fusion math (empty / single / agreement / high-conf
        override / normalisation), p95-range correctness, and min-cut
        clip semantics.
      • cog/{manifest.template.json, config.schema.json, README.md} +
        cog/artifacts/ placeholder dir.
    • v2/Cargo.toml: registers the new workspace member.

    Verified locally:

    cargo check -p cog-person-count --no-default-features → clean
    cargo test -p cog-person-count --no-default-features → 8/8 pass
    cargo test -p cog-person-count --lib → 7/7 pass
    cargo build -p cog-person-count --release → 2.36 MB binary
    ./cog-person-count version → "person-count 0.3.0"
    ./cog-person-count manifest → JSON skeleton
    ./cog-person-count health → backend:stub,
    count:1, conf:0,
    p95:[1,1]
    Cold-start: 30 sequential health invocations → 53.3 ms/invocation
    (vs cog-pose-estimation's 76.2 ms — smaller dep tree)

    cog/README.md adds:

    • Security section — six-row threat table covering safetensor mmap
      trust, non-finite outputs, sensing fetch failures, fusion
      divide-by-zero / log-of-zero, min-cut degenerate cases, and stdout
      spoofing.
    • Performance / optimization section — binary size, release profile
      (already opt-level=3 / lto=fat / codegen-units=1 / strip=true at
      workspace level), cold-start comparison table, projected warm-path
      latency budget.

    Still pending (separate PRs, ADR-103 §"Migration"):

    • Train count_v1.safetensors on the existing 1,077 paired samples
      with n_persons labels (Candle on RTX 5080, same script that
      produced pose_v1.safetensors yesterday).
    • run subcommand wiring (long-running polling loop, same shape as
      cog-pose-estimation::runtime).
    • Cross-compile + sign + GCS upload (mirror of cog-pose-estimation
      release pipeline).
    • Server-side csi.rs::score_to_person_count call-site rewire to
      consume this cog when installed; falls back to PR #491's heuristic
      when not.
    下载附件