ONNX Runtime LLM:跨硬件的生成式 AI 推理
引言
随着大语言模型(LLM)的兴起,开发者面临一个核心挑战:如何让这些含数十亿参数的模型在实际应用中快速、高效地运行,同时适应多样化的硬件环境。ONNX Runtime(ORT)作为一款跨平台的高性能推理引擎,通过其专门的生成式AI扩展(GenAI),为LLM推理提供了一套开箱即用的解决方案。本教程将带你从零开始,理解并实践ONNX Runtime LLM,实现一次开发,即可在CPU、GPU、NPU乃至移动设备上流畅运行生成式AI任务。
什么是ONNX Runtime
ONNX Runtime是微软主导的开源推理加速器,旨在优化和运行开放神经网络交换格式(ONNX)的模型。它支持从PyTorch、TensorFlow等主流框架导出的模型,并通过硬件特定的执行提供者(Execution Provider)实现跨平台加速。传统ORT擅长处理计算机视觉、自然语言理解等判别式模型,而针对生成式AI的Transformer架构,微软推出了ONNX Runtime GenAI扩展,原生支持贪婪搜索、束搜索、Top‑P采样等解码策略。
ONNX Runtime GenAI的核心优势
统一的跨硬件体验
只需一份ONNX模型,即可通过配置不同的执行提供者在多种硬件上推理:
- CPU:利用MKL‑DNN和oneDNN进行向量化加速,支持int8/int4量化
- GPU(NVIDIA/AMD):集成CUDA/TensorRT和ROCm,释放张量核心性能
- NPU/移动端:通过QNN(Qualcomm Neural Network)EP支持移动SoC的AI引擎,或在Apple Silicon上通过CoreML EP加速
原生生成算法支持
GenAI扩展内置了完整的生成流程,无需开发者手动实现循环调用:
- 多种搜索策略(贪婪、束搜索、Nucleus Sampling)
- KV缓存管理,高效处理长序列
- 前缀缓存与批处理优化
极致的量化压缩
支持将FP32/FP16模型量化为int4或int8,大幅降低内存占用和延迟,同时保持可接受的输出质量。结合ORT的QLINER压缩工具,甚至可以在笔记本电脑上运行70亿参数的模型。
环境配置与安装
推荐使用Python 3.10+环境,以下步骤将安装ONNX Runtime GenAI及相关工具。
pip install onnxruntime-genai
如果需要特定执行提供者(例如CUDA或DirectML),请选择对应版本:
pip install onnxruntime-genai-cuda # 适用于NVIDIA GPU
pip install onnxruntime-genai-directml # 适用于Windows GPU
验证安装:
import onnxruntime_genai as og
print(og.__version__)
模型准备:导出与量化
ONNX Runtime GenAI接受原生ONNX格式的Transformer模型。你可以从Hugging Face获取预转换的模型,或自行使用Optimum导出。
从Hugging Face获取ONNX模型
许多社区用户已上传经量化的opt‑onnx模型,例如“microsoft/phi‑2‑onnx”或“TheBloke/Llama‑2‑7B‑ONNX”。直接下载示例:
git lfs install
git clone https://huggingface.co/microsoft/phi-2-onnx
使用Transformers导出
如果不使用预转换版本,可通过Optimum工具将PyTorch模型转为ONNX:
pip install optimum[onnxruntime]
optimum-cli export onnx --model <model_name> <output_path> --task text-generation-with-past
应用int4量化
对导出的模型进行量化以减小体积并加速推理:
optimum-cli onnxruntime quantize --onnx_model <model_path> --quantization_mode int4 --output <quantized_path>
现在,你拥有了一个可被GenAI加载的ONNX模型目录。
实战:加载模型并执行生成
以下示例展示如何加载量化后的Phi‑2模型并进行文本生成。
import onnxruntime_genai as og
# 指定模型目录(包含model.onnx和相关配置)
model_path = "./phi-2-int4"
# 创建模型和分词器
model = og.Model(model_path)
tokenizer = og.Tokenizer(model)
tokenizer_stream = tokenizer.create_stream()
# 输入提示
prompt = "写一首关于秋叶的简短俳句:"
input_tokens = tokenizer.encode(prompt)
# 设置生成参数
params = og.GeneratorParams(model)
params.input_ids = input_tokens
params.max_length = 200
params.temperature = 0.7
params.do_sample = True
params.top_p = 0.95
# 创建生成器并产生输出
generator = og.Generator(model, params)
print("生成的文本:")
while not generator.is_done():
generator.compute_logits()
generator.generate_next_token()
new_token = generator.get_output_tokens()[generator.get_current_sequence_length() - 1]
print(tokenizer_stream.decode(new_token), end='', flush=True)
运行后,你会看到模型流式输出俳句。该流程同样适用于对话式AI,只需将聊天记录拼接为相应模板即可。
高级配置:执行提供者与硬件选择
ONNX Runtime GenAI默认使用CPU执行。若要启用GPU,在创建Model时指定execution_provider属性:
import onnxruntime_genai as og
# 使用CUDA
model = og.Model(model_path, config=og.Config(execution_provider="cuda"))
# 使用DirectML(Windows GPU)
model = og.Model(model_path, config=og.Config(execution_provider="directml"))
# 对于Qualcomm NPU,使用qnn
model = og.Model(model_path, config=og.Config(execution_provider="qnn"))
通过更改执行提供者,无需修改生成代码即可切换到目标硬件。
性能优化技巧
调整批处理大小
对于支持批处理的场景,可以同时处理多个提示以提升吞吐率。在GeneratorParams中设置batch_size。
使用更小的模型变体
从7B向2B甚至1B参数量压缩,选择经过蒸馏的轻量模型。ONNX Runtime GenAI对tiny模型仍有很好的加速比。
开启KV缓存优化
在导出模型时确保包含“with past”的注意力机制,GenAI默认利用KV缓存避免重复计算,对于多轮对话尤为重要。
尝试int4/int8量化
如前所述,量化不仅减少显存占用,还大幅提高计算密度。在内存受限的CPU上,int4模型有时可比FP16快数倍。
常见问题与排错
加载模型时报“Failed to initialize”错误
检查模型路径是否包含model.onnx和genai_config.json。此配置文件记录了生成所需的特殊属性,由导出工具自动生成。
推理速度远低于预期
确认使用了正确的执行提供者,并且执行提供者已正确安装(如CUDA Toolkit版本匹配)。在CPU上,检查oneDNN是否被调用(设置环境变量ORT_DISABLE_ONEDNN=1以测试对比)。
输出结果重复或无意义
适当降低temperature,或关闭do_sample使用贪婪搜索;检查分词器是否与模型匹配。
总结
通过ONNX Runtime GenAI,开发者获得了一条通往跨硬件生成式AI的捷径。从模型导出、量化、部署到多硬件适配,整个流程简化且统一。无论是云端GPU集群还是边缘手机NPU,都可以用同一套ONNX模型和API完成推理。现在,开始你的第一个跨硬件LLM服务吧!