资讯详情

LangChain4j 进程内 ONNX 评分模型(In-process Scoring/Reranking)完整指南

📅 2026/9/15 19:36:48 | 华诺云谱 👁 阅读
LangChain4j 进程内 ONNX 评分模型(In-process Scoring/Reranking)完整指南
LangChain4j 进程内 ONNX 评分模型In-process Scoring/Reranking完整指南【免费下载链接】langchain4jLangChain4j is an idiomatic, open-source Java library for building LLM-powered applications on the JVM. It offers a unified API over popular LLM providers and vector stores, and makes implementing tool calling (including MCP support), agents and RAG easy. It integrates seamlessly with enterprise Java frameworks like Quarkus and Spring Boot.项目地址: https://gitcode.com/GitHub_Trending/la/langchain4j导读本文讲解 LangChain4j 中基于 ONNX Runtime 的本地进程内评分scoring / reranking模型——langchain4j-onnx-scoring模块。它让评分模型与你的应用运行在同一个 Java 进程内无需任何远程服务、API Key 或网络请求特别适合 RAG 检索阶段的本地重排序re-ranking。读完本文你将掌握该模块的依赖配置、CPU/GPU 两种运行方式、四个构造函数与核心参数的作用、底层执行原理以及如何将它与ScoringModel接口、TextSegment和批量评分能力结合使用。什么时候应该使用进程内评分模型LangChain4j 的 scoring-reranking-models 集成目录下同时提供多类评分模型包括 Cohere、Jina AI、Vertex AI、Voyage AI、Watsonx、Xinference 等远程/托管服务以及本文的主角——进程内In-processONNX 模型。选择它的典型场景包括数据隐私与合规文本片段不需要离开本机离线与本地部署无外网环境也能完成重排序低延迟与低成本评分推理发生在 JVM 进程内省去网络往返与按量计费统一 API它与所有远程模型一样实现ScoringModel接口上层 RAG 代码无需区分实现。工作原理从 ONNX 模型到分数从源码结构看langchain4j-onnx-scoring模块包含三个核心类见 langchain4j-onnx-scoring/src/main/java/dev/langchain4j/model/scoring/onnx类职责OnnxScoringModel对外门面提供多种构造函数与默认参数实现ScoringModel与AutoCloseableAbstractInProcessScoringModel抽象基类实现scoreAll(...)批量评分与close()资源释放OnnxScoringBertCrossEncoder底层基于 BERT 的交叉编码器cross-encoder负责分词、构建张量、执行 ONNX 会话并提取分数推理链路如下对应 OnnxScoringBertCrossEncoder.java 的scoreAll与encode方法使用 DJL 的HuggingFaceTokenizer由ai.djl.huggingface:tokenizers提供对(query, document)进行成对批量编码从编码结果中取出input_ids、attention_mask若模型声明包含token_type_ids输入则一并构造代码会通过session.getInputNames()动态探测通过OrtEnvironment.createSession(modelPath, options)创建 ONNX 会话将三个张量喂给模型运行从输出中取出 logits。这里做了兼容处理extractLogits同时支持float[][]shape[batch, k]与float[][][]shape[batch, 1, 1]例如BAAI/bge-reranker-base经 Optimum 导出时产生两种输出形状每个样本取其第一个标量作为分数见 OnnxScoringBertCrossEncoder.java 及对应测试 OnnxScoringBertCrossEncoderTest.java若开启normalize对 logit 施加 sigmoid 变换1 / (1 exp(-x))将分数压缩到(0, 1)区间否则原样返回 logit 值。分词器配置在 OnnxScoringBertCrossEncoder.java 中硬编码了三项策略padding true批内补齐到等长truncation LONGEST_FIRST超长时优先截断最长片段modelMaxLength由构造函数传入的modelMaxLength - 2为[CLS]、[SEP]两个特殊 token 预留空间。安装依赖在pom.xml中加入以下依赖当前文档示例使用1.20.0-beta30本仓库父 POM 已演进至1.21.0-beta31-SNAPSHOT请按你的实际发布版本替换versiondependency groupIddev.langchain4j/groupId artifactIdlangchain4j-onnx-scoring/artifactId version1.20.0-beta30/version /dependency该模块的传递依赖见 langchain4j-onnx-scoring/pom.xml包括dev.langchain4j:langchain4j-core提供ScoringModel接口与Response、TextSegment等基础类型com.microsoft.onnxruntime:onnxruntimeONNX Runtime Java 绑定当前仓库版本为 1.22.0内部携带对应平台的 JNI 原生库ai.djl:api与ai.djl.huggingface:tokenizers当前仓库版本 0.36.0提供 Hugging Face 分词器能力。快速开始CPU 模式默认情况下评分模型使用 CPU 推理。假设你已准备好两个文件model.onnxONNX 格式模型和tokenizer.jsonHugging Face 分词器文件最小可用示例String pathToModel /home/langchain4j/model.onnx; String pathToTokenizer /home/langchain4j/tokenizer.json; OnnxScoringModel scoringModel new OnnxScoringModel(pathToModel, pathToTokenizer); ResponseDouble response scoringModel.score(query, passage); Double score response.content();score(String text, String query)是 ScoringModel 接口 提供的默认方法内部会包装为TextSegment并委托给score(TextSegment, query)最终统一走scoreAll(...)。因此单段与批量评分的结果语义完全一致且score会校验返回的分数数量恰好为 1。批量评分一次调用多个候选片段实际 RAG 场景中检索阶段通常一次性返回多个候选片段需要为它们统一打分排序。AbstractInProcessScoringModel实现的scoreAll(ListTextSegment, String)会对整批(query, passage)对做一次 ONNX 推理而非逐个循环并顺带统计总 token 数回填到Response的TokenUsage中见 AbstractInProcessScoringModel.java。import dev.langchain4j.data.segment.TextSegment; ListTextSegment segments List.of( TextSegment.from(Berlin has a population of 3,520,031 registered inhabitants...), TextSegment.from(New York City is famous for the Metropolitan Museum of Art.) ); OnnxScoringModel scoringModel new OnnxScoringModel(pathToModel, pathToTokenizer); ResponseListDouble response scoringModel.scoreAll(segments, How many people live in Berlin?); ListDouble scores response.content(); // 顺序与 segments 一一对应集成测试 OnnxScoringModelIT.java 使用Xenova/ms-marco-MiniLM-L-6-v2的量化 ONNX 模型验证过这一行为对上面两段文本分别得到约8.663与-11.246的分数与官方 Python 输出一致误差在 0.1% 内且response.tokenUsage().totalTokenCount() 0——分数越高代表与查询越相关可用于对候选片段降序重排。资源生命周期AutoCloseable 与 try-with-resourcesOnnxScoringModel实现了AutoCloseable。它背后持有 ONNX 会话OrtSession与 DJL 分词器两个原生资源不再使用时必须调用close()释放否则会长期占用 JVM 堆外内存与原生句柄。推荐用 try-with-resources 保证确定性释放ListTextSegment segments List.of( TextSegment.from(Berlin has a population of 3,520,031 registered inhabitants...) ); try (OnnxScoringModel scoringModel new OnnxScoringModel(pathToModel, pathToTokenizer)) { ResponseListDouble response scoringModel.scoreAll(segments, How many people live in Berlin?); System.out.println(response.content()); }close()的实现细节见 OnnxScoringBertCrossEncoder.java值得注意幂等内部有closed标志多次调用close()不会报错测试 OnnxScoringModelIT.java 的should_allow_calling_close_multiple_times验证了这一点异常抑制若 session 与 tokenizer 关闭时都抛异常后一个异常会被addSuppressed附加到先抛出的异常上初始化失败自愈如果模型会话创建成功但分词器加载失败或 SessionOptions 关闭失败构造器会通过closeOnFailure释放已创建的资源并附加抑制异常见生命周期测试 OnnxScoringBertCrossEncoderLifecycleTest.java。GPU 加速切换 onnxruntime_gpu 与 CUDA如果模型较大、批处理量高可以切换 ONNX Runtime 的 GPU 执行提供方CUDA Execution Provider。做法是排除默认的 CPU 版onnxruntime引入onnxruntime_gpudependency groupIddev.langchain4j/groupId artifactIdlangchain4j-onnx-scoring/artifactId version1.20.0-beta30/version exclusions exclusion groupIdcom.microsoft.onnxruntime/groupId artifactIdonnxruntime/artifactId /exclusion /exclusions /dependency !-- 1.20.0 对应支持 CUDA 12.x 的 GPU 运行时 -- dependency groupIdcom.microsoft.onnxruntime/groupId artifactIdonnxruntime_gpu/artifactId version1.20.0/version /dependency然后在代码中构造OrtSession.SessionOptions并启用 CUDAaddCUDA(0)中的0为设备号通过带options的构造函数传入String pathToModel /home/langchain4j/model.onnx; String pathToTokenizer /home/langchain4j/tokenizer.json; OrtSession.SessionOptions options new OrtSession.SessionOptions(); options.addCUDA(0); OnnxScoringModel scoringModel new OnnxScoringModel(pathToModel, options, pathToTokenizer); ResponseDouble response scoringModel.score(query, passage); Double score response.content();需要说明GPU 版要求本机已安装匹配 CUDA 版本的驱动与运行时CUDA 12.x且 ONNX Runtime 的 GPU 二进制仅支持特定平台架构onnxruntime_gpu的可用平台范围小于 CPU 版请以 ONNX Runtime 官方发布说明为准。若你的项目同时运行在只具备 CPU 的机器上可把 GPU 依赖标记为可选或按 profile 隔离。构造函数与高级参数OnnxScoringModel提供了四个构造函数见 OnnxScoringModel.java由浅入深覆盖不同定制需求构造函数说明OnnxScoringModel(String pathToModel, String pathToTokenizer)最简形式使用默认 SessionOptions 与默认参数OnnxScoringModel(String pathToModel, OrtSession.SessionOptions options, String pathToTokenizer)自定义 SessionOptions如 CUDA 加速OnnxScoringModel(String pathToModel, String pathToTokenizer, int modelMaxLength)自定义最大序列长度OnnxScoringModel(String pathToModel, OrtSession.SessionOptions options, String pathToTokenizer, int modelMaxLength, boolean normalize)全参数形式同时控制模型长度与分数归一化两个默认参数的含义modelMaxLength默认 510模型可接受的最大 token 长度。默认值 510 来源于512 - 2即预留[CLS]与[SEP]两个特殊 token。不同模型在tokenizer_config.json中声明不同的model_max_length加载前应核对模型配置。集成测试在加载ms-marco-MiniLM-L-6-v2时显式传入了512见 OnnxScoringModelIT.java并建议对照模型仓库中的tokenizer_config.json确认该值。normalize默认false是否对模型输出的 logit 做 sigmoid 归一化。为false时直接返回 logit可正可负跨度无上限为true时映射到(0, 1)。是否需要归一化取决于下游用法——若只是对候选片段做相对排序原始 logit 即可若需要把分数当作概率语义使用再开启归一化。此外构造器内部对原生库加载失败做了友好包装wrapNativeLibraryLoadFailure见 OnnxScoringModel.java当出现UnsatisfiedLinkError、NoClassDefFoundError或ExceptionInInitializerError时会抛出带有排障提示的RuntimeException提示检查 Windows 上是否安装 Visual C Redistributable、JVM 架构x64/ARM64是否与原生库匹配等对应测试 OnnxScoringModelTest.java。获取与准备 ONNX 模型OnnxScoringModel只要求两个本地文件ONNX 格式的模型文件与tokenizer.json分词器。获取途径主要有两种直接使用已转换模型Hugging Face 的Xenova组织下托管了大量已经转换好的 ONNX 格式模型如集成测试使用的ms-marco-MiniLM-L-6-v2下载model_quantized.onnx与tokenizer.json两个文件即可参见 OnnxScoringModelIT.java 的下载逻辑自行转换如果你的候选模型还不是 ONNX 格式可以使用 Hugging Face Optimum 的 ONNX 导出器把模型转换为 ONNX 格式导出后同样得到.onnx模型文件与tokenizer.json。适用模型类型提示该实现是 BERT 交叉编码器架构类名即OnnxScoringBertCrossEncoder面向为(query, document)对打分的重排序任务设计。常见的 cross-encoder 重排模型如 ms-marco 系列、bge-reranker 系列均适用对于需要输入token_type_ids的模型如 BERT 类实现会自动探测并补齐该输入。在 RAG 流程中集成重排序进程内评分模型的最终价值在于接入 RAG 的重排序环节。由于它实现了ScoringModel接口可以无缝替换远程评分服务先用向量检索召回 Top-K 候选片段再用scoreAll对全部候选与用户查询打分最后按分数降序截取 Top-N 作为最终上下文。因为整个推理在进程内完成重排序阶段不会引入网络延迟与外部依赖且批量评分只需一次 ONNX 推理调用。常见问题排查UnsatisfiedLinkError/NoClassDefFoundErrorONNX Runtime 原生库加载失败。先确认 JVM 架构x64/ARM64与 ONNX Runtime 原生二进制的架构一致Windows 上安装最新版 Microsoft Visual C Redistributable确认安全软件未拦截从临时目录加载 DLL详见 OnnxScoringModel.java 的完整提示。IllegalStateException: Unsupported ONNX scoring output shape模型输出的张量形状不是[batch, k]或[batch, 1, 1]说明模型导出方式与当前实现不兼容可考虑用 Optimum 重新导出。分数数量与输入不一致score(...)要求单次恰好返回一个分数若通过批量方法误传了多个片段请改用scoreAll(...)。显存/内存占用偏高确认使用后调用close()释放 ONNX 会话与分词器或直接使用 try-with-resourcesclose()幂等可放心多次调用。小结langchain4j-onnx-scoring为 LangChain4j 提供了完全本地化、进程内的评分重排序能力一次依赖引入、两个本地文件即可完成 CPU 推理通过排除依赖并引入onnxruntime_gpu、调用addCUDA即可切换 GPU 加速四个构造函数与modelMaxLength、normalize参数覆盖了从最简到深度定制的全部场景底层 BERT 交叉编码器对 2D/3D 输出形状的兼容处理使其可稳定运行在不同导出方式的模型上。结合ScoringModel统一接口与批量scoreAll方法它可以直接嵌入 RAG 检索链作为完全离线、隐私友好的重排序方案。【免费下载链接】langchain4jLangChain4j is an idiomatic, open-source Java library for building LLM-powered applications on the JVM. It offers a unified API over popular LLM providers and vector stores, and makes implementing tool calling (including MCP support), agents and RAG easy. It integrates seamlessly with enterprise Java frameworks like Quarkus and Spring Boot.项目地址: https://gitcode.com/GitHub_Trending/la/langchain4j创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。