前言

为什么要进行本地部署大模型?

本地部署 DeepSeek 主要是为了保障数据隐私安全、实现低延迟离线运行、降低长期使用成本、满足行业合规要求以及支持深度定制化开发。

一、下载及安装

  • 访问Ollama进行下载
    image
  • 系统选择(这里我们以Windows为例)
    image
  • 下载安装
    如果我们下载好默认安装的话会直接安装到D盘,我们直接cmd打开命令窗口输入。
    D:\>OllamaSetup.exe /DIR=D:\Ollama
    这样我们就会安装到指定的D盘Ollama的目录下了。
    安装以后我打开命令窗口输入 ollama -v查看版本信息如果存在即安装成功,我们顺手再输入ollama list查看模型信息发现为空
    image

二、配置环境变量

设置OLLAMA_HOST的作用是为了允许局域网内其他设备访问本地Ollama服务
image
如果我们对下载模型地址没要求,直接下载模型即可,如果要配置首先我们Quit Ollama,退出Ollama然后去环境变量中配置模型下载地址如下新建OLLAMA_MODELS这个环境变量
image

三、模型下载

因为各个模型对硬件要求不一致,所以我简单列出了各个模型的区别

模型版本 参数数量 文件大小 适用场景 优点 缺点 CPU要求 内存要求 显卡(英伟达40/50系列)
1.5B 1.5B 1.1GB 资源有限的环境 文件较小,易于下载和部署 性能较低,适用于较简单的任务 4核及以上 8GB+ RTX 4060 8GB(可选,纯CPU也可运行)
7B 7B 4.7GB 需要较高性能的任务 平衡了性能和文件大小,适用范围广泛 相比小模型,仍需要较强的硬件支持 8核及以上 16GB+ RTX 4060 Ti 16GB 或 RTX 4070 12GB
8B 8B 4.9GB 中等性能需求的任务 性能好,适合大部分NLP任务 文件大小较大,部署时需要较大存储空间 8核及以上 16GB+ RTX 4070 Ti 12GB 或 RTX 4080 16GB
14B 14B 9.0GB 高性能应用,复杂任务 适用于复杂推理和大规模任务 需要较强的计算资源和存储支持 12核及以上 32GB+ RTX 4080 16GB 或 RTX 5070Ti 16GB
32B 32B 20GB 大规模高负载任务 高度优化,能够处理复杂任务 对硬件要求极高,计算资源消耗大 16核及以上 64GB+ RTX 4090 24GB(需INT4量化)
70B 70B 43GB 超高性能任务,科研应用 极高的计算能力和性能,适用于尖端研究 对硬件和存储要求非常苛刻,下载和运行困难 24核及以上 128GB+ 2×RTX 4090 24GB(SLI)或 RTX 5090
671B 671B 404GB 超大规模高复杂度任务 性能最强,适用于最复杂的应用和任务 极高的硬件需求,几乎只适用于大型数据中心 64核及以上 512GB+ 4×RTX 4090 24GB(集群)

就拿我的设备为例:显卡5070Ti 16GB CPU i7-14700KF(14核20线程) 64GB 最好的就是14B的模型。
然后我们去官网去准备下载
image
image
image
到下面这个页面我们就可以获取相对应下载模型的指令
image
下载好以后输入ollama list,r如果如下就显示安装成功
image
如果我们之前有配置地址那么模型下载的地址就在我们配置的环境变量的地址里面,否则就在C盘的文件中。

四、下载设置可视化聊天

访问Chatbox官网https://chatboxai.app/zh
image
下载好打开后我们这里设置之前我们设置的本地访问的路径
image
这里我们对模型设置要求
image

五、Java代码调用本地模型

首先我们先保证ollama是开启的,打开cmd,输入ollama serve,如果显示如下则成功,失败则再重新检查。
image
紧接着我们要开始配置模型和路径地址,模型我们可以在cmd输入我们的ollama list查看所有可用的模型,然后加上我们之前设置的本地访问路径
image
最后将完整代码附上,如下

package com.example.demo.chat;

import com.alibaba.fastjson.JSONObject;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import org.apache.hc.core5.http.HttpHeaders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ChatDemo {
    private static final Logger log = LoggerFactory.getLogger(ChatDemo.class);
    // Ollama本地聊天API地址(固定)
    private static final String OLLAMA_CHAT_ENDPOINT = "http://localhost:11434/api/chat";
    // 本地部署的DeepSeek模型名称(需与ollama list显示一致)
    private static final String DEEPSEEK_MODEL = "deepseek-r1:14b";

    /**
     * 调用本地DeepSeek模型进行对话
     * @param body 传入符合Ollama格式的JSON字符串,例如:
     *             {"messages":[{"role":"user","content":"你的问题"}]}
     * @return 模型生成的响应文本
     */
    public String chat(String body) {
        String result = null;
        try {
            // 1. 发送POST请求(移除Authorization头,使用本地Ollama地址)
            HttpResponse response = HttpRequest.post(OLLAMA_CHAT_ENDPOINT)
                    .header(HttpHeaders.CONTENT_TYPE, "application/json")
                    .body(appendModelToBody(body))
                    .timeout(60000)
                    .execute();

            // 2. 处理响应结果
            result = response.body();
            log.debug("Ollama API返回原始数据:{}", result);

            if (!response.isOk()) {
                log.error("本地模型调用失败,状态码:{},响应:{}", response.getStatus(), result);
                return null;
            }

            // 3. 解析Ollama响应,提取message.content字段
            JSONObject jsonResult = JSONObject.parseObject(result);
            if (jsonResult.getBooleanValue("done")) {
                return jsonResult.getJSONObject("message").getString("content");
            } else {
                log.error("模型生成未完成,响应:{}", result);
                return null;
            }
        } catch (Exception e) {
            log.error("调用本地DeepSeek模型发生异常", e);
            // 常见错误提示
            if (e.getMessage().contains("Connection refused")) {
                log.error("解决方案:请先启动Ollama服务(命令:ollama serve)并检查11434端口是否占用");
            } else if (result != null && result.contains("model not found")) {
                log.error("解决方案:请执行命令下载模型:ollama pull deepseek-r1:14b");
            }
            return null;
        }
    }

    private String appendModelToBody(String body) {
        JSONObject jsonBody = JSONObject.parseObject(body);
        if (!jsonBody.containsKey("model")) {
            jsonBody.put("model", DEEPSEEK_MODEL);
        }
        // 确保关闭流式响应
        if (!jsonBody.containsKey("stream")) {
            jsonBody.put("stream", false);
        }
        return jsonBody.toString();
    }

    // 测试方法
    public static void main(String[] args) {
        ChatDemo client = new ChatDemo();
        // 构造符合要求的请求体
        String requestBody = "{\"messages\":[{\"role\":\"user\",\"content\":\"用Java写一个冒泡排序算法\"}]}";
        String response = client.chat(requestBody);
        System.out.println("本地DeepSeek模型响应:\n" + response);
    }
}

好啦以上就是本期的全部内容