codelor-color 2.2.0__tar.gz → 2.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codelor_color-2.2.0 → codelor_color-2.2.2}/CHANGELOG.md +30 -0
- {codelor_color-2.2.0/codelor_color.egg-info → codelor_color-2.2.2}/PKG-INFO +2 -2
- codelor_color-2.2.2/codelor_color/_version.py +1 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/codelor_color/model.py +22 -19
- {codelor_color-2.2.0 → codelor_color-2.2.2/codelor_color.egg-info}/PKG-INFO +2 -2
- {codelor_color-2.2.0 → codelor_color-2.2.2}/pyproject.toml +3 -3
- {codelor_color-2.2.0 → codelor_color-2.2.2}/tests/test_model.py +2 -2
- codelor_color-2.2.0/codelor_color/_version.py +0 -1
- {codelor_color-2.2.0 → codelor_color-2.2.2}/LICENSE +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/MANIFEST.in +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/README.md +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/codelor_color/__init__.py +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/codelor_color.egg-info/SOURCES.txt +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/codelor_color.egg-info/dependency_links.txt +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/codelor_color.egg-info/requires.txt +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/codelor_color.egg-info/top_level.txt +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/requirements.txt +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/setup.cfg +0 -0
- {codelor_color-2.2.0 → codelor_color-2.2.2}/tests/conftest.py +0 -0
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.2.2] - 2026-10-21
|
|
6
|
+
|
|
7
|
+
Patch release fixing the remaining mypy error from CI.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `SobelEdge` declares its `sx`/`sy` buffers with class annotations so mypy
|
|
12
|
+
types them as `Tensor` (previously `Tensor | Module`, which broke
|
|
13
|
+
`F.conv2d`). No behaviour change: buffers and `state_dict` keys are identical.
|
|
14
|
+
|
|
15
|
+
## [2.2.1] - 2026-10-21
|
|
16
|
+
|
|
17
|
+
Patch release: the 2.2.0 files already on PyPI cannot be replaced (PyPI
|
|
18
|
+
releases are immutable), so the CI/lint fixes ship as 2.2.1. No behaviour
|
|
19
|
+
change; weights and API are identical to 2.2.0.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Python 3.8/3.9 support dropped: `requires-python` is now `>=3.10`
|
|
24
|
+
(matching current PyTorch). The 2.2.0 metadata on PyPI still advertises
|
|
25
|
+
`>=3.8`.
|
|
26
|
+
- Annotations use modern syntax (`tuple[...]`, `X | Y`,
|
|
27
|
+
`collections.abc.Sequence`) required by current ruff (UP006/UP007/UP045).
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Lint errors reported by the GitHub Actions CI on the 2.2.0 tag.
|
|
32
|
+
- `CodelorColor._get()` now casts `nn.ModuleList` lookups so mypy accepts
|
|
33
|
+
the weight-tying indirection.
|
|
34
|
+
|
|
5
35
|
## [2.2.0] - 2026-10-21
|
|
6
36
|
|
|
7
37
|
Architecture weights are unchanged: checkpoints trained for 2.1.0 load as-is.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codelor-color
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: A lightweight PyTorch Transformer architecture for Chroma Key (Green Screen).
|
|
5
5
|
Author-email: PlimbAi <plimb.ai.contact@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -9,7 +9,7 @@ Project-URL: Bug Tracker, https://github.com/Plimb-ai/codelor-color/issues
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
12
|
-
Requires-Python: >=3.
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: torch>=2.0.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.2"
|
|
@@ -10,8 +10,9 @@ from __future__ import annotations
|
|
|
10
10
|
import json
|
|
11
11
|
import logging
|
|
12
12
|
import warnings
|
|
13
|
+
from collections.abc import Sequence
|
|
13
14
|
from pathlib import Path
|
|
14
|
-
from typing import Any,
|
|
15
|
+
from typing import Any, cast
|
|
15
16
|
|
|
16
17
|
import torch
|
|
17
18
|
import torch.nn as nn
|
|
@@ -25,7 +26,7 @@ logger = logging.getLogger(__name__)
|
|
|
25
26
|
# ============================================================
|
|
26
27
|
|
|
27
28
|
#: Default reference color used when none is supplied (RGB in [0, 1]).
|
|
28
|
-
DEFAULT_REF_RGB:
|
|
29
|
+
DEFAULT_REF_RGB: tuple[float, float, float] = (0.20, 0.85, 0.30)
|
|
29
30
|
|
|
30
31
|
#: Channel width of the stem feature maps at 1/4 (``f4``) resolution.
|
|
31
32
|
STEM_W1: int = 32
|
|
@@ -42,7 +43,7 @@ POS_EMB_STD: float = 0.02
|
|
|
42
43
|
EPS: float = 1e-6
|
|
43
44
|
|
|
44
45
|
#: Hyper-parameters accepted by :meth:`CodelorColor.config` / ``config.json``.
|
|
45
|
-
HYPERPARAM_KEYS:
|
|
46
|
+
HYPERPARAM_KEYS: tuple[str, ...] = (
|
|
46
47
|
"dim",
|
|
47
48
|
"depth",
|
|
48
49
|
"heads",
|
|
@@ -108,7 +109,7 @@ class DropPath(nn.Module):
|
|
|
108
109
|
return x * mask / keep
|
|
109
110
|
|
|
110
111
|
|
|
111
|
-
def rope_2d(q: Tensor, k: Tensor, h: int, w: int, base: float = ROPE_BASE) ->
|
|
112
|
+
def rope_2d(q: Tensor, k: Tensor, h: int, w: int, base: float = ROPE_BASE) -> tuple[Tensor, Tensor]:
|
|
112
113
|
"""Apply 2D rotary position embeddings, splitting the head dim in half for x and y."""
|
|
113
114
|
B, Hh, N, D = q.shape
|
|
114
115
|
d4 = D // 4
|
|
@@ -243,7 +244,7 @@ class ConvNeXtStem(nn.Module):
|
|
|
243
244
|
self.down8 = AntiAliasDownsample(STEM_W1, STEM_W2)
|
|
244
245
|
self.down16 = AntiAliasDownsample(STEM_W2, dim)
|
|
245
246
|
|
|
246
|
-
def forward(self, x: Tensor) ->
|
|
247
|
+
def forward(self, x: Tensor) -> tuple[Tensor, Tensor, Tensor]:
|
|
247
248
|
x = self.patch(x)
|
|
248
249
|
x = x + self.block1(x)
|
|
249
250
|
f4 = x
|
|
@@ -255,6 +256,9 @@ class ConvNeXtStem(nn.Module):
|
|
|
255
256
|
class SobelEdge(nn.Module):
|
|
256
257
|
"""Fixed Sobel X/Y filters returning the gradient magnitude of a gray image."""
|
|
257
258
|
|
|
259
|
+
sx: Tensor
|
|
260
|
+
sy: Tensor
|
|
261
|
+
|
|
258
262
|
def __init__(self) -> None:
|
|
259
263
|
super().__init__()
|
|
260
264
|
sx = torch.tensor([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]).float().view(1, 1, 3, 3)
|
|
@@ -304,7 +308,7 @@ class GatedDecoder(nn.Module):
|
|
|
304
308
|
|
|
305
309
|
def forward(
|
|
306
310
|
self, latent: Tensor, f4: Tensor, f8: Tensor, img: Tensor, ref_rgb: Tensor
|
|
307
|
-
) ->
|
|
311
|
+
) -> tuple[Tensor, Tensor]:
|
|
308
312
|
B, _, H, W = img.shape
|
|
309
313
|
x = self.proj16(latent)
|
|
310
314
|
aux = self.aux_head(x)
|
|
@@ -380,14 +384,13 @@ class CodelorColor(nn.Module):
|
|
|
380
384
|
self.norm_out = RMSNorm(dim)
|
|
381
385
|
self.decoder = GatedDecoder(dim)
|
|
382
386
|
|
|
383
|
-
def _get(self, i: int) ->
|
|
384
|
-
if self.tied_after > 0 and i >= self.tied_after
|
|
385
|
-
|
|
386
|
-
return self.blocks[i], self.color_xattn[i]
|
|
387
|
+
def _get(self, i: int) -> tuple[Block, ColorCrossAttention]:
|
|
388
|
+
idx = i - self.tied_after if self.tied_after > 0 and i >= self.tied_after else i
|
|
389
|
+
return cast(Block, self.blocks[idx]), cast(ColorCrossAttention, self.color_xattn[idx])
|
|
387
390
|
|
|
388
391
|
def forward(
|
|
389
392
|
self, img: Tensor, ref_rgb: Tensor, return_aux: bool = False
|
|
390
|
-
) ->
|
|
393
|
+
) -> Tensor | tuple[Tensor, Tensor]:
|
|
391
394
|
"""Predict foreground logits.
|
|
392
395
|
|
|
393
396
|
Args:
|
|
@@ -435,7 +438,7 @@ class CodelorColor(nn.Module):
|
|
|
435
438
|
main, aux = self.decoder(latent, f4, f8, img, ref_rgb)
|
|
436
439
|
return (main, aux) if return_aux else main
|
|
437
440
|
|
|
438
|
-
def config(self) ->
|
|
441
|
+
def config(self) -> dict[str, Any]:
|
|
439
442
|
"""Return the hyper-parameters needed to rebuild this model.
|
|
440
443
|
|
|
441
444
|
The result is accepted both directly and nested under a
|
|
@@ -464,7 +467,7 @@ class CodelorColor(nn.Module):
|
|
|
464
467
|
# ============================================================
|
|
465
468
|
|
|
466
469
|
def load_from_pretrained(
|
|
467
|
-
path_or_repo:
|
|
470
|
+
path_or_repo: str | Path, device: str | torch.device = "cpu"
|
|
468
471
|
) -> CodelorColor:
|
|
469
472
|
"""Build a :class:`CodelorColor` and load ``model.safetensors`` from it.
|
|
470
473
|
|
|
@@ -513,7 +516,7 @@ def load_from_pretrained(
|
|
|
513
516
|
return model.eval().to(device)
|
|
514
517
|
|
|
515
518
|
|
|
516
|
-
def _as_batch(image_tensor: Tensor, name: str = "image_tensor") ->
|
|
519
|
+
def _as_batch(image_tensor: Tensor, name: str = "image_tensor") -> tuple[Tensor, bool]:
|
|
517
520
|
"""Validate an image tensor and return it with a batch dimension plus a squeeze flag."""
|
|
518
521
|
if not isinstance(image_tensor, Tensor):
|
|
519
522
|
raise TypeError(f"{name} must be a torch.Tensor, got {type(image_tensor).__name__}")
|
|
@@ -547,10 +550,10 @@ def _sync_model_device(model: nn.Module, device: torch.device) -> None:
|
|
|
547
550
|
def predict_mask(
|
|
548
551
|
model: nn.Module,
|
|
549
552
|
image_tensor: Tensor,
|
|
550
|
-
color_rgb:
|
|
553
|
+
color_rgb: Sequence[float] | None = None,
|
|
551
554
|
threshold: float = 0.5,
|
|
552
|
-
device:
|
|
553
|
-
) ->
|
|
555
|
+
device: str | torch.device = "cpu",
|
|
556
|
+
) -> tuple[Any, Any]:
|
|
554
557
|
"""Compute a foreground mask for an image.
|
|
555
558
|
|
|
556
559
|
Args:
|
|
@@ -592,9 +595,9 @@ def predict_mask(
|
|
|
592
595
|
def remove_green(
|
|
593
596
|
image_tensor: Tensor,
|
|
594
597
|
model: nn.Module,
|
|
595
|
-
color_rgb:
|
|
598
|
+
color_rgb: Sequence[float] | None = None,
|
|
596
599
|
threshold: float = 0.5,
|
|
597
|
-
device:
|
|
600
|
+
device: str | torch.device = "cpu",
|
|
598
601
|
) -> Tensor:
|
|
599
602
|
"""Return an RGBA tensor where the alpha channel is ``1 - P(foreground)``.
|
|
600
603
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codelor-color
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: A lightweight PyTorch Transformer architecture for Chroma Key (Green Screen).
|
|
5
5
|
Author-email: PlimbAi <plimb.ai.contact@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -9,7 +9,7 @@ Project-URL: Bug Tracker, https://github.com/Plimb-ai/codelor-color/issues
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
12
|
-
Requires-Python: >=3.
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: torch>=2.0.0
|
|
@@ -7,7 +7,7 @@ name = "codelor-color"
|
|
|
7
7
|
dynamic = ["version"]
|
|
8
8
|
description = "A lightweight PyTorch Transformer architecture for Chroma Key (Green Screen)."
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
11
|
license = "MIT"
|
|
12
12
|
authors = [
|
|
13
13
|
{name = "PlimbAi", email = "plimb.ai.contact@gmail.com"}
|
|
@@ -50,7 +50,7 @@ addopts = "-q"
|
|
|
50
50
|
|
|
51
51
|
[tool.ruff]
|
|
52
52
|
line-length = 100
|
|
53
|
-
target-version = "
|
|
53
|
+
target-version = "py310"
|
|
54
54
|
exclude = ["build", "dist"]
|
|
55
55
|
|
|
56
56
|
[tool.ruff.lint]
|
|
@@ -58,6 +58,6 @@ select = ["E", "F", "W", "I", "UP", "B"]
|
|
|
58
58
|
ignore = ["E501"]
|
|
59
59
|
|
|
60
60
|
[tool.mypy]
|
|
61
|
-
python_version = "3.
|
|
61
|
+
python_version = "3.10"
|
|
62
62
|
ignore_missing_imports = true
|
|
63
63
|
check_untyped_defs = true
|
|
@@ -6,7 +6,7 @@ import json
|
|
|
6
6
|
import re
|
|
7
7
|
import warnings
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
9
|
+
from typing import Any
|
|
10
10
|
|
|
11
11
|
import numpy as np
|
|
12
12
|
import pytest
|
|
@@ -26,7 +26,7 @@ ROOT = Path(__file__).resolve().parents[1]
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def small_model(**kwargs) -> CodelorColor:
|
|
29
|
-
params:
|
|
29
|
+
params: dict[str, Any] = dict(
|
|
30
30
|
dim=32, depth=2, heads=4, tied_after=1, max_tokens=64, drop_path_rate=0.1
|
|
31
31
|
)
|
|
32
32
|
params.update(kwargs)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|