趋近智
对大型语言模型进行量化后,主要目的是通常是加快推理速度并减少资源消耗。前一节讨论了通用指标,而本节将专门关注衡量两个基本性能指标:延迟和吞吐量。了解如何准确地对这些方面进行测试,对于评估量化工作的效果以及做出明智的部署决策非常重要。
延迟 指的是处理单个推理请求所需的时间。对于生成文本的LLM,这可以是:
吞吐量 衡量系统处理推理请求的速度。它通常表示为:
优化延迟通常侧重于最小化单个请求的处理时间,这可能以牺牲整体系统使用率为代价。优化吞吐量旨在最大化并发处理的请求或token数量,这可能涉及批处理等技术,这些技术可能会稍微增加单个请求的延迟。量化直接影响模型内部操作的计算速度,从而影响延迟和吞吐量。
准确衡量延迟需要仔细考量测量范围和潜在的噪声来源。
隔离推理时间: 理想情况下,您希望纯粹测量模型前向传递中花费的时间。这通常不包括数据预处理(分词)和后处理(逆分词),尽管包含这些步骤的端到端延迟测量对于理解完整的用户体验也很有价值。
预热运行: 在开始测量之前,执行几次推理请求。最初的运行可能会产生模型加载、内核编译(尤其是在GPU上)或缓存填充等开销,这些不反映稳定状态的性能。丢弃这些预热迭代的时间数据。
多次测量和统计: 单次计时可能存在噪声。对相同的输入运行推理多次(例如,100或1000次迭代),并计算描述性统计数据:
硬件特定计时:
time.perf_counter() 进行高精度计时。time.perf_counter())不足以测量GPU操作的时间。CPU可能在GPU完成工作之前很早就提交完任务。请使用GPU特定的同步机制。例如,在PyTorch中:import torch
import time
# 假设模型和输入数据已在目标GPU设备上
# model = model.to('cuda')
# input_data = input_data.to('cuda')
# 预热运行
for _ in range(10):
_ = model(input_data)
torch.cuda.synchronize() # 确保预热完成
# 使用CUDA事件进行精确计时
start_event = torch.cuda.Event(enable_timing=True)
end_event = torch.cuda.Event(enable_timing=True)
num_runs = 100
latencies = []
for _ in range(num_runs):
start_event.record()
_ = model(input_data) # 要计时操作
end_event.record()
# 等待GPU操作完成
torch.cuda.synchronize()
# 计算毫秒级耗时
latency_ms = start_event.elapsed_time(end_event)
latencies.append(latency_ms)
avg_latency = sum(latencies) / num_runs
print(f"Average latency over {num_runs} runs: {avg_latency:.3f} ms")
# 如有需要,可以使用numpy或其他库计算P95、P99等
# import numpy as np
# p95_latency = np.percentile(latencies, 95)
# print(f"P95 latency: {p95_latency:.3f} ms")
这种 torch.cuda.Event 方法准确测量了GPU上两个记录点之间的时间。请始终记住使用 torch.cuda.synchronize(),以确保CPU在记录结束时间或计算统计数据之前等待GPU完成。
吞吐量测量通常涉及模拟并发请求或处理批量输入。
这个图表表明,对于基线(FP16)模型和量化(INT8)模型,吞吐量通常会随批量大小的增加而增加,其中量化模型实现了更高的吞吐量,尤其是在更大的批量大小下。饱和可能在图中未显示的最大批量下发生。
请注意,延迟和吞吐量并非固定数值;它们很大程度上取决于:
bitsandbytes、AutoGPTQ)、推理服务器(例如,vLLM、TensorRT-LLM、TGI)、CUDA版本、驱动版本。TensorRT-LLM等框架中的优化内核可以在支持的硬件上显著提高特定量化格式(如INT4或INT8)的性能。“在报告结果时,务必指明完整的硬件和软件环境、所使用的模型、量化方法以及确切的工作负载参数(输入/输出长度、批量大小、并发级别),以确保可复现性和公平比较。一致且严谨的测量对于理解部署量化LLM的优势和权衡非常重要。”
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造