当前位置: 首页 > news >正文

spring AI 的简单使用

1. 引入

Spring 官⽅推出的⾸个稳定版⼈⼯智能(AI)集成框架. 旨在帮助 Java/Spring 开发者更便捷地在企业级应⽤中集成 AI 能⼒ (如⼤语⾔模型、机器学习、向量数据库、图像⽣成等)。
它主要提供了以下功能:
• ⽀持主要的AI模型提供商, ⽐如 Anthropic、OpenAI、Microsoft、Amazon、Google 和 Ollama, 此外它⽀持的模型种类也⾮常多, ⽐如: 聊天模型, 嵌⼊模型, 图像模型, ⾳频模型, 内容审核等.
• 跨 AI 提供商的可移植 API ⽀持. ⽀持聊天 (Chat) , ⽂本到图像 (text-to-image) 和嵌⼊(Embedding) 模型的统⼀接⼝, 同时提供同步和流式 API 选项. ⽀持访问模型特定功能.
总之, Spring AI 为 ⾮AI专家的开发者也能快速调⽤⼤语⾔模型, 提供了构建 AI 应⽤的基础抽象层, 允许开发⼈员通过极少的代码修改即可轻松替换组件, 简化集成了AI功能的应⽤程序开发。
spring AI 官网 链接

2. 术语介绍

2.1 模型

模型是人工智能系统的核心组件,通过算法和大量数据训练而成,能够执行特定任务,如预测、分类或生成内容,⽐如ChatGPT、DeepSeek、通义千问等等. 每种模型能⼒不同, 适合的任务也不同。
我们给模型的叫 输入;模型返回给我们的叫 输出

Spring AI 的能让我们在 Java/Spring 应⽤中, 能更方便地:① 选择不同的 模型 ;
② 构造和发送 输⼊ (Prompt) ;③接收并处理 输出 (AI 的响应) 。

2.2 LLM

LLMLarge Language Model 大语言模型,也称⼤型语⾔模型。是⼈⼯智能模型中专⻔处理⽂本的⼀种类型, 属于语⾔模型的范畴。
特点是:规模庞⼤, 参数数量通常在数百亿到万亿级别。
以下是几个代表模型:
• GPT-5(OpenAI)
◦ ⽀持 128K⻓上下⽂(128K token的上下文长度大约可以支持128,000个汉字) , 在多轮复杂推理、创意写作中表现突出
• DeepSeek R1(深度求索)
◦ 开源, 专注于逻辑推理与数学求解, ⽀持128K⻓上下⽂和多语⾔ (20+语⾔) , 在科技领域表现突出
• Qwen2.5-72B-Instruct (阿⾥巴巴)
◦ 通义千问开源模型家族重要成员, 擅⻓代码⽣成结构化数据 (如JSON) 处理⻆⾊扮演对话等, 尤其适合企业级复杂任务, ⽀持包括中⽂英⽂法语等29种语⾔
• Gemini 2.5 Pro (Google)
◦ 多模态融合标杆 , ⽀持图像/代码/⽂本混合输⼊, 适合跨模态任务 (如图⽂⽣成、技术⽂档解析)

2.3 提示词

提示词是用户或系统提供给大语言模型 (LLM) 的指令或文本 ,用于引导模型生成特定输出。
用户提示词:我们使用 ai 工具时,发给 它 的文字,文件等就属于 用户提示词。
系统提示词:一般是开发者预设的,它 对 ai 进行了行为预设,划定边界等,像你使用 ai 时,它告诉你问题暂时不能回答之类的,就是受到了系统提示词的规范。

2.4 词元

词元(即 Token)是自然语言处理(NLP)中的基本单位,指文本分割后的最小语义单元。使文本被拆解为模型可理解的离散单元.。

词元具体形式取决于分词策略,可以是单词、子词(Subword)、字符或符号。例如,英文句子“I love NLP”可能被拆分为词元 [“I”, “love”, “NLP”],而中文句子“我喜欢NLP”可能被拆分为 [“我”, “喜欢”, “NLP”]。不同模型的分词策略不同, 同一个词在不同模型中可能被拆分成不同词元。

前面的 模型的上下文 (如128K) 指的就是词元数量限制, 此外,如果充值使用 AI 的 API,就会知道收费通常按词元数计费。 词元数越多, 计算耗时和内存占用越⾼,因此在使用时, 应尽量避免冗余词(如请, 谢谢) ,这样不仅能省钱,还可以给 AI 减负。

3. Spring AI 快速入门

3.1 环境要求

JDK 要至少 JDK17 或以上版本。
Spring Boot 版本至少 3.2 以上。
IDEA 使用 专业版。

3.2 条件准备

3.2.1 deepseek api 申请

DeepSeek 网址
在这里插入图片描述
进入 API 开放平台,先进行充值(1 块钱一般就够用了)。
在这里插入图片描述

然后在 API keys 中进行 API 申请。
注意:这里要记住 API keys,因为它只在创建时显示,后面都不显示了。如果,手太快点了关闭,没有记住那就再申请一个。
此外,别人如果知道了你的 API key 也是可以使用的,所有要妥善报存。

3.2.2 阿里云百炼平台API-KEY 申请

阿里云百炼平台 API 申请,
按照网页说明进行申请,新人有 百万 token 的免费额度
在这里插入图片描述

3.3 基于 deepseek 的简单使用

Spring AI 为OpenAI及兼容的API服务(如DeepSeek)设计了Starter spring-ai-openaispring-boot-starter , 用于快速集成大语⾔模型能力到 Spring Boot 应用中.
核心价值包括:
• 简化配置:自动动封装 OpenAI API 的请求/响应等逻辑
• 统⼀接口:提供 ChatClient 等标准化接口, 支持无缝切换不同模型提供商
• Spring ⽣态集成:与 Spring Boot 的⾃动配置、依赖注⼊等特性深度整合

3.3.1 项目创建

Spring AI 中
在这里插入图片描述
在这里插入图片描述

3.3.2 配置文件设置

这里用的 .yml 进行配置,不是 .properties

spring:ai:openai:api-key: sk-your-key  #你申请的 api keybase-url: https://api.deepseek.comchat:options:model: deepseek-chat  #使用的 deepseek 模型temperature: 0.7  
#在AI模型的temperature参数中,值的大小直接影响生成文本的特性:
#较低值(如0.1-0.3):输出更加确定性和保守,倾向于选择最高概率的词汇,适合需要准确性和一致性的场景
#中等值(如0.4-0.7):在创造性和可靠性之间取得平衡,会产生适度变化的输出
#较高值(如0.8-1.0):输出更加随机和创造性,适合需要多样性和新颖性的场景
#您当前设置的0.7属于中等偏高,会使模型输出有一定创造性但不会过于随机

3.3.3 ChatModel 使用

package com.example.saidemo;import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredOpenAiChatModel openAiChatModel;@RequestMapping("/chat")public String chat(String message){//call() 调用AIreturn openAiChatModel.call(message);}
}

前面说过,deepseek 的 API 是兼容的,这里使用 OpenAiChatModel
使用示例:
在这里插入图片描述

3.3.4 ChatClient 使用

ChatModel 属于底层接口,而 ChatClient 则是高阶接口,它基于 ChatModel 进行了再次封装。ChatClient 使用链式调用,可读性更强。

简单对话

@RestController
@RequestMapping("/dp")
public class DPChat {private final ChatClient chatClient;public DPChat(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@RequestMapping("/chat2")public String chat2(String message){return chatClient.prompt().user(message).call().content();}
}

ChatClient 不支持使用用 @Autowired 进行直接注入,需要调用 ChatClient.Builder 下的 build() 才可以。
使用示例:
在这里插入图片描述
角色预设
为了方便后续使用,我们将 ChatClient 单独定义。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatClientConfig {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.build();}
}

这样后面就可以直接使用 @Autowired 进行注入。

回顾前文,我们知道系统提示词能够对模型进行预设,为它指定规范。所以,这里的角色预设就是设置 系统提示词
操作如下:

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatClientConfig {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.defaultSystem("你叫小明,你是一个不专业的写信者").build();}
}

使用 defaultSystem() 进行设置。
使用示例:
在这里插入图片描述
结构化输出
就是当你输入提示词后, AI 根据你所规定的结构,进行回答。
首先,我们使用JDK16提供的新关键词 record 来定义⼀个实体类

    record Recipe(String dish, List<String> ingredients) {}

通过 entity() ⽅法将模型输出转为自定义实体,(模型会自动匹配并填充)。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredChatClient chatClient;record Recipe(String dish, List<String> ingredients) {}@RequestMapping("/chat3")public String chat1(String message){Recipe recipe = chatClient.prompt().user(String.format("请根据用户的描述,生成一个菜谱。用户的描述是:%s", message)).call().entity(Recipe.class);return recipe.toString();}
}    

使用示例:
在这里插入图片描述
流式输出
运行之前的代码,你会发现和常用的 AI 工具不同,它是直接将完整结果发送过来,这就导致用户等待时间过长。想要和使用的 AI 工具的输出效果相同,就要采用流式输出,逐步生成内容而非一次性返回完整结果。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.util.List;@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredChatClient chatClient;@RequestMapping("/chat4")public Flux<String> chat1(String message){return chatClient.prompt().user(String.format("请根据用户的描述,生成一个菜谱。用户的描述是:%s", message)).stream().content();}
}

直接运行,你会发现输出结果为乱码:
在这里插入图片描述
这是因为没有对输出结果的类型进行设置,对 @RequestMapping("/chat4") 进行如下修改,就能够正确输出了。

    @RequestMapping(value = "/chat4" ,produces = "text/html;charset=utf-8")

运行结果:
在这里插入图片描述
(流式效果不好展示,这里只展示最终效果,感兴趣的可以自己试一试)

打印日志
Spring AI 借助Advisors 来实现日志打印的功能.。

Advisors 是基于 AOP思想实现的, 在具体实现上进行了领域适配. 其设计核心借鉴了Spring AOP 的拦截机制, 各个Advisor以链式结构运⾏,序列中的每个Advisor都有机会对传入的请求和传出的响应进行处理。 这种链式处理机制确保了每个Advisor可以在请求和响应流中添加自己的逻辑, 从而实现更灵活和可定制的功能。如下图:
在这里插入图片描述
主要应用场景:
• 敏感词过滤
• 建⽴聊天历史
• 对话上下⽂管理

可以直接在Config 中添加,那么后续使用 ChatClient 都会有。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatClientConfig {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.defaultSystem("你叫小明,你是一个不专业的写信者").defaultAdvisors(new SimpleLoggerAdvisor()).build();}
}

同样,也可以在单个接口中添加,仅对这一个起作用:

@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredChatClient chatClient;@RequestMapping(value = "/chat4" ,produces = "text/html;charset=utf-8")public Flux<String> chat1(String message){return chatClient.prompt().user(String.format("请根据用户的描述,生成一个菜谱。用户的描述是:%s", message)).advisors(new SimpleLoggerAdvisor()).stream().content();}
}

3.3.5 ChatModel 拓展

Ctrl + 左键进入之前代码中的 call() 方法,会发现它调用了 参数类型为 Promptcall() 方法。

接下来使用 Prompt 来使用 call() 方法。
简单使用

    @RequestMapping("/chatByPrompt")public String chatByPrompt (String msg) {Prompt prompt = new Prompt(msg);ChatResponse response = chatModel.call(prompt);return response.getResult().getOutput().getText();}

角色预设

    @RequestMapping("/role")public String role(String msg) {SystemMessage systemMessage = new SystemMessage("你叫dp,是对话ai机器人");UserMessage userMessage = new UserMessage(msg);Prompt prompt = new Prompt(userMessage,systemMessage);ChatResponse response = chatModel.call(prompt);return response.getResult().getOutput().getText();}

流式响应

    @RequestMapping(value = "/stream" ,produces = "text/html;charset=utf-8"  )public Flux<String> stream (String msg) {Prompt prompt = new Prompt(msg);Flux<ChatResponse> response = chatModel.stream(prompt);return response.map(x->x.getResult().getOutput().getText());}

.map(x->x.getResult().getOutput() .getText()) 方法,用于操作流中元素。
基于代码可知,chatModel.stream(prompt); 的返回类型为 Flux<ChatResponse>。你可以理解为 response (流) 是一辆列车,是由很多节组成的连续一长串,这每一节都是 类型为 ChatResponse 的元素。

map 方法则是操作每一节,并返回生成新的 流,且不改变原流。这里 x 就代指 response 中的元素(也可以使用其他字母来代指),x 经过 getResult().getOutput().getText() 就变成了 String 类型,所以新的流就是 Flux<String> 类型。

3.3.6 Client & Model 对比

维度ChatModelChatClient
交互⽅式⼿动构建Prompt, 解析响应链式API, ⾃动封装请求与响应
结构化输出⼿动解析⽂本⽀持 .entity(Class) ⾃动映射POJO
扩展能⼒依赖外部组件内置Advisor机制, 提供更⾼级的功能, 如提供上下⽂记忆, RAG等功能
适合场景适合需要精细控制模型参数的场景, ⽐如模型实验, 参数调优等定制需求适合快速构建AI服务, 如带记忆的客服系统

3.4 流式编程 - 资料了解

HTTP 协议本身设计为无状态的 请求-响应模式,严格来说, 是无法做到服务器主动推送消息到客户端, 但通过Server-Sent Events (服务器发送事件, 简称SSE)技术可实现流式传输,允许服务器主动向浏览器推送数据流。
服务器会告诉客户端,接下来要发送的是流消息(streaming), 这时客户端不会关闭连接,会⼀直等待服务器发送过来新的数据流。
SSE(Server-Sent Events)是⼀种基于 HTTP 的轻量级实时通信协议,浏览器通过内置的
EventSource API接收并处理这些实时事件。
特点:
基于 HTTP 协议
复⽤标准了 HTTP/HTTPS 协议,⽆需额外端⼝或协议,兼容性好且易于部署 。
单向通信机制
SSE 仅支持服务器向客户端的单向数据推送,客户端通过普通 HTTP 请求建⽴连接后,服务器可持续发送数据流,但客户端无法通过同⼀连接向服务器发送数据。
自动重连机制
⽀持断线重连,连接中断时,浏览器会⾃动尝试重新连接(⽀持 retry 字段指定重连间隔)
自定义消息类型
客户端发起请求后,服务器保持连接开放, 响应头设置 Content-Type: text/event-stream,标识为事件流格式, 持续推送事件流。

数据格式
每⼀次发送的消息,由若干个message组成, 每个message之间由 \n\n 分隔, 每个message内部由若干行组成, 每⼀行都是如下格式:

[field]: value\n

前端代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SSE</title>
</head>
<body><div id="sse"></div>
</body>
<script>let eventSource = new EventSource('/sse/data')eventSource.onmessage = function (event) {document.getElementById('sse').innerHTML = event.data;}// eventSource.addEventListener('foo', (event) => {//     document.getElementById('sse').innerHTML = event.data;// })// eventSource.addEventListener('end', (event) => {//     eventSource.close()// })
</script>
</html>

EventSource('/sse/data') 中填写的是后端接口。
后端代码:

package com.example.saidemo;import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.awt.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.Date;@Slf4j
@RequestMapping("/sse")
@RestController
public class SseController {@RequestMapping("/data")public void data(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回响应:  data");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();for (int i = 0; i < 10; i++) {String s = "data: " + new Date() + "\n\n";writer.write(s);writer.flush();Thread.sleep(1000L);}}@RequestMapping("/retry")public void retry(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回响应:  retry");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();String s = "retry: 2000\n";s += "data: " + new Date() + "\n\n";writer.write(s);writer.flush();}@RequestMapping("/event")public void event(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回响应:  event");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();for (int i = 0; i < 10; i++) {String s = "event: foo\n";  //自定义事件,对应前端注释掉的代码s += "data: " + new Date() + "\n\n";writer.write(s);writer.flush();Thread.sleep(1000L);}}@RequestMapping("/end")public void end(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回响应:  event");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();for (int i = 0; i < 10; i++) {String s = "event: foo\n";	//自定义事件,对应前端注释掉的代码s += "data: " + new Date() + "\n\n";writer.write(s);writer.flush();Thread.sleep(1000L);}writer.write("event: end\ndata: EOF\n\n");}@RequestMapping(value = "/stream",produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> stream() {return Flux.interval(Duration.ofSeconds(1)) //发送间隔.map(s->new Date().toString());  }
}

自动重连的体现:
在这里插入图片描述
运行后,访问前端页面,发现数字一直在改变。但实际后端 /sse/data 接口中只定义发送 10 次。这是因为当该接口的完整逻辑执行完后,进行了自动重连。

3.5 基于 Spring AI Alibaba 的简单使用

3.5.1 项目创建

项目创建时,添加的依赖:
在这里插入图片描述

3.5.2 配置文件设置

pom 文件的配置:

<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-bom</artifactId><version>1.0.0.2</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId></dependency>
</dependencies>

.yml 文件配置:

spring:ai:dashscope:api-key: #你在百炼平台申请的 API KEYchat:options:model: qwen-vl-max-latest #模型名称multi-model: true #是否启⽤多模型

3.5.3 ChatModel 使用

由于使用类似,不同的是 这里使用 ChatModel 类,不再使用 OpenAiChatModel
所以,不再细说,只进行代码展示和必要说明。

package com.example.salidemo;import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/ali")
public class AliController {@Autowiredprivate ChatModel chatModel;@RequestMapping("/chat")public String chat(String message){return chatModel.call(message);}
}

使用示例:
在这里插入图片描述

3.5.4 ChatClient 使用

直接使用

package com.example.salidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.util.List;@RestController
@RequestMapping("/chat")
public class ChatController {private ChatClient chatClient;public ChatController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@RequestMapping("/chat")public String chat(String message){return chatClient.prompt().user(message).call().content();}
}    

角色预设
这里同样将 ChatClient 单独迁出,并使用 @Bean 注解进行注入。

单独类:

package com.example.salidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatConfiguration {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.defaultSystem("你是一个专业的演员,在每次回复前加上{word}").build();}
}

这里的 {word} 就相当于占位符,在实际使用时可进行替换,否则 原样输出。像这样:
在这里插入图片描述

    @RequestMapping("/word")public String word(String message,String word){return chatClient.prompt().user(message).system(sp->sp.param("word",word)).call().content();}

system(sp->sp.param("word",word)) 替换操作。sp 是Lambda表达式的参数名称,可以自由命名,但必须与后续调用保持一致。
如果有多个参数,使用方法如下:

//链式调用param方法:
.system(sp -> sp.param("word1", word1).param("word2", word2).param("word3", word3))//使用Map传递多个参数:
Map<String, Object> params = new HashMap<>();
params.put("word1", word1);
params.put("word2", word2);
.system(sp -> sp.params(params))//使用对象封装参数(推荐):
record WordParams(String word1, String word2) {}
.system(sp -> sp.entity(new WordParams(word1, word2)))

之前的 基于 deepseek 的ChatClient 同样适用。

结构化输出

    record ActorFilms(String actor, List<String> films){}@RequestMapping("/entify")public String entify(String actor){return chatClient.prompt().user(String.format("帮我生成%S参演的作品",actor)).call().entity(ActorFilms.class).toString();}

流式输出

    @RequestMapping(value = "/stream",produces = "text/html;charset=utf-8")public Flux<String> stream(String message){return this.chatClient.prompt().user(message).stream().content();}

3.5.5 多模态的使用。

多模态性指模型同时理解和处理文本、图像、音频及其他数据格式等多源信息的能力。
这里展示 处理图片的能力。

@RestController
@RequestMapping("/multi")
public class MultiController {private final ChatClient chatClient;public MultiController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@RequestMapping("/image")public String image(String prompt) throws URISyntaxException, MalformedURLException {String url = "https://tse4-mm.cn.bing.net/th/id/OIP-C.TCq0ItOzbTzC11dudmqMrgHaLJ?w=195&h=294&c=7&r=0&o=5&dpr=1.5&pid=1.7";//网上随便找的网图List<Media> mediaList = List.of(new Media(MimeTypeUtils.IMAGE_JPEG, new URI(url).toURL().toURI()));//用户提示词UserMessage userMessage = UserMessage.builder().text(prompt).media(mediaList).build();//调用模型String response = chatClient.prompt(new Prompt(userMessage)).call().content();return response;}
}

文章转载自:

http://4poXvYuw.tLfyb.cn
http://tQuYBWcI.tLfyb.cn
http://c22gEkBq.tLfyb.cn
http://giwb1vWi.tLfyb.cn
http://xBjsPd3I.tLfyb.cn
http://3W1NTuXr.tLfyb.cn
http://Wyb5ldUD.tLfyb.cn
http://TJuFdxFD.tLfyb.cn
http://znSVwRaa.tLfyb.cn
http://6VPPlIsi.tLfyb.cn
http://4T7RZCMB.tLfyb.cn
http://GX8wFeRr.tLfyb.cn
http://3MuOneY4.tLfyb.cn
http://2Om4bHPZ.tLfyb.cn
http://LcvCqQZm.tLfyb.cn
http://aVgvEPKv.tLfyb.cn
http://LdFmSPll.tLfyb.cn
http://ohQDRQ75.tLfyb.cn
http://jRqg49iK.tLfyb.cn
http://4MsjcbE4.tLfyb.cn
http://fpyNr3Fo.tLfyb.cn
http://sha0U6xH.tLfyb.cn
http://WKjn8D0A.tLfyb.cn
http://hzkmzrbi.tLfyb.cn
http://E19JU8go.tLfyb.cn
http://LZNzpXmp.tLfyb.cn
http://D1SOsaRi.tLfyb.cn
http://ofudHKDr.tLfyb.cn
http://R7MeIwwv.tLfyb.cn
http://xTnhKon2.tLfyb.cn
http://www.dtcms.com/a/368195.html

相关文章:

  • 【yolo】YOLOv8 训练模型参数与多机环境差异总结
  • 算法(keep learning)
  • C/C++中的可变参数 (Variadic Arguments)函数机制
  • 深度学习:CNN 模型训练中的学习率调整(基于 PyTorch)
  • Mattermost教程:用Docker搭建自己的开源Slack替代品 (团队聊天)
  • Electron 性能优化:内存管理和渲染效率
  • 数字隔离器,新能源汽车PTC中的“电气安全卫士”
  • 2025 汽车租赁大会:九识智能以“租赁+运力”革新城市智能配送
  • 云原生部署_Docker入门
  • javaweb(【概述和安装】【tomeat的使用】【servlet入门】).
  • 基于SpringBoot的社区智能垃圾管理系统【2026最新】
  • 基于飞算JavaAI的在线图书借阅平台设计实现
  • dbeaver工具连接inceptor星环数据库
  • Linux内核网络安全序列号生成机制解析
  • Buzz语音转文字:开源神器,高效记录会议
  • Docker 容器核心指令与数据库容器化实践
  • 自制扫地机器人 (五) Arduino 手机远程启停设计 —— 东方仙盟
  • docker 安装kafaka常用版本
  • Pytorch Yolov11 OBB 旋转框检测+window部署+推理封装 留贴记录
  • PyTorch 中.backward() 详解使用
  • conda配置pytorch虚拟环境
  • Conda环境隔离和PyCharm配置,完美同时运行PaddlePaddle和PyTorch
  • PyTorch训练循环详解:深入理解forward()、backward()和optimizer.step()
  • PyTorch 训练显存越跑越涨:隐式保留计算图导致 OOM
  • PyTorch图像数据转换为张量(Tensor)并进行归一化的标准操作
  • 图像去雾:从暗通道先验到可学习融合——一份可跑的 PyTorch 教程
  • EN-DC和CA的联系与区别
  • python + Flask模块学习 1 基础用法
  • 【Flask】测试平台中,记一次在vue2中集成编辑器组件tinymce
  • 【分享】基于百度脑图,并使用Vue二次开发的用例脑图编辑器组件