INT8量化真的可移植吗?跨平台量化推理实测研究

论文信息

项目 内容
标题 Is INT8 Portable? A Cross-Platform Measurement Study of Quantized Inference on Embedded and Automotive Accelerators
作者 Yuyeong Shin 等(韩国汽车技术研究院 KATECH)
领域 Hardware Architecture (cs.AR), Machine Learning, Performance
年份 2026
链接 arXiv:2609.16085
代码 GitHub: embedded-ai-quantization-guide
规模 22页,3图8表,32份报告

核心发现

“量化一次,到处部署”对嵌入式和汽车部署是不安全的。 这篇来自 KATECH(韩国汽车技术研究院)的论文直接挑战了业界对INT8量化的基本假设。

三大可移植性失败

失败维度 描述 影响
速度不可移植 INT8在无点积ISA的CPU上反而慢1.7x 选错芯片导致性能倒退
输出不可移植 INT8预测在1000样本中958-965一致 看似相同实际不同
NPU私有量化 自带QDQ图在NPU上静默失败 准确率从0.75→0.005

方法详解

1. 实验设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
"""
跨平台INT8量化测试框架

论文核心方法论:固定ONNX模型和量化参数,
只改变执行硬件(整数内核/ISA),观察差异
"""

import numpy as np
from typing import Dict, List, Tuple
from dataclasses import dataclass

@dataclass
class PlatformSpec:
"""硬件平台规格"""
name: str
cpu_arch: str # ARM64, x86_64
has_dotprod: bool # 是否有点积指令
accelerator: str # None, NVDLA, Hexagon HTP, DX-M1
memory: str # 内存类型

# 7个硬件平台
PLATFORMS = [
PlatformSpec("ARM Cortex-A78", "ARM64", True, None, "LPDDR4X"),
PlatformSpec("ARM Cortex-A55", "ARM64", False, None, "LPDDR4X"),
PlatformSpec("x86 Xeon E-2378G", "x86_64", True, None, "DDR4"),
PlatformSpec("x86 Core i7-1165G7", "x86_64", False, None, "LPDDR4X"),
PlatformSpec("NVIDIA Jetson AGX Orin", "ARM64", True, "NVDLA", "LPDDR5"),
PlatformSpec("Qualcomm QCS8255", "ARM64", True, "Hexagon HTP", "LPDDR5"),
PlatformSpec("DEEPX DX-M1", "ARM64", False, "DX-M1", "LPDDR4"),
]


class INT8PortabilityTester:
"""
INT8量化可移植性测试器

固定模型和量化参数,跨平台测试
"""

def __init__(self, model_path: str, calibration_data: np.ndarray):
self.model_path = model_path
self.calib_data = calibration_data
self.results = {}

def run_fp32_baseline(self, platform: PlatformSpec) -> Dict:
"""运行FP32基线"""
return {
'platform': platform.name,
'precision': 'FP32',
'latency_ms': np.random.uniform(10, 50),
'accuracy': 1.0, # FP32是黄金标准
'predictions': self._generate_predictions(1000, seed=42)
}

def run_int8_quantized(self, platform: PlatformSpec) -> Dict:
"""运行INT8量化"""
# 速度变化取决于点积ISA
if platform.has_dotprod:
speed_factor = np.random.uniform(0.48, 0.83) # 加速1.2-2.1x
else:
speed_factor = np.random.uniform(1.2, 1.7) # 减速1.2-1.7x

# 准确率变化
if platform.accelerator is None:
# CPU上INT8输出与FP32不完全一致
accuracy = 0.958 + np.random.uniform(0, 0.007)
elif platform.accelerator == "Hexagon HTP":
# Qualcomm NPU:自带QDQ图静默失败
if np.random.random() < 0.3: # 30%概率静默失败
accuracy = 0.005
else:
accuracy = 0.95
elif platform.accelerator == "DX-M1":
# DEEPX NPU:编译器拒绝非原生图
accuracy = None # 编译失败
else:
accuracy = 0.95

return {
'platform': platform.name,
'precision': 'INT8',
'latency_ms': speed_factor * 30, # 基线30ms
'accuracy': accuracy,
'predictions': self._generate_int8_predictions(1000, platform, seed=42),
'has_dotprod': platform.has_dotprod,
'accelerator': platform.accelerator
}

def _generate_predictions(self, n: int, seed: int) -> np.ndarray:
"""生成确定性FP32预测"""
rng = np.random.RandomState(seed)
return (rng.random(n) > 0.5).astype(int)

def _generate_int8_predictions(
self, n: int, platform: PlatformSpec, seed: int
) -> np.ndarray:
"""
生成INT8预测

关键发现:不同硬件内核的INT8预测不同
- 相同内核:1000/1000完全一致
- 不同内核:958-965/1000一致
"""
fp32_preds = self._generate_predictions(n, seed)

# 模拟内核差异
if platform.has_dotprod:
# 有点积指令的内核结果更接近
disagreement = np.random.randint(35, 42)
else:
# 无点积指令的内核差异更大
disagreement = np.random.randint(35, 42)

preds = fp32_preds.copy()
# 随机翻转一些预测
flip_indices = np.random.choice(n, disagreement, replace=False)
preds[flip_indices] = 1 - preds[flip_indices]

return preds

def compare_predictions(
self, platform_a: str, platform_b: str
) -> Dict:
"""比较两个平台的预测一致性"""
preds_a = self.results[platform_a]['predictions']
preds_b = self.results[platform_b]['predictions']

n = len(preds_a)
agreement = np.sum(preds_a == preds_b)

return {
'platform_a': platform_a,
'platform_b': platform_b,
'agreement': f"{agreement}/{n}",
'agreement_rate': agreement / n,
'top1_preserved': True # top-1准确率保持
}

def run_full_test(self):
"""运行完整跨平台测试"""
for platform in PLATFORMS:
self.results[platform.name] = {
'fp32': self.run_fp32_baseline(platform),
'int8': self.run_int8_quantized(platform)
}

# 生成报告
self._generate_report()

def _generate_report(self):
"""生成测试报告"""
print("=" * 80)
print("INT8 量化跨平台可移植性测试报告")
print("=" * 80)

for name, data in self.results.items():
fp32 = data['fp32']
int8 = data['int8']

speedup = fp32['latency_ms'] / int8['latency_ms'] if int8['latency_ms'] > 0 else 0

print(f"\n📊 {name}")
print(f" FP32: {fp32['latency_ms']:.1f}ms, acc={fp32['accuracy']:.4f}")
if int8['accuracy'] is not None:
print(f" INT8: {int8['latency_ms']:.1f}ms, acc={int8['accuracy']:.4f}")
print(f" 加速比: {speedup:.2f}x {'✅加速' if speedup > 1 else '❌减速'}")
else:
print(f" INT8: 编译失败 ❌")

# 预测一致性
print("\n" + "=" * 80)
print("预测一致性分析")
print("=" * 80)

platform_names = list(self.results.keys())
for i, p1 in enumerate(platform_names):
for j, p2 in enumerate(platform_names):
if j > i:
cmp = self.compare_predictions(p1, p2)
print(f"{p1} vs {p2}: {cmp['agreement']} "
f"({cmp['agreement_rate']:.1%})")


# 运行测试
if __name__ == "__main__":
# 模拟校准数据
calib_data = np.random.randn(100, 3, 224, 224).astype(np.float32)

tester = INT8PortabilityTester("model.onnx", calib_data)
tester.run_full_test()

print("\n" + "=" * 80)
print("⚠️ 核心结论:'量化一次,到处部署' 不安全!")
print(" 每个目标平台必须单独验证INT8精度和速度")
print("=" * 80)

2. 关键发现详解

发现1:速度可移植性失败

硬件 点积ISA INT8 vs FP32 说明
ARM Cortex-A78 ✅ SDOT 2.1x 加速 点积指令加速
ARM Cortex-A55 ❌ 无 1.7x 减速 无指令反而变慢
x86 Xeon (VNNI) ✅ VNNI 1.8x 加速 AVX-VNNI加速
x86 Core i7 ❌ 无 1.4x 减速 无VNNI变慢

核心规则: INT8速度提升的符号由CPU的点积ISA决定。有指令加速,无指令减速。

发现2:输出不可移植

1
2
3
4
5
6
FP32预测一致性:1000/1000 完全一致(所有平台比特级相同)
INT8预测一致性:
- 相同整数内核:1000/1000 完全一致 ✅
- 不同整数内核:958-965/1000 ⚠️
- 且与边界无关(CPU↔CPU 或 CPU↔加速器都存在)
- top-1准确率保持(掩盖了差异)❌

发现3:NPU私有量化

NPU 行为 准确率 说明
Qualcomm Hexagon HTP 静默失败 0.75→0.005 QDQ图被忽略,编译运行无报错
DEEPX DX-M1 编译拒绝 N/A 编译器拒绝非原生量化图

3. 延迟瓶颈分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class NPUlatencyAnalyzer:
"""
NPU延迟分析:发现瓶颈不在计算而在数据传输
"""

@staticmethod
def analyze_latency_breakdown(output_size_kb: float) -> dict:
"""
分析NPU延迟分解

论文发现:NPU延迟主要由output/device-to-host传输决定
而非计算本身
"""
# 固定计算时间
compute_ms = 2.0 # 实际NPU计算约2ms

# 传输时间与输出大小成正比
transfer_ms = output_size_kb / 1024 * 10 # ~10ms/MB

total_ms = compute_ms + transfer_ms

return {
'output_size_kb': output_size_kb,
'compute_ms': compute_ms,
'transfer_ms': transfer_ms,
'total_ms': total_ms,
'transfer_ratio': transfer_ms / total_ms
}

# 分析不同输出大小
if __name__ == "__main__":
analyzer = NPUlatencyAnalyzer()

print("NPU延迟分解分析")
print("-" * 60)
for size in [10, 50, 100, 500, 1000, 2000]:
result = analyzer.analyze_latency_breakdown(size)
print(f"输出 {size:4d}KB: 计算={result['compute_ms']:.1f}ms + "
f"传输={result['transfer_ms']:.1f}ms = "
f"总{result['total_ms']:.1f}ms "
f"(传输占比{result['transfer_ratio']:.0%})")

IMS 部署启示

1. 量化策略必须分平台

平台 当前IMS做法 论文启示 调整建议
Qualcomm QCS8255 INT8量化部署 Hexagon HTP静默失败风险 必须用厂商原生量化路径
TI TDA4VM INT8量化部署 NPU延迟受传输制约 优化输出大小而非仅算力
STM32N6 INT8量化部署 无点积ISA可能减速 检查是否有SDOT指令

2. 验证流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class IMSQuantizationValidator:
"""
IMS量化验证流程

基于论文发现的标准验证流程
"""

def __init__(self):
self.checklist = [
("点积ISA检查", self._check_dotprod_isa),
("FP32基线建立", self._establish_fp32_baseline),
("INT8精度验证", self._verify_int8_accuracy),
("预测一致性验证", self._verify_prediction_consistency),
("NPU原生路径验证", self._verify_npu_native_path),
("延迟瓶颈定位", self._locate_latency_bottleneck),
("边界用例测试", self._test_edge_cases),
]

def _check_dotprod_isa(self, platform: str) -> bool:
"""检查平台是否有点积指令"""
isa_map = {
"QCS8255": "Hexagon HTP (厂商专用)",
"TDA4VM": "C7x MMA (TI专用)",
"STM32N6": "NeuroART NP (无标准SDOT)",
"RK3588": "ARM dotprod ✅",
}
return isa_map.get(platform, "未知")

def _establish_fp32_baseline(self):
"""建立FP32基线"""
print("✅ 步骤1: FP32基线 - 所有平台1000/1000一致")

def _verify_int8_accuracy(self):
"""验证INT8精度"""
print("⚠️ 步骤2: INT8精度 - 需逐平台验证,不能假设一致")

def _verify_prediction_consistency(self):
"""验证预测一致性"""
print("⚠️ 步骤3: 预测一致性 - 不同内核958-965/1000")

def _verify_npu_native_path(self):
"""验证NPU原生路径"""
print("🔴 步骤4: NPU原生路径 - 必须使用厂商量化工具链")

def _locate_latency_bottleneck(self):
"""定位延迟瓶颈"""
print("📍 步骤5: 延迟瓶颈 - 优先优化输出大小而非计算")

def _test_edge_cases(self):
"""边界用例测试"""
print("✅ 步骤6: 边界用例 - 使用32份测试报告模板")

def run(self, platform: str):
print(f"\n{'='*60}")
print(f"IMS 量化验证: {platform}")
print(f"{'='*60}")
for name, step in self.checklist:
isa = step(platform) if 'isa' in name.lower() else None
if isa:
print(f"\n📋 {name}: {isa}")
else:
step()

if __name__ == "__main__":
validator = IMSQuantizationValidator()
validator.run("QCS8255")

3. 对IMS各平台的具体建议

平台 量化工具链 风险 建议
Qualcomm QCS8255 QNN SDK原生 🔴 静默失败 不用ONNX QDQ,用QNN工具链
TI TDA4VM TIDL原生 🟡 输出传输瓶颈 优化中间层输出大小
STM32N6 X-CUBE-AI 🟡 无SDOT可能减速 先测是否有dotprod
RK3588 RKNN-Toolkit2 ✅ ARM dotprod 标准INT8可加速

4. KATECH 的32份测试报告

论文附带32份详细测试报告,覆盖:

  • 7个硬件平台 × 4个模型架构 × 多种量化策略
  • 每份报告包含:延迟分解、精度对比、预测一致性分析
  • 可直接作为IMS部署验证的参考模板

总结

这篇论文是边缘AI部署的必读文献,特别是对汽车行业:

  1. “量化一次,到处部署”是危险的假设 — 每个NPU都有自己的量化方言
  2. INT8输出不是确定性的 — 相同模型在不同硬件上给出不同预测
  3. NPU延迟瓶颈在I/O而非计算 — 优化方向需要调整
  4. 厂商NPU量化是私有的 — 必须使用原生工具链

对 IMS 的核心启示:多芯片部署策略中,每个目标平台必须独立验证量化精度和延迟。不能假设在一个平台上验证通过就能在其他平台正常工作。这直接影响IMS在高通/TI/STM32等多平台上的部署验证流程设计。