简介:这份文档面向需要在银河麒麟V10(Kylin-Desktop-V10-SP1,ARM64架构)上离线部署大语言模型的技术人员,解决无外网或受限网络环境下搭建AI服务的问题。内容围绕ollama服务安装、deepseek-r1:14b蒸馏模型的离线下载与导入、系统服务与环境变量配置,以及chatbox客户端安装、桌面快捷方式创建和远程连接方式展开,适合具备一定Linux命令行基础、希望掌握国产操作系统AI部署流程的读者。资源包共1个docx文件,约2.69MB,以图文步骤形式记录完整操作路径与关键配置项。目前已有5531人学习下载。读者可据此获得从模型拉取、gguf文件重命名导入到服务开机自启的完整排错思路,并学会将模型配置为系统服务、通过chatbox实现本地交互,同时了解远程访问本地模型的参数设置,便于在飞腾FT-2000等无显卡设备上稳定运行。
1. 银河麒麟V10离线部署deepseek:一台没显卡的ARM机器怎么把大模型跑起来
手里有一台银河麒麟V10的ARM机器,CPU是飞腾FT-2000,没显卡,网络还出不去——这种场景下想跑个本地大模型,很多人第一反应是"不可能"。但实际拆下来,ollama加deepseek-r1蒸馏模型加chatbox这套组合,在纯CPU的ARM环境里是能跑通的,14b的蒸馏版大概9GB,内存够就能推理,速度不快但能用。这份部署指南解决的就是"离线+ARM+无显卡"三个约束同时存在时的落地问题,适合在信创环境里做AI能力预研的工程师,也适合手头只有国产化整机、想先跑通再谈优化的开发者。整条链路分四段:装ollama、配系统服务、离线导入模型、装chatbox客户端,每一步都有具体的路径和参数,照着走能复现。
2. 装ollama并配成systemd服务:路径、用户和三个环境变量
ollama是整个链路的底座,它负责加载GGUF模型文件、暴露HTTP API、管理模型生命周期。在ARM的麒麟V10上装ollama不能用apt,官方也没提供麒麟的包,正确做法是下载arm64的tgz压缩包手动解压。这一步的关键不是解压本身,而是解压之后的三件事:建独立用户、写systemd单元、配环境变量文件。这三件事决定了ollama能不能开机自启、模型文件放哪、能不能被远程访问。
2.1 解压与目录规划
先把压缩包放到一个统一的工作目录下,示例里用的是/opt/deepseek,这个目录后面还要放chatbox和模型,所以提前规划好能省很多事。解压命令用tar -C直接指定目标目录,避免先cd再解压的来回切换。
# 进入工作目录,压缩包已经放在这里 cd /opt/deepseek # 创建ollama的安装目录 mkdir ollama # 解压到指定目录,-C 指定解压目标,-xzf 对应 tgz 格式 tar -C /opt/deepseek/ollama -xzf ollama-linux-arm64.tgz # 确认解压结果,bin目录下应该有ollama可执行文件 ls /opt/deepseek/ollama/bin/解压完成后/opt/deepseek/ollama/bin/ollama就是主程序。这里有个容易忽略的点:tgz包里除了bin还有lib目录,里面是ollama依赖的动态库,所以后续配环境变量时PATH要指向bin,但整个ollama目录都不能随便挪,挪了lib路径就断了。
2.2 创建专用用户与权限归属
ollama官方推荐用独立的系统用户跑服务,不用root也不用当前登录用户。这样做的好处是服务进程权限收敛,模型文件归属清晰,后续chown一次就行。
# 创建ollama系统用户,-r表示系统用户,-s /bin/false禁止登录 # -U创建同名用户组,-m创建家目录,-d指定家目录位置 sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama # 把当前用户加入ollama组,方便后续操作模型文件 sudo usermod -a -G ollama $(whoami) # 把整个ollama目录的属主改成ollama用户 sudo chown -R ollama:ollama /opt/deepseek/ollama-s /bin/false这个参数很关键,它让ollama用户不能登录shell,纯做服务账户用。usermod -a -G把当前用户加进组,是为了后面不用sudo也能读模型目录,但改完组之后当前终端要重新登录才生效,这个坑后面避坑章节会细说。
2.3 写systemd单元与环境变量文件
systemd单元负责拉起ollama进程,环境变量文件负责告诉ollama模型放哪、监听哪个地址。两者分开写的好处是改配置不用动单元文件,systemctl daemon-reload之后重启服务就行。
# 创建systemd服务单元 sudo vim /etc/systemd/system/ollama.service单元文件内容如下:
[Unit] Description=Ollama Service After=network-online.target [Service] ExecStart=/opt/deepseek/ollama/bin/ollama serve User=ollama Group=ollama Restart=always RestartSec=3 EnvironmentFile=/opt/deepseek/ollama/ollama.conf [Install] WantedBy=default.targetExecStart指向解压出来的ollama二进制,User和Group指定用ollama账户跑,Restart=always保证进程挂了自动拉起,EnvironmentFile把环境变量从单独文件读进来。接着写环境变量文件:
sudo vim /opt/deepseek/ollama/ollama.confOLLAMA_HOME=/opt/deepseek/ollama OLLAMA_MODELS="/opt/deepseek/ollama/models" OLLAMA_HOST="0.0.0.0" OLLAMA_ORIGINS="*" PATH=$OLLAMA_HOME/bin:$PATH四个变量的作用分别是:OLLAMA_HOME定安装根目录,OLLAMA_MODELS定模型文件存放路径,OLLAMA_HOST设成0.0.0.0表示监听所有网卡,OLLAMA_ORIGINS设成*允许跨域请求。后两个是给远程访问用的,如果只在本机用,OLLAMA_HOST可以改成127.0.0.1更安全。PATH那行是为了让服务进程内部调用ollama子命令时能找到二进制。
2.4 启动服务并验证状态
配置写完,按顺序执行重载、开机自启、启动、查状态四步。
# 重载systemd配置,让新单元生效 sudo systemctl daemon-reload # 设置开机自启 sudo systemctl enable ollama # 立即启动服务 sudo systemctl start ollama # 查看运行状态 sudo systemctl status ollama状态输出里看到Active: active (running)就说明服务起来了,日志里会打印[GIN-debug]开头的路由注册信息,那是ollama内置的HTTP框架在注册API端点。如果状态是failed,用journalctl -u ollama -n 50看最近50行日志,常见原因是路径写错或权限不对。
最后把ollama的bin目录加进系统PATH,这样终端里直接敲ollama就能用:
sudo vim /etc/profile # 追加一行 export PATH=/opt/deepseek/ollama/bin:$PATH # 让配置生效 source /etc/profile注意source /etc/profile要在当前终端执行,新开的终端会自动读。到这一步ollama服务就跑起来了,但还没有模型,下一步解决离线导入。
3. 离线导入deepseek-r1模型:从联网机器拉取到GGUF重命名
离线环境最大的障碍是模型文件拿不到。ollama的pull命令需要联网,麒麟机器出不去,所以要在另一台同架构(arm64)的联网机器上先把模型拉下来,再想办法把模型文件抠出来拷过去。这里的关键是理解ollama的模型存储结构——它不是存一个单独的gguf文件,而是存一堆按sha256命名的blob,外加一个manifest。要离线迁移,得先用ollama show --modelfile把模型定义导出来,找到FROM指向的那个blob,重命名成gguf再导入。
3.1 在联网机器上拉取模型
找一台同样是arm64架构、能联网的机器,装上ollama,然后拉取deepseek-r1的14b蒸馏版。
# 联网机器上执行,拉取14b蒸馏模型 ollama pull deepseek-r1:14b # 确认模型已下载 ollama listdeepseek-r1:14b是蒸馏版本,体积约9GB,相比完整版对内存和算力要求低很多,适合纯CPU推理。拉取完成后模型存在~/.ollama/models下,但直接拷这个目录到离线机器不一定能用,因为manifest里的路径和blob命名是绑定的,更稳妥的方式是导出modelfile再重建。
3.2 导出modelfile并定位GGUF文件
这一步是整个离线迁移的核心。ollama show --modelfile会把模型的完整定义打印出来,其中FROM那一行指向的就是实际的模型权重文件。
# 查看模型的modelfile定义 ollama show --modelfile deepseek-r1:14b输出内容里找到FROM开头的那一行,它后面跟的是一个路径,通常指向~/.ollama/models/blobs/sha256-xxxx这样的文件。把这个路径记下来,然后把整个输出内容复制保存成modelfile.txt。接着把FROM指向的那个blob文件复制出来,重命名为deepseek-r1-14b.gguf。
# 假设FROM指向的blob路径是 /root/.ollama/models/blobs/sha256-6e9f90f02bb3... # 复制并重命名 cp /root/.ollama/models/blobs/sha256-6e9f90f02bb3b39b59e81916e8cfce9deb45aeaeb9a54a5be4414486b907dc1e \ /tmp/deepseek-r1-14b.gguf # 确认文件大小,14b模型约9GB ls -lh /tmp/deepseek-r1-14b.gguf同时要修改modelfile.txt里的FROM行,把原来的blob路径改成新的gguf文件名,这样在离线机器上导入时才能找到文件。改完后把modelfile.txt和deepseek-r1-14b.gguf一起拷到离线机器,比如放到/opt/deepseek/下。
3.3 在离线机器上导入模型
离线机器上ollama服务已经在跑,现在用ollama create从modelfile导入模型。
# 进入存放modelfile和gguf的目录 cd /opt/deepseek # 从modelfile创建模型,-f指定modelfile路径 ollama create deepseek-r1:14b -f modelfile.txt导入过程会输出一系列copying file、parsing GGUF、creating new layer的日志,最后出现success就表示导入完成。这里的逻辑是ollama读取modelfile里的FROM指向的gguf文件,解析GGUF格式,然后按自己的blob结构重新组织存储到OLLAMA_MODELS指定的目录下。导入完成后验证:
# 列出已导入的模型 ollama list # 运行模型进入交互 ollama run deepseek-r1:14bollama list应该能看到deepseek-r1:14b,大小约9GB。ollama run进入交互后出现>>>提示符就说明模型加载成功,可以输入问题测试。纯CPU推理首token延迟会比较明显,14b模型在飞腾FT-2000上大概几秒到十几秒出第一个字,后面逐字输出,属于正常范围。
3.4 配置模型开机自启
ollama服务本身开机自启了,但模型不会自动加载,需要再写一个systemd单元来拉起模型。
sudo vim /etc/systemd/system/deepseek.service[Unit] Description=deepseek Service After=ollama.service [Service] ExecStart=/opt/deepseek/ollama/bin/ollama run deepseek-r1:14b ExecStop=/opt/deepseek/ollama/bin/ollama stop deepseek-r1:14b User=ollama Group=ollama Restart=always RestartSec=3 EnvironmentFile=/opt/deepseek/ollama/ollama.conf [Install] WantedBy=default.targetAfter=ollama.service保证ollama先起来再拉模型,ExecStop在服务停止时卸载模型释放内存。启用:
sudo systemctl daemon-reload sudo systemctl enable deepseek注意这个单元只enable不start,因为模型常驻内存会占资源,按需启动更合理。如果希望开机就加载,加一个sudo systemctl start deepseek即可。
4. 装chatbox客户端并配桌面图标:AppImage在麒麟上的落地
模型跑起来了,但命令行交互对普通用户不友好,chatbox作为图形客户端能直接对接ollama的API。麒麟V10是ARM64架构,chatbox官方提供了arm64的AppImage包,AppImage的好处是免安装、单文件、双击即用,但在麒麟上直接双击可能会因为缺依赖或没执行权限而失败,需要补几个步骤。
4.1 AppImage的放置与执行权限
把下载的AppImage放到/opt/deepseek下,然后赋予执行权限。
# 进入工作目录 cd /opt/deepseek # 赋予执行权限 chmod +x Chatbox-1.9.8-arm64.AppImage # 先命令行试运行,确认能起来 ./Chatbox-1.9.8-arm64.AppImage命令行运行能看到chatbox窗口弹出就说明AppImage本身没问题。如果报错提示缺库,最常见的是缺zlib1g-dev,麒麟的源里如果有就直接sudo apt install zlib1g-dev,离线环境则用dpkg装对应的deb包:
sudo dpkg -i zlib1g-dev_1%3a1.2.11.dfsg-2kylin1.5k0.2_arm64.deb装完依赖再运行AppImage,一般就能正常启动。
4.2 制作桌面图标
AppImage每次都要进目录敲命令太麻烦,做一个.desktop文件放到桌面,双击就能开。
# 在桌面创建desktop文件 sudo vim ~/Desktop/Chatbox.desktop[Desktop Entry] Version=1.0 Name=Chatbox Comment=AI Chat Client Exec=/opt/deepseek/Chatbox-1.9.8-arm64.AppImage Icon=/opt/deepseek/Chatbox.png Terminal=false Type=Application Categories=Utility;Application;Exec指向AppImage的绝对路径,Icon指向提前准备好的png图标,Terminal=false表示不弹终端窗口。保存后赋执行权限:
chmod +x ~/Desktop/Chatbox.desktop双击图标就能打开chatbox。如果图标显示为空白或双击无反应,检查Exec路径是否写对、AppImage是否有执行权限、Icon文件是否存在。
4.3 配置chatbox对接ollama
打开chatbox后进设置,模型提供方选OLLAMA API,API域名填http://127.0.0.1:11434,模型选deepseek-r1:14b。11434是ollama的默认端口,如果之前改过OLLAMA_HOST的端口,这里要对应改。配置保存后新建对话,输入问题就能看到模型回复。
远程连接的情况,比如在另一台网络互通的机器上装chatbox,API域名填ollama所在机器的IP加端口,比如http://192.168.1.100:11434。前提是ollama的OLLAMA_HOST设成了0.0.0.0,且防火墙放行了11434端口。OLLAMA_ORIGINS="*"也是为远程跨域准备的,如果只本机用可以收紧成具体域名。
5. 避坑与排查:离线部署里最容易翻车的五个点
这套流程走下来,大部分问题集中在权限、路径、依赖和网络配置上。下面五条是实际部署里出现频率最高的,每条按现象、原因、解决三段说。
5.1 ollama服务启动失败,日志报permission denied
现象:systemctl status ollama显示failed,journalctl里看到permission denied打开某个文件或目录。
原因:ollama目录的属主没改成ollama用户,或者OLLAMA_MODELS指向的目录ollama用户没有写权限。systemd以ollama身份跑服务,但目录还是root的,自然写不进去。
解决:sudo chown -R ollama:ollama /opt/deepseek/ollama,确认OLLAMA_MODELS指向的目录也在chown范围内。如果模型目录单独放在别处,也要一并chown。
5.2 导入模型时报file not found
现象:ollama create执行到一半报找不到文件,或者parsing GGUF阶段失败。
原因:modelfile.txt里的FROM行还指向原来的blob路径,没改成重命名后的gguf文件名;或者gguf文件不在当前工作目录下,ollama按相对路径找不到。
解决:打开modelfile.txt确认FROM那行写的是deepseek-r1-14b.gguf而不是一长串sha256路径,且gguf文件和modelfile在同一目录,执行ollama create时也在这个目录下。
5.3 chatbox连不上ollama,提示connection refused
现象:chatbox配置好API域名后发消息报连接失败。
原因:三种可能——ollama服务没跑、OLLAMA_HOST没设成0.0.0.0导致只监听本地、防火墙挡了11434端口。
解决:先systemctl status ollama确认服务在跑,再ss -tlnp | grep 11434看监听地址是不是0.0.0.0:11434,如果是127.0.0.1:11434就改ollama.conf里的OLLAMA_HOST然后重启服务。远程访问还要确认防火墙放行。
5.4 当前用户加组后不生效
现象:usermod -a -G ollama $(whoami)执行了,但当前终端还是读不了模型目录。
原因:Linux的组权限在登录时确定,改完组之后当前会话不会自动刷新,要重新登录或开新终端才生效。
解决:退出当前终端重新登录,或者用newgrp ollama临时切换组。最省事的办法是直接开一个新终端窗口。
5.5 AppImage双击无反应或报缺库
现象:桌面图标双击没反应,或者命令行运行报error while loading shared libraries。
原因:麒麟V10的ARM环境里缺AppImage运行需要的依赖库,最常见的是zlib相关。
解决:命令行运行AppImage看具体报错,缺什么装什么。zlib1g-dev用dpkg离线装,其他库同理。装完依赖再试,确认AppImage有执行权限。
6. 进阶技巧:用ollama API做批量推理和远程调用
命令行交互和chatbox适合日常对话,但如果要把模型能力接进自己的脚本或系统,直接调ollama的HTTP API更灵活。ollama暴露了/api/generate和/api/chat两个主要端点,前者单轮生成,后者多轮对话。下面这段Python脚本演示怎么批量跑问题列表,把结果存成文件,适合做批量测试或数据标注。
import requests import json # ollama服务的地址,本机就是127.0.0.1,远程换成对应IP OLLAMA_URL = "http://127.0.0.1:11434/api/generate" # 待处理的问题列表 questions = [ "用一句话解释什么是操作系统", "ARM架构和x86架构的主要区别是什么", "什么是GGUF格式", ] results = [] for q in questions: payload = { "model": "deepseek-r1:14b", # 模型名要和ollama list里一致 "prompt": q, "stream": False, # False表示等生成完一次性返回 "options": { "temperature": 0.7, # 控制随机性,0到1之间 "num_predict": 256, # 最多生成256个token } } # 超时设长一点,纯CPU推理首token慢 resp = requests.post(OLLAMA_URL, json=payload, timeout=300) data = resp.json() results.append({ "question": q, "answer": data.get("response", ""), "eval_count": data.get("eval_count", 0), # 生成的token数 }) print(f"完成: {q[:20]}...") # 结果写文件 with open("/opt/deepseek/batch_results.json", "w", encoding="utf-8") as f: json.dump(results, f, ensure_ascii=False, indent=2) print(f"共处理 {len(results)} 条")这段脚本的关键参数有三个:stream设False适合批量场景,不用处理流式分块;temperature控制输出随机性,做事实性问答可以调到0.2左右更稳定;num_predict限制最大生成长度,防止单条卡太久。timeout要设大,纯CPU上14b模型生成256个token可能要一两分钟,设小了会超时。
远程调用时把OLLAMA_URL换成ollama所在机器的IP,前提是OLLAMA_HOST已经设成0.0.0.0且防火墙放行。如果脚本跑在另一台机器上,还要确认网络互通。批量跑的时候建议加个间隔或控制并发,ollama默认单请求串行处理,同时发太多会排队。
验证API是否通,可以先用curl快速测一下:
# 测ollama是否响应 curl http://127.0.0.1:11434/api/tags # 测生成接口 curl http://127.0.0.1:11434/api/generate -d '{ "model": "deepseek-r1:14b", "prompt": "你好", "stream": false }'/api/tags返回模型列表,能看到deepseek-r1:14b就说明服务正常。/api/generate返回JSON里response字段就是模型输出。这两个接口通了,后面接什么系统都好办。
从那以后我每次在离线环境部署模型,都先把ollama.conf里的OLLAMA_MODELS和OLLAMA_HOST确认一遍再启动服务,这两个参数错了后面全是白忙。模型导入前也一定先ollama show --modelfile把FROM路径核对清楚,重命名那步看着简单,实际最容易漏。希望帮到你。
本文还有配套的精品资源,点击获取