Small NLP models, especially BERT-family encoders, remain important in industrial workloads such as classification, ranking, and retrieval even in the era of large language models. On server CPUs, INT8 quantization offers an attractive latency-throughput-cost trade-off, but users increasingly expect such acceleration to be available directly in the native PyTorch stack. We integrate SmoothQuant into TorchAO and optimize the resulting inference path for Intel Xeon CPUs through graph-level fusion in TorchInductor and efficient INT8 GEMM kernel selection across oneDNN-, AVX512_VNNI-, and AMX-based implementations. Across BERT, DistilBERT, and XLM-RoBERTa benchmarks, the approach delivers up to 5.8x end-to-end throughput speedup with negligible---and in some cases no measurable---accuracy loss relative to the FP32 baseline. We also validated our work by detailed performance analysis with roofline models. The implementation has been upstreamed to PyTorch and TorchAO, enabling out-of-the-box deployment with native PyTorch tooling
Figures & tables
Figure 1: SmoothQuant workflow built on TorchAO and TorchInductor. TorchAO prepares and quantizes the model, TorchInductor fuses INT8 subgraphs, and the CPP backend selects between oneDNN and template-based GEMM kernels. C++ code is generated and compiled for deployment.
Xeon Generation
Codename
Model
Physical Cores
Instruction Support
3rd Gen
Ice Lake
8358
64
AVX512F, AVX512_VNNI
6th Gen
Granite Rapids
6980P
256
AVX512F, AVX512_VNNI, AMX
Table 1: Hardware platforms used for baseline collection.
Item
Value
Model
BERT-large
Input shape
Batch size 1, sequence length 256
Precision modes
FP32 on both platforms; BF16 on Granite Rapids
Launch strategy
Multi-instance with weight-sharing on each socket
Cores per instance
4
Number of instances
Number of physical cores / 4
Table 2: Baseline collection setup.
Baseline
Linear-Block
Attention
LayerNorm
Other
FP32 on Ice Lake
88.5%
10.4%
0.6%
0.5%
FP32 on Granite Rapids
86.9%
11.8%
0.8%
0.5%
BF16 on Granite Rapids
72.70%
19.75%
5.99%
1.56%
Table 3: Baseline hotspot breakdown for the BERT-large analysis case under the same multi-instance setup used for throughput benchmarking. Operator shares are aggregated from representative profiler logs. The linear-block consists of GEMM and fused post-operations such as bias addition, activation, and residual addition.
Platform
FP32 Throughput (TFLOPS)
BF16 Throughput (TFLOPS)
INT8 Throughput (TOPS)
Memory Bandwidth (GB/s)
FP32 Balance Point (FLOPs/byte)
BF16 Balance Point (FLOPs/byte)
INT8 Balance Point (OPs/byte)
Ice Lake
6.76
N/A
27.03
175.00
38.63
N/A
154.46
Granite Rapids
19.66
262.14
524.29
700.00
28.09
374.49
748.99
Table 4: Estimated peak compute and measured memory bandwidth per socket, balance point for different data types on the evaluated platforms.
Arithmetic Intensity (ops/byte)
GEMM Shape M × K × N
Occurrences per forward pass
FP32
BF16
INT8
256×1024×1024
96
85.33
146.29
227.56
256×1024×4096
24
97.52
163.84
248.24
256×4096×1024
24
97.52
186.18
341.33
Table 5: BERT-large GEMM shapes and their arithmetic intensity.
GEMM Shape
Effective Memory Bandwidth (GB/s)
Arithmetic Intensity (OPs/byte)
Balance Point (OPs/byte)
256×1024×1024
807.69
227.56
649.12
256×1024×4096
819.15
248.24
640.04
256×4096×1024
875.00
341.33
599.19
Table 6: Effective memory bandwidth and balance point for INT8 GEMM on Granite Rapids.
GEMM Shape
FP32 Throughput (TFLOPS)
BF16 Throughput (TFLOPS)
INT8 Throughput (TOPS)
INT8 vs FP32 Speedup
INT8 vs BF16 Speedup
256×1024×1024
19.66
102.40
183.79
9.35 ×
1.79 ×
256×1024×4096
19.66
114.69
203.35
10.34 ×
1.77 ×
256×4096×1024
19.66
130.33
298.67
15.19 ×
2.29 ×
Weighted Average
19.66
114.69
218.87
11.13 ×
1.91 ×
Table 7: Estimated GEMM throughput and speedup on Granite Rapids.
Model
Model ID
BERT-large
bert-large-uncased
DistilBERT
distilbert-base-uncased
XLM-RoBERTa
xlm-roberta-base
Table 8: Models used for the performance benchmark.
Table 9: Task-finetuned checkpoints used for accuracy evaluation. The model marked by * is finetuned on SQuAD 2.0 but still workable for the test on SQuAD 1.1.
Method
Short Name
No quantization, no AMP
FP32
No quantization, with AMP
BF16
SmoothQuant, static quantization
Smooth-Static
SmoothQuant, dynamic quantization
Smooth-Dynamic
Table 10: Quantization methods used in the experiments.
Model
Method
Throughput Speedup
Linear-Block Speedup
BERT-large
Smooth-Dynamic
2.22 ×
3.59 ×
BERT-large
Smooth-Static
2.58 ×
3.87 ×
DistilBERT
Smooth-Dynamic
1.90 ×
3.31 ×
DistilBERT
Smooth-Static
2.30 ×
3.35 ×
XLM-RoBERTa
Smooth-Dynamic
1.86 ×
3.05 ×
XLM-RoBERTa
Smooth-Static
2.17 ×
3.71 ×
Table 11: INT8 speedup over FP32 on Ice Lake.
Model
Method
Throughput Speedup
Linear-Block Speedup
BERT-large
Smooth-Dynamic
5.02 ×
9.92 ×
BERT-large
Smooth-Static
5.82 ×
8.67 ×
DistilBERT
Smooth-Dynamic
4.24 ×
7.60 ×
DistilBERT
Smooth-Static
5.37 ×
8.84 ×
XLM-RoBERTa
Smooth-Dynamic
4.17 ×
7.58 ×
XLM-RoBERTa
Smooth-Static
5.41 ×
8.71 ×
Table 12: INT8 speedup over FP32 on Granite Rapids.
Model
Method
Throughput Speedup
Linear-Block Speedup
BERT-large
Smooth-Dynamic
1.37 ×
1.84 ×
BERT-large
Smooth-Static
1.59 ×
1.61 ×
DistilBERT
Smooth-Dynamic
0.98 ×
1.45 ×
DistilBERT
Smooth-Static
1.24 ×
1.69 ×
XLM-RoBERTa
Smooth-Dynamic
0.99 ×
1.50 ×
XLM-RoBERTa
Smooth-Static
1.29 ×
1.67 ×
Table 13: INT8 speedup over BF16 on Granite Rapids.
Throughput Speedup
Linear-Block Speedup
Platform
Method
Baseline
Realized
Estimated
Gap
Realized
Estimated
Gap
Ice Lake
Smooth-Dynamic
FP32
2.22 ×
3.15 ×
29.59%
3.59 ×
4.00 ×
10.22%
Ice Lake
Smooth-Static
FP32
2.58 ×
3.15 ×
18.17%
3.87 ×
4.00 ×
3.21%
Granite Rapids
Smooth-Dynamic
FP32
5.02 ×
7.06 ×
28.89%
9.92 ×
11.13 ×
10.89%
Granite Rapids
Smooth-Static
FP32
5.82 ×
7.06 ×
17.56%
8.67 ×
11.13 ×
22.12%
Granite Rapids
Smooth-Dynamic
BF16
1.37 ×
1.53 ×
10.41%
1.84 ×
1.91 ×
3.58%
Table 14: Realized speedup of BERT-large over estimated speedup ceiling on both evaluated platforms.
Post-training INT8 (W8A8) quantization of diffusion transformers is widely deployed as a speed optimization, yet on consumer Ampere GPUs it is frequently slower than the FP8 and NF4 alternatives it is meant to beat. We trace this to a software artifact: the production "INT8" forward quantizes weights and activations only to immediately dequantize them back to bf16 and run a bf16 matrix multiply, never engaging the GPU's INT8 tensor cores, so the hardware's compute advantage is left entirely unrealized. We close this gap with a single fused Triton INT8 GEMM (int8xint8->int32 on Ampere tensor cores, with per-token x per-channel dequantization and bias folded into the epilogue, autotuned per GEMM shape) dropped into the Ideogram 4.0 diffusion transformer's linear layers in place of the dequantize-to-bf16 path. In the kernel, the int8xint8->int32 accumulation is bit-exact against torch._int_mm and the dequantized output matches the reference at cosine similarity 1.0 with no NaNs, running 2.8-4.2x faster than bf16 per GEMM. End to end it delivers a ~1.1x (~9-10%) speedup at 768px, and at 1024px it generates an image in 156.5 s on a single RTX 3090, faster than the single-card NF4 (164.5 s) and FP8 (172.9 s) baselines, at no measurable quality cost on these point estimates (PickScore/CLIPScore). INT8 thus goes from the slowest variant to the fastest, and 1024px becomes single-GPU feasible. The primary speed criterion (beat FP8, by ~9.5%) is comfortably met; the NF4 margin (~4.9%, single-run n=4) is within run-to-run variance we did not quantify and is best read as consistent with meeting the stretch target. We close with an honest deployment map: the win is specific to consumer Ampere, and on A100 and B200 the same kernel loses to those cards' fast native bf16/FP8 paths.
Large language models (LLMs) have transformed artificial intelligence, but their computational requirements remain prohibitive for most users. Standard inference demands expensive datacenter GPUs or cloud API access, leaving over one billion personal computers underutilized for AI workloads. Ternary models offer a path forward: their weights are constrained to {-1, 0, +1}, theoretically eliminating the need for floating-point multiplication. However, existing frameworks fail to exploit this structure, treating ternary models as dense floating-point networks. We address this gap with custom SIMD kernels that replace matrix multiplication with simple addition and subtraction operations, targeting the integer dot product instructions available on modern CPUs. Our implementation, Litespark-Inference, is pip-installable and integrates directly with Hugging-Face, achieving 18.15x higher throughput, 7.15x faster time-to-first-token and 6.03x memory reduction compared to standard PyTorch inference on Apple Silicon, with comparable or higher throughput speedups up to 95.81x on Intel and AMD processors.
Nii Osae Osae Dade, Tony Morri, Moinul Hossain Rahat +2
Transformer prefill reuses weights across tokens and is dominated by matrix multiplication and activation data movement; single-token decode has limited reuse and is dominated by weight and KV-cache reads. We present FUTRANSFORMER, a CUDA implementation of a Llama-style Transformer block for NVIDIA Hopper GPUs. It applies CODA's GEMM-plus-epilogue approach to inference, adding direct KV-cache placement, folding the fixed RMSNorm gain into weights, writing FP8 output directly with delayed scaling, and supporting prefill without padding. Decode uses INT4 projection weights and an INT4 KV-cache copy. Weights and keys follow Tensor Core fragment layouts for direct dequantization into MMA operands without full intermediate tiles. A block-diagonal Hadamard transform reduces cache quantization error from outlier channels. On one H100, prefill is up to 1.48x faster than compiled PyTorch FP8 and reaches 1.29 PFLOP/s. For gate/up projection with SwiGLU at the 8B shape, our BF16 path is 1.13x faster than CODA. Our FP8 path is 2.02-2.18x faster than the evaluated BF16 CODA path. Across 8B and 70B shapes at batches 1-32, INT4 decode is 1.3-2.4x faster than the faster of PyTorch's BF16 and INT4 blocks at each point: 2.1-3.3x faster than compiled, CUDA-graphed BF16 and 1.3-6.3x faster than the same block using PyTorch's INT4 projection kernel, which targets a single query row and loses to BF16 at batch 32. It is also 31-51% faster than our FP8 path. Complete Llama-3.1-8B decode takes 2.8 ms per step at batch one, versus 8.1 ms for the compiled transformers implementation. Decoding every WikiText-2 token through the INT4 weight path raises perplexity from 6.24 to 7.23 with round-to-nearest weights or 6.99 with GPTQ in the same format; the rotated INT4 cache adds 0.20. The kernels match a quantized reference computation within 0.001 perplexity.