news 2026/5/23 17:49:49

在Java中加载和调用Embedding模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在Java中加载和调用Embedding模型

推荐方案

  1. 生产环境推荐:使用ONNX Runtime方案,性能好,无需Python依赖
  2. 快速原型开发:使用REST API方案,部署简单
  3. 需要完整功能:考虑DeepSeek4j等专用Java库
  4. 灵活性要求高:使用DJL,支持多种模型格式

方法1:使用ONNX Runtime(推荐)

这是最直接且性能较好的Java集成方式。

步骤1:将BGE-M3转换为ONNX格式(Python端)
安装依赖

pip install torch transformers onnx onnxruntime

加载模型、设置为评估模式并导出onnx

importtorchfromFlagEmbeddingimportBGEM3FlagModel model=BGEM3FlagModel('BAAI/bge-m3',use_fp16=True)model.eval()# 设置为评估模式dummy_input=torch.tensor([[0]*model.config.hidden_size])# 需要根据模型结构调整onnx_path="bge_m3.onnx"torch.onnx.export(model,dummy_input,onnx_path,opset_version=13,input_names=['input_ids','attention_mask'],# 根据实际输入调整output_names=['output'])
步骤2:在Java中使用ONNX Runtime(Maven依赖)
<dependency><groupId>com.microsoft.onnxruntime</groupId><artifactId>onnxruntime</artifactId><version>1.17.0</version></dependency>

Java代码示例:

importai.onnxruntime.*;importjava.nio.file.Paths;importjava.util.*;publicclassBGE_M3_ONNX{privateOrtSessionsession;privateOrtEnvironmentenv;publicBGE_M3_ONNX(StringmodelPath)throwsOrtException{env=OrtEnvironment.getEnvironment();OrtSession.SessionOptionsopts=newOrtSession.SessionOptions();session=env.createSession(modelPath,opts);}publicfloat[]getEmbedding(Stringtext)throwsOrtException{// 文本预处理(需要实现分词器)// 这里简化处理,实际需要将文本转换为input_ids和attention_mask// 准备输入long[]inputIds=tokenize(text);// 需要实现tokenize方法long[]attentionMask=createAttentionMask(inputIds);// 创建输入Tensorlong[]shape={1,inputIds.length};OnnxTensorinputIdsTensor=OnnxTensor.createTensor(env,inputIds,shape);OnnxTensorattentionMaskTensor=OnnxTensor.createTensor(env,attentionMask,shape);// 准备输入MapMap<String,OnnxTensor>inputs=newHashMap<>();inputs.put("input_ids",inputIdsTensor);inputs.put("attention_mask",attentionMaskTensor);// 运行推理OrtSession.Resultresults=session.run(inputs);// 获取输出OnnxTensoroutputTensor=(OnnxTensor)results.get("output");float[]embeddings=(float[])outputTensor.getValue();returnembeddings;}privatelong[]tokenize(Stringtext){// 需要实现BGE-M3的分词逻辑// 可以使用HuggingFace的tokenizer或实现简单的分词returnnewlong[]{101,2345,6789,102};// 示例}privatelong[]createAttentionMask(long[]inputIds){long[]mask=newlong[inputIds.length];Arrays.fill(mask,1L);returnmask;}publicvoidclose()throwsOrtException{if(session!=null){session.close();}}}

方法2:使用Deep Java Library (DJL)

DJL是亚马逊开发的Java深度学习库,支持PyTorch、TensorFlow等模型。

Maven依赖:

<dependency><groupId>ai.djl</groupId><artifactId>api</artifactId><version>0.27.0</version></dependency><dependency><groupId>ai.djl.pytorch</groupId><artifactId>pytorch-engine</artifactId><version>0.27.0</version></dependency>

Java代码示例:

importai.djl.Model;importai.djl.inference.Predictor;importai.djl.modality.Input;importai.djl.modality.Output;importai.djl.translate.TranslateException;importai.djl.translate.Translator;importjava.nio.file.Paths;publicclassBGE_M3_DJL{privateModelmodel;privatePredictor<String,float[]>predictor;publicvoidloadModel(StringmodelPath)throwsException{model=Model.newInstance("bge-m3");model.load(Paths.get(modelPath));// 创建Translator(需要自定义实现)Translator<String,float[]>translator=newBGETranslator();predictor=model.newPredictor(translator);}publicfloat[]getEmbedding(Stringtext)throwsTranslateException{returnpredictor.predict(text);}publicvoidclose(){if(predictor!=null){predictor.close();}if(model!=null){model.close();}}// 自定义TranslatorstaticclassBGETranslatorimplementsTranslator<String,float[]>{@Overridepublicfloat[]processOutput(ai.djl.ndarray.NDListlist){// 处理模型输出returnlist.get(0).toFloatArray();}@Overridepublicai.djl.ndarray.NDListprocessInput(TranslatorContextctx,Stringinput){// 文本预处理和tokenization// 需要实现分词逻辑returnnewai.djl.ndarray.NDList();}}}

方法3:通过REST API调用

如果模型部署在Python服务中,可以通过HTTP调用。

Python服务端(FastAPI):

fromfastapiimportFastAPIfrompydanticimportBaseModelfromFlagEmbeddingimportBGEM3FlagModelimportnumpyasnp app=FastAPI()model=BGEM3FlagModel('BAAI/bge-m3',use_fp16=True)classEmbeddingRequest(BaseModel):texts:list[str]@app.post("/embed")asyncdefget_embeddings(request:EmbeddingRequest):embeddings=model.encode(request.texts)['dense_vecs']return{"embeddings":embeddings.tolist()}

Java客户端:

importcom.fasterxml.jackson.databind.ObjectMapper;importokhttp3.*;publicclassBGE_M3_API_Client{privatestaticfinalStringAPI_URL="http://localhost:8000/embed";privatefinalOkHttpClientclient=newOkHttpClient();privatefinalObjectMappermapper=newObjectMapper();publicfloat[][]getEmbeddings(List<String>texts)throwsException{// 构建请求体Map<String,Object>requestBody=newHashMap<>();requestBody.put("texts",texts);Stringjson=mapper.writeValueAsString(requestBody);RequestBodybody=RequestBody.create(json,MediaType.parse("application/json"));Requestrequest=newRequest.Builder().url(API_URL).post(body).build();try(Responseresponse=client.newCall(request).execute()){if(!response.isSuccessful()){thrownewRuntimeException("请求失败: "+response.code());}StringresponseBody=response.body().string();Map<String,Object>result=mapper.readValue(responseBody,Map.class);// 解析返回的向量List<List<Double>>embeddingsList=(List<List<Double>>)result.get("embeddings");float[][]embeddings=newfloat[embeddingsList.size()][];for(inti=0;i<embeddingsList.size();i++){List<Double>vec=embeddingsList.get(i);embeddings[i]=newfloat[vec.size()];for(intj=0;j<vec.size();j++){embeddings[i][j]=vec.get(j).floatValue();}}returnembeddings;}}}

方法4:使用DeepSeek4j(专用Java库)

根据搜索结果,DeepSeek4j提供了BGE-M3的Java支持。

代码示例:

importcom.deepseek4j.embedding.EmbeddingClient;importcom.deepseek4j.embedding.EmbeddingRequest;importcom.deepseek4j.embedding.EmbeddingResponse;publicclassBGE_M3_DeepSeek4j{publicstaticvoidmain(String[]args){EmbeddingClientclient=newEmbeddingClient();EmbeddingRequestrequest=EmbeddingRequest.builder().model("bge-m3:latest").input("What is BGE M3?").build();try{EmbeddingResponseresponse=client.embed(request);float[]embedding=response.getEmbedding();System.out.println("向量维度: "+embedding.length);System.out.println("向量: "+Arrays.toString(embedding));}catch(Exceptione){e.printStackTrace();}}}

注:

  1. 分词器实现:BGE-M3使用特定的分词器,需要正确处理
  2. 模型大小:BGE-M3模型较大,需要足够内存
  3. 性能优化:考虑批处理、GPU加速等优化手段
  4. 错误处理:添加适当的异常处理和资源清理
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 3:48:25

Whisper Diarization:智能语音转写与多说话人识别技术指南

Whisper Diarization&#xff1a;智能语音转写与多说话人识别技术指南 【免费下载链接】whisper-diarization Automatic Speech Recognition with Speaker Diarization based on OpenAI Whisper 项目地址: https://gitcode.com/GitHub_Trending/wh/whisper-diarization …

作者头像 李华
网站建设 2026/5/22 11:07:57

从数据准备到模型生成:GPT-SoVITS完整流程拆解

从数据准备到模型生成&#xff1a;GPT-SoVITS完整流程拆解 在语音交互日益普及的今天&#xff0c;我们早已不再满足于机械、千篇一律的“AI音”。无论是虚拟主播深情并茂地讲述故事&#xff0c;还是智能助手用熟悉的声音提醒日程&#xff0c;个性化语音合成&#xff08;TTS&…

作者头像 李华
网站建设 2026/5/19 0:04:58

GPT-SoVITS支持多语言吗?实测结果来了!

GPT-SoVITS支持多语言吗&#xff1f;实测结果来了&#xff01; 在虚拟主播、AI配音和个性化语音助手日益普及的今天&#xff0c;一个关键问题摆在开发者面前&#xff1a;我们能否用一段中文录音&#xff0c;让同一个声音自然地说出英文、日文甚至法语&#xff1f; 这不再是科…

作者头像 李华
网站建设 2026/5/21 13:19:52

自媒体人福音:用GPT-SoVITS生成专属播客语音

自媒体人福音&#xff1a;用GPT-SoVITS生成专属播客语音 在内容创作进入“音频红利期”的今天&#xff0c;越来越多的自媒体人开始尝试将文字、视频脚本转化为播客或有声节目。但现实是&#xff0c;高质量语音内容的制作往往卡在“声音”这一环——请专业配音成本高&#xff0c…

作者头像 李华
网站建设 2026/5/21 4:01:51

vcf2phylip终极指南:一键转换VCF格式,快速构建系统发育树

vcf2phylip终极指南&#xff1a;一键转换VCF格式&#xff0c;快速构建系统发育树 【免费下载链接】vcf2phylip Convert SNPs in VCF format to PHYLIP, NEXUS, binary NEXUS, or FASTA alignments for phylogenetic analysis 项目地址: https://gitcode.com/gh_mirrors/vc/vc…

作者头像 李华