DeepSeek 是由中国杭州深度求索公司开发的智能 AI 助手,一个基于人工智能技术构建的虚拟助手,旨在通过自然语言处理和机器学习算法来理解并回应用户的问题与请求。它可以提供多种服务,包括但不限于信息检索、数据分析、语言翻译、知识问答以及日常生活的辅助建议等。
其实,早在春节期间就了解和学习过 DeepSeek,因为当时在极短的时间内就引起了国内外的广泛关注,根据官方的说法,它的综合性能可以与 ChatGPT 等熟知的 AI 大模型媲美,甚至在某些方面更加优秀,而且还是开源免费。后来,随着访问的人越来越多,以及可能受国外的某些因素影响,导致网页访问经常出现服务器繁忙,因此大家开始在本地部署 DeepSeek 大模型。所以,当时我也尝试在本地部署过,但是后来因为一些原因搁置了,本来不打算写出来发布的,现在想想既然都做了,不如就分享出来和大家讨论讨论。
准备需要运行 DeepSeek 的虚拟机操作系统,我这边使用基于 Ubuntu 系统,版本 23.10。
虚拟机的内存和硬盘分区配置,如果想运行比较大的 DeepSeek 参数模型,需要配置大一些。
虚拟机的 CPU 配置,由于没有 GPU,所以 DeepSeek 所有的计算过程需要靠纯 CPU 来处理。
DeepSeek 支持多种运行方式,我这里使用到 Ollama,这是一款用于启动和运行大语言模型的开源工具,支持多种操作系统类型安装。其他不多作介绍,这个有点类似于 Docker,DeepSeek 模型就是运行在上面的容器。
如果直接使用上图中的脚本安装,可能会遇到网络问题无法进行,众所周知的原因,所以下面就采用另外一种方式,使用离线安装包手动安装。你可以访问“https://gh.llkk.cc”代理下载安装包,或者使用以下命令直接在服务器上下载。
curl -O https://gh.llkk.cc/https://github.com/ollama/ollama/releases/download/v0.5.8/ollama-linux-amd64.tgz
下载或上传安装包到服务器后,使用 tar
命令将安装包解压到 /usr
目录,然后运行 ollama serve
启动 Ollama。默认情况下,Ollama 服务侦听端口为 11434,如果需要从外部访问服务,则需要从防火墙放开该端口。
sudo tar -C /usr -xzf ollama-linux-amd64.tgz
重新打开一个终端窗口,使用 ollama -v
命令验证 Ollama 版本。运行以下命令,为 Ollama 创建用户和组,创建自启动服务文件,最后启动 Ollama 服务。
sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama
sudo usermod -a -G ollama $(whoami)
vim /etc/systemd/system/ollama.service//添加以下内容:
[Unit]
Description=Ollama Service
After=network-online.target[Service]
ExecStart=/usr/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=$PATH"[Install]
WantedBy=default.targetsudo systemctl daemon-reload
sudo systemctl enable ollama
sudo systemctl start ollama
sudo systemctl status ollama
安装 Ollama 工具后,使用 ollama -h
可以查看命令帮助。
访问 Ollama 模型仓库,找到并点击 DeepSeek-R1 模型,这里列出有关 DeepSeek-R1 所有模型的介绍以及使用方法。最低是 1.5b 参数模型,最高是 671b 参数模型,b 是 billion,表示 10 亿,1.5b 就代表 15 亿参数模型。越低代表参数越少,所需资源就越少,智能程度相对也就越低,越高代表参数越多,所需资源就越多,智能程度相对也就越高。
直接运行以下命令,默认是下载 DeepSeek-R1 7b 模型,Ollama 会将模型拉取到本地仓库,然后直接运行该模型。在消息对话框中,我向它打个招呼,然后问问它叫什么,它会给出简单的回答。
ollama run deepseek-r1
在消息对话框中,运行 /?或 /help
可以查看帮助,运行 /set
命令可以对模型设置一些参数,运行 """
可以输入多行进行提问。
运行 /show info
命令查看当前模型的详细信息。
可以安装使用 htop
工具了解系统的负载情况,DeepSeek-R1 7b 模型加载所消耗的系统内存为 6G 左右。
实际上,7b 参数的 DeepSeek-R1 模型根本不能用。根据官方的说法,DeeSeek-R1 模型在综合性能上(数学、代码和推理等方面)可以和 OpenAI-o1 相媲美,DeeSeek-R1 32b 参数模型优于 OpenAI-o1-mini,所以下面看看运行 32b 参数模型的效果。
可能大家通过 Ollama 运行 AI 模型,在下载模型的时候,会遇到开始下载速度比较快,但是过一会儿后,下载速度却变得越来越慢,你必须使用 Ctrl + C 强制停止,然后再重新运行命令,速度才会升起来,如下图所示。
对于此问题,我让 DeepSeek 写了一个自动化脚本,只需要在脚本中定义你要拉取的模型名字,当运行脚本后,它会自动检测下载的速度,一旦低于设置的阈值(比如 10 MB/s),则会停止下载并重新执行任务。
#!/bin/bash# 定义需要拉取的模型
IMAGE="your-model-name"# 拉取的命令
COMMAND="ollama pull $IMAGE"# 设定最低速度阈值 (10MB/s),单位 KB/s
THRESHOLD=10240# 执行拉取并获取初始时间
start_time=$(date +%s)# 执行拉取命令
$COMMAND &# 记录拉取任务的进程ID
PULL_PID=$!# 等待 1 分钟(60 秒),确保有足够的时间进行初始下载
echo "等待 1 分钟开始判断下载速度..."
sleep 60# 记录开始时间后,监控下载速度
while true; do# 从命令输出文件 pull_output.log 中获取下载速度信息speed=$(grep -oP '\d+\sKB/s|\d+\sMB/s' pull_output.log | tail -n 1)# 如果没有获取到速度信息,跳过if [ -z "$speed" ]; thenecho "无法获取下载速度,等待下次检查..."sleep 60continuefi# 打印获取到的速度信息(调试)echo "检测到下载速度:$speed"# 提取速度的数值和单位speed_value=$(echo $speed | awk '{print $1}')speed_unit=$(echo $speed | awk '{print $2}')# 将单位转换为统一的单位 KB/sif [[ "$speed_unit" == "MB/s" ]]; thenspeed_value=$(echo "$speed_value * 1024" | bc)fi# 打印转换后的速度(调试)echo "转换后的下载速度:$speed_value KB/s"# 如果速度低于设定的阈值,重新执行任务if (( speed_value < THRESHOLD )); thenecho "下载速度低于阈值(${speed_value}KB/s),正在重新拉取任务..."# 终止当前拉取任务kill $PULL_PID# 重新开始拉取$COMMAND &# 获取新的进程IDPULL_PID=$!# 重新开始计时start_time=$(date +%s)fi# 休眠 1 分钟(60 秒),然后继续监控sleep 60
done
将以上脚本内容粘贴到脚本文件内(比如 auto_pull_model.sh),赋予执行权限并运行脚本,最终的执行效果如下所示。
root@deepseek:~# vim auto_pull_model.sh
root@deepseek:~# chmod +x auto_pull_model.sh
root@deepseek:~# ./auto_pull_model.sh
等待 1 分钟开始判断下载速度...
pulling manifest
pulling 6340dc3229b0... 6% ▕███ ▏ 303 MB/4.9 GB 5.3 MB/s 14m33s
pulling manifest
pulling 6340dc3229b0... 6% ▕███ ▏ 303 MB/4.9 GB 5.3 MB/s 14m33s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 16% ▕█████████ ▏ 764 MB/4.9 GB 5.2 MB/s 13m20s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 25% ▕███████████████ ▏ 1.3 GB/4.9 GB 6.1 MB/s 10m0s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 33% ▕███████████████████ ▏ 1.6 GB/4.9 GB 5.2 MB/s 10m27s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 43% ▕██████████████████████████ ▏ 2.1 GB/4.9 GB 6.4 MB/s 7m15s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 57% ▕██████████████████████████████████ ▏ 2.8 GB/4.9 GB 5.1 MB/s 6m53s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 70% ▕█████████████████████████████████████████ ▏ 3.4 GB/4.9 GB 4.1 MB/s 6m6s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 77% ▕██████████████████████████████████████████████ ▏ 3.8 GB/4.9 GB 2.9 MB/s 6m19s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 84% ▕██████████████████████████████████████████████████ ▏ 4.1 GB/4.9 GB 1.1 MB/s 11m49s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 89% ▕█████████████████████████████████████████████████████ ▏ 4.4 GB/4.9 GB 802 KB/s 11m13s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 94% ▕████████████████████████████████████████████████████████ ▏ 4.6 GB/4.9 GB 933 KB/s 5m29s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 99% ▕███████████████████████████████████████████████████████████ ▏ 4.9 GB/4.9 GB 1.0 MB/s 1m3s
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
pulling manifest
pulling 6340dc3229b0... 100% ▕████████████████████████████████████████████████████████████▏ 4.9 GB
pulling 369ca498f347... 100% ▕████████████████████████████████████████████████████████████▏ 387 B
pulling 6e4c38e1172f... 100% ▕████████████████████████████████████████████████████████████▏ 1.1 KB
pulling f4d24e9138dd... 100% ▕████████████████████████████████████████████████████████████▏ 148 B
pulling 0cb05c6e4e02... 100% ▕████████████████████████████████████████████████████████████▏ 487 B
verifying sha256 digest
writing manifest
success
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
./auto_pull_model.sh: line 57: kill: (136726) - No such process
pulling manifest
pulling 6340dc3229b0... 100% ▕████████████████████████████████████████████████████████████▏ 4.9 GB
pulling 369ca498f347... 100% ▕████████████████████████████████████████████████████████████▏ 387 B
pulling 6e4c38e1172f... 100% ▕████████████████████████████████████████████████████████████▏ 1.1 KB
pulling f4d24e9138dd... 100% ▕████████████████████████████████████████████████████████████▏ 148 B
pulling 0cb05c6e4e02... 100% ▕████████████████████████████████████████████████████████████▏ 487 B
verifying sha256 digest
writing manifest
success
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
./auto_pull_model.sh: line 57: kill: (136748) - No such process
pulling manifest
pulling 6340dc3229b0... 100% ▕████████████████████████████████████████████████████████████▏ 4.9 GB
pulling 369ca498f347... 100% ▕████████████████████████████████████████████████████████████▏ 387 B
pulling 6e4c38e1172f... 100% ▕████████████████████████████████████████████████████████████▏ 1.1 KB
pulling f4d24e9138dd... 100% ▕████████████████████████████████████████████████████████████▏ 148 B
pulling 0cb05c6e4e02... 100% ▕████████████████████████████████████████████████████████████▏ 487 B
verifying sha256 digest
writing manifest
success
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
./auto_pull_model.sh: line 57: kill: (136769) - No such process
pulling manifest
pulling 6340dc3229b0... 100% ▕████████████████████████████████████████████████████████████▏ 4.9 GB
pulling 369ca498f347... 100% ▕████████████████████████████████████████████████████████████▏ 387 B
pulling 6e4c38e1172f... 100% ▕████████████████████████████████████████████████████████████▏ 1.1 KB
pulling f4d24e9138dd... 100% ▕████████████████████████████████████████████████████████████▏ 148 B
pulling 0cb05c6e4e02... 100% ▕████████████████████████████████████████████████████████████▏ 487 B
verifying sha256 digest
writing manifest
success
检测到下载速度:242 KB/s
转换后的下载速度:242 KB/s
下载速度低于阈值(242KB/s),正在重新拉取任务...
./auto_pull_model.sh: line 57: kill: (136792) - No such process
pulling manifest
pulling 6340dc3229b0... 100% ▕████████████████████████████████████████████████████████████▏ 4.9 GB
pulling 369ca498f347... 100% ▕████████████████████████████████████████████████████████████▏ 387 B
pulling 6e4c38e1172f... 100% ▕████████████████████████████████████████████████████████████▏ 1.1 KB
pulling f4d24e9138dd... 100% ▕████████████████████████████████████████████████████████████▏ 148 B
pulling 0cb05c6e4e02... 100% ▕████████████████████████████████████████████████████████████▏ 487 B
verifying sha256 digest
writing manifest
success ^C
root@deepseek:~#
使用 ollama list
列出本地仓库中所有的模型,确保已成功下载,使用以下命令运行 DeepSeek-R1 32b 模型,添加 --verbose
参数可以在每次回答后都显示详细处理信息,比如了解生成 token 的速度,当然也可以在对话框中开启该参数。
ollama run deepseek-r1:32b --verbose
运行 32b 参数模型后,使用 htop 工具查看模型所占用的系统资源情况。
向它打个招呼并让它介绍一下自己,根据回复可以发现这个模型的思考过程更加全面,差不多每秒 3 个 token。
当我发送问题给它时,它会先进行深度思考,这个计算过程会将系统的 CPU 全部拉慢,然后思考完回复时,CPU 会降到 80% 左右。
我让它描写一篇春天的文章,要求字数500,含有花、草、树木、小动物。
以下是它的回复:
春天,是一年中最富有生机与希望的季节。当最后一丝寒意退去,大地仿佛被按下了一键启动,开始了一场生命的大狂欢。
清晨,阳光温柔地洒在大地上,万物都笼罩在这金色的薄纱中。远处的山坡上,迎春花已经迫不及待地绽放了,金黄的小花朵像一个个小铃铛,在微风中轻轻摇晃,仿佛在欢快地歌唱。不远处的桃树也开了,粉嫩的花瓣像是少女的脸颊,羞涩而温柔。樱花不甘示弱,纷纷扬扬地洒落着粉色的花雨,空气中弥漫着淡淡的花香。
草地上,嫩绿的小草顽强地从土里钻出来,为大地铺上了一层崭新的地毯。蒲公英的种子随风飘散,在阳光下像一群tiny的伞兵,轻盈地起舞。偶尔有几只小兔子从草丛中窜出,它们的耳朵竖得笔直,警惕地四处张望,随后又蹦蹦跳跳地钻进了另一片草丛。
树木也不甘寂寞,纷纷抽出了新芽。柳树最先换上了嫩绿的新装,柔软的枝条在春风中轻轻摇曳,像是在向路人招手。梧桐树也不甘落后,在枝头挂满了淡紫色的花序,远远望去,仿佛是一串串精致的风铃。
小动物们也纷纷出动了。蜜蜂忙着在花间采蜜,翅膀发出“嗡嗡”的声音,不时停在花朵上,沾满花粉的身体显得格外忙碌。蝴蝶也不甘寂寞,在花丛中翩翩起舞,红的、黄的、蓝的,像是给春天增添了一道流动的彩虹。
鸟儿们更是活跃。麻雀在枝头跳跃,叽叽喳喳地唱着欢快的歌谣;燕子从南方飞回,在空中划出优美的弧线,不时俯冲下来啄食昆虫;画眉鸟也不甘示弱,在树林中梳理羽毛,准备迎接春天的到来。
春天不仅是一个季节,更是一种心情。它带来了希望、生机与活力,让我们感受到了大自然的鬼斧神工和生命的奇妙。走在这样的春日里,仿佛每一处风景都在向我们诉说着生命的故事,让人忍不住停下脚步,静静地感受这份美好。
我让它用 Python 写一个简单的贪吃蛇游戏。
以下是它的回复(我没有验证,欢迎有朋友验证后告诉我正确性):
以下是一个用 Python 编写的简单贪吃蛇小游戏的代码示例。我们将使用 `pygame` 库来实现这个游戏。### 代码:
```python
import pygame
import random
import time# 初始化 Pygame
pygame.init()# 设置窗口大小
width = 800
height = 600
window = pygame.display.set_mode((width, height))
pygame.display.set_caption("贪吃蛇游戏")# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)# 蛇的大小和速度
snake_block = 20
snake_speed = 15# 初始化字体
font = pygame.font.SysFont(None, 50)def our_snake(snake_block, snake_list):for x in snake_list:pygame.draw.rect(window, GREEN, [x[0], x[1], snake_block, snake_block])def message(msg, color):mesg = font.render(msg, True, color)window.blit(mesg, [width/6, height/3])def gameLoop():game_over = Falsegame_close = Falsex1 = width / 2y1 = height / 2x1_change = 0y1_change = 0snake_List = []Length_of_snake = 1foodx = round(random.randrange(0, width - snake_block) / snake_block) * snake_blockfoody = round(random.randrange(0, height - snake_block) / snake_block) * snake_blockclock = pygame.time.Clock()while not game_over:while game_close:window.fill(BLACK)message("你输了!按 Q 退出或 C 重新开始", RED)pygame.display.update()for event in pygame.event.get():if event.type == pygame.KEYDOWN:if event.key == pygame.K_q:game_over = Truegame_close = Falseif event.key == pygame.K_c:gameLoop()for event in pygame.event.get():if event.type == pygame.QUIT:game_over = Trueif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:x1_change = -snake_blocky1_change = 0elif event.key == pygame.K_RIGHT:x1_change = snake_blocky1_change = 0elif event.key == pygame.K_UP:y1_change = -snake_blockx1_change = 0elif event.key == pygame.K_DOWN:y1_change = snake_blockx1_change = 0if x1 >= width or x1 < 0 or y1 >= height or y1 < 0:game_close = Truex1 += x1_changey1 += y1_changewindow.fill(BLACK)pygame.draw.rect(window, RED, [foodx, foody, snake_block, snake_block])snake_Head = []snake_Head.append(x1)snake_Head.append(y1)snake_List.append(snake_Head)if len(snake_List) > Length_of_snake:del snake_List[0]for x in snake_List[:-1]:if x == snake_Head:game_close = Trueour_snake(snake_block, snake_List)pygame.display.update()if x1 == foodx and y1 == foody:foodx = round(random.randrange(0, width - snake_block) / snake_block) * snake_blockfoody = round(random.randrange(0, height - snake_block) / snake_block) * snake_blockLength_of_snake += 1clock.tick(snake_speed)pygame.quit()quit()# 运行游戏循环
gameLoop()
```### 说明:
1. **初始化**:首先导入所需的库并初始化 Pygame。
2. **窗口设置**:设置游戏窗口的大小和标题。
3. **颜色定义**:定义游戏中的几种基本颜色(黑色、白色、红色、绿色)。
4. **蛇的属性**:定义蛇的大小和移动速度。
5. **绘制函数**:- `our_snake`:用于在屏幕上绘制蛇的身体。- `message`:用于显示游戏消息。
6. **游戏循环**:- 处理游戏结束和重新开始的情况。- 获取键盘输入,控制蛇的方向。- 检测边界碰撞。- 更新蛇的位置并重新绘制屏幕。- 检测蛇是否吃到食物,并增加长度。
7. **运行游戏**:调用 `gameLoop` 函数开始游戏。### 如何运行:
1. 确保你已经安装了 Pygame 库。如果没有安装,可以使用以下命令进行安装:```bashpip install pygame```
2. 将上述代码保存为一个 Python 文件(例如:`snake_game.py`)。
3. 在终端中运行该文件:```bashpython snake_game.py```### 控制方式:
- 使用方向键控制蛇的移动。
- 按下 `Q` 键退出游戏。
- 按下 `C` 键重新开始游戏。希望你喜欢这个简单的贪吃蛇小游戏!如果需要调整速度或增加难度,可以修改 `snake_speed` 的值。
然后,我又转变话题,问它有关《三体》的问题。从这里回答来看,效果不尽人意......,可能它比较适合数学或代码类问题,像知识类则需要更大的参数量或者联网才行。
运行 ollama ps
命令可以查看正在运行的 AI 模型,能够看到该模型完全由 CPU 进行计算处理。
默认情况下,使用 Ollama 运行模型,模型加载生成响应后只会在内存中保留 5 分钟,然后就会释放掉,这样的话如果重新发起提问,就会再次等待模型加载,如果希望保持长时间的加载,可以添加 --keepalive
参数。
事实上,32b 参数量也就勉强够用,要想使用更聪明的 DeepSeek,你需要运行完整版的 DeepSeek-R1 671b 参数模型。