Resolves which QConfig applies to each module in a model.
A QConfig says how to quantize; a QConfigMapping says where.
lucid.quantization.prepare / lucid.quantization.prepare_qat
consult a mapping for every candidate module and insert (or skip) observers
according to the resolved recipe. The mapping is a small three-tier lookup table
plus a resolution rule.
Three tiers, most-specific-wins. For a module of type T at qualified name
"a.b.c" the mapping is queried in order:
- module name — an exact
set_module_nameentry; - module type — a
set_object_typeentry; - global — the
set_globalfallback.
The first tier that has an entry wins, so a per-name rule overrides a per-type rule, which overrides the global default. This lets you set one recipe for the whole model and then carve out exceptions with surgical precision.
Mapping to None means "do not quantize". Any tier may map to None to
exclude a module from quantization even when a broader tier would have quantized
it — e.g. keep a numerically sensitive final classifier in float while quantizing
everything else.
Fluent construction. Every setter returns self, so a mapping is typically
built in a single chained expression.
Notes
- The name / type tiers are plain dicts, so re-setting the same key overwrites the previous entry; there is no merge.
- Type matching is by exact type identity (the dict is keyed on the class
object), not
isinstance— a subclass is not matched by a base-class rule unless you register the subclass explicitly. - The default mappings from
get_default_qconfig_mapping/get_default_qat_qconfig_mappingset only the global tier; you add per-type / per-name overrides on top.
Examples
>>> import lucid.nn as nn
>>> import lucid.quantization as Q
>>> mapping = (
... Q.QConfigMapping()
... .set_global(Q.get_default_qconfig()) # default everywhere
... .set_object_type(nn.Linear, None) # ... except Linears
... .set_module_name("head", Q.get_default_qconfig()) # ... but quantize "head"
... )
>>> # "head" is a Linear, but the per-name rule (tier 1) beats the per-type rule:
>>> mapping.get_qconfig(nn.Linear, "head") is not None
True
>>> # any other Linear falls to the per-type rule → excluded from quantization:
>>> mapping.get_qconfig(nn.Linear, "encoder.fc") is None
True
>>> # a Conv2d has no name / type rule → the global default applies:
>>> mapping.get_qconfig(nn.Conv2d, "features.0") is not None
TrueSee Also
QConfig—The recipe a mapping resolves to.get_default_qconfig_mapping—A mapping preloaded with the static-PTQ default.get_default_qat_qconfig_mapping—A mapping preloaded with the QAT default.
Used by 3
Constructors
1Instance methods
4Resolve the QConfig for a module, most-specific tier first.
Implements the resolution rule: a per-name entry (tier 1) wins over a per-type
entry (tier 2), which wins over the global fallback (tier 3). Returns None
when the winning tier maps to None or when no tier matches and no global
default was set — in both cases the caller leaves the module in float.
Parameters
module_typetypemodule_namestrReturns
QConfig or NoneThe resolved recipe, or None to signal "do not quantize".
set_global(qconfig: QConfig | None)Set the fallback QConfig used when no more specific rule matches.
The global tier is the lowest-priority tier (below per-type and per-name), so
it defines the model-wide default behaviour. Pass None to make "leave in
float" the default and then opt in specific types / names on top.
Parameters
qconfigQConfig or NoneNone to leave such modules unquantized.Returns
QConfigMappingself, so setters can be chained fluently.
set_module_name(name: str, qconfig: QConfig | None)Bind a QConfig to the single module at a qualified name.
A per-name rule is the highest-priority tier: it overrides both the per-type
rule and the global fallback for exactly the module whose dotted path in the
parent model equals name (e.g. "encoder.layer.0.attention"). Pass
None to exclude just that one module.
Parameters
namestrqconfigQConfig or NoneNone to leave it unquantized.Returns
QConfigMappingself, so setters can be chained fluently.
set_object_type(module_type: type, qconfig: QConfig | None)Bind a QConfig to every module of an exact type.
A per-type rule sits above the global fallback but below a per-name rule.
Matching is by exact class identity, not isinstance — register a subclass
explicitly if you need it. Pass None to exclude every module of this type
from quantization.
Parameters
module_typetypelucid.nn.Linear).qconfigQConfig or Nonemodule_type, or None to skip them.Returns
QConfigMappingself, so setters can be chained fluently.