ConvReLU3d
Conv3dConvReLU3d(in_channels: int, out_channels: int, kernel_size: _IntTuple, stride: _IntTuple, padding: _IntTuple, dilation: _IntTuple, groups: int, bias: bool)Quantized 3-D convolution with a fused ReLU — int8 kernel, float compute.
A fused (intrinsic) block for volumetric / video models: the quantized
counterpart of the float nn.intrinsic.ConvReLU3d, installed by
lucid.quantization.convert / from_float. It behaves exactly
like lucid.nn.quantized.Conv3d — int8 per-output-channel kernel,
float convolution, output fake-quantized to the calibrated grid — but folds a
ReLU into the layer so conv + activation share one quantized output. The 3-D
kernel makes int8 storage especially valuable here, since a volumetric filter
(out, in/groups, kd, kh, kw) is large.
Why fuse. During calibration the fused module's activation observer sat
after the ReLU, so it recorded the post-ReLU (non-negative) range. To
reproduce those numerics at inference the ReLU must run before the output
fake-quant — the job of the overridden _activation hook. Requantizing the
conv → relu pair once, against the tighter non-negative range, uses the
int8 grid more efficiently than quantizing the raw conv output then clamping.
Encoding (int8 kernel) happens once at from_float; decode + convolve +
fused ReLU + requantize run on every forward:
where are the per-output-channel kernel scale / zero-point
and the outer fake-quant snaps the post-ReLU result to the scalar calibrated
output (scale, zero_point).
Parameters
in_channelsintout_channelsintkernel_sizeint or tuple of intstrideint or tuple of intpaddingint or tuple of intdilationint or tuple of intgroupsintbiasboolAttributes
weight_int8Tensorint8 kernel codes, shape
(out_channels, in_channels/groups, kd, kh, kw).weight_scaleTensor(out_channels,).weight_zero_pointTensor(out_channels,).scale, zero_pointTensorbiasTensor or None(out_channels,), or None.Notes
- Produced by
convert/from_float, not constructed directly; the constructor is inherited unchanged fromlucid.nn.quantized.Conv3dand only the_activationhook differs. from_floataccepts a float fusednn.Sequential([0]is the conv) or a single-layer QAT fused module; the shared wiring copies the fused qconfig / observer onto the weighted child before quantizing.- Output is non-negative (ReLU precedes the fake-quant) — calibrate the fused module so the observed grid matches inference.
Examples
>>> import lucid, lucid.nn as nn
>>> q = nn.quantized.ConvReLU3d(2, 4, 3, 1, 1, 1, 1, True) # via convert()
>>> q(lucid.randn(1, 2, 8, 8, 8)).shape
(1, 4, 8, 8, 8)
>>> bool((q.weight_int8 == 0).all().item()) # zeroed until from_float
TrueSee Also
- lucid.nn.quantized.Conv3d—The un-fused quantized 3-D conv it extends.
- lucid.nn.quantized.ConvReLU2d—The 2-D fused analogue (vision workhorse).
- lucid.quantization.convert—Installs this layer from a calibrated model.
Used by 1
Class methods
1from_float(mod: nn.Module)Quantize a calibrated float convolution module.