latest (dev)
Copy
Latest development documentation · Updated 2026-10-15
Source code for tensorplay.ao.nn.quantized.dynamic.modules.linear
"""Dynamically quantized linear module.
Weights use the configured tensor or output-channel grid. Activations use
one affine grid over the complete input at each call. The output stays in
the float domain.
"""
from __future__ import annotations
import tensorplay
from tensorplay import nn
__all__ = ["Linear"]
[docs]
class Linear(nn.Module):
_FUSED_RELU = False
def __init__(self, in_features, out_features, bias_=True, dtype=tensorplay.qint8):
super().__init__()
if dtype not in (tensorplay.qint8, tensorplay.float16):
raise ValueError('Dynamic linear weights require signed 8-bit or half storage')
from ...packed import PackedWeight, PackedHalfWeight
self.dtype = dtype
self.in_features, self.out_features = int(in_features), int(out_features)
weight = tensorplay.zeros(out_features, in_features)
bias = tensorplay.zeros(out_features) if bias_ else None
self._packed_params = (PackedHalfWeight(weight, bias) if dtype == tensorplay.float16
else PackedWeight(tensorplay._C.quantize_per_tensor(weight, 1., 0, dtype), bias))
self.reduce_range = True
@property
def weight(self):
return self._packed_params.weight
@property
def bias(self):
return self._packed_params.bias
@property
def weight_scales(self):
return self._packed_params.scales
@property
def weight_zero_points(self):
return self._packed_params.zero_points
def set_weight_bias(self, weight, bias):
if tuple(weight.shape) != (self.out_features, self.in_features):
raise ValueError('Dynamic linear weight dimensions do not match the module')
self._packed_params.set_weight_bias(weight, bias)
def forward(self, x):
if self.dtype == tensorplay.float16:
return self._packed_params.run(x, relu=self._FUSED_RELU)
if x.is_quantized():
x = x.dequantize()
quantized = (tensorplay._C.quantize_per_tensor_dynamic(x, tensorplay.quint8, self.reduce_range)
if x.numel() else tensorplay._C.quantize_per_tensor(x, .1, 0, tensorplay.quint8))
return self._packed_params.run(quantized, relu=self._FUSED_RELU, output_float=True).to(x.dtype)
@classmethod
def from_float(cls, mod, use_precomputed_fake_quant=False):
from ...packed import quantize_module_weight, conversion_source
source = conversion_source(mod)
if not isinstance(source, nn.Linear):
raise TypeError('Dynamic linear conversion requires a floating linear module')
qconfig = getattr(source, 'qconfig', getattr(mod, 'qconfig', None))
dtype = qconfig.weight().dtype if qconfig is not None else tensorplay.qint8
result = cls(source.in_features, source.out_features, source.bias is not None, dtype=dtype)
weight = source.weight.detach() if dtype == tensorplay.float16 else quantize_module_weight(source, use_precomputed_fake_quant)
result.set_weight_bias(weight, source.bias.detach() if source.bias is not None else None)
return result
def extra_repr(self):
return f'in_features={self.in_features}, out_features={self.out_features}, bias={self.bias is not None}'Help improve this page
Found an error, an unclear step, or a missing example?
Was this page helpful?

