From e26f71d15d61af40469ff58149ba3cb8d9cf5efe Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 30 Aug 2026 10:05:04 +0200 Subject: [PATCH] Gather every model under one tree at the repository root The weights were in two places: face detection and recognition in `models/face/`, segmentation in `core/dr-segment/models/`. Nothing was wrong with either path, but between them there was nowhere to look to answer "how much model does this application carry", and that number is about to start growing. So the crate-local copy moves up beside the other. `models/` now holds `face/` and `segment/`, and a `du -sh` of one directory is the whole answer. No content changes: the .onnx and its vocabulary are byte-identical, and `LICENCE.md` moves up a level to cover the tree rather than one crate. The LFS pattern in `.gitattributes` is `*.onnx` and already matched both locations, so only its comment needed the new path. `include_bytes!` is relative to the source file and `build.rs` runs with the crate root as its working directory, which is why the two paths climb a different number of levels. Co-Authored-By: Claude Opus 5 (1M context) --- .gitattributes | 2 +- .gitea/workflows/build-and-test.yml | 8 ++++---- core/dr-segment/build.rs | 4 ++-- core/dr-segment/src/lib.rs | 2 +- core/dr-segment/src/semantic.rs | 8 ++++---- {core/dr-segment/models => models}/LICENCE.md | 0 .../models => models/segment}/yolo26n-seg.classes.json | 0 .../dr-segment/models => models/segment}/yolo26n-seg.onnx | 0 tools/export-seg-model.sh | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) rename {core/dr-segment/models => models}/LICENCE.md (100%) rename {core/dr-segment/models => models/segment}/yolo26n-seg.classes.json (100%) rename {core/dr-segment/models => models/segment}/yolo26n-seg.onnx (100%) diff --git a/.gitattributes b/.gitattributes index 4d03e0a..17249bf 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,6 @@ # Model weights live in LFS. # -# `core/dr-segment/models/*.onnx` is ~11 MB of binary that changes wholesale +# `models/**/*.onnx` is tens of MB of binary that changes wholesale # when it changes at all. In ordinary git objects every future revision of it # would be stored in full, in every clone, forever — and the one thing nobody # can do with it is a useful diff. diff --git a/.gitea/workflows/build-and-test.yml b/.gitea/workflows/build-and-test.yml index 0945317..db31c3a 100644 --- a/.gitea/workflows/build-and-test.yml +++ b/.gitea/workflows/build-and-test.yml @@ -57,7 +57,7 @@ jobs: # The model, which is in LFS and is not optional. # - # `core/dr-segment/models/*.onnx` is tracked in LFS (.gitattributes), so a + # `models/**/*.onnx` is tracked in LFS (.gitattributes), so a # plain checkout writes a ~130-byte pointer where 11 MB should be, and # `dr-segment`'s build script panics by design rather than embedding a # pointer and failing at inference. That failure reads like a broken build @@ -97,7 +97,7 @@ jobs: git config --local lfs.url \ "https://x-access-token:${LFS_TOKEN}@gitea.tourolle.paris/dtourolle/DarkRoom.git/info/lfs" git lfs pull - ls -l core/dr-segment/models/ + ls -lR models/ - name: Cache cargo uses: actions/cache@v4 @@ -174,7 +174,7 @@ jobs: # The model, which is in LFS and is not optional. # - # `core/dr-segment/models/*.onnx` is tracked in LFS (.gitattributes), so a + # `models/**/*.onnx` is tracked in LFS (.gitattributes), so a # plain checkout writes a ~130-byte pointer where 11 MB should be, and # `dr-segment`'s build script panics by design rather than embedding a # pointer and failing at inference. That failure reads like a broken build @@ -214,7 +214,7 @@ jobs: git config --local lfs.url \ "https://x-access-token:${LFS_TOKEN}@gitea.tourolle.paris/dtourolle/DarkRoom.git/info/lfs" git lfs pull - ls -l core/dr-segment/models/ + ls -lR models/ - name: Cache cargo uses: actions/cache@v4 diff --git a/core/dr-segment/build.rs b/core/dr-segment/build.rs index dcd300e..276ff85 100644 --- a/core/dr-segment/build.rs +++ b/core/dr-segment/build.rs @@ -1,6 +1,6 @@ //! Check the model is a model and not an LFS pointer. //! -//! `models/*.onnx` is stored in Git LFS (see `.gitattributes`). A clone made +//! `models/segment/*.onnx` is stored in Git LFS (see `.gitattributes`). A clone made //! without git-lfs installed, or with `GIT_LFS_SKIP_SMUDGE` set, leaves a //! ~130-byte text pointer at that path instead of the weights. //! @@ -12,7 +12,7 @@ use std::path::Path; -const MODEL: &str = "models/yolo26n-seg.onnx"; +const MODEL: &str = "../../models/segment/yolo26n-seg.onnx"; fn main() { println!("cargo:rerun-if-changed={MODEL}"); diff --git a/core/dr-segment/src/lib.rs b/core/dr-segment/src/lib.rs index 4909f5b..e82eb75 100644 --- a/core/dr-segment/src/lib.rs +++ b/core/dr-segment/src/lib.rs @@ -26,7 +26,7 @@ //! //! That combination is also what repairs the vocabulary problem. The shipped //! model is COCO-trained, so it recognises subjects and has no class for sky, -//! foliage or wall (`models/LICENCE.md`). Selecting those falls to arm A, +//! foliage or wall (`models/LICENCE.md` at the repository root). Selecting those falls to arm A, //! which never needed a vocabulary to begin with. pub mod distance; diff --git a/core/dr-segment/src/semantic.rs b/core/dr-segment/src/semantic.rs index d01865a..fe530df 100644 --- a/core/dr-segment/src/semantic.rs +++ b/core/dr-segment/src/semantic.rs @@ -20,7 +20,7 @@ //! behaviour, and it is worth being glad of rather than working around. //! //! So arm B here contributes *subjects*, and the watershed contributes -//! everything else. See `models/LICENCE.md` for why no ADE20K variant is +//! everything else. See `models/LICENCE.md` at the repository root for why no ADE20K variant is //! shipped instead. //! //! # Cost, and where it may run @@ -198,15 +198,15 @@ pub struct SemanticModel { classes: Vec>, } -/// The weights that ship with this crate (`models/`, AGPL — see LICENCE.md). +/// The weights, from the repository-root `models/segment/` (AGPL — see `models/LICENCE.md`). /// /// Embedded rather than read from a path because Android hands the app no /// filesystem location to read from (ARCH §6.9) — the same reasoning that has /// the Lensfun database shipping inside its crate. #[cfg(feature = "embedded-model")] -const EMBEDDED_MODEL: &[u8] = include_bytes!("../models/yolo26n-seg.onnx"); +const EMBEDDED_MODEL: &[u8] = include_bytes!("../../../models/segment/yolo26n-seg.onnx"); #[cfg(feature = "embedded-model")] -const EMBEDDED_CLASSES: &str = include_str!("../models/yolo26n-seg.classes.json"); +const EMBEDDED_CLASSES: &str = include_str!("../../../models/segment/yolo26n-seg.classes.json"); impl SemanticModel { /// Load the model that ships with this crate. diff --git a/core/dr-segment/models/LICENCE.md b/models/LICENCE.md similarity index 100% rename from core/dr-segment/models/LICENCE.md rename to models/LICENCE.md diff --git a/core/dr-segment/models/yolo26n-seg.classes.json b/models/segment/yolo26n-seg.classes.json similarity index 100% rename from core/dr-segment/models/yolo26n-seg.classes.json rename to models/segment/yolo26n-seg.classes.json diff --git a/core/dr-segment/models/yolo26n-seg.onnx b/models/segment/yolo26n-seg.onnx similarity index 100% rename from core/dr-segment/models/yolo26n-seg.onnx rename to models/segment/yolo26n-seg.onnx diff --git a/tools/export-seg-model.sh b/tools/export-seg-model.sh index 5468390..911effa 100755 --- a/tools/export-seg-model.sh +++ b/tools/export-seg-model.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Re-export the segmentation model that ships in core/dr-segment/models/. +# Re-export the segmentation model that ships in models/ at the repository root. # # The .onnx is committed (D14), so this is not part of any build — it exists so # the committed artefact is reproducible rather than a binary someone once @@ -24,7 +24,7 @@ set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO="$(cd "${HERE}/.." && pwd)" -OUT="${REPO}/core/dr-segment/models" +OUT="${REPO}/models/segment" MODEL="${1:-yolo26n-seg}" IMGSZ="${2:-640}"