Repository navigation
release: 0.5.0 - #101
Open
nathanhubens wants to merge 1 commit into
Open
release: 0.5.0#101nathanhubens wants to merge 1 commit into
nathanhubens wants to merge 1 commit into
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 0.5.0: changelog section dated and version bumped to 0.5.0. Export and clean are idempotent;
nbdev-testpasses locally.Changelog
Breaking Changes
PruneCallbackandPruner(schedule=Schedule)now honour the schedule'sstart_pctandend_pct. The levels handed to torch-pruning used to map stepiofnstraight into the schedule's shape function, sostart_pctandend_pctwere never read:one_shot(start_pct=0.5) pruned at the first step, andagpanditerative(start_pct=0.2) began ramping from the first step. The levels are now the schedule's ownprogress(i / n), built in one place (Pruner._to_tp_scheduler) for both entry points:one_shotprunes once, at the first step at or paststart_pct;agpanditerativebegin at theirstart_pct; the full ratio is reached atend_pctand held after it. A schedule withstart_pct=0andend_pct=1(one_cycle,cos,lin,Schedule(f)) produces the same levels as before, level for level, and a plain torch-pruning scheduler callable is passed through unchanged — Migration: aSchedulewithstart_pct > 0, such asone_shotoragp, now waits for it; pass a schedule withstart_pct=0to keep the old timingNew Features
Pruner(..., reg=1e-4)builds torch-pruning'sGroupNormPrunerinstead of itsMetaPruner, and the newPruner.regularize(scale=1.)adds DepGraph's group penalty to the gradients already computed: every channel of a dependency group receivesreg * gamma * won each tensor it spans — the convolution's filter, the batch-norm weight and the input slices of the layers that read it.gammaruns from1on the group's most important channel to2**alphaon its least important one (alpha=4by default), measured on the square root of the pruner's owncriteriascore. It is called afterbackwardand before the optimizer step, andscalemultiplies the penalty for gradients that are themselves scaled (a mixed-precision loss scale, gradient accumulation). Only the groups the pruner will prune are penalized, so a per-layer dict leaves the layers it does not target alone; a group with a constant importance (a single channel among them) is skipped instead of producingnangradients, with one warning if every group is; the groups are rebuilt after eachprune_model(). Biases, frozen parameters and a depthwise convolution's own kernels are not penalized.regandalphaare keyword-only andreg < 0is refused.reg=0, the default, builds the sameMetaPruneras before and prunes identically apart from the device fix below.PruneCallbackrefusesreg: useGroupRegularizeCallbackGroupRegularizeCallback(pruner, schedule=None)applies aPruner's group penalty during a fastai fit:before_stepcallspruner.regularize(), afterGradientAccumulationhas skipped the batches that do not step and beforeMixedPrecisionunscales the gradients, so the penalty is added once per optimizer step and multiplied by the loss scale of atorch.amp.GradScalerwhen one is active. ASchedulemultiplies the penalty by its progress and is copied, so the module-level schedules other callbacks share are not advanced. Pruning stays a separate call after the fit:pruner.prune_model(), thenlearn.fit(n, reset_opt=True), because the prune replaces the parameters the optimizer holds. APrunerwithreg=0is refused, and so are, atbefore_fit, aPrunerbuilt on another model thanlearn.model,NonNativeMixedPrecisionand aPruneCallbackin the same fitRegularizeCallback(norm=2)penalizes the L2 norm of each group of the chosengranularity(group lasso) instead of every weight separately. The default,norm=1, is unchanged byte for byte and is an elementwise L1 whatever the granularity, since the groups partition the weights; groups are taken within one layer and do not follow cross-layer couplings such as the next layer's input channels or BatchNorm parametersBug Fixes
Pruner.group_importancereturns its scores on the device of the layers it scored instead of fastai's default device, which put them on the GPU for a model on the CPU whenever one was available. The ranking a prune step makes is unchanged: torch-pruning moves the scores to the CPU before ranking themPruneCallbacklogs, at the end of each epoch, the pruning ratio torch-pruning actually applied. torch-pruning'sstep()advances its step counter before reading the level, so afterksteps the model is at levelk; the log printed levelk - 1, one step behind, and the last epoch did not print the final targetPruneCallbackhands the batch it takes fromlearn.dls.one_batch()to thePrunerasexample_inputs, so the dependency graph is traced on the fit's own data. It was read and then dropped, and thePrunertraced on its defaulttorch.randn(1, 3, 224, 224), which failed on a model that does not accept a 224x224 image. Anexample_inputspassed to the callback still winsDependencies
torch-pruning>=1.5