JAVA接入DeepSeek大模型接口开发---阿里云的百炼模型
前言
随着大模型的越来越盛行,现在很多企业开始接入大模型的接口,今天我从java开发角度来写一个demo的示例,用于接入DeepSeek大模型,国内的大模型有很多的接入渠道,今天主要介绍下阿里云的百炼模型,因为这个模型是免费的,只要注册一个账户,就会免费送百万的token进行学习,今天就从一个简单的可以执行的示例开始进行介绍,希望可以分享给各位正在学习的同学们。
概念原理:
DeepSeek大模型是由深度求索(DeepSeek)公司开发的一种生成式人工智能模型,其核心目标是结合大规模语言模型与深度搜索技术,提供更精准、全面的信息服务和交互体验。以下从技术定位、核心功能及底层原理三个层面展开说明:
1. DeepSeek大模型的定位
DeepSeek旨在成为“搜索增强型大语言模型”,与传统搜索引擎或纯生成式AI(如ChatGPT)不同,它通过以下方式融合两者优势:
- 搜索增强生成:将网络检索结果作为输入的一部分,辅助模型生成更实时、可信的内容。
- 多模态交互:支持文本、图像、语音等多模态输入,扩展应用场景。
- 长文本处理:优化上下文记忆能力,支持复杂任务的多轮对话。
2. 深度搜索(DeepSeek)的核心功能
深度搜索技术主要解决传统搜索的三大痛点:
- 语义鸿沟:通过深度理解用户意图(而非关键词匹配),精准定位信息。例如,将“如何修复电脑蓝屏”转化为技术文档、论坛讨论和教程视频的关联。
- 信息过时:实时抓取最新数据(如新闻、学术文献),动态更新知识库。
- 长尾查询:通过生成能力补全冷门问题的信息缺失,如专业领域的细分问题。
具体技术手段包括:
- 混合检索架构:结合向量数据库(语义搜索)与图数据库(知识关联),提升召回率。
- 生成式补全:对检索结果不足的部分,用大模型生成补充内容,并标注来源可信度。
- 多模态索引:对图像、表格等非文本数据建立嵌入表示(Embedding),实现跨模态检索。
3. 底层技术原理
DeepSeek的技术栈可分为四层架构:
(1)基础模型层
- Transformer架构:采用解码器-only结构(类似GPT),通过自注意力机制捕捉长距离依赖。
- 参数规模:推测为百亿级参数(具体未公开),支持复杂推理和生成任务。
- 优化策略:可能引入混合专家系统(MoE)降低计算成本,或采用量化技术加速推理。
(2)预训练与微调
- 多任务预训练:
-
- 语言建模:掩码语言模型(MLM)学习文本表征。
- 知识注入:通过检索增强预训练(REALM等范式),将外部知识融入模型。
- 对话建模:基于指令微调(Instruction Tuning)提升任务完成能力。
- 持续学习:通过增量预训练吸收新数据,避免知识过时。
(3)搜索融合层
- 动态检索:在用户输入时实时触发搜索,将结果编码为模型可读的向量。
- 上下文融合:将检索内容与用户历史对话拼接,作为生成输入的上下文。
- 可控生成:通过强化学习(RLHF)优化生成方向,确保答案符合搜索目标。
(4)系统优化层
- 异构硬件适配:针对CPU/GPU/NPU优化推理速度,支持高并发场景。
- 延迟-质量平衡:根据场景动态调整搜索深度和生成长度,例如简单问题直接检索,复杂问题启动生成。
JAVA实战
第一步:依赖的配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring.ai.text</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>17</java.version>
<spring-ai.version>0.8.1</spring-ai.version>
</properties>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- 使用DashScope SDK -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<version>2.5.0</version> <!-- 使用最新版本 -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
第二步:接口的开发
package org.example;
import com.alibaba.dashscope.base.HalfDuplexServiceParam;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import java.lang.System;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class QwenController {
private static StringBuilder reasoningContent = new StringBuilder();
private static StringBuilder finalContent = new StringBuilder();
private static boolean isFirstPrint = true;
@GetMapping("/qwen")
public String askQuestion(String question) throws NoApiKeyException, InputRequiredException {
Generation gen = new Generation();
HalfDuplexServiceParam generationParam = buildGenerationParam(question);
Flowable<GenerationResult> result = gen.streamCall(generationParam);
result.blockingForEach(message -> handleGenerationResult(message));
return reasoningContent.toString();
}
@GetMapping("/deepseek")
public String askDeepSeekQuestion(String question) throws NoApiKeyException, InputRequiredException {
Generation gen = new Generation();
HalfDuplexServiceParam generationParam = buildDeepSeekGenerationParam(question);
Flowable<GenerationResult> result = gen.streamCall(generationParam);
result.blockingForEach(message -> handleGenerationResult(message));
return reasoningContent.toString();
}
private static HalfDuplexServiceParam buildDeepSeekGenerationParam(String Msg) {
return GenerationParam.builder()
// 若没有配置环境变量,请用百炼API Key将下行替换为:.apiKey("sk-xxx")
.apiKey("")
// 此处以 qwq-32b 为例,可按需更换模型名称
.model("deepseek-r1")
.prompt(Msg)
.build();
}
private static HalfDuplexServiceParam buildGenerationParam(String Msg) {
return GenerationParam.builder()
// 若没有配置环境变量,请用百炼API Key将下行替换为:.apiKey("sk-xxx")
.apiKey("")
// 此处以 qwq-32b 为例,可按需更换模型名称
.model("qwq-32b")
.prompt(Msg)
.build();
}
private static void handleGenerationResult(GenerationResult message) {
String reasoning = message.getOutput().getChoices().get(0).getMessage().getContent();
String content = message.getOutput().getChoices().get(0).getMessage().getContent();
if (!reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================思考过程====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (!content.isEmpty()) {
finalContent.append(content);
if (!isFirstPrint) {
System.out.println("\n====================完整回复====================");
isFirstPrint = true;
}
System.out.print(content);
}
}
}
代码中的模型选择,可以选择目前百炼支持的模型,比如说阿里云的模型,比如说deepseek的模型,一般有deepseek-v1、deepseek-v2、deepseek-v3以及deepseek-r1等,每种不同的模型具备不同的推理能力不一样。具体的会在接口调用的时候进行介绍。
第三步:运行效果
3.1deepseek-r1的调用情况
3.2qwq-32b的调用情况
总结:
从运行的效果来看,整个的思考过程以及生成的结果来看,两个模型的思考几乎是差不多的,现在随着国内的大模型逐步开源,并且相互之间进行模型之间的学习以及蒸馏,这样的话,整个国内的AI大模型就会达到良性的发展,随着使用的人数越来越多,也能反向的促进人工智能的发展与进步。