Post-Training Compression¶
What is post-training compression?
The post-training compression (PTC) pipeline turns a trained policy checkpoint into a deployment artifact for edge or resource-constrained hardware. A PTC run can export a floating-point model, apply pruning, quantize the policy, and save either a Torch Export .pt2 artifact or an ExecuTorch .pte artifact.
The pipeline owns the end-to-end compression job: checkpoint loading, optional model preparation, pruning, quantization workflow execution, deployment backend export, serialization, and reporting.
Quantization details live in the dedicated Quantization page. This page describes how PTC orchestrates those workflows.
Architecture¶
The PTC package is centered on
PostTrainingCompressor.
It operates on CompressionTarget
entries, then delegates quantization and deployment to separate abstractions:
- Quantization workflows decide how the policy is exported or quantized: no quantization, eager, or PyTorch 2 Export.
- Deployment backends decide the final artifact format: e.g. Torch Export
.pt2or ExecuTorch.pte.
Pipeline Flow¶
PostTrainingCompressor.compress()
|
+-- resolve_modules() Per-module targets or global fallback
+-- _resolve_quantization_workflow() none, eager, or pt2e path
+-- _validate_deployment_backend_compatibility()
| Validate workflow mode vs deployment backend
|
+-- workflow.load_policy_context() Load float or QAT-prepared checkpoint
+-- validate() Check preparation/pruning module paths
+-- workflow.validate_targets() Check quantization target paths
|
+-- _prepare_and_prune() Per target:
| +-- prepare_batchnorms() Replace FrozenBN with standard BN
| +-- fuse_conv_batchnorm() Fold BN weights into Conv2d
| +-- pruner.prune() x N Apply pruners sequentially
|
+-- ExportablePolicy.from_policy() Positional tensor I/O wrapper
+-- workflow.quantize() Export or quantize policy
+-- deployment_backend.export() Build .pt2 descriptor or .pte bytes
+-- save_compressed_model() Artifact, metadata, normalizer, tokenizer
|
+-- optional QuantizationReport Coverage, size, divergence, speed
Key Classes¶
| Class | Module | Role |
|---|---|---|
PostTrainingCompressor |
src/versatil/post_training_compression/compressor.py |
Pipeline orchestrator. Resolves targets, validates compatibility, prepares/prunes, exports, saves. |
CompressionTarget |
src/versatil/post_training_compression/compression_target.py |
Per-module preparation and pruning config: module_path, preparation, pruning list. |
QuantizationModuleTarget |
src/versatil/quantization/module_target.py |
Per-module quantization target owned by the selected quantization workflow. |
ExportablePolicy |
src/versatil/models/exportable_policy.py |
Wraps Policy with positional tensor I/O for torch.export. |
DeploymentBackend |
src/versatil/post_training_compression/deployment_backends/base.py |
Base class for final deployment artifact generation. |
TorchInductorBackend |
src/versatil/post_training_compression/deployment_backends/torch_inductor.py |
Saves Torch Export .pt2 artifacts. |
ExecutorchXNNPACKBackend |
src/versatil/post_training_compression/deployment_backends/executorch_xnnpack.py |
Lowers exported programs to ExecuTorch XNNPACK .pte artifacts. |
CompressedCheckpointLoader |
src/versatil/checkpoint_loading/compressed_policy.py |
Loads compressed checkpoint metadata, normalizer, tokenizer, and deployment artifact. |
CompressedPolicyRuntime |
src/versatil/inference/policy_runtime/compressed_runtime.py |
Runs compressed policies through the inference runtime interface. |
Compression Targets¶
CompressionTarget lets the config apply preparation and pruning globally or
to selected submodules. Each target contains:
module_path: dotted module path, or""for the root policy;preparation: optional BatchNorm replacement and fusion settings;pruning: ordered list of pruners.
When modules is empty, PTC creates a single root target from the top-level
preparation and pruning fields.
Quantization targets are configured separately under quantization.targets.
See Quantization for the target schema.
Preparation¶
Preparation runs before pruning and quantization:
prepare_batchnorms_for_quantization()replaces non-standard BatchNorm variants with standardnn.BatchNorm2din eval mode with tracking disabled.fuse_all_conv_batchnorm_pairs()folds consecutive Conv2d and BatchNorm2d pairs into a single Conv2d with adjusted weights and bias, replacing the BatchNorm withnn.Identitywhere appropriate.
Pruning¶
Pruning is specified as a list of
BasePruner
instances. The list is applied sequentially, so structured and unstructured
pruning can be composed on the same target.
UnstructuredPruner: global L1 magnitude pruning. Defaults to convolution and linear layers; normalization scales and embedding tables are never pruned.StructuredPruner: per-layer channel pruning along a configured dimension. By default it targets Conv1d, Conv2d, and Linear layers.
Quantization Hook¶
PTC calls exactly one workflow mode per compression run:
none: float export throughNoQuantizationWorkflow;eager: eager torchao PTQ or eager QAT conversion;pt2e: PyTorch 2 Export graph quantization.
The workflow returns a QuantizedContext containing the exported float graph,
the exported or quantized graph, example inputs, and serialized workflow mode.
See Quantization for the workflow contract, QAT behavior,
calibration, and PT2E backend details.
Deployment Backends¶
Deployment backends run after the workflow returns a QuantizedContext.
| Backend | Artifact format | Output file | Notes |
|---|---|---|---|
TorchInductorBackend |
torch_export_pt2 |
compressed_policy.pt2 |
Default backend. Saves the selected exported module as a Torch Export archive. |
ExecutorchXNNPACKBackend |
executorch_pte |
compressed_policy.pte |
Lowers the selected exported program with ExecuTorch XNNPACK. |
The deployment backend is stored in metadata so inference can load the artifact according to its file format.
For PT2E quantization, TorchInductorBackend pairs with X86InductorBackend,
and ExecutorchXNNPACKBackend pairs with XNNPACKPT2EBackend.
Compressed Checkpoints¶
A compressed checkpoint directory contains:
compressed/<timestamp>/
+-- compressed_policy.pt2 | compressed_policy.pte
+-- normalizer.pt
+-- compression_metadata.json
+-- quantization_config.yaml
+-- config.yaml
+-- tokenizer/
compression_metadata.json records:
- model filename and artifact format;
- deployment backend name;
- input and output key ordering;
- source training checkpoint path;
- torch and torchao versions;
- workflow mode (
none,eager, orpt2e); - PT2E backend flags when applicable.
CompressedCheckpointLoader reads the metadata, normalizer, tokenizer, and
artifact. CompressedPolicyRuntime then exposes the same runtime interface used
by the inference client for floating-point policies.
Compressed artifacts are not standalone
Currently, compressed models are not fully standalone: they still require a complete VersatIL installation, including its dependencies. Since this is not ideal for edge deployment, self-contained edge-device inference runtime is currently under development.
Hydra Configuration¶
PTC configs live under src/versatil/hydra_configs/end_to_end_ptq/. Top-level fields serve
as defaults for preparation and pruning. Entries in modules can override
preparation and pruning for specific submodules. Quantization is configured once
at the top level through quantization, and module-level quantization
granularity is expressed inside quantization.targets.
checkpoint_path: ???
checkpoint_name: last.ckpt
output_directory: null
calibration_steps: 16
generate_report: false
preparation:
replace_frozen_batchnorm: true
fuse_conv_batchnorm: true
pruning:
- _target_: versatil.post_training_compression.pruning.UnstructuredPruner
amount: 0.5
quantization:
_target_: versatil.quantization.workflows.pt2e.PT2EQuantizationWorkflow
targets:
- _target_: versatil.quantization.module_target.PT2EQuantizationModuleTarget
module_path: ""
pt2e_backend:
_target_: versatil.quantization.pt2e.backends.x86_inductor.X86InductorBackend
is_dynamic: false
is_qat: false
reduce_range: false
deployment_backend:
_target_: versatil.post_training_compression.deployment_backends.torch_inductor.TorchInductorBackend
modules: []
Set quantization: null for floating-point export. Replace the quantization block with
an eager or PT2E workflow as described in Quantization.
Compatibility Rules¶
- A compression run uses one quantization workflow:
none,eager, orpt2e. modulesdo not carry quantization configs. Usequantization.targetsfor module-level quantization.- Export currently runs on CPU. PT2E calibration also runs on CPU because the exported graph records device metadata.