From 642a6a48c25b28d77263301c7721c7d635ed5027 Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Sun, 15 Feb 2026 01:33:06 +0100 Subject: [PATCH 1/9] fix: update ty pre-commit entry to skip `tests/` folder --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8daac431..c05df366 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,7 @@ repos: hooks: - id: ty name: type checking using ty - entry: uvx ty check . + entry: uvx ty check src/pruna language: system types: [python] pass_filenames: false From e05bae81aa284cdb8e9fb7d6a103a018b26b57c2 Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Sun, 15 Feb 2026 01:36:48 +0100 Subject: [PATCH 2/9] build: update ty to version 0.0.16 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 18193b70..af1383ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ invalid-return-type = "ignore" # mypy is more permissive with return types invalid-parameter-default = "ignore" # mypy is more permissive with parameter defaults no-matching-overload = "ignore" # mypy is more permissive with overloads unresolved-reference = "ignore" # mypy is more permissive with references -possibly-unbound-import = "ignore" +possibly-missing-import = "ignore" missing-argument = "ignore" [tool.coverage.run] @@ -181,7 +181,7 @@ dev = [ "pytest-rerunfailures", "coverage", "docutils", - "ty==0.0.1a21", + "ty==0.0.16", "types-PyYAML", "logbar", "pytest-xdist>=3.8.0", From f521b21cf5f89e8ca9bce897b727102da5ed1962 Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Sun, 15 Feb 2026 01:52:02 +0100 Subject: [PATCH 3/9] build: ignore possibly-missing-attribute and unused-type-ignore-comment --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index af1383ff..842f7ae7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,9 @@ invalid-parameter-default = "ignore" # mypy is more permissive with parameter de no-matching-overload = "ignore" # mypy is more permissive with overloads unresolved-reference = "ignore" # mypy is more permissive with references possibly-missing-import = "ignore" +possibly-missing-attribute = "ignore" missing-argument = "ignore" +unused-type-ignore-comment = "ignore" [tool.coverage.run] source = ["src/pruna"] From 88ae72a8a3e90ae87609d288f635f8a162c187a5 Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Sun, 15 Feb 2026 01:53:58 +0100 Subject: [PATCH 4/9] fix: adapt signature of get_model_dependent_hyperparameter_defaults to parent method --- src/pruna/algorithms/hqq.py | 4 ++-- src/pruna/algorithms/hqq_diffusers.py | 4 ++-- src/pruna/algorithms/llm_compressor.py | 4 ++-- src/pruna/algorithms/sage_attn.py | 9 +++------ src/pruna/algorithms/torchao.py | 4 ++-- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/pruna/algorithms/hqq.py b/src/pruna/algorithms/hqq.py index ae8563a9..57395385 100644 --- a/src/pruna/algorithms/hqq.py +++ b/src/pruna/algorithms/hqq.py @@ -26,7 +26,7 @@ from pruna.algorithms.base.pruna_base import PrunaAlgorithmBase from pruna.algorithms.base.tags import AlgorithmTag as tags from pruna.config.hyperparameters import Boolean -from pruna.config.smash_config import SmashConfigPrefixWrapper +from pruna.config.smash_config import SmashConfig, SmashConfigPrefixWrapper from pruna.config.target_modules import ( TARGET_MODULES_TYPE, TargetModules, @@ -132,7 +132,7 @@ def model_check_fn(self, model: Any) -> bool: return is_causal_lm(model) or is_janus_llamagen_ar(model) or is_transformers_pipeline_with_causal_lm(model) def get_model_dependent_hyperparameter_defaults( - self, model: Any, smash_config: SmashConfigPrefixWrapper + self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper ) -> TARGET_MODULES_TYPE: """ Get default values for the target_modules based on the model and configuration. diff --git a/src/pruna/algorithms/hqq_diffusers.py b/src/pruna/algorithms/hqq_diffusers.py index 54b0a61f..6544f740 100644 --- a/src/pruna/algorithms/hqq_diffusers.py +++ b/src/pruna/algorithms/hqq_diffusers.py @@ -26,7 +26,7 @@ from pruna.algorithms.base.pruna_base import PrunaAlgorithmBase from pruna.algorithms.base.tags import AlgorithmTag as tags -from pruna.config.smash_config import SmashConfigPrefixWrapper +from pruna.config.smash_config import SmashConfig, SmashConfigPrefixWrapper from pruna.config.target_modules import ( TARGET_MODULES_TYPE, TargetModules, @@ -128,7 +128,7 @@ def model_check_fn(self, model: Any) -> bool: return any(isinstance(attr_value, tuple(transformer_and_unet_models)) for attr_value in model.__dict__.values()) def get_model_dependent_hyperparameter_defaults( - self, model: Any, smash_config: SmashConfigPrefixWrapper + self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper ) -> TARGET_MODULES_TYPE: """ Get default values for the target_modules based on the model and configuration. diff --git a/src/pruna/algorithms/llm_compressor.py b/src/pruna/algorithms/llm_compressor.py index 7696bb9f..120d91c3 100644 --- a/src/pruna/algorithms/llm_compressor.py +++ b/src/pruna/algorithms/llm_compressor.py @@ -21,7 +21,7 @@ from pruna.algorithms.base.pruna_base import PrunaAlgorithmBase from pruna.algorithms.base.tags import AlgorithmTag as tags -from pruna.config.smash_config import SmashConfigPrefixWrapper +from pruna.config.smash_config import SmashConfig, SmashConfigPrefixWrapper from pruna.config.target_modules import ( TARGET_MODULES_TYPE, TargetModules, @@ -98,7 +98,7 @@ def model_check_fn(self, model: Any) -> bool: return is_causal_lm(model) or is_transformers_pipeline_with_causal_lm(model) def get_model_dependent_hyperparameter_defaults( - self, model: Any, smash_config: SmashConfigPrefixWrapper + self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper ) -> TARGET_MODULES_TYPE: """ Get the default hyperparameters for the model. diff --git a/src/pruna/algorithms/sage_attn.py b/src/pruna/algorithms/sage_attn.py index 236102e8..db0ed4ff 100644 --- a/src/pruna/algorithms/sage_attn.py +++ b/src/pruna/algorithms/sage_attn.py @@ -22,7 +22,7 @@ from pruna.algorithms.base.pruna_base import PrunaAlgorithmBase from pruna.algorithms.base.tags import AlgorithmTag as tags -from pruna.config.smash_config import SmashConfigPrefixWrapper +from pruna.config.smash_config import SmashConfig, SmashConfigPrefixWrapper from pruna.config.target_modules import TARGET_MODULES_TYPE, TargetModules, map_targeted_nn_roots from pruna.engine.save import SAVE_FUNCTIONS @@ -91,10 +91,7 @@ def _apply(self, model: Any, smash_config: SmashConfigPrefixWrapper) -> Any: target_modules = smash_config["target_modules"] if target_modules is None: - target_modules = self.get_model_dependent_hyperparameter_defaults( - model, - smash_config - ) + target_modules = self.get_model_dependent_hyperparameter_defaults(model, smash_config) def apply_sage_attn( root_name: str | None, @@ -153,7 +150,7 @@ def get_hyperparameters(self) -> list: def get_model_dependent_hyperparameter_defaults( self, model: Any, - smash_config: SmashConfigPrefixWrapper, + smash_config: SmashConfig | SmashConfigPrefixWrapper, ) -> TARGET_MODULES_TYPE: """ Get model-dependent default hyperparameters for this algorithm. diff --git a/src/pruna/algorithms/torchao.py b/src/pruna/algorithms/torchao.py index 1621f105..0d853afa 100644 --- a/src/pruna/algorithms/torchao.py +++ b/src/pruna/algorithms/torchao.py @@ -24,7 +24,7 @@ from pruna.algorithms.base.pruna_base import PrunaAlgorithmBase from pruna.algorithms.base.tags import AlgorithmTag as tags -from pruna.config.smash_config import SmashConfigPrefixWrapper +from pruna.config.smash_config import SmashConfig, SmashConfigPrefixWrapper from pruna.config.target_modules import TARGET_MODULES_TYPE, TargetModules, map_targeted_nn_roots, target_backbone from pruna.engine.model_checks import ( get_diffusers_transformer_models, @@ -172,7 +172,7 @@ def model_check_fn(self, model: Any) -> bool: return isinstance(model, torch.nn.Module) def get_model_dependent_hyperparameter_defaults( - self, model: Any, smash_config: SmashConfigPrefixWrapper + self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper ) -> TARGET_MODULES_TYPE: """ Get default values for the target_modules based on the model and configuration. From 22731e878377f2040d47a9fbf882f95a22e93c47 Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Sun, 15 Feb 2026 01:56:38 +0100 Subject: [PATCH 5/9] build: add type ignore rules --- src/pruna/algorithms/c_translate.py | 4 ++-- src/pruna/algorithms/torch_dynamic.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pruna/algorithms/c_translate.py b/src/pruna/algorithms/c_translate.py index 51e876a5..0b9be863 100644 --- a/src/pruna/algorithms/c_translate.py +++ b/src/pruna/algorithms/c_translate.py @@ -393,7 +393,7 @@ def __call__( x_tensor = x["input_ids"] else: x_tensor = x - token_list = [self.tokenizer.convert_ids_to_tokens(x_tensor[i]) for i in range(len(x_tensor))] + token_list = [self.tokenizer.convert_ids_to_tokens(x_tensor[i]) for i in range(len(x_tensor))] # type: ignore[not-subscriptable] return self.generator.generate_batch(token_list, min_length=min_length, max_length=max_length, *args, **kwargs) # type: ignore[operator] @@ -468,7 +468,7 @@ def __call__( x_tensor = x["input_ids"] else: x_tensor = x - token_list = [self.tokenizer.convert_ids_to_tokens(x_tensor[i]) for i in range(len(x_tensor))] + token_list = [self.tokenizer.convert_ids_to_tokens(x_tensor[i]) for i in range(len(x_tensor))] # type: ignore[not-subscriptable] return self.translator.translate_batch( # type: ignore[operator] token_list, min_decoding_length=min_decoding_length, diff --git a/src/pruna/algorithms/torch_dynamic.py b/src/pruna/algorithms/torch_dynamic.py index e3b1ac3f..ce9d1f76 100644 --- a/src/pruna/algorithms/torch_dynamic.py +++ b/src/pruna/algorithms/torch_dynamic.py @@ -107,7 +107,7 @@ def _apply(self, model: Any, smash_config: SmashConfigPrefixWrapper) -> Any: else: modules_to_quantize = {torch.nn.Conv1d, torch.nn.Conv2d, torch.nn.Conv3d, torch.nn.Linear} - quantized_model = torch.quantization.quantize_dynamic( + quantized_model = torch.quantization.quantize_dynamic( # type: ignore[deprecated] model, modules_to_quantize, dtype=getattr(torch, smash_config["weight_bits"]), From 932cb22f715f589dbe07c01918bd05af4574379c Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Sun, 15 Feb 2026 01:59:24 +0100 Subject: [PATCH 6/9] fix: update supported hyperparameter names retrieval in SmashConfig --- src/pruna/config/smash_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pruna/config/smash_config.py b/src/pruna/config/smash_config.py index 8b0f640d..11e5b2ef 100644 --- a/src/pruna/config/smash_config.py +++ b/src/pruna/config/smash_config.py @@ -286,7 +286,7 @@ def load_from_json(self, path: str | Path) -> None: setattr(self, name, config_dict.pop(name)) # Keep only values that still exist in the space, drop stale keys - supported_hparam_names = {hp.name for hp in SMASH_SPACE.get_hyperparameters()} + supported_hparam_names = {hp.name for hp in list(SMASH_SPACE.values())} saved_values = {k: v for k, v in config_dict.items() if k in supported_hparam_names} # Seed with the defaults, then overlay the saved values From b43041c6c3e2b24a9a6aeb069a0cb065913993e6 Mon Sep 17 00:00:00 2001 From: Amine Saboni <43726203+SaboniAmine@users.noreply.github.com> Date: Wed, 18 Feb 2026 16:56:44 +0100 Subject: [PATCH 7/9] ci: enforce pr title format via a github actions workflow (#538) --- .github/workflows/pr-title.yaml | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/pr-title.yaml diff --git a/.github/workflows/pr-title.yaml b/.github/workflows/pr-title.yaml new file mode 100644 index 00000000..8a432ca1 --- /dev/null +++ b/.github/workflows/pr-title.yaml @@ -0,0 +1,46 @@ +name: PR Title Convention + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + branches: [main] + +permissions: + pull-requests: read + +jobs: + check-title: + name: Validate PR title + runs-on: ubuntu-22.04 + timeout-minutes: 1 + steps: + - name: Check conventional commit format + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + # Allowed conventional commit types + TYPES="feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert" + + # Pattern: type(optional-scope): description + # OR: type!: description (breaking change) + PATTERN="^($TYPES)(\(.+\))?\!?: .+" + + if echo "$PR_TITLE" | grep -qP "$PATTERN"; then + echo "PR title is valid: $PR_TITLE" + else + echo "::error::PR title does not follow Conventional Commits." + echo "" + echo "Got: $PR_TITLE" + echo "" + echo "Expected: [optional scope]: " + echo "" + echo "Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert" + echo "Read more: https://www.conventionalcommits.org/en/v1.0.0/" + echo "" + echo "Examples:" + echo " feat: add new optimization algorithm" + echo " fix: resolve memory leak in model loading" + echo " ci(pruna): pin transformers version" + echo "" + exit 1 + fi \ No newline at end of file From c00e487e7f81521b647af2941b6a4eeae8940ab4 Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Wed, 18 Feb 2026 23:43:37 +0100 Subject: [PATCH 8/9] build(ty): bump ty 0.0.16 to 0.0.17 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 265d23a1..b9d1ff71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -183,7 +183,7 @@ dev = [ "pytest-rerunfailures", "coverage", "docutils", - "ty==0.0.16", + "ty==0.0.17", "types-PyYAML", "logbar", "pytest-xdist>=3.8.0", From d3a842fc1c322fde08d02a48e7c6be800ccb0cd7 Mon Sep 17 00:00:00 2001 From: Renato Sortino Date: Wed, 18 Feb 2026 23:44:41 +0100 Subject: [PATCH 9/9] build: add ty ignore comment to bypass invalid-method-override error --- src/pruna/algorithms/hqq.py | 2 +- src/pruna/algorithms/hqq_diffusers.py | 2 +- src/pruna/algorithms/llm_compressor.py | 2 +- src/pruna/algorithms/sage_attn.py | 2 +- src/pruna/algorithms/torchao.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pruna/algorithms/hqq.py b/src/pruna/algorithms/hqq.py index 43280318..bcc7645e 100644 --- a/src/pruna/algorithms/hqq.py +++ b/src/pruna/algorithms/hqq.py @@ -135,7 +135,7 @@ def model_check_fn(self, model: Any) -> bool: def get_model_dependent_hyperparameter_defaults( self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper - ) -> TARGET_MODULES_TYPE: + ) -> TARGET_MODULES_TYPE: # ty: ignore[invalid-method-override] """ Provide default `target_modules` using `target_backbone` to target the model backbone. diff --git a/src/pruna/algorithms/hqq_diffusers.py b/src/pruna/algorithms/hqq_diffusers.py index 9ae24bdb..24e71bd8 100644 --- a/src/pruna/algorithms/hqq_diffusers.py +++ b/src/pruna/algorithms/hqq_diffusers.py @@ -131,7 +131,7 @@ def model_check_fn(self, model: Any) -> bool: def get_model_dependent_hyperparameter_defaults( self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper - ) -> TARGET_MODULES_TYPE: + ) -> TARGET_MODULES_TYPE: # ty: ignore[invalid-method-override] """ Provide default `target_modules` by detecting transformer and unet components in the pipeline. diff --git a/src/pruna/algorithms/llm_compressor.py b/src/pruna/algorithms/llm_compressor.py index b95b4b6d..605eb738 100644 --- a/src/pruna/algorithms/llm_compressor.py +++ b/src/pruna/algorithms/llm_compressor.py @@ -99,7 +99,7 @@ def model_check_fn(self, model: Any) -> bool: def get_model_dependent_hyperparameter_defaults( self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper - ) -> TARGET_MODULES_TYPE: + ) -> TARGET_MODULES_TYPE: # ty: ignore[invalid-method-override] """ Provide default `target_modules` using `target_backbone` to target the model backbone. diff --git a/src/pruna/algorithms/sage_attn.py b/src/pruna/algorithms/sage_attn.py index 99e1401f..ecffba7e 100644 --- a/src/pruna/algorithms/sage_attn.py +++ b/src/pruna/algorithms/sage_attn.py @@ -151,7 +151,7 @@ def get_model_dependent_hyperparameter_defaults( self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper, - ) -> TARGET_MODULES_TYPE: + ) -> TARGET_MODULES_TYPE: # ty: ignore[invalid-method-override] """ Provide default `target_modules` targeting all transformer modules. diff --git a/src/pruna/algorithms/torchao.py b/src/pruna/algorithms/torchao.py index a65fba8a..dbc92f72 100644 --- a/src/pruna/algorithms/torchao.py +++ b/src/pruna/algorithms/torchao.py @@ -175,7 +175,7 @@ def model_check_fn(self, model: Any) -> bool: def get_model_dependent_hyperparameter_defaults( self, model: Any, smash_config: SmashConfig | SmashConfigPrefixWrapper - ) -> TARGET_MODULES_TYPE: + ) -> TARGET_MODULES_TYPE: # ty: ignore[invalid-method-override] """ Provide default `target_modules` using `target_backbone`, with additional exclusions.