|
82 | 82 | "- `QuantLinear` — linear layer with quantized weights (and optionally biases)\n", |
83 | 83 | "- `QuantReLU` — ReLU that clips and quantizes activations to a fixed bit-width\n", |
84 | 84 | "\n", |
85 | | - "We use `weight_bit_width=6` and `bit_width=6` throughout, matching the 6-bit precision from Part 2a.\n", |
86 | | - "Unlike regular PyTorch, every forward pass applies the quantization, so the model trains with the actual fixed-point precisions used on the FPGA." |
| 85 | + "We use `weight_bit_width=6`, `bias_bit_width=6`, and `bit_width=6` throughout, matching the 6-bit precision from Part 2a.\n", |
| 86 | + "Unlike regular PyTorch, every forward pass applies the quantization, so the model trains with the actual fixed-point precisions used on the FPGA. Additionally, we specify FixedPoint quantizers to enforce power of two scales, which are generally better handled by hls4ml.\n", |
| 87 | + "Note, these particular quantizers have a maximum bit width of 8-bits, though narrower is allowed." |
87 | 88 | ] |
88 | 89 | }, |
89 | 90 | { |
|
93 | 94 | "metadata": {}, |
94 | 95 | "outputs": [], |
95 | 96 | "source": [ |
| 97 | + "from brevitas.quant import Int8BiasPerTensorFixedPointInternalScaling, Int8WeightPerTensorFixedPoint, Uint8ActPerTensorFixedPoint\n", |
| 98 | + "\n", |
96 | 99 | "class JetTaggerBrevitas(nn.Module):\n", |
97 | 100 | " def __init__(self):\n", |
98 | 101 | " super().__init__()\n", |
99 | | - " self.fc1 = qnn.QuantLinear(16, 64, bias=False, weight_bit_width=6)\n", |
100 | | - " self.relu1 = qnn.QuantReLU(bit_width=6)\n", |
101 | | - " self.fc2 = qnn.QuantLinear(64, 32, bias=False, weight_bit_width=6)\n", |
102 | | - " self.relu2 = qnn.QuantReLU(bit_width=6)\n", |
103 | | - " self.fc3 = qnn.QuantLinear(32, 32, bias=False, weight_bit_width=6)\n", |
104 | | - " self.relu3 = qnn.QuantReLU(bit_width=6)\n", |
105 | | - " self.output = qnn.QuantLinear(32, 5, bias=False, weight_bit_width=6)\n", |
| 102 | + " self.fc1 = qnn.QuantLinear(16, 64, weight_quant=Int8WeightPerTensorFixedPoint, weight_bit_width=6,\n", |
| 103 | + " bias_quant=Int8BiasPerTensorFixedPointInternalScaling, bias_bit_width=6)\n", |
| 104 | + " self.relu1 = qnn.QuantReLU(act_quant=Uint8ActPerTensorFixedPoint, bit_width=6)\n", |
| 105 | + " self.fc2 = qnn.QuantLinear(64, 32, weight_quant=Int8WeightPerTensorFixedPoint, weight_bit_width=6,\n", |
| 106 | + " bias_quant=Int8BiasPerTensorFixedPointInternalScaling, bias_bit_width=6)\n", |
| 107 | + " self.relu2 = qnn.QuantReLU(act_quant=Uint8ActPerTensorFixedPoint, bit_width=6)\n", |
| 108 | + " self.fc3 = qnn.QuantLinear(32, 32, weight_quant=Int8WeightPerTensorFixedPoint, weight_bit_width=6,\n", |
| 109 | + " bias_quant=Int8BiasPerTensorFixedPointInternalScaling, bias_bit_width=6)\n", |
| 110 | + " self.relu3 = qnn.QuantReLU(act_quant=Uint8ActPerTensorFixedPoint, bit_width=6)\n", |
| 111 | + " self.output = qnn.QuantLinear(32, 5, weight_quant=Int8WeightPerTensorFixedPoint, weight_bit_width=6,\n", |
| 112 | + " bias_quant=Int8BiasPerTensorFixedPointInternalScaling, bias_bit_width=6)\n", |
106 | 113 | "\n", |
107 | 114 | " def forward(self, x):\n", |
108 | 115 | " x = self.relu1(self.fc1(x))\n", |
|
233 | 240 | "source": [ |
234 | 241 | "## Convert to hls4ml via QONNX\n", |
235 | 242 | "\n", |
236 | | - "`config_from_onnx_model` reads the Quant nodes embedded in the QONNX graph and derives per-layer precision automatically. " |
| 243 | + "`config_from_onnx_model` reads the Quant nodes embedded in the QONNX graph and derives per-layer precision automatically." |
237 | 244 | ] |
238 | 245 | }, |
239 | 246 | { |
|
251 | 258 | " backend='Vitis',\n", |
252 | 259 | ")\n", |
253 | 260 | "\n", |
254 | | - "for layer in config.get('LayerName', {}):\n", |
255 | | - " if layer.startswith('Softmax'):\n", |
256 | | - " config['LayerName'][layer]['Implementation'] = 'legacy'\n", |
257 | | - "\n", |
258 | 261 | "print('-----------------------------------')\n", |
259 | 262 | "plotting.print_dict(config)\n", |
260 | 263 | "print('-----------------------------------')\n", |
|
408 | 411 | ], |
409 | 412 | "metadata": { |
410 | 413 | "kernelspec": { |
411 | | - "display_name": "hls4ml-tutorial", |
| 414 | + "display_name": "Python 3 (ipykernel)", |
412 | 415 | "language": "python", |
413 | 416 | "name": "python3" |
414 | 417 | }, |
|
422 | 425 | "name": "python", |
423 | 426 | "nbconvert_exporter": "python", |
424 | 427 | "pygments_lexer": "ipython3", |
425 | | - "version": "3.10.16" |
| 428 | + "version": "3.12.13" |
426 | 429 | } |
427 | 430 | }, |
428 | 431 | "nbformat": 4, |
|
0 commit comments