Skip to content

Commit c355da6

Browse files
committed
Update model manifests for v0.2.0
1 parent 6bf7403 commit c355da6

10 files changed

Lines changed: 170 additions & 46 deletions

File tree

MODELS.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,9 @@ packages are generated.
6161

6262
Cutie release packages are generated under `cutie/releases/` and contain the
6363
four ONNX slices needed by libopenshot's Cutie Object Mask backend. The Cutie
64-
exporter also writes `cutie/releases/cutie-models.json` with asset names,
65-
dimensions, and checksums.
64+
exporter updates `cutie/models.json` with asset names, dimensions, and
65+
checksums.
66+
67+
EfficientSAM release packages are generated under `efficient-sam/releases/`.
68+
The EfficientSAM exporter updates `efficient-sam/models.json` with asset names,
69+
checksums, and sizes.

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ zip files as GitHub Release assets after reviewing upstream model licenses.
2424
Common outputs:
2525

2626
```text
27-
yolo/releases/ YOLO zip packages and yolo/models.json
28-
efficient-sam/releases/ EfficientSAM zip packages
29-
cutie/releases/ Cutie zip packages and cutie-models.json
27+
yolo/models.json YOLO release catalog
28+
yolo/releases/ YOLO zip packages
29+
efficient-sam/models.json EfficientSAM release catalog
30+
efficient-sam/releases/ EfficientSAM zip packages
31+
cutie/models.json Cutie release catalog
32+
cutie/releases/ Cutie zip packages
3033
```
3134

3235
## Quick Commands
@@ -45,8 +48,9 @@ python cutie/scripts/export_cutie_quality_tiers.py
4548

4649
EfficientSAM:
4750

48-
See [`efficient-sam/README.md`](efficient-sam/README.md). Its export/release
49-
tooling will live there as it is promoted from experiments.
51+
```bash
52+
python efficient-sam/scripts/package_efficient_sam.py
53+
```
5054

5155
## Links
5256

cutie/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ The script:
5555
memory readout graph.
5656
6. Validates each tier with OpenCV DNN.
5757
7. Writes zip assets under `cutie/releases`.
58+
8. Updates the release catalog at `cutie/models.json`.
5859

5960
Generated local directories:
6061

@@ -98,8 +99,8 @@ cutie-opencv-medium-640x368.zip
9899
cutie-decode-640x368.onnx
99100
```
100101

101-
The exporter also writes `cutie/releases/cutie-models.json` with asset names,
102-
dimensions, checksums, and sizes.
102+
The exporter also updates `cutie/models.json` with asset names, dimensions,
103+
checksums, and sizes.
103104

104105
## Individual Scripts
105106

cutie/models.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"version": "0.2.0",
3+
"release": "v0.2.0",
4+
"base_url": "https://github.com/OpenShot/openshot-onnx/releases/download/v0.2.0",
5+
"models": [
6+
{
7+
"id": "cutie-low",
8+
"name": "Cutie: Low",
9+
"description": "Fastest 16:9 Cutie propagation tier",
10+
"asset": "cutie-opencv-low-480x272.zip",
11+
"sha256": "5ef34a24f84ee076de7d4b7439bd423cb5d50b69a3810b57bdd50010ac6db28d",
12+
"bytes": 129998832
13+
},
14+
{
15+
"id": "cutie-medium",
16+
"name": "Cutie: Medium",
17+
"description": "Balanced 16:9 Cutie propagation tier",
18+
"asset": "cutie-opencv-medium-640x368.zip",
19+
"sha256": "64f79a30d4e53f2aad597772968f18dcc3806ef8dfbe1fefcbf4b58fac069709",
20+
"bytes": 130823166,
21+
"recommended": true
22+
},
23+
{
24+
"id": "cutie-high",
25+
"name": "Cutie: High",
26+
"description": "Higher-detail 16:9 Cutie propagation tier",
27+
"asset": "cutie-opencv-high-960x544.zip",
28+
"sha256": "56c5b4823610c8f87b551b82893ef0450f900c254b4ff729f24aec30dea2124f",
29+
"bytes": 131949289
30+
},
31+
{
32+
"id": "cutie-very-high",
33+
"name": "Cutie: Very High",
34+
"description": "Highest-detail 16:9 Cutie propagation tier",
35+
"asset": "cutie-opencv-very-high-1280x720.zip",
36+
"sha256": "eb3cae8692f6fc08d1acb7e511934159373e6913d8ab3343f7622c1ab4302693",
37+
"bytes": 133618997
38+
}
39+
]
40+
}

cutie/scripts/export_cutie_quality_tiers.py

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
DEFAULT_WEIGHTS = CUTIE_DIR / "weights" / "cutie-base-mega.pth"
2424
DEFAULT_MODELS_DIR = CUTIE_DIR / "models"
2525
DEFAULT_RELEASE_DIR = CUTIE_DIR / "releases"
26-
DEFAULT_RELEASE_TAG = "v0.1.0"
26+
DEFAULT_MODELS_JSON = CUTIE_DIR / "models.json"
27+
DEFAULT_RELEASE_TAG = "v0.2.0"
2728
DEFAULT_RELEASE_BASE_URL = (
2829
"https://github.com/OpenShot/openshot-onnx/releases/download"
2930
)
@@ -194,11 +195,7 @@ def package_tier(args: argparse.Namespace, tier: Tier) -> dict[str, object]:
194195
"asset": zip_path.name,
195196
"sha256": file_sha256(zip_path),
196197
"bytes": zip_path.stat().st_size,
197-
"width": tier.width,
198-
"height": tier.height,
199-
"memory_frames": args.memory_frames,
200-
"top_k": args.top_k,
201-
"recommended": tier.id == "medium",
198+
**({"recommended": True} if tier.id == "medium" else {}),
202199
}
203200

204201

@@ -221,17 +218,40 @@ def validate_tier(args: argparse.Namespace, tier: Tier, probe: Path) -> None:
221218
shutil.rmtree(staging)
222219

223220

221+
def model_sort_key(item: dict[str, object]) -> tuple[int, str]:
222+
order = {f"cutie-{tier.id}": index for index, tier in enumerate(TIERS)}
223+
model_id = str(item["id"])
224+
return (order.get(model_id, len(order)), model_id)
225+
226+
227+
def catalog_entry(entry: dict[str, object]) -> dict[str, object]:
228+
keys = ("id", "name", "description", "asset", "sha256", "bytes", "recommended")
229+
catalog = {key: entry[key] for key in keys if key in entry}
230+
if not catalog.get("recommended", False):
231+
catalog.pop("recommended", None)
232+
return catalog
233+
234+
224235
def write_manifest(args: argparse.Namespace, entries: list[dict[str, object]]) -> None:
236+
existing_models: dict[str, dict[str, object]] = {}
237+
if args.models_json.exists():
238+
existing = json.loads(args.models_json.read_text(encoding="utf-8"))
239+
for model in existing.get("models", []):
240+
existing_models[str(model["id"])] = catalog_entry(model)
241+
242+
updated_models = {**existing_models}
243+
for entry in entries:
244+
updated_models[str(entry["id"])] = catalog_entry(entry)
245+
225246
manifest = {
226-
"schema": 1,
227-
"name": "Cutie OpenCV ONNX Models",
228-
"release_tag": args.release_tag,
229-
"download_base_url": f"{args.release_base_url}/{args.release_tag}",
230-
"models": entries,
247+
"version": args.release_tag.removeprefix("v"),
248+
"release": args.release_tag,
249+
"base_url": f"{args.release_base_url.rstrip('/')}/{args.release_tag}",
250+
"models": sorted(updated_models.values(), key=model_sort_key),
231251
}
232-
path = args.release_dir / "cutie-models.json"
233-
path.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8")
234-
print(f"Wrote {path}")
252+
args.models_json.parent.mkdir(parents=True, exist_ok=True)
253+
args.models_json.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
254+
print(f"Wrote {args.models_json}")
235255

236256

237257
def selected_tiers(names: list[str]) -> list[Tier]:
@@ -247,6 +267,7 @@ def main() -> None:
247267
parser.add_argument("--weights", type=Path, default=DEFAULT_WEIGHTS)
248268
parser.add_argument("--models-dir", type=Path, default=DEFAULT_MODELS_DIR)
249269
parser.add_argument("--release-dir", type=Path, default=DEFAULT_RELEASE_DIR)
270+
parser.add_argument("--models-json", type=Path, default=DEFAULT_MODELS_JSON)
250271
parser.add_argument("--release-tag", default=DEFAULT_RELEASE_TAG)
251272
parser.add_argument("--release-base-url", default=DEFAULT_RELEASE_BASE_URL)
252273
parser.add_argument("--tier", choices=[tier.id for tier in TIERS], action="append")
@@ -263,6 +284,7 @@ def main() -> None:
263284
args.weights = args.weights.expanduser().resolve()
264285
args.models_dir = args.models_dir.expanduser().resolve()
265286
args.release_dir = args.release_dir.expanduser().resolve()
287+
args.models_json = args.models_json.expanduser().resolve()
266288

267289
if not args.skip_export and not args.skip_clone:
268290
ensure_cutie_checkout(args.cutie_root)

efficient-sam/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ The script:
8383
3. Converts the upstream Small model to a static `1024x1024` OpenCV-friendly ONNX.
8484
4. Compiles the C++ OpenCV DNN probe.
8585
5. Validates a forward pass when sample data is available.
86-
6. Writes zip assets and a manifest under `efficient-sam/releases/`.
86+
6. Writes zip assets under `efficient-sam/releases/`.
87+
7. Updates the release catalog at `efficient-sam/models.json`.
8788

8889
The Small conversion requires:
8990

@@ -130,8 +131,8 @@ efficient-sam-small-static-1024.zip
130131
image_segmentation_efficientsam_s_static_1024.onnx
131132
```
132133

133-
The exporter also writes `efficient-sam/releases/efficient-sam-models.json`
134-
with the asset name, checksum, model filename, and size.
134+
The exporter also updates `efficient-sam/models.json` with the asset name,
135+
checksum, and size.
135136

136137
## Probe
137138

efficient-sam/models.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"version": "0.2.0",
3+
"release": "v0.2.0",
4+
"base_url": "https://github.com/OpenShot/openshot-onnx/releases/download/v0.2.0",
5+
"models": [
6+
{
7+
"id": "efficient-sam-tiny-1024",
8+
"name": "EfficientSAM: Tiny 1024",
9+
"description": "Fast prompted seed-mask generator for Object Mask",
10+
"asset": "efficient-sam-tiny-1024.zip",
11+
"sha256": "fe34dc1f6c2493cb4ce1433d5b93731f18a0a0325bb4a116bc4f6e7e43c64123",
12+
"bytes": 44738821,
13+
"recommended": true
14+
},
15+
{
16+
"id": "efficient-sam-small-static-1024",
17+
"name": "EfficientSAM: Small 1024",
18+
"description": "Higher-quality prompted seed-mask generator for Object Mask",
19+
"asset": "efficient-sam-small-static-1024.zip",
20+
"sha256": "f082d77fbb88fe236d8cf6bc391e73a43300979adce6ef5747055a86fac6e54d",
21+
"bytes": 107791958
22+
}
23+
]
24+
}

efficient-sam/scripts/package_efficient_sam.py

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
EFFICIENT_SAM_DIR = SCRIPT_DIR.parent
2222
DEFAULT_MODELS_DIR = EFFICIENT_SAM_DIR / "models"
2323
DEFAULT_RELEASE_DIR = EFFICIENT_SAM_DIR / "releases"
24-
DEFAULT_RELEASE_TAG = "v0.1.0"
24+
DEFAULT_MODELS_JSON = EFFICIENT_SAM_DIR / "models.json"
25+
DEFAULT_RELEASE_TAG = "v0.2.0"
2526
DEFAULT_RELEASE_BASE_URL = (
2627
"https://github.com/OpenShot/openshot-onnx/releases/download"
2728
)
@@ -153,33 +154,59 @@ def package_model(variant: ModelVariant, model_path: Path, release_dir: Path) ->
153154
"asset": zip_path.name,
154155
"sha256": sha256_file(zip_path),
155156
"bytes": zip_path.stat().st_size,
156-
"model": variant.model_name,
157-
"source_model": variant.source_name,
158-
"model_sha256": sha256_file(model_path),
159-
"input_size": [1024, 1024],
160-
"recommended": variant.recommended,
161157
}
158+
if variant.recommended:
159+
entry["recommended"] = True
162160
print(f"Wrote {zip_path}")
163161
return entry
164162

165163

166-
def write_manifest(release_dir: Path, release_tag: str, release_base_url: str, entries: list[dict[str, object]]) -> None:
164+
def model_sort_key(item: dict[str, object]) -> tuple[int, str]:
165+
order = {variant.id: index for index, variant in enumerate(VARIANTS.values())}
166+
model_id = str(item["id"])
167+
return (order.get(model_id, len(order)), model_id)
168+
169+
170+
def catalog_entry(entry: dict[str, object]) -> dict[str, object]:
171+
keys = ("id", "name", "description", "asset", "sha256", "bytes", "recommended")
172+
catalog = {key: entry[key] for key in keys if key in entry}
173+
if not catalog.get("recommended", False):
174+
catalog.pop("recommended", None)
175+
return catalog
176+
177+
178+
def write_manifest(
179+
models_json: Path,
180+
release_tag: str,
181+
release_base_url: str,
182+
entries: list[dict[str, object]],
183+
) -> None:
184+
existing_models: dict[str, dict[str, object]] = {}
185+
if models_json.exists():
186+
existing = json.loads(models_json.read_text(encoding="utf-8"))
187+
for model in existing.get("models", []):
188+
existing_models[str(model["id"])] = catalog_entry(model)
189+
190+
updated_models = {**existing_models}
191+
for entry in entries:
192+
updated_models[str(entry["id"])] = catalog_entry(entry)
193+
167194
manifest = {
168-
"schema": 1,
169-
"name": "EfficientSAM OpenCV ONNX Models",
170-
"release_tag": release_tag,
171-
"download_base_url": f"{release_base_url}/{release_tag}",
172-
"models": entries,
195+
"version": release_tag.removeprefix("v"),
196+
"release": release_tag,
197+
"base_url": f"{release_base_url.rstrip('/')}/{release_tag}",
198+
"models": sorted(updated_models.values(), key=model_sort_key),
173199
}
174-
path = release_dir / "efficient-sam-models.json"
175-
path.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8")
176-
print(f"Wrote {path}")
200+
models_json.parent.mkdir(parents=True, exist_ok=True)
201+
models_json.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
202+
print(f"Wrote {models_json}")
177203

178204

179205
def main() -> None:
180206
parser = argparse.ArgumentParser()
181207
parser.add_argument("--models-dir", type=Path, default=DEFAULT_MODELS_DIR)
182208
parser.add_argument("--release-dir", type=Path, default=DEFAULT_RELEASE_DIR)
209+
parser.add_argument("--models-json", type=Path, default=DEFAULT_MODELS_JSON)
183210
parser.add_argument("--release-tag", default=DEFAULT_RELEASE_TAG)
184211
parser.add_argument("--release-base-url", default=DEFAULT_RELEASE_BASE_URL)
185212
parser.add_argument(
@@ -196,6 +223,7 @@ def main() -> None:
196223

197224
args.models_dir = args.models_dir.expanduser().resolve()
198225
args.release_dir = args.release_dir.expanduser().resolve()
226+
args.models_json = args.models_json.expanduser().resolve()
199227

200228
selected = VARIANTS.values() if args.variant == "all" else [VARIANTS[args.variant]]
201229
entries = []
@@ -225,7 +253,7 @@ def main() -> None:
225253
validate_model(probe, model_path, args.release_dir / "_validate" / variant.id)
226254
entries.append(package_model(variant, model_path, args.release_dir))
227255

228-
write_manifest(args.release_dir, args.release_tag, args.release_base_url, entries)
256+
write_manifest(args.models_json, args.release_tag, args.release_base_url, entries)
229257

230258

231259
if __name__ == "__main__":

yolo/models.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"version": "0.1.0",
3-
"release": "v0.1.0",
4-
"base_url": "https://github.com/OpenShot/openshot-onnx/releases/download/v0.1.0",
2+
"version": "0.2.0",
3+
"release": "v0.2.0",
4+
"base_url": "https://github.com/OpenShot/openshot-onnx/releases/download/v0.2.0",
55
"models": [
66
{
77
"id": "yolo26n-seg",

yolo/scripts/export_yolo_seg_onnx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
LABEL_MANIFEST = REPO_ROOT / "models" / "labels" / "manifest.json"
2828
MODELS_JSON = REPO_ROOT / "models.json"
2929
DEFAULT_RELEASE_DIR = REPO_ROOT / "releases"
30-
DEFAULT_RELEASE_TAG = "v0.1.0"
30+
DEFAULT_RELEASE_TAG = "v0.2.0"
3131
DEFAULT_RELEASE_BASE_URL = (
3232
"https://github.com/OpenShot/openshot-onnx/releases/download"
3333
)

0 commit comments

Comments
 (0)