ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

内网离线部署DeepSeek全攻略:从模型导入到RAG知识库落地

内网离线部署DeepSeek全攻略:从模型导入到RAG知识库落地

简介:面向政企单位及内网环境的DeepSeek离线部署指南,适合IT运维人员和有一定技术基础的学习者。包体为单个PDF文档,约5.28MB,内容涵盖离线资源准备、多平台环境部署、数据导入与访问控制等完整流程。文中给出模型、Ollama安装包及客户端的离线获取途径,并详述两种实现RAG的方法,其中通过Cherry Studio简化数据馈送的方案尤其适合新手。安全加固部分针对Ollama API、Lobe Chat及宝塔面板的访问控制做了专项说明,同时覆盖国产操作系统与CPU架构的适配要点,可帮助内网用户在无互联网条件下搭建安全可用的AI知识库。目前已有1370人学习下载,兼具教学手册与实战参考价值,既能引导初学者逐步完成配置,也能为有经验者提供安全加固与排错思路。

1. 内网部署 DeepSeek:为什么离线部署比在线跑通更难

在政企内网里把 DeepSeek 跑起来,从来不是“装个软件”那么简单。你要面对的是没有外网的模型获取通道、动辄几十 GB 的模型文件传输、以及“数据不能出内网”这条红线。在线教程里顺手写的pip install、git clone、ollama run,在内网环境全都失效。这份资源的核心价值,就是把「离线资源准备 → 多平台部署 → 数据投喂 → 访问控制 → 国产化适配」这条链路完整打通,让内网用户不用到处找工具链接。它适合有基本运维经验的实施人员,也适合刚接触大模型部署的技术爱好者——前提是你愿意按步骤走,而不是跳过校验直接开跑。这篇笔记,我把整份教程拆开讲清楚,重点放在你照着做时会遇到的那些真实卡点。

2. 离线资源准备:模型包、安装包与导入环节的完整闭环

2.1 获取模型离线包的三个可靠渠道

内网部署的第一步是把模型文件弄到手,这一步最容易踩坑:很多人以为“有网下载就行”,但实际上模型仓库的域名、文件大小、校验机制都会影响你能否顺利把模型搬进内网。我一般优先推荐以下三个来源,顺序按可靠性从高到低排:

  • Ollama 官方仓库:直接获取 GGUF 格式模型,与 Ollama 运行时天然兼容。官方的 DeepSeek 模型按参数规模分 7b、8b、14b、32b、70b 等版本,可以按机器显存和内存来选择。这个渠道的优势是模型格式标准,导入后直接用ollama run拉起,不需要额外转换。
  • ModelScope(魔搭社区):搜索“GGUF deepseek”可以找到适合 Ollama 直接导入的模型文件。国内访问稳定性更好,适合有网环境下批量下载后拷入内网。下载时注意勾选文件完整性校验,魔搭对 GGUF 文件通常会附带 SHA256 哈希值。
  • Hugging Face:资源最全,但需要处理好网络环境。下载后建议先用sha256sum核对官方哈希,防止文件在传输过程中损坏或被篡改。这一步看起来多余,实际上我遇到过不止一次模型文件下到一半断掉、ollama 导入时报“文件格式错误”的情况,而问题源头就是哈希对不上。

除模型本体外,还要顺手准备一个向量模型。RAG 功能需要把文本切成向量做相似度检索,nomic-embed-text是 Ollama 生态里最常见的文本向量模型,在离线导入时和主模型走同一条链路。

2.2 GGUF 模型手动导入:Modelfile 是容易被忽略的一环

从网上下载的模型文件通常散落在本地目录,不能直接用ollama run启动。你需要通过ollama create命令把 GGUF 文件注册到 Ollama 的模型库中。常见做法是新建一个名为Modelfile的文本文件,内容非常简单,只有一行:

FROM ./deepseek-r1-abliterated:32b.Q4_K_M.gguf

这里FROM后面跟的是模型文件名,注意文件名里的冒号:会与 Ollama 的 tag 语法冲突,我习惯把文件重命名为不带冒号的格式再写进去。保存好 Modelfile 后,把终端cd到模型文件所在目录,执行:

ollama create deepseek-r1-32b -f Modelfile ollama list

第一条命令把 GGUF 文件注册为名为deepseek-r1-32b的本地模型;第二条命令确认导入结果。如果ollama list里能看到对应模型,说明导入成功。这里有个细节:ollama create接收的-f参数是 Modelfile 的路径,且 Modelfile 必须与 GGUF 文件在同一目录下,否则会报“文件不存在”的错误。

2.3 大文件传输:分割、合并与完整性校验

模型文件动辄几十 GB,内网 U 盘或共享文件夹传输时,FAT32 格式的存储设备有单文件 4GB 上限。Linux 下建议用split分割,到目标机器再cat合并:

split -b 4G deepseek-r1-32b.Q4_K_M.gguf model_part_ cat model_part_* > deepseek-r1-32b.Q4_K_M.gguf

Windows 下用 7-Zip 做分卷压缩即可,右键选择“分卷大小”输入4000M,解压时把所有分卷放在同一目录再解压。传输完毕后务必跑一次哈希校验——这步是血泪教训换来的:内网传输工具偶尔会丢数据,而模型文件哪怕损坏一个字节,导入时也不会立刻报错,往往要到推理时才发现输出全是乱码。

2.4 安装包离线分发:不只是拷贝一个可执行文件

Ollama 的 Linux 安装看似简单,curl -fsSL https://ollama.com/install.sh | sh一条命令搞定,但内网环境没法直接执行。我通常在联网机器上先跑一遍安装脚本,然后把/usr/bin/ollama这个二进制文件拷贝到内网,放在/usr/local/bin/下并赋可执行权限:

sudo cp ollama /usr/local/bin/ sudo chmod +x /usr/local/bin/ollama

注意这个二进制文件是动态链接的,内网机器上缺 glibc 依赖时会出现cannot execute binary file报错。所以拷完二进制后,建议顺手执行ldd /usr/local/bin/ollama看依赖是否齐全。

Ollama 本体之外,客户端离线包也要提前备好。Cherry Studio、Chatbox、Lobe Chat 这三类客户端对应不同使用场景:Cherry Studio 适合新手在桌面上喂数据建 RAG 知识库;Lobe Chat 是多用户 Web 界面,带访问码和用户管理,适合团队共用一台服务器的情况。Lobe Chat 走 Docker 部署,在有网的服务器上先拉镜像再导出:

docker pull lobehub/lobe-chat docker save -o lobe-chat.tar lobehub/lobe-chat

把lobe-chat.tar拷贝到内网后,用docker load -i lobe-chat.tar导入镜像。实际操作时建议确认 Docker 版本兼容性,内网服务器 Docker 版本过旧时,镜像层的格式可能不兼容。

3. 多平台部署实操:从环境变量到服务自启的完整配置

3.1 Windows Server 部署:环境变量与防火墙缺一不可

Windows Server 上的 Ollama 部署流程本身不复杂,双击安装包一路下一步即可,真正的卡点集中在环境变量配置和防火墙放行上。安装完成后,打开“系统属性 → 环境变量”,在系统变量里新建:

  • OLLAMA_HOST=0.0.0.0:11434——这个值决定 Ollama 服务监听哪种地址。只在本机访问就填localhost:11434;需要内网其他机器访问,必须改成0.0.0.0:11434,否则服务只回环在本地。
  • OLLAMA_MODELS=D:\ollama\models——模型文件存放路径。离线导入的模型较多时,建议单独指定一个数据盘目录,避免系统盘空间被撑爆。

配置完环境变量后重启 Ollama 服务。这里有一个常见的翻车点:很多人改完环境变量不重启服务,或者直接在任务管理器里结束进程再手动启动,导致新配置不生效。Windows 服务管理器里找到Ollama服务,右键“重新启动”即可。

防火墙是第二个坑。Windows Server 默认防火墙会拦截入站流量,内网其他机器访问http://服务器IP:11434超时,基本都是这个原因。放行端口用管理员权限 PowerShell 执行:

netsh advfirewall firewall add rule name="Ollama" dir=in action=allow protocol=TCP localport=11434 netsh advfirewall firewall add rule name="LobeChat" dir=in action=allow protocol=TCP localport=3010

执行完可以用Get-Service Ollama确认服务运行状态,再用Get-Process -Name ollama看进程是否正常监听。

3.2 Linux Server 部署:用 systemd 而不是 nohup 拉起服务

Linux 下很多人图省事,直接ollama serve &丢后台,结果是每次 SSH 断开服务也跟着退出。我一般用 systemd 管理服务,这是生产环境最稳妥的方式。在/etc/systemd/system/ollama.service写入:

[Unit] Description=Ollama Service After=network.target [Service] User=youruser WorkingDirectory=/home/youruser ExecStart=/usr/local/bin/ollama serve Environment="OLLAMA_HOST=0.0.0.0:11434" Environment="OLLAMA_MODELS=/data/ollama/models" Restart=always [Install] WantedBy=multi-user.target

然后依次执行:

sudo systemctl daemon-reload sudo systemctl enable ollama sudo systemctl start ollama

这里User字段建议用一个普通用户而不是 root,避免模型文件权限过高引发安全问题。Restart=always保证 Ollama 进程意外退出后自动拉起,内网环境没人盯着服务器时这个配置能省很多事。

同机的防火墙配置别忘,CentOS 用 firewalld,Ubuntu 用 ufw:

sudo firewall-cmd --permanent --add-port=11434/tcp && sudo firewall-cmd --reload

3.3 macOS 部署与应用层账密保护

macOS 部署方式和 Linux 基本一致,环境变量写到~/.zshrc:

export OLLAMA_HOST="0.0.0.0:11434" export OLLAMA_MODELS="/Volumes/Data/ollama/models" source ~/.zshrc

macOS 上有个坑是 Gatekeeper 会拦截未签名的二进制文件,安装 Ollama 时如果提示“无法验证开发者”,需要在“系统设置 → 隐私与安全性”里手动允许。Lobe Chat 的 Docker 部署在所有平台通用,但 macOS 上要注意 Docker Desktop 的资源配额——默认只有 2GB 内存,跑 32B 模型会频繁 OOM,建议在 Docker Desktop 设置里调到 8GB 以上。

Web 端 Lobe Chat 的ACCESS_CODE是一个文本字符串,用户在浏览器打开服务地址时会被要求输入访问码,能挡住大多数非授权访问:

docker run -d -p 3210:3210 \ -e OPENAI_API_KEY=sk-xxxx \ -e ACCESS_CODE=your-secret-code \ --name lobe-chat \ lobehub/lobe-chat

这里的OPENAI_API_KEY在对接 Ollama 本地模型时可以填一个占位符,关键是OLLAMA_BASE_URL环境变量要指向 Ollama 实际监听地址,例如http://服务器IP:11434/v1。

4. 离线数据投喂:从文本清洗到 RAG 知识库的两条路径

4.1 文档解析与分块策略:先处理格式,再谈效果

RAG 链路的第一步是把文档转成可检索的文本。项目正文中给出的方案基于 Python 脚本,先做格式解析再分块。我实际操作时发现,单靠python-docx提取段落会丢掉表格和页眉页脚信息,更稳妥的做法是分类型处理:

  • DOCX 文件:python-docx提取段落和表格上下文。
  • PDF 文件:pdfminer.six处理扫描件效果一般,优先选数字版 PDF。
  • TXT/Markdown 文件:直接读取,但要注意编码问题,统一转成 UTF-8。
# 文本处理示例 from docx import Document import jieba import re def extract_docx_text(filepath): doc = Document(filepath) text = '\n'.join([p.text for p in doc.paragraphs]) # 清洗控制字符与多余空白 text = re.sub(r'\s+', ' ', text) return text def chunk_text(text, chunk_size=500, overlap=50): """按固定长度切块,保留少量重叠防止语义断裂""" chunks = [] for i in range(0, len(text), chunk_size - overlap): chunks.append(text[i:i + chunk_size]) return chunks # 中文分词示例 text = "这是一段测试文本" seg_list = jieba.cut(text, cut_all=False) print("/".join(seg_list))

分块参数直接影响检索质量:块太大,向量化后语义不精确,检索命中率下降;块太小,上下文信息不足。我用 500 字符加 50 字符重叠的组合,在政企行业文档上效果比较稳。chunk_size调整时留意一点:英文按 token 切可能 500 字符没问题,中文 500 字符大约能覆盖一段完整语义,再大就容易把多个主题混在一起。

4.2 向量化与向量库:离线模型的加载路径

向量化这一步要用 embedding 模型把文本块转成浮点数组。离线环境下不要在线拉模型,把下载好的bge-large-zh-v1.5这类 embedding 模型放到本地目录,用sentence-transformers直接加载:

from sentence_transformers import SentenceTransformer model = SentenceTransformer('/data/embedding/bge-large-zh-v1.5') embeddings = model.encode(chunks)

向量存哪里?内网场景我优先推荐 ChromaDB,因为它是纯本地存储,不需要单独部署服务端。注意chromadb.Client()默认把数据写在当前目录的./chroma文件夹,生产环境建议显式指定持久化路径:

import chromadb client = chromadb.PersistentClient(path="/data/chroma_db") collection = client.create_collection("company_kb") collection.add( embeddings=[emb.tolist() for emb in embeddings], documents=chunks, ids=[f"id_{i}" for i in range(len(chunks))] )

这串代码是把文本块和向量一起写入本地集合,后续查询时用collection.query(query_embeddings=...)做相似度搜索。

4.3 Cherry Studio 实现 RAG:新手的上手路径

对不熟悉 Python 的运维人员,手动走完整条 RAG 链路有门槛。项目正文推荐的 Cherry Studio 方案大幅简化了这个过程:客户端自带知识库功能,只需要在 Ollama 里提前导入一个 embedding 模型,然后在 Cherry Studio 的设置中添加模型。

操作流程是:打开 Cherry Studio → 进入设置 → 添加模型 → 输入 Ollama 中向量模型的名称(如nomic-embed-text)。之后在对话界面新建知识库,把 pdf、txt、docx 文档直接拖进去,客户端会自动完成分块、向量化、检索的整条链路。这种方式不用写一行代码,但对服务器性能有一定要求——向量化过程会占用 CPU 和内存。走 Python 脚本方式则更灵活,但前期配置更繁琐。我的建议是:验证阶段用 Cherry Studio,生产环境再落到代码方案上,两条路能平滑切换。

5. 访问控制与安全加固:Ollama API 未授权访问的排查与防护

5.1 未授权访问的暴露面有多大

Ollama 默认加载模型后,API 是完全开放的。只要OLLAMA_HOST=0.0.0.0:11434,内网任何机器都能直接调用模型接口生成内容,既消耗算力,也存在数据泄露风险。更严重的情况是攻击者向内网服务器投递恶意提示词,诱导模型输出敏感信息或执行越权操作。对于“数据不能出内网”的政企环境,API 暴露是一个必须处理的隐患。

5.2 三种防护手段的组合用法

第一层:Ollama 服务本身绑定访问来源。如果只有少数几台客户端需要调用 API,可以限制 Ollama 监听端口只对这些 IP 开放,以 Linux 防火墙为例:

sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 port port=11434 protocol=tcp accept' sudo firewall-cmd --reload

把192.168.1.0/24替换为你内网的合法网段,这一步把 API 暴露范围从“所有机器”缩小到“指定网段”。

第二层:反向代理做访问认证。在 Ollama API 前面套一层带身份校验的反向代理,能有效阻止非授权访问。常见做法是用 Nginx 配合 Basic Auth 或 Token 鉴权,将http://服务器IP:11434反向代理到内网可访问的地址,同时校验请求头。

第三层:宝塔面板的防火墙规则。如果是用了宝塔面板的 Linux 环境,可以直接在“安全”菜单中添加端口放行规则,只放行 11434 端口给指定 IP。宝塔面板本身也支持反向代理,配置起来相对简单,适合对纯命令行操作不熟悉的运维人员。

5.3 必看排查点:三处容易忽略的异常

现象一:客户端连接 Ollama 超时,但服务器本机访问正常。原因:Ollama 服务只监听了localhost:11434,没有绑定0.0.0.0。 解决:修改OLLAMA_HOST为0.0.0.0:11434并重启服务,确认端口监听用netstat -an | grep 11434。

现象二:Lobe Chat 能打开页面,但对话时提示“模型连接失败”。原因:Lobe Chat 配置里的OLLAMA_BASE_URL指向了错误地址,或者 Ollama 未放行 11434 端口。 解决:把OLLAMA_BASE_URL改为实际的 Ollama 服务地址(注意是http://IP:11434/v1而不是不带/v1的路径),并在防火墙中确认端口已放行。

现象三:内外网传输后模型导入失败,报“file format error”。原因:大文件在拷贝过程中损坏,通常由存储介质格式限制或传输工具断点续传异常导致。 解决:不要跳过哈希校验这步。传输前对文件执行一次sha256sum,传输后再执行一次,比对两个值是否一致。不一致就重新传输,不要尝试直接导入。

5.4 一个完整的加固落地建议

把上述手段串起来的实际操作顺序是:先确认 Ollama 只监听内网 IP → 在防火墙放行指定来源 → 在 Lobe Chat 或 Nginx 层设置访问认证 → 最后用curl http://服务器IP:11434/api/tags从非授权机器上验证是否返回 401 或拒绝连接。这套流程走完后,再启动知识库服务,后续只需要关注日志和模型运行状态即可。

6. 国产化适配与部署后的验证方法:从兼容性检查到链路自测

国产化适配看起来像是一个“玄学”问题,实际上只是需要多确认几个兼容性指标。首先是操作系统,银河麒麟、统信 UOS 这类基于 Linux 内核的国产系统,Ollama 的 Linux 二进制通常可以直接运行,但要注意 glibc 版本——过老的系统需要升级基础库。其次是 CPU 架构,当前主流国产服务器有 x86_64 和 ARM64(鲲鹏、飞腾等)两种。Ollama 官方对两种架构都有支持,但 ARM64 下的模型推理性能相比 x86 可能有差距,选型时要根据实际跑批测试的结果来定,不能只看参数。

判断一个部署是否真正成功,我习惯走一遍全链路自测,而不是只看进程活着就算完。推荐按下面三个命令依次检查:

ollama list # 确认模型已导入并可见 curl http://localhost:11434/api/tags # 验证 API 正常响应 ollama run deepseek-r1-32b "你好,请简单介绍你自己" # 实测生成是否正常

第三条命令跑通后,再去 Lobe Chat 或 Cherry Studio 里发起一轮对话,验证 Web 链路是否完整。走完这三步,部署才算是真正“落地可用”而不是“看起来可用”。另外,服务重启后的自启验证也得做——重启服务器,检查systemctl status ollama是否为 active 状态,这一步能提前发现服务依赖配置缺失的隐患。

这套部署流程我前后实践过三遍,每一次都在校验和权限配置上花掉了预期之外的时间。从那以后,我每次在内网环境里部署模型,都会强制自己先走一遍哈希校验和端口排查,再做服务启动。这个习惯帮我避开了不少半夜被叫起来处理“模型突然不可用”的尴尬。希望这份拆解笔记能帮你在内网部署 DeepSeek 时少踩几个坑,顺利把知识库跑起来。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进