一、引言:DeepSeek的性价比优势与开源生态
1. 成本对比:DeepSeek的百万tokens成本仅为OpenAI的1/280。
OpenAI的训练成本高昂,与其对算力的极端依赖直接相关。据披露,GPT-4o的训练成本高达1.1亿美元,主要源于其采用的百万级英伟达A100/H100 GPU集群 。这种“堆算力”的模式不仅消耗巨额资金,还受限于英伟达GPU的出口管制政策,进一步推高成本。
相比之下,DeepSeek通过算法架构创新将训练成本压缩至557.6万美元(仅为GPT-4o的5%),其核心突破在于绕开CUDA生态的硬件依赖。
DeepSeek的案例证明,算法突破比硬件堆砌更具颠覆性。当行业还在争论“多少块H100才能训练大模型”时,DeepSeek已通过架构创新让算力需求“瘦身”90%。这种“用算法换算力”的思路,不仅为AI普惠铺平道路,更可能改写全球科技竞争的底层逻辑。
2. 开源优势:低成本+开源使得DeepSeek的全球用户用户爆炸式增长。开源策略使DeepSeek生态繁荣,并且支持本地化部署。DeepSeek-R1模型性能与OpenAI持平,但推理成本更低。
二、Ollama本地部署DeepSeek
Ollama是一款轻量级本地大语言模型运行框架,支持在CPU/GPU设备上离线运行DeepSeek、Llama等开源模型,无需依赖云端服务。
训练好的大模型(LLM),是要有自己的运行环境的,包括NLP(神经网络)和机器学习和Transformers机制。
我们来到ollama官网ollama.com/ ,把ollama下载下来。然后来到ollama官网的Models页面,这里有很多ollama支持本地部署的大模型,我们选择deepseek-r1
这里的1.5b,7b中的“b”表示模型的参数量(Parameter Count),单位是亿(Billion,简写为b),用于衡量模型的规模和复杂度。这里我就以1.5b为例,复制命令ollama run deepseek-r1:1.5b到cmd运行,电脑会自动下载deepseek1.5b版本的源代码。
下载成功是这样的,我们就完成了deepseek的本地部署。
三、后端接入DeepSeek
在后端接入deepseek前需要明白:
- 本地运行的 deepseek,是可以被 ajax 通信的
- 端口为11434
- 接口路径为/api/chat
- 发送post请求
向AI发post请求时要传的参数data要写成下面的样子, 这是openai 制定的行业标准
// 当前 openai 制定的标准,行业标准
const data = {
model: 'deepseek-r1:1.5b', // 模型名称
messages: [
{
role: 'user', // 角色
content:'你好'
}
],
stream: false // 是否流式返回
}
我们先用postman来测试一下朝http://localhost:11434/api/chat 发送post请求会得到什么(得先确保本地部署的deepseek在运行中)
{
"model": "deepseek-r1:1.5b",
"created_at": "2025-02-28T03:54:01.210382Z",
"message": {
"role": "assistant",
"content": "<think>\n\n</think>\n\n你好!很高兴见到你,有什么我可以帮忙的吗?无论是学习、工作还是生活中的问题,都可以告诉我哦!😊"
},
"done_reason": "stop",
"done": true,
"total_duration": 2284946300,
"load_duration": 16541100,
"prompt_eval_count": 4,
"prompt_eval_duration": 1405000000,
"eval_count": 31,
"eval_duration": 860000000
}
以上是朝http://localhost:11434/api/chat 发送post请求得到的结果。可以看到,message.content里面就是AI给我们返回的内容。
我们在后端把AI返回的内容打印出来看看。
const Koa = require('koa');
const app = new Koa();
const axios = require('axios');
const Router = require('koa-router'); // 路由
const router = new Router();
const bodyParser = require('koa-bodyparser'); // 解析请求体
app.use(async (ctx) => { // 中间件
// 获取前端传过来的参数
// 利用 ajax 将内容交给 deepseek 模型 (已经在本地部署了)
// 模型返回结果
// 返回给前端
if (ctx.url === '/') {
const message = '你好'
// 当前 openai 制定的标准,行业标准
const data = {
model: 'deepseek-r1:1.5b', // 模型名称
messages: [
{
role: 'user', // 角色
content: message
}
],
stream: false // 是否流式返回
}
// 跟 deepseek 模型进行通信
const response = await axios.post("http://localhost:11434/api/chat", data)
console.log(response.data.message.content);
ctx.body = {
code: 200,
content: response.data.message.content
}
}
})
app.use(bodyParser())
app.listen(3000, () => {
console.log('server is running at port 3000');
});
在浏览器访问http://localhost:3000/, 可以看到后端打印出来了AI给我们返回的内容。
接下来我们用vue + koa + deepseek(离线调用)来写一个和AI聊天的网页。
在后端定义一个接口,当前端向该接口发请求时,把前端传来的提示语放入data的messages的content中,然后后端用axios向本地的deepseek发送post请求,传入data作为参数,再把后端得到的AI回复返回给前端。以下是后端代码:
const Koa = require('koa');
const app = new Koa();
const axios = require('axios');
const Router = require('koa-router'); // 路由
const router = new Router();
const bodyParser = require('koa-bodyparser'); // 解析请求体
app.use(async(ctx, next) => { // 处理跨域
ctx.set('Access-Control-Allow-Origin', '*'); // 允许所有域名访问我这个后端
ctx.set('Access-Control-Allow-Methods', 'OPTIONS, GET, PUT, POST, DELETE'); // 允许的请求方法
ctx.set('Access-Control-Allow-Headers', 'x-requested-with, accept, origin, content-type'); // 允许的请求头
// 请求预检(http协议规定每一个 http 请求发送前都会自动发送一个预检请求)
if (ctx.method === 'OPTIONS') {
ctx.status = 204
return;
}
await next();
})
app.use(bodyParser())
router.post('/deepseek/chat', async (ctx) => {
console.log(ctx.request.body)
const message = ctx.request.body.content // 前端传过来的消息
const data = {
model: 'deepseek-r1:1.5b', // 模型名称
messages: [
{
role: 'user', // 角色
content: message
}
],
stream: false // 是否流式返回
}
// 跟 deepseek 模型进行通信
await axios.post("http://localhost:11434/api/chat", data).then(response => {
console.log(response.data.message.content);
ctx.body = {
code: 200,
content: response.data.message.content
}
})
})
app.use(router.routes()) // 启动路由
app.listen(3000, () => {
console.log('server is running at port 3000');
});
接下来看前端代码
定义一个响应式数组conversation,里面存储用户与AI的交互内容,数组里有一个个对象,每个对象包含role:user/assistant 和 content:存储具体对话内容,以此来区分哪些话是用户说的,哪些话是AI说的。
const conversation = ref([
{
role: "user",
content: "你好"
},
{
role: "assistant",
content: "您好!我是您的 AI 智能助手。"
}
])
当用户输入内容点击发送按钮时,把用户输入的内容添加到conversation数组中去 然后给后端发请求并把用户输入的内容传给后端,后端返回AI输出的内容给前端,然后再把AI的回复添加到conversation数组中去。在html用v-for中遍历conversation数组就可以将对话展示在页面上了。
const send = async() => {
if(question.value.trim() === ""){
return
}
conversation.value.push({
role: "user",
content: question.value
})
// 发送请求
const msg = {
role: "user",
content: question.value
}
const res = await axios.post('http://localhost:3000/deepseek/chat', msg)
conversation.value.push({
role: "assistant",
content: res.data.content
})
以下是完整的前端代码:
<template>
<div>
<div class="hd">deepseek 智能助手</div>
<div class="bd">
<div class="bot answer">
ai:
<span>您好!我是您的 AI 智能助手。我可以帮助您解答问题、编写代码、进行创作等。请问有什么我可以帮您的吗?</span>
</div>
<div class="chat" v-for="item in conversation">
<div class="user question" v-if="item.role === 'user'">
me:
<span>{{item.content}}</span>
</div>
<div class="bot answer" v-if="item.role === 'assistant'">
ai:
<span v-html="item.content"></span>
</div>
</div>
</div>
<div class="ft">
<div class="input">
<input type="text" placeholder="请输入您的问题" v-model="question">
<button @click="send">发送</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import axios from 'axios'
const conversation = ref([])
const question = ref("")
const send = async() => {
if(question.value.trim() === ""){
return
}
conversation.value.push({
role: "user",
content: question.value
})
// 发送请求
const msg = {
role: "user",
content: question.value
}
const res = await axios.post('http://localhost:3000/deepseek/chat', msg)
conversation.value.push({
role: "assistant",
content: res.data.content
})
}
</script>
<style lang="css" scoped>
.hd{
height: 60px;
background: #FFFFFF;
border-radius: 0px 0px 0px 0px;
border: 1px solid #E5E7EB;
line-height: 60px;
padding: 0 30px;
}
.bd{
height: calc(100vh - 140px);
background: #F9FAFB;
overflow-y: auto;
padding: 30px 20%;
box-sizing: border-box;
}
.bot{
padding: 10px 20px;
background: #F3F4F6;
border-radius: 16px 16px 16px 16px;
margin-bottom: 20px;
}
.user{
padding: 10px 20px;
background: #8E6FF7;
border-radius: 16px 16px 16px 16px;
color: #fff;
margin-bottom: 20px;
}
.ft{
height: 80px;
background: #FFFFFF;
border-radius: 0px 0px 0px 0px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px 0;
box-sizing: border-box;
}
.input{
width: 700px;
height: 100%;
display: flex;
}
.input input{
flex: 1;
padding: 0 20px;
font-size: 16px;
}
.input button{
width: 80px;
margin-left: 20px;
}
</style>
这样就完成了一个简易的AI聊天页面,效果如下: