文章目录
-
- 前言
- [一、Java 程序员的"Python 霸凌":我们受够了](#一、Java 程序员的"Python 霸凌":我们受够了)
- 二、Ollama:大模型界的"应用商店"
-
- [2.1 安装 Ollama:比装 QQ 还简单](#2.1 安装 Ollama:比装 QQ 还简单)
- [2.2 硬件要求:别被吓退,8G 显存也能玩](#2.2 硬件要求:别被吓退,8G 显存也能玩)
- [三、召唤 Qwen 3.5:让阿里大厨进厨房](#三、召唤 Qwen 3.5:让阿里大厨进厨房)
-
- [3.1 拉取模型:一键召唤](#3.1 拉取模型:一键召唤)
- [3.2 本地测试:先尝后买](#3.2 本地测试:先尝后买)
- [四、Spring Boot 3.x 集成:Java 程序员的春天](#四、Spring Boot 3.x 集成:Java 程序员的春天)
-
- [4.1 项目初始化:选对战车](#4.1 项目初始化:选对战车)
- [4.2 Maven 配置:引入弹药库](#4.2 Maven 配置:引入弹药库)
- [4.3 YAML 配置:打通任督二脉](#4.3 YAML 配置:打通任督二脉)
- [五、代码实战:5 行代码跑通对话](#五、代码实战:5 行代码跑通对话)
-
- [5.1 极简版:直接注入 ChatClient](#5.1 极简版:直接注入 ChatClient)
- [5.2 进阶版:带历史记忆的对话](#5.2 进阶版:带历史记忆的对话)
- [六、性能调优:让 Qwen 3.5 跑得更欢](#六、性能调优:让 Qwen 3.5 跑得更欢)
-
- [6.1 量化模型:显存不够,精度来凑](#6.1 量化模型:显存不够,精度来凑)
- [6.2 上下文长度:别让 AI 失忆](#6.2 上下文长度:别让 AI 失忆)
- [6.3 流式输出:告别转圈圈](#6.3 流式输出:告别转圈圈)
- 七、避坑指南:我踩过的雷你别踩
-
- [坑 1:Ollama 默认只能本地访问](#坑 1:Ollama 默认只能本地访问)
- [坑 2:中文乱码](#坑 2:中文乱码)
- [坑 3:内存泄漏](#坑 3:内存泄漏)
- [坑 4:模型下载卡住](#坑 4:模型下载卡住)
- [八、写在最后:Java 的 AI 时代真的来了](#八、写在最后:Java 的 AI 时代真的来了)
无意间发现了一个CSDN大神的人工智能教程,忍不住分享一下给大家。很通俗易懂,重点是还非常风趣幽默,像看小说一样。床送门放这了👉 http://blog.csdn.net/jiangjunshow
前言
本文手把手教你在 Windows/Linux 上通过 Ollama 本地部署阿里 Qwen 3.5 大模型,并用 Spring Boot 3.x + Spring AI 1.1.0 搭建 Java 后端服务。无需 Python 环境,5 行代码实现 AI 对话,附完整 Maven 依赖、YAML 配置和可运行的 Controller 代码,显存 8GB 就能跑 9B 参数模型。
一、Java 程序员的"Python 霸凌":我们受够了
说实话,这年头做 Java 开发真的有点憋屈。每次想玩点 AI 大模型,网上一搜教程,清一色的 Python:pip install 这、conda env 那,好像不会 Python 就不配搞 AI 似的。
我就纳闷了,咱们 Java 生态圈养了这么多年的 Spring Boot,难道就只能在旁边看着 Python 吃香的喝辣的?
更离谱的是,很多公司为了跑个本地大模型,非要单独部署一套 Python 微服务,然后让 Java 后端通过 HTTP 调来调去。这就好比你在家里想吃碗面条,非要点外卖让骑手从隔壁厨房端过来------明明灶台上就有锅,干嘛不自己煮?
好消息是,2025 年开始,局面彻底变了。阿里发布的 Qwen 3.5 系列模型在中文理解能力上直接屠榜,而 Ollama 这个"模型外卖平台"让本地部署变得比安装微信还简单。再加上 Spring AI 1.1.0 的强势更新,Java 开发者终于可以挺直腰杆说:不用 Python,我们也能玩转大模型!
二、Ollama:大模型界的"应用商店"
打个比方,如果大模型是各种菜系的大厨,那 Ollama 就是高端人才市场。你不需要亲自去猎头(配置 Python 环境)、不用装修厨房(安装 CUDA)、不用给大厨发工资(购买 API Key),只需要敲一行命令,就能让 Qwen 3.5 这个"满汉全席级大厨"来你家(本地电脑)上班。
2.1 安装 Ollama:比装 QQ 还简单
不管你用 Windows、Mac 还是 Linux,Ollama 的安装都堪称无脑:
Windows 用户:
直接访问 ollama.com,下载 .exe 文件双击运行,一路下一步。安装完成后,右下角会出现一个羊驼图标,右键点击选择"Open Web UI"就能验证是否成功。
Linux 用户(Ubuntu/CentOS):
打开终端,复制粘贴这行命令,回车:
bash
curl -fsSL https://ollama.com/install.sh | sh
装好后执行:
bash
systemctl status ollama
看到绿色的 active (running) 就说明大厨已经到岗。
验证安装:
bash
ollama --version
如果显示类似 ollama version 0.6.0 的版本号,恭喜你,地基已经打好。
2.2 硬件要求:别被吓退,8G 显存也能玩
很多人一听"本地部署大模型"就想到四路 RTX 4090,其实 Qwen 3.5 这次发了很多个尺寸,从手机能跑的 0.8B 到服务器级的 397B 都有。
对于咱们 Java 开发者做测试或者中小型企业应用,9B 版本是甜点选择:
- 显存需求:8GB 就能流畅跑(量化版)
- 响应速度:RTX 3060 级别显卡,首 token 延迟不到 1 秒
- 中文能力:写作、代码、推理都不输 GPT-4 初版
如果你只有核显或者老笔记本,也可以试试 4B 版本,虽然聪明程度差了点,但写个 CRUD 代码、解释个算法还是没问题。
三、召唤 Qwen 3.5:让阿里大厨进厨房
Ollama 装好后,下载模型就是一句话的事,比 Docker pull 镜像还快。
3.1 拉取模型:一键召唤
打开终端(Windows 就是 CMD 或 PowerShell),输入:
bash
ollama pull qwen3.5:9b
这时候 Ollama 会从仓库下载模型权重,大概 6GB 左右,网速快的话十分钟搞定。下载过程中你可以去泡杯咖啡,进度条走完后,你的电脑里就住着一个精通中文的 AI 大脑了。
如果你想试试更小更快的版本,可以换:
bash
ollama pull qwen3.5:4b # 适合轻薄本
ollama pull qwen3.5:35b # 需要 24G 显存,性能怪兽
3.2 本地测试:先尝后买
下载完成后,先别急着写代码,在终端里直接对话试试:
bash
ollama run qwen3.5:9b
你会看到光标等待输入,这时候打个招呼:
你好,请用 Java 写个单例模式,要带线程安全的那种
如果 Qwen 3.5 立刻给你吐出一段完美的双重检查锁代码,还附带注释解释 volatile 关键字的作用,那就说明一切正常。按 Ctrl+D 退出对话模式。
重点来了:Ollama 默认会开启一个 REST API 服务,地址是 http://localhost:11434,而且神奇的是,它兼容 OpenAI 的接口格式!这意味着什么?意味着你不需要学新的 API 规范,直接用 OpenAI 的客户端都能连上,简直是降维打击。
四、Spring Boot 3.x 集成:Java 程序员的春天
好了,大厨已经就位,现在该 Java 出场当服务员了。我们要用 Spring AI 这个"翻译官",让 Java 代码能和 Qwen 3.5 顺畅交流。
4.1 项目初始化:选对战车
打开 Spring Initializr(start.spring.io),选择:
- Project: Maven
- Spring Boot: 3.3.x(必须 3.x,因为 Spring AI 需要 Jakarta EE 命名空间)
- Java: 17 或 21
- Dependencies: Spring Web、Spring AI
如果你习惯命令行,也可以:
bash
spring init --dependencies=ai,web my-qwen-app
4.2 Maven 配置:引入弹药库
Spring AI 目前最新稳定版是 1.1.0-M3(2025 年 10 月发布),虽然带 M 字样,但亲测生产环境稳如老狗。在 pom.xml 里加入 BOM 管理:
xml
org.springframework.ai
spring-ai-bom
1.1.0-M3
pom
import
org.springframework.ai
spring-ai-ollama-spring-boot-starter
org.springframework.ai
spring-ai-openai-spring-boot-starter
注意这里我们同时引入了 Ollama 和 OpenAI 的 starter,后者是为了用它的 POJO 类,毕竟接口格式兼容,不用白不用。
4.3 YAML 配置:打通任督二脉
在 application.yml 里写上这几行,Spring AI 就能自动识别你本地的 Ollama:
yaml
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
model: qwen3.5:9b
options:
temperature: 0.7
num-predict: 2048
chat:
client:
enabled: true
这里 temperature 相当于大厨的"创意程度",0.7 是平衡点,想让它更严谨就调低,想更发散就调高。num-predict 是最大生成 token 数,防止话痨。
五、代码实战:5 行代码跑通对话
配置搞定,现在写 Java 代码,简单到离谱。
5.1 极简版:直接注入 ChatClient
java
@RestController
@RequestMapping("/ai")
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@GetMapping("/ask")
public String ask(@RequestParam String question) {
return chatClient.prompt()
.user(question)
.call()
.content();
}
}
就这几行,一个 REST API 就搭好了。启动项目,浏览器访问:
http://localhost:8080/ai/ask?question=用Java写个快速排序,并解释时间复杂度
你会看到 Qwen 3.5 返回的 Markdown 格式代码和详细解释,延迟也就几百毫秒。
5.2 进阶版:带历史记忆的对话
上面那个版本每次对话都是失忆状态,如果你想做上下文连续聊天,得加个记忆功能:
java
@Service
public class ChatService {
private final ChatClient chatClient;
// 用 Map 模拟用户会话缓存,生产环境建议换 Redis
private final Map> sessionStore = new ConcurrentHashMap<>();
public ChatService(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
public String chat(String sessionId, String userInput) {
// 获取或创建历史记录
List history = sessionStore.computeIfAbsent(sessionId, k -> new ArrayList<>());
// 添加用户消息
history.add(new UserMessage(userInput));
// 调用模型
String response = chatClient.prompt()
.messages(history)
.call()
.content();
// 添加 AI 回复到历史
history.add(new AssistantMessage(response));
// 防止上下文过长,保留最近 10 轮
if (history.size() > 20) {
history = history.subList(history.size() - 20, history.size());
sessionStore.put(sessionId, history);
}
return response;
}
}
对应的 Controller:
java
@RestController
@RequestMapping("/chat")
public class ConversationController {
@Autowired
private ChatService chatService;
@PostMapping("/talk")
public String talk(@RequestBody ChatRequest request) {
return chatService.chat(request.getSessionId(), request.getMessage());
}
}
@Data
class ChatRequest {
private String sessionId;
private String message;
}
这样你就可以用 Postman 测试连续对话了,第一轮问"我叫张三",第二轮问"我刚才说了什么",它能准确回答出来。
六、性能调优:让 Qwen 3.5 跑得更欢
本地部署最大的焦虑就是"我的显卡够不够用"。别慌,Ollama 提供了丰富的参数让你做取舍。
6.1 量化模型:显存不够,精度来凑
如果你只有 6GB 显存,跑 9B 模型可能会爆。这时候可以换个量化版本:
bash
ollama pull qwen3.5:9b-q4_K_M
q4_K_M 表示 4-bit 量化,模型体积从 6GB 压缩到 4GB 左右,虽然智商会下降 5%,但速度提升明显,而且省出来的显存可以塞更长的上下文。
6.2 上下文长度:别让 AI 失忆
Qwen 3.5 官方支持 256K 上下文,但默认 Ollama 可能只开 2K。在 Java 代码里可以动态调整:
java
ChatResponse response = chatClient.prompt()
.user(longText)
.options(OllamaOptions.builder()
.withNumCtx(16384) // 开启 16K 上下文
.withTemperature(0.8)
.build())
.call()
.chatResponse();
注意上下文越长,显存占用越高,16K 大概需要多占 2-3GB 显存,自己权衡。
6.3 流式输出:告别转圈圈
大模型生成文字是个逐字蹦的过程,如果你等它全部写完再返回,用户会以为卡死了。改成流式输出(SSE)体验好很多:
java
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux streamAsk(@RequestParam String question) {
return chatClient.prompt()
.user(question)
.stream()
.content();
}
前端配合 EventSource 就能实现打字机效果,跟 ChatGPT 网页版一样丝滑。
七、避坑指南:我踩过的雷你别踩
虽然整套方案已经很成熟,但总有几个小坑会让你 debugging 到半夜。
坑 1:Ollama 默认只能本地访问
如果你在服务器上部署,发现其他机器调不通 11434 端口,那是因为 Ollama 默认绑定 127.0.0.1。需要设置环境变量:
bash
export OLLAMA_HOST=0.0.0.0:11434
Windows 用户在系统环境变量里加就行。
坑 2:中文乱码
如果返回的中文显示为问号,检查 application.yml 加上:
yaml
server:
servlet:
encoding:
charset: UTF-8
enabled: true
force: true
坑 3:内存泄漏
长时间运行后如果 Java 进程内存暴涨,可能是没有正确关闭响应流。确保使用 try-with-resources 或者正确管理 ChatClient 的生命周期。
坑 4:模型下载卡住
ollama pull 时如果进度条不动,大概率是网络问题。可以配置镜像加速,或者在路由器上开启科学上网。
八、写在最后:Java 的 AI 时代真的来了
写到这里,其实挺感慨的。几年前我们还在争论"Java 适合做 AI 吗",现在 Spring AI + Ollama 的组合已经让这件事变得比写个 CRUD 还简单。
Qwen 3.5 在中文场景下的表现确实惊艳,写代码能比肩 GPT-4,写文案甚至更有"人味儿"。最关键的是,这一切都在你本地的机器上运行,数据不用上传到别人的服务器,深夜加班调代码也不用怕按 token 收费收到天价账单。
所以,别再让 Python 成为你的心理阴影了。打开 IDEA,新建一个 Spring Boot 项目,半小时后你就能拥有一个属于自己的 AI 助手。这感觉,就像是在自家后院搭了个五星级厨房,想吃什么,自己说了算。