网站首页 > java教程 正文
Ollama 是一个用于在本地运行大型语言模型(LLM)的工具,它简化了模型的下载、部署和使用流程,支持多种开源模型,包括 DeepSeek、Llama 3 等。通过 Ollama,你可以在本地设备上快速启动并与 LLM 交互,无需依赖云端服务。
本地部署 DeepSeek 的步骤
1. 安装 Ollama
首先需要安装 Ollama,支持 Windows、macOS 和 Linux 系统。以下是不同系统的安装方法:
macOS/Linux(使用 Homebrew):
brew install ollama |
Linux/Windows(手动安装):
curl https://ollama.ai/install.sh | sh |
Windows(使用 PowerShell):
iwr https://ollama.ai/install.ps1 -useb | iex |
2. 下载 DeepSeek 模型
安装完成后,使用以下命令下载 DeepSeek 模型:
ollama pull deepseek:7b-chat |
你也可以下载其他版本的 DeepSeek 模型,例如更大参数的版本:
ollama pull deepseek:67b-chat |
3. 启动 DeepSeek 模型
下载完成后,通过以下命令启动模型并进入交互界面:
ollama run deepseek:7b-chat |
4. 通过 API 使用 DeepSeek
Ollama 提供了 HTTP API,你可以通过编程方式与模型交互。以下是一个使用 Python 发送请求的示例:
import requests import json # 发送请求到Ollama API response = requests.post( "http://localhost:11434/api/generate", json={ "model": "deepseek:7b-chat", "prompt": "请介绍一下人工智能的发展历程", "stream": False } ) # 处理响应 if response.status_code == 200: print(json.loads(response.text)["response"]) else: print(f"Error: {response.status_code}, {response.text}") |
进阶配置
如果你需要自定义模型参数,可以创建一个配置文件(例如deepseek-config.yaml):
base: deepseek:7b-chat parameters: temperature: 0.7 top_p: 0.9 max_tokens: 2048 |
然后使用以下命令基于配置文件创建自定义模型:
ollama create my-deepseek -f deepseek-config.yaml |
启动自定义模型:
ollama run my-deepseek |
通过以上步骤,你可以在本地环境中部署并使用 DeepSeek 模型,享受高效的本地 AI 体验。
在本地部署了deepseek后,就可以使用java代码来调用deepseek的接口发送请求获得响应数据了
以下是一个使用 Java 调用 DeepSeek 模型的完整示例,基于 Ollama 的 HTTP API 实现:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; /** * DeepSeek模型Java客户端,通过Ollama API进行交互 */ public class DeepSeekClient { private static final String API_URL = "http://localhost:11434/api/generate"; private final String modelName; private final ExecutorService executorService; public DeepSeekClient(String modelName) { this.modelName = modelName; this.executorService = Executors.newSingleThreadExecutor(); } /** * 同步调用DeepSeek模型 * @param prompt 输入提示 * @return 模型生成的响应 * @throws IOException 网络异常 */ public String generate(String prompt) throws IOException { return generate(prompt, 0.7, 0.9, 2048); } /** * 同步调用DeepSeek模型,支持自定义参数 * @param prompt 输入提示 * @param temperature 温度参数,控制随机性 * @param topP 核采样参数 * @param maxTokens 最大生成token数 * @return 模型生成的响应 * @throws IOException 网络异常 */ public String generate(String prompt, double temperature, double topP, int maxTokens) throws IOException { URL url = new URL(API_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); connection.setDoOutput(true); // 构建请求JSON String requestBody = String.format(""" { "model": "%s", "prompt": "%s", "temperature": %.2f, "top_p": %.2f, "max_tokens": %d, "stream": false } """, modelName, escapeJson(prompt), temperature, topP, maxTokens); try (OutputStream os = connection.getOutputStream()) { byte[] input = requestBody.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { try (BufferedReader br = new BufferedReader( new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } return parseResponse(response.toString()); } } else { try (BufferedReader br = new BufferedReader( new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } throw new IOException("HTTP error code: " + responseCode + ", Response: " + response); } } } /** * 异步调用DeepSeek模型(流式响应) * @param prompt 输入提示 * @param responseConsumer 响应处理器 * @return CompletableFuture用于异步处理 */ public CompletableFuture<Void> generateStream(String prompt, Consumer<String> responseConsumer) { return CompletableFuture.runAsync(() -> { try { URL url = new URL(API_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); connection.setDoOutput(true); // 构建流式请求JSON String requestBody = String.format(""" { "model": "%s", "prompt": "%s", "stream": true } """, modelName, escapeJson(prompt)); try (OutputStream os = connection.getOutputStream()) { byte[] input = requestBody.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { try (BufferedReader br = new BufferedReader( new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) { String responseLine; while ((responseLine = br.readLine()) != null) { if (!responseLine.isEmpty()) { String content = parseStreamResponse(responseLine); if (content != null && !content.isEmpty()) { responseConsumer.accept(content); } } } } } else { try (BufferedReader br = new BufferedReader( new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } throw new IOException("HTTP error code: " + responseCode + ", Response: " + response); } } } catch (Exception e) { throw new RuntimeException("Error generating stream", e); } }, executorService); } /** * 关闭客户端资源 */ public void close() { if (executorService != null && !executorService.isShutdown()) { executorService.shutdown(); } } private String parseResponse(String jsonResponse) { int startIndex = jsonResponse.indexOf("\"response\":\""); if (startIndex == -1) return ""; startIndex += "\"response\":\"".length(); int endIndex = jsonResponse.indexOf("\"", startIndex); return jsonResponse.substring(startIndex, endIndex).replace("\\\"", "\""); } private String parseStreamResponse(String jsonLine) { int startIndex = jsonLine.indexOf("\"response\":\""); if (startIndex == -1) return null; startIndex += "\"response\":\"".length(); int endIndex = jsonLine.indexOf("\"", startIndex); if (endIndex == -1) return null; return jsonLine.substring(startIndex, endIndex).replace("\\\"", "\""); } private String escapeJson(String input) { if (input == null) return ""; return input.replace("\\", "\\\\") .replace("\"", "\\\"") .replace("\b", "\\b") .replace("\f", "\\f") .replace("\n", "\\n") .replace("\r", "\\r") .replace("\t", "\\t"); } public static void main(String[] args) { try (DeepSeekClient client = new DeepSeekClient("deepseek:7b-chat")) { // 同步调用示例 String response = client.generate("请简要介绍Java的多线程机制"); System.out.println("DeepSeek同步响应: " + response); // 异步流式调用示例 System.out.println("\nDeepSeek异步流式响应:"); client.generateStream("列举5个Java集合框架中的常用类", chunk -> System.out.print(chunk)) .exceptionally(ex -> { System.err.println("Error: " + ex.getMessage()); return null; }) .join(); } catch (Exception e) { e.printStackTrace(); } } } |
这个 Java 客户端具有以下特点:
- 完整功能支持:
- 同步和异步调用模式支持参数自定义(temperature、top_p、max_tokens 等)支持流式响应处理
- 健壮性设计:
- 完善的异常处理机制资源自动关闭(实现 AutoCloseable 接口)JSON 转义处理
- 易用性:
- 简单的 API 接口示例代码包含同步和异步调用演示
使用说明:
- 确保 Ollama 服务已启动并加载 DeepSeek 模型:
ollama run deepseek:7b-chat |
- 直接运行 main 方法测试客户端功能
- 可根据需要调整参数,如:
// 使用更高的temperature增加创造性 client.generate("写一首关于春天的诗", 1.0, 0.8, 1024); |
- 对于生产环境,建议:
- 添加连接池管理增加更完善的重试机制添加日志记录考虑使用更专业的 JSON 处理库
这个实现完全基于 Java 标准库,无需额外依赖,方便集成到各种 Java 项目中。
- 上一篇: Java 对象和类
- 下一篇: 译文:理解Java中的弱引用
猜你喜欢
- 2025-05-15 Java学习123——虚拟方法调用(Virtual Method Invocation)
- 2025-05-15 什么是JNI?为什么会有Native层?如何使用?
- 2025-05-15 Socket通信
- 2025-05-15 译文:理解Java中的弱引用
- 2025-05-15 Java 对象和类
- 2025-05-15 java中的强引用、软引用、弱引用和虚引用
你 发表评论:
欢迎- 05-15java使用iText解析PDF文件
- 05-15java 将pdf 形成的图片,每页一张图片 保存为pdf文件
- 05-15Java学习123——虚拟方法调用(Virtual Method Invocation)
- 05-15什么是JNI?为什么会有Native层?如何使用?
- 05-15Socket通信
- 05-15译文:理解Java中的弱引用
- 05-15Java 调用 DeepSeek 模型的完整示例及特点
- 05-15Java 对象和类
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)