让 Embedding 成为基础设施:在 PVE + LXC 中部署独立嵌入服务
本文最后更新于 93 天前,其中的信息可能已经有所发展或是发生改变,如有失效可到评论区留言。
文章摘要
核心问题在于embedding需从实验性能力转变为稳定基础服务。技术方案通过PVE部署LXC容器,基于Debian 12运行Ollama,配置独立网络监听与模型存储路径,实现服务隔离与长期运行。结果成功构建独立嵌入服务环境,保障模型加载与向量化任务的稳定性,为知识库和RAG应用提供可靠基础能力。
Qwen3-8B · 2026-06-07

1 当 embedding 从实验走向基础能力

在之前介绍RAG的文章中,我介绍过:将切分好的文本进行向量化的核心工具是”嵌入模型“(参见文章:从零理解 RAG(一):原理与完整流程解析),也在后续的一篇实战文章中介绍过:通过”chatbox以及ollama自建的嵌入模型来实现简易的本地知识库的步骤(参见文章:使用Ollama自建嵌入模型 + Chatbox 知识库实战),

在那个阶段,embedding 更像是一种“实验性能力”:它被用于验证流程是否可行,验证模型效果是否可接受,以及验证本地部署在功能上是否能够替代云端服务。只要能够跑通一次完整流程,稳定性、运行环境、长期维护这些问题,往往并不会被放在优先级很高的位置。

但随着使用场景逐渐增多,embedding 的角色也在悄然发生变化:无论是持续维护的本地知识库,还是后续可能引入的 RAG、全文检索、相似度计算,甚至更偏工程化的知识图谱或 AI 增强博客功能,embedding 都不再是“一次性生成即可”的临时步骤,而正在逐渐演变为一种常驻的基础能力

当 embedding 从“偶尔使用”变为“反复调用”,原本一些被忽略的问题便开始显现出来:比如它是否应该继续依附在桌面系统之上(例如以 macOS 上的 Ollama 实例作为长期运行环境)?是否应该和日常使用的操作系统、工具链、桌面环境共享同一个运行边界?一旦系统更新、环境变化或工具升级引入不确定性,这种基础能力是否会被无意中破坏?

从工程角度来看,embedding 具有非常鲜明的特征:它是非自回归的计算过程,不处于用户实时交互链路上,对稳定性、可复现性以及长期运行行为的一致性有着更高要求。换句话说,它更接近“基础设施”,而不是一个适合长期运行在个人桌面系统中的“应用程序”。

也正是基于这样的判断,我开始重新审视 embedding 的部署方式:与其让它继续依附在 macOS 等桌面环境中,随着系统升级和工具变动而被动漂移,不如将其明确剥离出来,放入一个运行边界清晰、行为可预测、更新节奏可控的独立环境中,作为一项专门的服务长期存在。

同时,从资源特性来看,embedding 功能对 GPU 的依赖并不高,对计算资源的整体需求也相对可控;在多数实际场景中,即便是普通的 Intel CPU 或类似配置,也足以支撑日常知识库文章的向量化需求。这使得将 embedding 独立部署在通用计算节点上,在工程上是一个成本与稳定性都较为平衡的选择。

因此,我最终在家里 Intel CPU 的 mini 主机上,通过 PVE 使用 LXC 部署一个固定版本的 Linux 系统,专门承载 Ollama 的嵌入模型服务。这样可以降低系统更新和运行环境变化对知识库构建流程的影响,同时确保服务运行的可控性与可复现性。

在后续章节中,我将从工程特性分析出发,解释 embedding 为什么适合被独立部署,并结合实际环境,完整展示如何在 PVE 中通过 LXC 部署一个专门用于提供嵌入服务的 Linux 环境,为后续的知识库和 RAG 应用打下稳定的基础。


注:

从纯工程效率角度来看,实现 embedding 功能最经济、最稳定的方式,其实是直接使用成熟商业服务提供的嵌入模型,例如 OpenAI 提供的 embedding API。这类服务在模型质量、稳定性以及长期维护成本上,远优于个人自建方案,也几乎不存在本文讨论的运行时不确定性问题。

然而,在国内实际使用中,这条路径并不总是可行。一方面,支付环节对银行卡和结算方式存在客观限制;另一方面,即使存在非主流接入方式,官方 API 的可用期限和稳定性也难以保证。对于仅用于 embedding 这一基础能力而言,引入额外的不确定性和维护成本,实际上并不划算。而一些常用第三方 API 服务商(如 OpenRouter、OhMyGPT 等)几乎只提供大语言模型接口,而 embedding 模型由于调用量、算力和应用场景限制,通常不提供。

正因如此,我选择放弃依赖外部商业服务,转而在 PVE 中通过 LXC 部署 Linux 环境,自建 Ollama 嵌入模型服务。这个选择并非追求性能或效果的最优,而是基于可控性、可持续性以及整体成本平衡的综合考量。


2 在可控环境中落地 embedding 服务

2.1 在PVE 中创建一个“只为 embedding 服务存在”的 LXC

在明确需要将 embedding 能力从桌面系统中剥离出来之后,接下来的问题并不是“怎么部署 Ollama”,而是embedding 这种能力,应该运行在什么形态的环境中

在我的实际场景中,这个问题可以拆解为三个更具体的工程判断:
1、为什么使用 LXC?
2、为什么选择 Debian 12?
3、这个环境究竟需要多少资源才算“合理”。


1. 为什么使用 LXC,而不是 VM 或容器编排方案

embedding 服务的运行特性,其实非常明确:常驻运行;长期稳定;不追求弹性伸缩;不需要频繁重建或销毁。它更像是一项基础设施能力,而不是一次性任务或短生命周期服务。

在这种前提下,相比完整虚拟机,LXC 的优势非常直接:

  • 它提供的是完整 Linux 系统视角,而不是被高度抽象的运行时
  • 可以原生使用 systemd,将 Ollama 当作长期运行的系统服务管理
  • 资源开销更低,启动和维护成本也更接近“真实服务器”

至于 Docker 或更复杂的容器编排方案,在 embedding 这个场景下反而显得过度设计:这里并不存在多实例扩展、镜像快速迭代或复杂依赖隔离的需求,引入额外的抽象层,只会增加长期维护心智负担。

因此,LXC 在这里并不是“技术上更先进”的选择,而是更贴近 embedding 服务实际运行形态的选择

2. 为什么选择 Debian 12

在确定使用 LXC 之后,操作系统的选择其实也遵循同一套判断逻辑:稳定性优先于新特性

Debian 12 之所以成为我的最终选择,主要有几个原因:

  • 发行节奏稳定,生命周期清晰,长期行为可预期
  • 在 server 与容器环境中拥有极高的普及度
  • Ollama 及其依赖的底层组件(如 llama.cpp)在 Debian 系系发行版上的兼容性和测试覆盖度更高

对 embedding 服务而言,操作系统并不是研究对象,而只是一个承载能力的平台。选择 Debian 12,本质上是选择了一条“变化最慢、意外最少”的路径。

注:选择Debian只是我个人的习惯,因为最熟悉,如果大家熟悉其他linux发行版,选择自己熟悉的也是一样的,不纠结。

3. 为什么资源规格不需要太大

最后一个问题是资源分配,embedding 的计算特性在第二章已经分析过:它是非自回归的、线性的计算过程,不处在用户实时交互的主链路上,也不存在持续的高并发压力。

因此,这个 LXC 的资源分配目标,并不是“跑得尽可能快”,而是:稳定、可预测,并且能够长期运行而无需频繁干预

在实际部署中,我为该 LXC 分配了如下规格,作为一个参考配置:CPU:2 核内存:4 GB磁盘:20 GB

这个配置对于 embedding 服务而言是完全充足的:embedding 的整体耗时主要受输入文本长度和模型本身计算特性影响,而非系统资源瓶颈。在日常使用中,即便连续处理多篇中等长度的中文文章,也不会对 CPU 或内存造成持续压力。

换句话说,为 embedding 服务配置过高规格的资源,不但不会带来实质收益,反而可能模糊它在整个系统中的真实定位——它应该是一个“安静地工作”的基础服务,而不是一个需要被重点关注和调优的性能节点。

需要说明的是,这样的资源分配并非“极限压缩”,而是基于 embedding 实际使用场景做出的有意识选择。在 PVE 的 LXC 环境下,资源调整和扩容成本本身就很低,如果未来模型规模或使用方式发生变化,再进行调整即可。


在明确了以上三个前提之后,LXC 的创建过程本身就变得相对简单了:

image.png

image.png

image.png

具体如何在PVE中创建LXC的步骤我在之前很多篇文章中讲过,这里就不再赘述了。

2.2 在Debian 12的LXC中部署Ollama

在前一节中,这个 LXC 的角色已经被限定得非常清楚:它不是一个通用算力节点,也不是交互入口,而是一个只为 embedding 服务存在的长期常驻组件。在这样的前提下,Ollama 在这里承担的职责也变得极其单一——只负责加载嵌入模型,并对外提供稳定的向量化接口。

正因为目标足够明确,Ollama 的部署反而不需要复杂的安装方式。从工程角度看,这里最重要的并不是“可玩性”或“可定制性”,而是行为的可预测性:安装过程是否清晰、运行方式是否稳定、升级路径是否明确。

Ollama 官方提供的安装脚本,恰好符合这一取向。它安装的是预编译好的官方二进制,默认以 systemd 服务的形式运行,不依赖 GPU 或平台特性,也不会对系统进行深度侵入式修改。对于一个运行在 LXC 中、职责单一、需要长期稳定运行的基础服务来说,这种“克制”的安装方式反而是最合适的选择。

因此,在这个 LXC 中,直接使用官方脚本即可完成全部安装工作(最近Ollama做过一次安装包格式调整,从tar.gz换成了tar.zst,只不过很多linux发行版并未自带zstd,所以需要自行安装):

apt update
apt install -y zstd
apt install -y curl
curl -fsSL https://ollama.com/install.sh | sh

image.png


在正常的网络环境下直接使用安装脚本即可完成(如上图),可惜的是,国内的网络环境恰巧是不正常的网络环境,所以需要使用科学或者魔法,以代理地址为http://192.168.1.1:8080为例:

export http_proxy="http://192.168.1.1:8080"
export https_proxy="http://192.168.1.1:8080"
curl -fsSL https://ollama.com/install.sh | sh

值得注意的是,如果直接使用出口路由器上的全局透明代理,也可能有问题,因为 curl | sh 对网络要求很严格:下载必须完整,TLS 不能中断,shell 不能收到半截脚本。而路由器的透明代理在 TCP/TLS 层可能会有 reset、分片或 IPv6 fallback 等不稳定情况,导致脚本中途失败。

所以,最稳妥的做法还是通过环境变量显式指定代理,让脚本内部的所有下载请求都走同一条稳定通道。


安装完成后,Ollama 会作为系统服务自动启动,此时可以通过 systemctl命令 查看其运行状态,确认服务已经正常工作:

image.png

注1:如果需要更新Ollama的版本,只需要重新运行安装时的脚本即可。

注2:本文中在 Debian 12 的 LXC 容器内部署 Ollama 时,采用的是 默认 CPU-only 运行模式。在 embedding 场景下,这种配置已经能够满足大多数知识库构建和日常向量化需求,因此未引入额外的加速依赖。不过,如果宿主机本身配备 NVIDIA 或 AMD 显卡,且有更高的吞吐或并发需求,Ollama 也支持通过相应参数和运行环境配置启用 GPU 加速(例如基于 NVIDIA Container Toolkit 或 ROCm 的方式)。但这通常涉及宿主机驱动、容器权限以及运行参数等一系列前置条件,配置复杂度和维护成本也会显著上升。由于本文的重点在于 embedding 服务的长期稳定运行与运行边界控制,而非追求极限性能,因此未对 GPU 加速路径展开说明。有相关需求的读者,可根据自身硬件条件自行查阅 Ollama 官方文档及对应 GPU 平台的部署说明。

2.3 (可选)配置ollama的监听地址及模型下载目录

在 Debian 12 的 LXC 中完成 Ollama 安装后,默认情况下其服务只监听 127.0.0.1:11434。这个地址意味着只有 LXC 内部可以访问,如果你希望从宿主机或者局域网的其他设备访问该服务,就需要将监听地址修改为 LXC 分配的网卡 IP(比如 192.168.x.y)。

Ollama 的监听行为并不是通过配置文件暴露出来的,而是通过 systemd 服务的环境变量进行控制。其服务文件路径为:

/etc/systemd/system/ollama.service

默认为空,需要自行添加以下内容:

Environment="OLLAMA_HOST=192.168.x.y:11434"  # 监听LXC网卡IP,端口可自定义
Environment="OLLAMA_ORIGINS=*"            # 允许所有跨域请求

如下图:

image.png

如果要指定Ollama模型的下载位置(默认情况下,Ollama 会将模型文件存放在系统目录中。对于 LXC 这种长期运行的基础服务而言,将模型数据与系统文件解耦,有利于后续的迁移、备份和磁盘管理),需要先新建目录然后正确配置权限:

mkdir -p /ollama/models
chown -R ollama:ollama /ollama
chmod -R 755 /ollama

同时和之前的操作一样,在ollama.service文件中添加以下的环境变量:

Environment="OLLAMA_MODELS=/ollama/models"

如下图:

image.png

最后,重启ollama的service即可:

systemctl daemon-reload
systemctl restart ollama

可以通过 ss -ntpl(或 netstat -ntpl)确认Ollama的监听状态来配电是否正常运行:

ss -ntpl
netstat -ntpl

Ollama正常运行时输出如下:

image.png

image.png

到这里,Ollama 已经作为一个系统级服务在 Debian 12 的 LXC 中稳定运行起来了。此时它仍然只是一个“运行时环境”,尚未加载任何模型。下一节,才会真正引入 embedding 所需的模型文件,并让这个 LXC 开始承担起实际的向量化任务。

2.4 下载并并运行嵌入模型

2.4.1 下载嵌入模型

在前面的步骤中,Ollama 已经作为 systemd 服务在 Debian 12 的 LXC 中稳定运行,并监听在指定的网络地址上。但需要注意的是,此时这个环境仍然只是一个“空的运行时”——它还没有加载任何模型,也尚未真正承担向量化任务。

在 Ollama 当前提供的模型列表中,可用于 embedding 的选择其实并不多。相比之下,nomic-embed-text 算是一个相对成熟、使用也比较广泛的嵌入模型,在中文场景中的表现也较为稳定。因此这次迁移到 Linux 环境时,我并没有更换模型,而是继续沿用nomic-embed-text 作为 embedding 能力的基础,该模型的下载通过 ollama pull 命令完成:

ollama pull nomic-embed-text

不过,在实际执行这一命令之前,有一个非常容易被忽略、但又十分关键的前提需要说明:Ollama 在设计上是一个典型的 client–server 架构——ollama serve 负责长期运行的服务进程,而 ollama pull、ollama embed 等命令本身只是客户端调用,它们并不会自动启动服务,而是通过网络请求与已经运行的 Ollama 服务通信。

在前一节中,为了便于局域网访问,我已经将 Ollama 服务的监听地址从默认的 127.0.0.1:11434 改为了 LXC 的实际网卡 IP。但需要注意的是:systemd 中的 Environment 变量,仅对该 service 生效。正因为此,监听地址是通过 systemd 的环境变量配置给 服务进程 的,并不会自动注入到交互式 shell 中。

这就意味着:如果直接在终端中执行 ollama pull,客户端仍然会尝试连接默认的 127.0.0.1:11434,从而出现”could not connect to ollama server”的错误提示,即便 Ollama 实际上已经在正确的地址上正常运行:

image.png

因此,在拉取模型之前,需要在当前 shell 中先显式指定 Ollama 服务地址,例如:

export OLLAMA_HOST=192.168.10.104:11434

或者在单次命令中临时指定:

OLLAMA_HOST=192.168.10.104:11434 ollama pull nomic-embed-text

在明确了客户端与服务端使用的是同一个地址之后,模型下载即可正常进行:

image.png

2.4.2 嵌入模型加载及运行方式

ollama pull 阶段的职责仅限于将模型文件下载并存储到本地,并不会立即加载模型,也不会主动拉起任何新的运行实例。无论是模型下载,还是后续的调用,ollama CLI 本质上都只是一个客户端,它始终依赖于已经可达的 Ollama Server

真正的模型加载发生在第一次成功调用该模型时。当某个 embedding 模型被首次调用后,Ollama 会在后台将其加载到内存中并进入常驻状态;只要该实例未被回收,后续的 embedding 请求都会复用同一个运行实例,而无需为每次请求重复初始化模型。

因此,验证模型是否“真的可用”,并不是看模型是否 pull 成功,而是看是否能够完成一次完整的调用链路。在 LXC 内部,可以通过下面这个最小命令进行验证:

OLLAMA_HOST=192.168.10.104:11434 ollama run nomic-embed-text "Hello world"

注:当前 Ollama CLI 并未提供单独的 embed 子命令,因此这里使用 ollama run 作为最小验证方式

如果命令能够正常返回一组向量数据,说明三件事情同时成立:Ollama Server 处于可连接状态;embedding 模型已被成功加载到内存;从客户端调用到向量输出的整条 embedding 路径已经打通。正常的输入如下图:

image.png

在这一过程中,我刻意没有在这个 LXC 中运行任何对话模型、Web UI 或 RAG 逻辑。它的职责被严格限制为一件事情:稳定、可预测地提供 embedding 能力。这样的取舍并不是功能上的妥协,而是工程上的分层选择——embedding 更像是一块基础设施,而不是一个需要频繁干预和调试的实验对象。

到这里,这个 Debian 12 的 LXC 才真正开始承担起向量化任务。

3 总结与后话:embedding 作为基础能力的运行位置

到这里,这个基于 PVE + LXC 的 Ollama 嵌入模型服务,已经完成了它的工程目标:在一个运行边界清晰、行为可预测的 Linux 环境中稳定运行,并通过网络接口持续提供 embedding 能力。

本文关注的并不是“如何跑通 embedding”,而是当 embedding 从一次性实验能力,演变为被反复调用的基础能力之后,它应该运行在什么样的环境中。当稳定性、可复现性和长期一致性成为核心诉求时,桌面系统所具备的灵活性,反而会转化为不确定性来源。

将 embedding 从 macOS 等桌面环境中剥离出来,放入一个更新节奏可控、依赖关系清晰的独立运行环境,本质上是在为后续的知识库和 RAG 流程降低长期风险。这一调整并不追求性能或效果上的最优,而是优先保证行为可预期、运行可持续。

需要说明的是,在条件允许的情况下,直接使用成熟商业服务提供的 embedding API,依然是工程效率和稳定性都更高的选择。本文讨论的方案,主要适用于无法或不便依赖外部服务、同时又希望 embedding 能够长期稳定运行的场景。

在此基础之上,模型效果、向量数据库选型以及 RAG 的具体实现,才有继续讨论的意义。至少在我的实践中,先把 embedding 的运行位置问题解决清楚,远比过早堆叠上层结构更重要。

📌 内容结构提示:
这篇内容属于「AI 学习地图」的一部分,你可以从这里查看完整内容路径: AI 学习地图
分享这篇文章
博客内容均系原创,转载请注明出处!博客的RSS地址为:https://blog.tangwudi.com/feed,欢迎订阅;如有需要,可以加入Telegram群一起讨论问题。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇