ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

银河麒麟V10离线部署DeepSeek-R1:Ollama模型搬运与systemd实践

银河麒麟V10离线部署DeepSeek-R1:Ollama模型搬运与systemd实践 简介面向需要在国产操作系统上离线部署大模型的技术人员以银河麒麟V10ARM64、飞腾FT-2000平台为示例提供了一套完整的DeepSeek-R1:14B部署手册。文档从环境准备讲起逐步演示ollama 0.5.7的安装、将模型服务注册为systemd系统服务、配置OLLAMA_MODELS与OLLAMA_HOST等环境变量以及离线下载模型后通过gguf文件导入模型的关键方法。同时也涵盖AI客户端chatbox的安装、桌面快捷方式创建和连接配置并补充了远程访问DeepSeek服务的思路。压缩包共1个docx文档大小2.69MB内容以命令、配置文件和路径示例为主明确标注了排查要点。已有5513人学习适合在无外网或受限网络环境中参照落地能显著减少摸索时间。1. 在银河麒麟V10 上离线部署 DeepSeek-R1先解决模型搬运问题在没有互联网的 arm64 机器上跑 DeepSeek-R1很多人上来就砸在同一个地方Ollama 装好了却拿不到模型。银河麒麟V10 SP1 使用的 Phytium FT-2000 是 ARMv8 架构主机没有显卡模型推理只能靠 CPU 和大内存。DeepSeek-R1 14B 的 Ollama 蒸馏版拉下来大约 9GB内网机器没法执行 ollama pull所以关键不是安装 Ollama而是把模型文件搬运进去并重建。这篇分享记录的是完整离线链路/opt/deepseek/ollama 下的 Ollama 0.5.7 服务、通过 Modelfile 导入的 deepseek-r1:14b 模型、以及作为图形入口的 Chatbox arm64 AppImage。命令可以直接照抄也可以把其中的 systemd 和 Modelfile 思路迁移到其他大模型部署场景。适合没有外网、只有局域网的大模型私有化部署也适合飞腾、鲲鹏这类 arm64 机器。2. 先装运行时Ollama 二进制解压与 systemd 服务化2.1 为什么选 Ollama 0.5.7 而不是裸跑 llama.cpp在无显卡的 arm64 机器上推理大模型有两条路一条是直接用 llama.cpp 编译对应可执行文件再手工写脚本处理分词、采样、上下文另一条是交给 Ollama它会帮你管好 GGUF 加载、上下文窗口和 HTTP API。我更倾向于 Ollama因为它的二进制是官方预编译的arm64 版本可以直接解压运行而且 systemd 留了环境变量入口方便把模型目录、监听地址和采样参数声明式地放进服务配置里。版本选择 0.5.7 是出于稳定性考虑这个版本在 arm64 的 Debian 系发行版上表现比较稳。不要为了新功能随意升大版本Ollama 的 Modelfile 格式和 API 偶尔会调整在隔离网络里升级一次的成本很高。下载时直接拿 ollama-linux-arm64.tgz不要依赖系统包管理器采用手工解压路径完全可控。2.2 把 arm64 二进制放到 /opt/deepseek/ollama创建目录并解压建议把路径固定为 /opt/deepseek/ollama这样后续的 systemd 单元、环境变量和备份脚本都不用改。执行# 创建服务目录并解压官方 arm64 压缩包 mkdir -p /opt/deepseek/ollama tar -C /opt/deepseek/ollama -xzf ollama-linux-arm64.tgztar的-C参数先切换工作目录再解包解压后能看到bin/ollama和lib/两个部分bin目录里的ollama是唯一需要关注的程序。如果解压时报Cannot open: No such file or directory先确认 tgz 文件名是否被浏览器改名以及当前用户对 /opt/deepseek 是否有写权限。2.3 创建最小权限用户并配置环境变量文件我建议用独立系统用户跑 Ollama而不是直接塞进 root。创建命令# 创建无法登录的 ollama 系统用户 sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama sudo usermod -a -G ollama $(whoami)-r表示创建系统用户-s /bin/false禁止登录-U同时创建同名用户组-m -d指定并创建家目录。把当前用户加进 ollama 组是为了后面执行ollama list、ollama create时能读写模型目录如果省略后续所有命令都要靠 sudo 兜底排错会很别扭。然后写环境变量文件 /opt/deepseek/ollama/ollama.conf内容如下# 模型文件存放位置独立目录方便后续挂盘扩容 OLLAMA_MODELS/opt/deepseek/ollama/models # 监听所有网卡开启局域网访问入口 OLLAMA_HOST0.0.0.0 # 浏览器跨域来源调试阶段保持宽松 OLLAMA_ORIGINS* PATH$OLLAMA_HOME/bin:$PATH注意原配置里OLLAMA_HOME也写了它的作用是给 ollama 自身定位运行资源。OLLAMA_MODELS单独指向 /opt/deepseek/ollama/models避免模型和二进制混在同一层以后扩容时直接把 models 目录挂到独立磁盘。OLLAMA_HOST0.0.0.0让 ollama serve 监听所有网卡这是远程访问的基础如果只在本机用可以改成127.0.0.1。OLLAMA_ORIGINS*是给浏览器端跨域请求用的Chatbox 桌面客户端走 HTTP API 不依赖它保留通配符能减少调试时被 CORS 拦截的概率。2.4 写系统服务单元ExecStart 与 EnvironmentFile用 systemd 管理 Ollama比 nohup 手动启动可靠得多。创建 /etc/systemd/system/ollama.service填入[Unit] DescriptionOllama Service Afternetwork-online.target [Service] ExecStart/opt/deepseek/ollama/bin/ollama serve Userollama Groupollama Restartalways RestartSec3 EnvironmentFile/opt/deepseek/ollama/ollama.conf [Install] WantedBydefault.targetExecStart必须写绝对路径不要写ollama因为 systemd 不继承用户 shell 的 PATH。User/Group指定为 ollama保证进程以最小权限运行。Restartalways配合RestartSec3进程崩溃后 3 秒拉起这对模型加载阶段内存陡增、偶发 OOM 的场景尤其重要。EnvironmentFile引用的就是上一步写的 ollama.confservice 进程启动前会把它解析成环境变量传给 ollama serve。2.5 启动、自启与状态检查接下来按顺序执行权限修正和启动命令# 把整个服务目录交给 ollama 用户 sudo chown -R ollama:ollama /opt/deepseek/ollama sudo systemctl daemon-reload sudo systemctl enable ollama sudo systemctl start ollama sudo systemctl status ollamachown 必须先做否则 ollama 用户对 /opt/deepseek/ollama 没有写权限服务起来后无法创建 models 目录日志里会一直报mkdir permission denied。daemon-reload 通知 systemd 重读新增的 unit 文件enable 建立开机自启软链start 立即拉起服务status 确认当前状态是active (running)。下面这张表是后续排错最常用的命令组合命令作用关键输出systemctl status ollama查看服务运行状态active (running) / failedjournalctl -u ollama -f实时跟踪服务日志GIN-debug 路由 /api/tagsollama list列出已导入的模型NAME、SIZE、MODIFIEDollama ps查看当前内存中的模型模型名、进程、时长看到 status 输出里有[GIN-debug]路由列表说明 API 已经起来下一步可以导入模型。3. 离线模型获取从联网机器把 14B 权重搬进内网3.1 问题的本质blob 文件才是模型本体Ollama 的模型并不是一个单一的 .gguf 文件放在固定路径而是由 Modelfile 定义、模型权重和参数模板共同组成的。执行ollama pull deepseek-r1:14b后真正的大文件会存到models/blobs/目录下文件名是sha256-xxxx这样的哈希值。这就是为什么很多人复制了整个~/.ollama目录到内网机器结果ollama list里看不到模型——漏掉了 Modelfile 索引或者 models 目录权限不对。正确的离线导入思路是只导出模型定义和模型层两样东西。模型定义即 Modelfile里面写清楚了FROM指向哪个权重文件、带哪些默认参数模型层就是FROM后面的 blob 文件把它复制出来重命名成 deepseek-r1-14b.gguf拿到内网后用ollama create重新组装。整个搬运体积约 9GB比整盘克隆小得多也方便用 U 盘或内网文件服务器中转。3.2 第一步在联网且同架构的机器上拉取模型准备工作是找一台能上网、架构同为 arm64 的 Linux 机器装好相同版本的 Ollama。虽然 GGUF 权重本身和 CPU 架构无关但 Ollama 运行时会按平台做校验跨架构复制后 create 阶段容易出问题所以不建议拿 x86 机器拉模型再搬到飞腾上。联网机器上依次执行# 拉取 DeepSeek-R1 14B 蒸馏模型 ollama pull deepseek-r1:14b # 导出模型定义后续会用到 FROM 行 ollama show --modelfile deepseek-r1:14b modelfile.txt head -n 10 modelfile.txtpull 子命令会从 Ollama Registry 下载模型耗时取决于带宽14B 的量化模型下载量约 9GB。如果长时间停在pulling manifest没有进度优先检查网络和 DNS而不是反复重试。show --modelfile会把模型定义导出到 modelfile.txthead 查看前 10 行重点看第 5 行附近有没有FROM字段。3.3 第二步从 blob 目录复制出 .gguf 文件拿到 modelfile.txt 后打开看 FROM 行的路径典型内容是这样FROM /root/.ollama/models/blobs/sha256-6e9f90f02bb3b39b59e81916e8cfce9deb45aeaeb9a54a5be4414486b907dc1e TEMPLATE {{- if .System }}... PARAMETER num_ctx 4096这里FROM指向的 sha256 文件就是模型权重层。可以直接手工复制也可以用命令提取# 从 FROM 行提取 blob 文件路径并复制为 .gguf MODEL_PATH$(grep -E ^FROM modelfile.txt | awk {print $2}) cp $MODEL_PATH deepseek-r1-14b.gguf ls -lh deepseek-r1-14b.ggufgrep 用行首的FROM做匹配awk 取第二个字段得到完整路径。复制完成后别急着走ls -lh确认文件大小约 9GB如果只有几十 KB说明 grep 匹配到的是其他 FROM 行或者 blob 路径不对。这个文件就是要拷贝进内网的核心资产传输可以用 U 盘或 scp拷完要校验 sha256避免复制过程中损坏。3.4 第三步在离线机器上重建模型把 deepseek-r1-14b.gguf 和 modelfile.txt 传到银河麒麟机器的 /opt/deepseek/ollama/ 下先修改 modelfile.txt 里的 FROM 行让路径指向本地文件# 把 FROM 修改为本地 GGUF 路径 sed -i s#^FROM .*#FROM /opt/deepseek/ollama/deepseek-r1-14b.gguf# modelfile.txt ollama create deepseek-r1:14b -f modelfile.txtsed 的-i直接改原文件用#代替/作为分隔符避免路径冲突。ollama create会根据新的FROM找到 GGUF计算哈希并注册到本地模型仓库。正常情况下输出会先显示gathering model components然后按 sha256 复制文件最后writing manifest提示 success。完成后运行ollama list能看到deepseek-r1:14b和大约 9GB 的大小。3.5 导入失败的三个高发点第一是 FROM 路径权限问题。离线机器上 ollama 服务由 ollama 用户运行模型文件不能放在普通用户家目录否则ollama create读到一半报 permission denied。放到 /opt/deepseek/ollama/ 下后执行一次sudo chown -R ollama:ollama /opt/deepseek/ollama。第二是 Modelfile 里混入了 Windows 换行符。如果 modelfile.txt 在 Windows 下改过运行时会出现unexpected token或unknown field错误用sed -i s/\r$// modelfile.txt清掉回车。第三是磁盘空间不足。14B 模型导入时本地需要一个完整副本加上原始 GGUF峰值占用接近 18GB。导入前用df -h /opt/deepseek确认剩余空间否则复制 blob 到一半就失败之后还要手动清理 models/manifests 里的残留记录。3.6 顺带验证Modelfile 里能改什么Modelfile 不只是用来导入它还是可直接编辑的模型配置入口。比如想让 DeepSeek-R1 的回答更收敛可以在文件末尾追加PARAMETER temperature 0.6再执行ollama create覆盖同名模型。Ollama 的 create 支持增量更新每次重新导入只会重建发生变化的 layer速度比首次导入快很多。Modelfile 字段作用常见值FROM指定模型权重文件路径本地 .gguf 或 registry 模型名TEMPLATE对话模板决定输入输出格式chatml、llama3 等PARAMETER采样和上下文参数num_ctx 4096、temperature 0.74. 客户端落地Chatbox AppImage 与桌面快捷方式4.1 为什么客户端选 Chatbox有 Ollama API 之后客户端的选择很多Open WebUI 要跑 DockerNode 版本还得处理 npm 依赖在离线系统上都不省心。Chatbox 的好处是官方直接提供 arm64 AppImage双击就能跑和本地 Ollama 之间走 HTTP API不用装运行时。它本质上是一个 Electron 应用配置好 API 地址和模型名就能把 DeepSeek-R1 当聊天窗口用支持多轮会话和上下文管理。对只想要一个聊天界面的人来说它是成本最低的方案。4.2 准备 AppImage 与图标将下载的 Chatbox arm64 AppImage 放到 /opt/deepseek/ 目录下# 复制 AppImage 并赋予执行权限 sudo cp Chatbox-1.9.8-arm64.AppImage /opt/deepseek/ sudo chmod x /opt/deepseek/Chatbox-1.9.8-arm64.AppImagechmod x之后才能执行。AppImage 对权限敏感如果发现双击无反应检查挂载选项是否带 noexecU 盘里的 AppImage 经常因此启动失败拷到 /opt/deepseek 后通常不会有这个问题。4.3 处理 zlib1g-dev 缺失在 Kylin-Desktop-V10 上双击 AppImage最常见的错误是缺少 zlib 库。原版系统镜像里 libz.so.1 有时不被 AppImage runtime 识别表现为双击后没有窗口终端运行时报error while loading shared libraries: libz.so.1。此时需要安装系统自带的 zlib1g-dev arm64 包# 安装麒麟源里的 zlib1g-dev arm64 包 sudo dpkg -i zlib1g-dev_1%3a1.2.11.dfsg-2kylin1.5k0.2_arm64.deb这个包的版本号里带%3a是 URL 编码的冒号在麒麟软件源里常见。如果系统已经预置该包dpkg 会提示 overwrite 或 already installed直接忽略即可。安装完再重新执行 AppImage通常就能正常弹出主窗口。4.4 编写桌面快捷方式并赋可执行权限为了不在终端里启动我一般会在桌面放一个 .desktop 文件。编辑 Chatbox.desktop[Desktop Entry] Version1.0 NameChatbox CommentDeepSeek R1 Client Exec/opt/deepseek/Chatbox-1.9.8-arm64.AppImage Icon/opt/deepseek/Chatbox.png Terminalfalse TypeApplication CategoriesUtility;Application;Exec必须是绝对路径最好用双引号包住含空格的文件名Icon指向桌面图标文件可以是 PNG。保存后在文件管理器中执行chmod x Chatbox.desktop否则系统会因为没有执行权限而拒绝用 Application 模式打开。之后双击桌面图标即可启动 Chatbox。4.5 在 Chatbox 里配置 Ollama API打开 Chatbox 设置选择 Ollama API 作为模型提供商API 域名填http://127.0.0.1:11434模型选择deepseek-r1:14b。如果下拉列表是空的说明 Ollama 服务没起来先回去看 service 状态。配置项如下配置项值说明模型提供商Ollama API走本地 HTTP 接口API 域名http://127.0.0.1:11434本机部署默认地址模型名deepseek-r1:14b和 ollama list 输出一致API Key留空本地服务不需要鉴权配置完成后发送第一条消息如果报Failed to fetch多半是 Ollama 没有监听 127.0.0.1或者 OLLAMA_HOST 被改成了别的。另外第一次发送消息时Ollama 需要把 14B 模型加载进内存在 FT-2000 上可能等待 1030 秒不要以为卡死。5. 服务稳定化开机自启与局域网访问配置5.1 两个服务的分工之前启动的 ollama.service 只负责 API 服务DeepSeek 模型本身不会开机自动加载。首次访问时模型才从磁盘加载响应慢是正常的。为了固定体验可以再做一个 deepseek.service让模型在开机后主动常驻。注意这个服务和 ollama.service 的差异ollama 服务负责网络入口deepseek 服务负责模型生命周期。创建 /etc/systemd/system/deepseek.service[Unit] DescriptionDeepSeek R1 Service Afterollama.service Requiresollama.service [Service] ExecStart/opt/deepseek/ollama/bin/ollama run deepseek-r1:14b ExecStop/opt/deepseek/ollama/bin/ollama stop deepseek-r1:14b Userollama Groupollama Restartalways RestartSec3 EnvironmentFile/opt/deepseek/ollama/ollama.conf [Install] WantedBydefault.targetAfterollama.service表示必须等 Ollama API 起来后再拉起模型Requires则保证 ollama 服务挂掉时 deepseek 也会被停掉避免模型进程先于 API 存在。ExecStart用ollama run让模型加载进内存ExecStop明确执行ollama stop释放权重。配置完成后# 加载新的服务单元并启用开机自启 sudo systemctl daemon-reload sudo systemctl enable deepseek sudo systemctl start deepseek ollama psollama ps能看到deepseek-r1:14b在列表里说明模型已经常驻。如果没有出现用journalctl -u deepseek -f看日志重点排查 FROM 路径和用户权限。5.2 不想常驻可以用 OLLAMA_KEEP_ALIVE其实不是每个场景都需要模型常驻。如果内存紧张可以不创建 deepseek.service而是在 ollama.conf 中追加OLLAMA_KEEP_ALIVE30m让模型在最近一次请求后保留 30 分钟再卸载。这个参数比常驻更节省内存适合多人共用同一台内网机器的场景。常驻方案适合个人或少数人测试响应快但 14B 模型会一直占着内存。5.3 局域网远程访问和防火墙配置由于 ollama.conf 里已经设置了OLLAMA_HOST0.0.0.0局域网内其他机器可以直接访问。在远程主机上装 Chatbox 或其他客户端把 API 域名从127.0.0.1改成服务端 IP例如http://192.168.1.20:11434即可调用 DeepSeek。验证命令# 查看远程 Ollama 已加载的模型列表 curl http://192.168.1.20:11434/api/tags curl http://192.168.1.20:11434/api/version执行后应返回 JSON 列表比如 models 数组里包含deepseek-r1:14b。如果 curl 超时检查服务端防火墙。银河麒麟V10 默认不一定开了 firewalld可以用sudo systemctl status firewalld确认如果开启执行# 放行 Ollama 默认端口 11434/tcp sudo firewall-cmd --permanent --add-port11434/tcp sudo firewall-cmd --reload11434 是 Ollama 默认端口和 HTTP API 一致。如果只允许内网访问可以在 firewalld 的 rich rule 里限定来源网段而不是直接把端口暴露给所有来源。5.4 远程客户端应该注意的 Cross-Origin 配置如果远程客户端是浏览器页面OLLAMA_ORIGINS*能避免大部分跨域拦截桌面 Chatbox 不关心这个头但如果同一台机器上还跑了 Web 前端建议把OLLAMA_ORIGINS配置成具体域名而不是*减少被其他页面利用的风险。这一步没有标准答案按内网安全策略收紧。6. 验证部署效果四条命令确认模型能服务6.1 看进程与模型状态服务和模型是否存活执行ollama ps即可会列出当前加载的模型名称和大小。如果列表为空先确认 deepseek.service 有没有启动成功。这个命令比ollama list更有价值因为它反映的是模型是否真正驻留在内存中。6.2 用 curl 做一次推理冒烟测试# 向本地 Ollama API 发送一次不流式生成请求 curl http://127.0.0.1:11434/api/generate -d { model: deepseek-r1:14b, prompt: 你好请用一句话介绍你自己, stream: false }返回结果里包含response字段就说明整条链路正常。注意第一次请求会在内部等待模型加载耗时可能超过 10 秒连续测两次后才具备参考价值。Chatbox 底层走的是/api/chat接口格式略有不同但同样通过这个端口。6.3 通过日志定位常见配置错误当 Chatbox 报错但 curl 正常时问题通常在客户端配置比如 API 域名写成了 https、端口写错、模型名带了空格。当 curl 也失败时按顺序看三处日志systemctl status ollama、journalctl -u ollama -n 50、journalctl -u deepseek -n 50。日志中出现exec format error说明拷贝的 ollama 二进制架构不对出现permission denied说明 /opt/deepseek/ollama 属主有问题出现address already in use说明已经有一个 ollama 进程在跑停掉旧的再启动 systemd 服务。6.4 调整上下文和采样参数的实用技巧如果发现模型回答开始重复多半是上下文或生成参数不合适。可以临时用环境变量OLLAMA_NUM_PARALLEL1限制并发或修改 Modelfile 中的num_ctx重新加载模型后生效。比如把num_ctx从 4096 提到 8192 会让模型记住更长的对话但内存占用也会增加在 16GB 内存的 FT-2000 机器上建议不要开太高。Chatbox 的模型设置里可以直接修改 temperature和 Modelfile 里的PARAMETER效果相同且不需要重启服务。把OLLAMA_KEEP_ALIVE调到 2h再观察内存曲线能找到一个内外网都更稳的平衡点。本文还有配套的精品资源点击获取
返回列表