Ollama Cloud 与自建服务器有什么区别
Ollama Cloud 与自托管 Ollama 共用一个 CLI 和 REST API,但模型名称、凭据位置及数据去向不同。本文说明哪些设置要改,以及请求何时离开您的机器。
Ollama Cloud 的变化,以及不变的内容
Ollama Cloud 会在 ollama.com 上运行模型,而不是在您自己的硬件上运行,同时保留您已经使用的相同 ollama 命令和 REST API。只有两项内容会变化:您请求的模型名称,以及凭据的存储位置。除此之外,应用程序无需修改。下面会介绍一个已记录的例外情况:结构化输出。
这种便利性也带来了风险。在代码中,向云端模型发送请求与向本地模型发送请求看起来完全相同。因此,您很容易忽略哪些提示词会在您控制的机器上运行,哪些提示词会发送给您无法控制的公司。本指南会明确区分这两种情况,然后介绍如何保留本地模型作为回退选项,让一个配置值决定请求使用哪一侧。
如果您还没有搭建本地环境,请先阅读在自己的 VPS 上运行 Ollama。下面的内容假设 Linux 主机上已经运行正常的 ollama。
访问 Ollama Cloud 的两种方式
访问托管模型有两种方式,二者不能互换。选择哪种方式将决定凭据存储在哪里、填写什么模型名称,以及在服务器上进行数据包捕获时能看到什么。
方式一:由本地 daemon 转发请求。 登录一次,然后请求名称以 -cloud 结尾的模型。
ollama signin
ollama pull gpt-oss:120b-cloud
ollama run gpt-oss:120b-cloud有些云模型使用单独的 cloud 标签,例如 gemma4:cloud。这也是 Ollama 的云文档目前为应用和 CLI 展示的格式。将 -cloud 或 :cloud 任一后缀都视为云模型。
ollama signin 将此计算机关联到您的 ollama.com 帐户。ollama signout 取消关联。登录后,应用仍会访问一直使用的本地端口:
curl http://localhost:11434/api/chat -d '{
"model": "gpt-oss:120b-cloud",
"messages": [{"role": "user", "content": "Why is the sky blue?"}],
"stream": false
}'再次查看这个 URL。它显示的是 localhost,推理并不是在那里执行的。本地 daemon 识别 -cloud 后缀,将请求转发到 ollama.com,再将响应流式传回。方式一的意义就在于此:已经指向11434 端口上的 Ollama API的应用可以保留原 URL 和客户端代码。对于普通聊天,只需更换模型字符串。结构化输出是例外。Ollama 文档说明:“Ollama 的云服务目前不支持结构化输出。”因此,如果应用在 format 参数中传入 JSON schema,并依赖响应符合该 schema,那么切换到云模型前必须修改应用:在自己的代码中执行验证并重试,或者继续让该请求使用本地模型。
方式二:客户端直接调用 ollama.com。 此时完全不会使用本地 daemon。请在 https://ollama.com/settings/keys 创建密钥,然后将其作为 bearer token 发送。
export OLLAMA_API_KEY=your_api_key
curl https://ollama.com/api/chat \
-H "Authorization: Bearer $OLLAMA_API_KEY" \
-d '{
"model": "gpt-oss:120b",
"messages": [{"role": "user", "content": "Why is the sky blue?"}],
"stream": false
}'注意模型名称。方式二使用 gpt-oss:120b,没有 -cloud 后缀。该后缀用于告知本地 daemon 将请求转发到上游,因此只能用于方式一。调用 https://ollama.com 时,请求已经直接发送到云端,应填写不带后缀的名称。这些名称的权威列表来自主机本身:
curl https://ollama.com/api/tags请运行该命令,不要相信文章中列出的任何模型列表,包括本文中的列表。模型目录会变化,而 api/tags 始终是最新的。
哪些客户端调用需要更改,哪些不需要
官方 Python 和 JavaScript 库会在构造客户端时接收主机地址和请求头。除此之外,后续代码无需修改。路径一中,构造函数为空,因为默认连接本地 daemon:
from ollama import Client
client = Client()
messages = [{'role': 'user', 'content': 'Why is the sky blue?'}]
for part in client.chat('gpt-oss:120b-cloud', messages=messages, stream=True):
print(part['message']['content'], end='', flush=True)路径二中,构造函数包含主机地址和令牌:
import os
from ollama import Client
client = Client(
host="https://ollama.com",
headers={'Authorization': 'Bearer ' + os.environ.get('OLLAMA_API_KEY')}
)
messages = [{'role': 'user', 'content': 'Why is the sky blue?'}]
for part in client.chat('gpt-oss:120b', messages=messages, stream=True):
print(part['message']['content'], end='', flush=True)两种情况下,client.chat() 调用、流式循环、消息列表和响应结构都完全相同。因此,从托管服务迁移到自托管,或反向迁移,属于配置变更,而不是代码重写;除非某个调用依赖结构化输出,而 Ollama 云服务目前不支持该功能。OpenAI 兼容接口在本地的行为也相同:将 OpenAI SDK 指向 http://localhost:11434/v1/,并使用 api_key='ollama';这是 SDK 强制要求的占位符,本地服务器会忽略它。
凭据存放位置,以及谁可以使用它
在路径二中,凭据位于您的环境中的 OLLAMA_API_KEY。不要让它出现在 shell 历史记录或代码仓库中。对于 systemd 服务,请将它写入 Environment= 行,或写入由 root 所有且权限为 600 的环境文件。
路径一更容易让人意外。登录凭据属于守护进程,而不是您本人。Ollama FAQ 记录了 Linux 上的服务身份:凭据位于 /usr/share/ollama/.ollama/id_ed25519.pub,由 ollama 服务用户所有。本地 API 不支持按请求进行身份验证,因此任何能够访问 11434 端口的调用方都会继承您的账户并消耗您的配额。只要守护进程监听 loopback,这样配置没有问题。将 OLLAMA_HOST=0.0.0.0:11434 设置为允许其他机器访问后,开放端口就意味着任何访问者都可能产生计费,因此在扩大绑定地址前,请先阅读如何在 Ollama 端点前配置身份验证。
为什么相同模型在本地运行时可用上下文更少
如果您认为模型在两种路径上的行为完全相同,这个差异很容易被忽略。实际并非如此,原因在于内存。
Ollama 会根据检测到的显存,为本地模型选择默认上下文长度。
此图表背后的数据
[
{
"label": "Under 24 GiB VRAM",
"default_context_tokens": "4,096"
},
{
"label": "24 to 48 GiB VRAM",
"default_context_tokens": "32,768"
},
{
"label": "48 GiB VRAM or more",
"default_context_tokens": "262,144"
}
]没有 GPU 的 VPS 处于最低档,因此本地模型的上下文长度从 4,096 个 token 开始;配备大容量显卡的机器则从 262,144 个 token 开始。云端模型不受这些档位限制:Ollama 文档说明,云端模型默认使用其最大上下文长度,因为用于保存上下文的内存不由您提供。
因此,对 gpt-oss:120b-cloud 有效的相同提示词,在小型机器上的本地模型中可能会被静默截断。请显式提高本地上限:
OLLAMA_CONTEXT_LENGTH=32768 ollama serve在 systemd 下,使用 Environment="OLLAMA_CONTEXT_LENGTH=32768" 和 systemctl edit ollama.service 设置该值,然后执行 systemctl daemon-reload && systemctl restart ollama。请注意,这意味着更长的上下文需要更大的键值缓存,而该缓存会占用模型权重之外的 RAM。设置过高会导致生成速度降低,或模型加载失败。正确设置 num_ctx 和 OLLAMA_CONTEXT_LENGTH介绍了相关计算方法,哪些模型适合您实际拥有的内存介绍了模型权重占用的内存。
实际离开您设备的数据
请准确理解这一点,因为这正是大多数读者选择自托管的首要原因。
在本地运行时,不会有任何数据离开设备。 Ollama 的隐私政策明确说明,对于本地使用,“我们不会收集、存储、传输您在本地处理的提示词、响应、模型交互或其他内容,也无法访问这些内容。”但有一项例外:拉取模型仍会从 ollama.com 下载,政策将“模型下载元数据”和您的 IP 地址列为收集内容。该注册表会知道您获取了哪些模型,但不知道您向模型询问了什么。
通过云端路径运行时,完整提示词和完整补全内容都会发送给第三方。 不存在只发送部分内容的情况。您发送的每个 token 和接收的每个 token 都会在 ollama.com 上处理。该政策称,公司会“暂时处理您的提示词和响应以提供服务”,并且“不使用您的输入或输出训练任何 AI 模型”;政策还说明,公司采取了“旨在最大限度减少提示词和响应内容留存的技术措施”。这是一项合理承诺,但它仍是其他人对您交付数据所作的承诺,而不是您自己的设备固有的安全属性。请像评估任何供应商承诺一样评估它,并在发送任何按合同或法律要求必须保留在您自有基础设施上的内容前重新阅读该政策。
陷阱在于路径一。您的代码显示为 http://localhost:11434,防火墙规则没有变化,但提示词仍会穿过互联网,因为模型名称末尾的 -cloud 后缀负责路由。localhost URL 无法告诉您推理发生在哪里,模型名称才可以。对于那些您专门通过自托管来保持私密的数据,这一点尤其重要:如果您运行自托管的位置跟踪器,以确保移动历史记录不会到达第三方,那么让 -cloud 模型汇总其中一周的数据,仍会将这些历史记录发送到 ollama.com。
对于绝不能转发提示词的服务器,应完全禁用这一选择。Ollama 提供仅本地模式:在服务环境中设置 OLLAMA_NO_CLOUD=1,或在 ~/.ollama/server.json 中设置 "disable_ollama_cloud": true,然后重启服务。守护进程将无法访问云端模型和 Web 搜索,因此即使误用了云端模型名称,也不会泄露任何内容。
将本地模型作为回退方案
由于两条路径使用相同的 API,因此可以将选择设为运行时配置,而不是在代码中维护两个分支。
最简单的版本完全不需要修改代码。让应用始终连接本地 daemon,并在配置中指定模型名称。将其设置为 llama3.2 时,应用在本机运行。将其设置为 gpt-oss:120b-cloud 时,同一个 daemon 会将请求转发到 ollama.com。只需一个环境变量,无需重新部署。
如果希望本地模型作为默认模型,并在请求超出本地处理能力时切换到云端,可以同时创建两个客户端,并按请求进行选择:
import os
from httpx import ConnectError
from ollama import Client, ResponseError
LOCAL_MODEL = os.environ.get("LOCAL_MODEL", "llama3.2")
CLOUD_MODEL = os.environ.get("CLOUD_MODEL", "gpt-oss:120b")
local = Client(host="http://127.0.0.1:11434")
cloud = Client(
host="https://ollama.com",
headers={"Authorization": "Bearer " + os.environ["OLLAMA_API_KEY"]},
)
def chat(messages):
try:
return local.chat(LOCAL_MODEL, messages=messages)
except (ConnectError, ResponseError) as err:
print(f"local inference failed ({err}); sending this prompt to ollama.com")
return cloud.chat(CLOUD_MODEL, messages=messages)httpx 会作为 ollama package 的依赖项安装,因此无需额外安装。ConnectError 用于处理 daemon 已停止的情况。ResponseError 用于处理 daemon 正在运行但拒绝请求的情况,例如本地从未拉取过该模型。
print 这一行并非可有可无。静默回退意味着:在升级期间 daemon 首次重启时,原本应保留在本机硬件上的提示内容会在不知情的情况下发送给第三方。应记录每次回退;对于任何敏感内容,应直接抛出错误,而不是回退。对于以隐私为重点的部署,最安全的回退策略是明确失败。
还有一点可以让本地模型真正适合作为默认模型:让模型常驻内存。仅使用 CPU 的 VPS 冷加载模型可能需要几十秒,这正是用户最初转向云端路径的原因。使用 keep_alive 让模型常驻内存 可以消除首次请求的延迟。
提交前需要比较的内容
不要只比较价格,也不要相信文章中看到的价格,包括本文日期。比较以下四项,并在供应商自己的页面上逐项核对:
- 模型可用性。 运行
curl https://ollama.com/api/tags查看当前托管模型目录。可在本地运行的模型则受 RAM 和 VRAM 限制。 - 上下文限制。 托管模型默认使用其最大上下文长度。本地模型则根据 VRAM 档位采用默认值,如上所述。如果您的工作负载是长文档,这一项本身就能决定选择。
- 速率限制。 托管推理按 token 计量:Ollama 的定价页面写明:“Usage is measured in tokens at each model's rates.” 付费方案包含每月额度,Ollama 会“uses included plan credits first, then draws from the purchased usage credit balance.” 每个方案都有并发上限(截至 October 27, 2026,$0 Pay as you go 档位和 Pro 支持 3 个并发请求,Max 和 Team 支持 10 个),超过上限的请求会进入队列,只有队列已满时才会被拒绝。您自己的服务器没有用量计量器,只有硬件本身的并发上限。这是另一类故障,而且通常更严重。
- 数据保留政策。 阅读实际政策文本,记录阅读日期,并在续费前重新核对。
关于费用,不要在这里重复计算。GPU VPS 何时超过按 token 计费会正确计算盈亏平衡点,其中包括人们常忘记的一点:空闲的 GPU 服务器与繁忙时的计费相同。
前面有多个供应商时,使用路由器怎么样?
第三种方案是路由器。它是一种代理,向应用提供统一的 API,并将请求分发到多个后端。自托管的 LiteLLM 代理或 OpenRouter 这样的托管服务都可以实现这一点。它的优势很明显:客户端只需配置一次,即可使用多个模型;当某个供应商暂时出现故障时,还可以执行故障转移。这是前面回退模式的自然扩展,只是将后端数量从两个扩展到了更多。
不过,必须明确其成本。托管路由器是另一个能够看到提示词的运营方,因此,你向一个供应商询问的数据保留问题,现在还必须向第二个供应商询问。自托管路由器可以将这一跳保留在自己的机器上,但你需要额外运行、修补和监控一个服务。路由器可以解决模型选择和可用性问题,但不能解决隐私问题,因为提示词最终仍会发送到路由所指向的位置。
实际会遇到的错误
API 会记录状态码,每个状态码都对应不同的问题。429 Too Many Requests 表示触发了速率限制,因此应降低请求频率后重试,而不是循环重新建立连接。502 Bad Gateway 是本主题特有的状态码:当无法访问云端模型时会返回该状态码。因此,在路径一中,这表示守护进程正常运行,但上游服务不可用。模型名称返回 404 Not Found 时,表示请求的主机上不存在该模型:通常是将 -cloud 名称直接发送给 https://ollama.com,或者从未拉取过本地模型。对于本地模型,登录与此无关,因为本地 API 不需要身份验证。错误以 JSON 形式返回。在流式响应过程中,错误会作为类似 {"error":"an error was encountered while running the model"} 的行出现在 NDJSON 响应中。这就是简单的流式客户端可能先输出部分答案,然后毫无说明地停止的原因。请解析每一行流式数据,并检查是否包含 error 键。
在本地侧,最常见的问题是 11434 端口连接被拒绝。这表示该端口没有进程监听:请检查 systemctl status ollama;如果守护进程正在运行,请检查 OLLAMA_HOST 是否将其移到了其他端口。另一个常见问题是,请求可以在 shell 中成功执行,却在容器中失败,因为容器的 localhost 不是宿主机的 localhost。
还有一种完全不显示错误消息的故障模式:没有网络连接。云端路径会完全停止工作,而本地路径不会受到影响。如果设备离开原有网络,或者服务提供商发生路由故障,这种差异就是整个产品的关键。
何时适合选择哪种方式
当工作负载具有突发性、模型过大而无法部署在 VPS 上,或您仍在评估某个模型是否值得作为基础时,使用 Ollama Cloud。按 token 付费通常优于为每天只运行二十分钟的空闲 GPU 持续付费;拥有 1200 亿参数的模型也无法部署在一台租金只够买一顿午餐的服务器上。
当提示词不能离开您的基础设施、机器必须在离线环境中工作,或负载足够稳定、租用的 GPU 能持续保持繁忙时,自行运行模型。稳定负载是最可靠的判断信号:按量计费的推理服务在持续运行时成本恰恰最高。如果您遇到 Ollama 单请求吞吐量成为瓶颈的情况,vLLM 处理并发负载的能力优于 Ollama;这属于更换推理引擎,而不是更换主机。如果您更愿意购买而不是自行构建这套私有环境,将仅提供报价的私有 AI 服务器与租用 GPU 自行构建方案进行比较可以说明实际构建内容,以及何时直接购买 API 更划算。
大多数实际部署最终都会同时使用这两种方式。只要明确划分边界,这没有问题。将模型名称写入配置,记录每次回退,您就始终能够回答这里唯一重要的问题:这些提示词中,哪些离开了您的基础设施?
FAQ
Ollama Cloud 会看到我的提示词吗?
会。在托管路径中,完整提示词和完整补全结果都会发送到 ollama.com,并在那里处理。Ollama 的隐私政策声明,它会“暂时处理您的提示词和响应以提供服务”,并且“不会使用您的输入或输出训练任何 AI 模型”,同时还说明了旨在尽量减少数据保留的措施。这是供应商针对您已经交出的数据作出的承诺。对于本地模型,同一政策声明公司“不会收集、存储、传输或访问您在本地处理的提示词、响应、模型交互或其他内容”。如果要求内容永不离开您的基础设施,则只有本地路径满足这一要求。
为什么模型在云端运行时,我的应用仍然指向 localhost?
因为本地 daemon 充当代理。当您运行 ollama signin,然后请求云模型(名称以 -cloud 或 :cloud 结尾的模型)时,daemon 会将请求转发到 ollama.com,再通过端口 11434 将响应流式传回。应用 URL 不会改变,这正是这种方式的作用:对于普通聊天请求,无需修改代码;但依赖结构化输出的调用需要重做,因为 Ollama Cloud 目前不支持结构化输出。这也意味着 localhost 地址无法说明推理实际发生的位置。请检查模型名称,而不是 URL。名称中的 cloud 标签表示提示词已经跨越互联网传输。
为什么同一个模型在本地运行时提供给我的上下文短得多?
Ollama 会根据可用的视频内存选择本地默认值:VRAM 少于 24 GiB 时约为 4k tokens,24 至 48 GiB 时为 32k,48 GiB 及以上时为 256k。没有 GPU 的 VPS 属于最低档。云模型默认使用最大上下文长度,因为用于保存上下文的内存属于供应商。使用 OLLAMA_CONTEXT_LENGTH 提高本地值,可将其设置为 OLLAMA_CONTEXT_LENGTH=32768 ollama serve,也可以在 systemctl edit ollama.service 下添加 Environment= 行。请注意,更长的上下文需要更大的 RAM key-value cache,因此在小型服务器上提高该值可能会降低生成速度,或导致模型无法加载。
云服务无法访问时,我可以自动回退到本地模型吗?
可以,而且只需几行代码,因为两条路径使用相同的 API。创建两个 Client 对象:一个不带 host 参数,连接本地 daemon;另一个使用 host="https://ollama.com",并添加 Authorization: Bearer header。然后在第一次调用外层捕获 httpx.ConnectError 和 ollama.ResponseError。请有意选择回退方向。优先使用本地模型、云模型作为回退,意味着原本要保密的提示词可能在 daemon 常规重启期间离开机器。因此应记录每次回退;对于敏感工作负载,应直接抛出错误,而不是回退。