Skip to content

Fix feature_info channels for pruned models#2723

Open
prawnsgupta wants to merge 1 commit into
huggingface:mainfrom
prawnsgupta:fix/pruned-feature-info-channels
Open

Fix feature_info channels for pruned models#2723
prawnsgupta wants to merge 1 commit into
huggingface:mainfrom
prawnsgupta:fix/pruned-feature-info-channels

Conversation

@prawnsgupta

Copy link
Copy Markdown

Summary

Pruned models report incorrect feature_info.channels() — the original (unpruned) channel counts rather than the actual pruned feature-map channels. This fixes #2370.

Affected models: efficientnet_b1_pruned, efficientnet_b2_pruned, efficientnet_b3_pruned, ecaresnet50d_pruned, ecaresnet101d_pruned.

Root cause

adapt_model_from_string() in timm/models/_prune.py rebuilds Conv2d/BatchNorm/Linear layers with pruned dimensions, but feature_info is populated at original build time and was never updated. So feature_info.channels() (and anything built on it, e.g. features_only=True) kept the dense channel counts.

Before (efficientnet_b1_pruned, features_only=True):

actual feature shapes : [16, 12, 35, 67, 320]
feature_info.channels : [16, 24, 40, 112, 320]   # wrong

Fix

Adds _adapt_feature_info(), called at the end of adapt_model_from_string(). It runs a single dry-run forward with hooks on the feature modules to read their true output channel counts and writes them back into feature_info. Properties:

  • Fixes all pruned models, since it lives in the shared _prune utility rather than any single model file.
  • Fail-safe — wrapped so any error leaves feature_info untouched and never breaks model construction (logs a warning).
  • Handles both the plain-list and FeatureInfo representations, and derives input channels/size from the model so it respects custom stems and pretrained_cfg input size.

After the fix, feature_info.channels() matches the real feature shapes for all five models.

Tests

Pruned models now pass the feature-extraction tests, so the *pruned* exclusions in tests/test_models.py (one marked # hopefully fix at some point) are removed. Verified locally:

  • test_model_forward_features, test_model_forward_intermediates_features, test_model_forward_intermediates28 passed for pruned models (previously excluded).
  • Non-pruned feature tests unaffected.

Note: the separate in_chans-on-pruned limitation (#1597) is out of scope here and left untouched.

Pruned models (efficientnet_b1/b2/b3_pruned, ecaresnet50d/101d_pruned)
reported the original, unpruned channel counts from
feature_info.channels(), not matching the actual feature map channels
produced with features_only=True.

adapt_model_from_string() rebuilds Conv/BN/Linear layers with pruned
dimensions but never updated feature_info, which is populated at
original build time. This adds _adapt_feature_info(), which runs a single
dry-run forward with hooks on the feature modules to read their true
output channel counts and writes them back. It is fail-safe: any error
leaves feature_info untouched and never breaks model construction, and it
handles both the plain-list and FeatureInfo representations.

With this, pruned models pass the feature extraction tests, so the
'*pruned*' exclusions (previously marked "hopefully fix at some point")
are removed from tests/test_models.py.

Fixes huggingface#2370
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] feature_info.channels() is not match

1 participant