ONNX Runtime GenAI C++ GPU 推理完整指南
问题背景
在使用 ONNX Runtime GenAI v0.12.0 进行 C++ GPU 推理时,遇到了多个挑战:
- C++ API 兼容性问题:官方预编译包只导出 C API,C++ API 符号缺失
- 库版本不匹配:初始下载的 onnxruntime 版本过旧(1.17.1),不支持 genai 所需的 API version
- 模型 Opset 兼容性:Phi-4 等新模型使用最新的 GroupQueryAttention softcap 属性,需要 onnxruntime v1.20+
解决方案
一、从 C++ API 改为 C API
官方预编译包不支持 C++ API(OgaModel、OgaTokenizer 等类),所以需要改用 C API 调用:
C++ API(不可用):
cpp
auto model = OgaModel::Create(model_path); // ❌ 链接时 undefined reference
C API(可用):
cpp
OgaModel* model = NULL;
CHECK_OGA(OgaCreateModel(model_path, &model)); // ✅ 官方包导出的符号
二、解决库依赖问题
运行时报错:
Failed to load onnxruntime. Set ORTGENAI_LOG_ORT_LIB envvar to enable detailed logging.
根本原因:genai SDK 需要链接 libonnxruntime.so,但官方预编译包缺少这个库。
解决方案:在 CMake 中自动下载兼容版本的 onnxruntime,并复制库文件到 genai SDK lib 目录。
三、版本匹配
不同版本要求:
| 组件 | 版本 | 需求 |
|---|---|---|
| onnxruntime-genai | 0.12.0 | ORT API version ≥ 18 |
| onnxruntime | 1.17.1 | 仅支持 API version ≤ 17 ❌ |
| onnxruntime | 1.18.1 | 支持 API version 18 ✅ |
| onnxruntime | 1.20.1 | 支持 API version 18+,新 Opset ✅✅ |
| Phi-4 ONNX 模型 | - | 需要 GroupQueryAttention softcap(1.20+) |
最终实现
1. 修改 CMakeLists.txt
cmake
# 添加 onnxruntime.cmake 支持(可选备选)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
set(SHERPA_ONNX_ENABLE_GPU ${ENABLE_CUDA})
include(onnxruntime) # 可选
# 自动下载和配置 genai SDK
include(onnxruntime-genai)
2. 关键文件:cmake/onnxruntime-genai.cmake
cmake
# ONNX Runtime GenAI v0.12.0 配置
include(FetchContent)
set(ONNX_GENAI_VERSION "0.12.0")
set(ONNXRUNTIME_VERSION "1.20.1") # 兼容最新模型
# 根据平台选择下载 URL
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
if(ENABLE_CUDA)
set(GENAI_URL "https://github.com/microsoft/onnxruntime-genai/releases/download/v${ONNX_GENAI_VERSION}/onnxruntime-genai-${ONNX_GENAI_VERSION}-linux-x64-cuda.tar.gz")
set(ORT_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/onnxruntime-linux-x64-gpu-${ONNXRUNTIME_VERSION}.tgz")
else()
set(GENAI_URL "https://github.com/microsoft/onnxruntime-genai/releases/download/v${ONNX_GENAI_VERSION}/onnxruntime-genai-${ONNX_GENAI_VERSION}-linux-x64.tar.gz")
set(ORT_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNXRUNTIME_VERSION}/onnxruntime-linux-x64-${ONNXRUNTIME_VERSION}.tgz")
endif()
endif()
# 下载 genai SDK
FetchContent_Declare(onnxruntime_genai URL ${GENAI_URL})
FetchContent_MakeAvailable(onnxruntime_genai)
set(ONNX_GENAI_SDK_DIR ${onnxruntime_genai_SOURCE_DIR})
set(ONNX_GENAI_INCLUDE_DIRS "${ONNX_GENAI_SDK_DIR}/include")
set(ONNX_GENAI_LIB_DIRS "${ONNX_GENAI_SDK_DIR}/lib")
# 下载兼容版本的 onnxruntime
FetchContent_Declare(onnxruntime_compat URL ${ORT_URL})
FetchContent_MakeAvailable(onnxruntime_compat)
# 复制 libonnxruntime.so* 到 genai SDK lib 目录
file(GLOB ORT_LIBS "${onnxruntime_compat_SOURCE_DIR}/lib/libonnxruntime.so*")
if(ORT_LIBS)
file(COPY ${ORT_LIBS} DESTINATION "${ONNX_GENAI_LIB_DIRS}")
message(STATUS "✓ Copied onnxruntime libraries")
endif()
message(STATUS "✅ ONNX Runtime GenAI v${ONNX_GENAI_VERSION} ready!")
3. C API 推理代码(test/test.cpp)
cpp
#include <ort_genai_c.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHECK_OGA(call) do { \
OgaResult* _res = (call); \
if (_res) { \
fprintf(stderr, "❌ Error: %s\n", OgaResultGetError(_res)); \
OgaDestroyResult(_res); \
exit(1); \
} \
} while(0)
int main() {
const char* model_path = "/mnt/f/cache/Phi-4-mini-instruct-onnx/gpu/gpu-int4-rtn-block-32";
const char* prompt = "用简单易懂的话解释 ONNX Runtime GenAI.用中文回答。";
OgaModel* model = NULL;
OgaTokenizer* tokenizer = NULL;
OgaSequences* sequences = NULL;
OgaGeneratorParams* params = NULL;
OgaGenerator* generator = NULL;
// 1. 加载模型
CHECK_OGA(OgaCreateModel(model_path, &model));
// 2. 创建 Tokenizer
CHECK_OGA(OgaCreateTokenizer(model, &tokenizer));
// 3. 编码 Prompt
CHECK_OGA(OgaCreateSequences(&sequences));
CHECK_OGA(OgaTokenizerEncode(tokenizer, prompt, sequences));
// 4. Generator 参数
CHECK_OGA(OgaCreateGeneratorParams(model, ¶ms));
CHECK_OGA(OgaGeneratorParamsSetSearchNumber(params, "max_length", 256));
CHECK_OGA(OgaGeneratorParamsSetSearchNumber(params, "temperature", 0.7f));
CHECK_OGA(OgaGeneratorParamsSetSearchNumber(params, "top_p", 0.9f));
CHECK_OGA(OgaGeneratorParamsSetSearchBool(params, "do_sample", 1));
// 5. 创建 Generator
CHECK_OGA(OgaCreateGenerator(model, params, &generator));
CHECK_OGA(OgaGenerator_AppendTokenSequences(generator, sequences));
// 6. Streaming 推理
printf("=== Streaming Output (GPU, C API) ===\n\n");
while (!OgaGenerator_IsDone(generator)) {
CHECK_OGA(OgaGenerator_GenerateNextToken(generator));
const int32_t* new_tokens = NULL;
size_t new_token_count = 0;
CHECK_OGA(OgaGenerator_GetNextTokens(generator, &new_tokens, &new_token_count));
if (new_token_count > 0) {
const char* text = NULL;
CHECK_OGA(OgaTokenizerDecode(tokenizer, new_tokens, new_token_count, &text));
printf("%s", text);
fflush(stdout);
OgaDestroyString(text);
}
}
printf("\n\n=== Done ===\n");
// 释放资源
OgaDestroyGenerator(generator);
OgaDestroyGeneratorParams(params);
OgaDestroySequences(sequences);
OgaDestroyTokenizer(tokenizer);
OgaDestroyModel(model);
return 0;
}
4. CMake 链接配置(test/CMakeLists.txt)
cmake
# 必须同时链接 onnxruntime-genai-cuda 和 onnxruntime
if(ENABLE_CUDA)
target_link_libraries(test_gpu PRIVATE onnxruntime-genai-cuda onnxruntime-genai)
else()
target_link_libraries(test_gpu PRIVATE onnxruntime-genai)
endif()
# 链接标准库
target_link_libraries(test_gpu PRIVATE pthread dl)
编译与运行
编译
bash
# 清除旧 build
rm -rf /mnt/f/Projects/onnx-genai-decoder/build_test
# 编译(自动下载 genai SDK 和 onnxruntime v1.20.1)
./build_test.sh
编译过程会自动:
- 下载 onnxruntime-genai v0.12.0 SDK
- 下载 onnxruntime v1.20.1(GPU 版本)
- 复制 libonnxruntime.so 到 genai SDK lib 目录
- 编译 test_gpu 可执行文件
运行
bash
# 设置库路径
export LD_LIBRARY_PATH=/mnt/f/Projects/onnx-genai-decoder/build_test/_deps/onnxruntime_genai-src/lib:$LD_LIBRARY_PATH
# 运行推理
/mnt/f/Projects/onnx-genai-decoder/build_test/bin/test_gpu
输出:

关键要点总结
| 问题 | 解决方案 |
|---|---|
| C++ API 符号缺失 | 改用官方导出的 C API(OgaCreateModel 等) |
| libonnxruntime.so 缺失 | CMake 自动下载兼容版本的 onnxruntime 并复制库文件 |
| 版本 API 不匹配(ORT v1.17) | 升级到 onnxruntime v1.20.1(支持最新 Opset 和 softcap 属性) |
| 模型 Opset 不兼容 | v1.20.1 原生支持 GroupQueryAttention softcap |
技术栈
- ONNX Runtime GenAI: v0.12.0
- ONNX Runtime: v1.20.1 (GPU/CUDA)
- CMake: v3.20+
- C++: 17 标准
- GPU: NVIDIA CUDA 支持
优势
✅ 自动化 :CMake 自动下载所有依赖,无需手动配置
✅ 跨平台 :支持 Linux/macOS/Windows(代码已预留平台判断)
✅ 版本兼容 :自动选择兼容的 onnxruntime 版本
✅ GPU 加速 :完整 CUDA 支持,高性能推理
✅ 流式输出:支持 token 级别的流式生成