双卡 A100 上如何给 Ollama 做轮询分发与健康检查,真正把吞吐跑满

一、为什么双实例比"一个实例看见两张卡"更适合吞吐优先场景

如果你的模型能完整装进单张 A100,那么对"整机总吞吐"来说,双实例双端口 往往比"单实例双卡自动调度"更直观、也更好控。原因很简单:你把 11434 固定给 GPU0,把 11435 固定给 GPU1,请求层再做轮询,这样两张卡会各自维护一份模型副本,各自处理一部分流量。Ollama 的 API 本身就是本地 HTTP 服务,天然适合被上层反向代理接入。(Ollama 文档)

这套思路的核心不是"花哨",而是可控 。单实例跨卡更适合"模型太大,单卡放不下";双实例更适合"模型能单卡放下,但我要吃满整机并发"。一旦你用轮询把流量稳定摊到两个实例上,双卡就不再是"理论资源",而会变成真正可被业务吞掉的吞吐能力。这个判断是基于 Ollama 的本地 API 形态和多实例部署方式做出的工程化设计。(Ollama 文档)

二、最小可用架构:11434 + 11435 + 一个入口层

推荐的结构非常简单:

  • ollama-gpu0127.0.0.1:11434
  • ollama-gpu1127.0.0.1:11435
  • 一个统一入口:Nginx 或 HAProxy
  • 业务系统只调用统一入口地址

这样做的好处是,业务代码永远只认一个入口,而后端两个 Ollama 实例可以独立重启、独立摘除、独立预热。只要入口层健康检查配置合理,一个实例挂了,流量会自动被送到另一个实例。HAProxy 官方文档明确把健康检查定义为"只让健康服务器保留在负载均衡轮转中";Nginx 也支持 upstream 服务器组,并能基于失败次数与超时做被动摘除。(HAProxy Technologies)

三、先别急着上 Nginx,先把两个实例本身验证通

反向代理只是"调度层",前提是你的两个 Ollama 实例都能独立工作。先分别检查:

bash 复制代码
curl http://127.0.0.1:11434/api/version
curl http://127.0.0.1:11435/api/version

/api/version 是最轻量的可达性检查接口,适合拿来做存活探测;如果你想看当前实例内存里有没有已经装载的模型,就查 /api/ps。这两个接口都属于官方 API。(Ollama 文档)

再分别试一条最小生成请求:

bash 复制代码
curl http://127.0.0.1:11434/api/generate -d '{
  "model": "gemma3",
  "prompt": "你好",
  "stream": false
}'

curl http://127.0.0.1:11435/api/generate -d '{
  "model": "gemma3",
  "prompt": "你好",
  "stream": false
}'

Ollama 的 /api/generate 接口要求至少提供 modelpromptstream 默认为 true,压测或联调阶段把它设成 false 更方便看完整返回。响应里还会带上 total_durationload_durationeval_counteval_duration 等指标,这些字段非常适合做性能分析。(Ollama 文档)

四、为什么"预热"是双实例吞吐稳定的关键

很多人在压测时发现一个很奇怪的现象:第一批请求慢,后面快;或者两台实例里总有一台突然比另一台慢一大截。问题往往不在显卡,而在模型装载与预热

Ollama 官方 FAQ 明确提到:你可以通过发送一个"空请求"来预加载模型,这对 /api/generate/api/chat 都生效。也就是说,在正式接流量之前,先对 1143411435 各打一遍预热请求,让两边都把模型拉进内存,再开始分流,首包延迟会明显更稳定。(Ollama 文档)

例如:

bash 复制代码
curl http://127.0.0.1:11434/api/generate -d '{"model":"gemma3"}'
curl http://127.0.0.1:11435/api/generate -d '{"model":"gemma3"}'

如果你本身已经配置了 OLLAMA_KEEP_ALIVE=-1,那预热效果会更明显,因为模型不会很快被卸掉。这样做的本质,就是把"第一次装载的代价"提前支付掉,而不是让真实用户帮你承担。相关预热方式来自官方 FAQ,模型常驻则来自运行参数设计。(Ollama 文档)

五、入口层选型:Nginx 够轻,HAProxy 更像"正经负载均衡器"

1)Nginx 的优点

Nginx 非常适合已经在线上普遍使用它的团队。它的 upstream 机制可以定义后端服务器组,再通过 proxy_pass 统一转发。官方文档说明,Nginx 支持多种负载分发方式,其中最常见的就是默认轮询;同时,max_failsfail_timeout 可以让后端在连续失败后被暂时标记为不可用。(Nginx)

2)Nginx 的限制

很多人以为 Nginx 开源版就能直接做完整主动健康检查,其实不是。ngx_http_upstream_hc_module 这个"周期性主动健康检查"模块是 商业订阅版本 才有;开源常见做法更多是依赖被动失败摘除,也就是通过真实请求失败次数来判断后端是否有问题。(Nginx)

3)HAProxy 的优点

如果你更看重"负载均衡本身",HAProxy 会更像专业工具。它原生支持健康检查;官方文档明确说明,健康检查的目的是确保只有健康服务器保留在轮转中,而且 balance 可以选择 roundrobinleastconn 等算法。对于 Ollama 这种长连接不算多、但单请求较重的推理服务,roundrobin 往往足够简单有效;如果你更关心当前连接数均衡,可以考虑 leastconn。(HAProxy Technologies)

六、Nginx 方案:最小够用版

如果你已经有 Nginx,只想快速把两台 Ollama 实例挂起来,这样配就够用了:

nginx 复制代码
upstream ollama_backend {
    server 127.0.0.1:11434 max_fails=3 fail_timeout=10s;
    server 127.0.0.1:11435 max_fails=3 fail_timeout=10s;
    keepalive 32;
}

server {
    listen 8080;
    server_name _;

    location / {
        proxy_pass http://ollama_backend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Connection "";
        proxy_connect_timeout 3s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;
    }
}

这套配置的含义是:把两个 Ollama 实例放进一个 upstream 组,由 Nginx 在它们之间分流;如果某个后端在 fail_timeout 期间连续失败达到 max_fails 次,就会被临时视为失败节点。Nginx 官方文档对 upstreammax_failsfail_timeout 的语义都有明确说明。(Nginx)

这里有个实战建议:Nginx 适合"已经有它"的环境,不适合把所有高级健康检查幻想都压在它身上。 如果你只是想快速把两个 Ollama 实例挂成一个统一入口,它很方便;但如果你要更明确的主动健康检查、熔断、重试与状态可视化,HAProxy 往往更省心。这个判断基于两者官方文档展示的能力边界。(Nginx)

七、HAProxy 方案:更像生产级标准答案

如果让我给"双 A100 + 双实例 Ollama"选一个更顺手的生产入口,我会更偏向 HAProxy。原因不是它"更高级",而是它对后端健康检查和负载均衡这件事更聚焦。

一个很实用的配置可以这样写:

haproxy 复制代码
global
    log /dev/log local0
    maxconn 10000

defaults
    mode http
    log global
    option httplog
    timeout connect 5s
    timeout client  300s
    timeout server  300s
    retries 2

frontend ollama_front
    bind *:8080
    default_backend ollama_back

backend ollama_back
    balance roundrobin
    option httpchk GET /api/version
    http-check expect status 200
    server gpu0 127.0.0.1:11434 check inter 3s fall 2 rise 2
    server gpu1 127.0.0.1:11435 check inter 3s fall 2 rise 2

这里最关键的是两点:

第一,balance roundrobin 会让请求轮流打到 gpu0gpu1。HAProxy 官方文档写得很明确,后端默认就是共享工作负载,且支持 roundrobinleastconn 等算法。(HAProxy Technologies)

第二,check 会对后端做健康检查;而 option httpchk GET /api/version 则把健康检查请求定向到 Ollama 的 GET /api/version 接口。HAProxy 官方文档对健康检查的定义非常清晰:不健康的服务器会被移出负载均衡轮转。(HAProxy Technologies)

如果你问我,为什么不是拿 /api/generate 来做健康检查?因为那太重了。/api/version 返回轻、快,而且足够验证进程是否正常提供 HTTP API;真正的"模型是否已预热",可以通过独立预热脚本和 /api/ps 来辅助判断。(Ollama 文档)

八、健康检查应该检查什么,别一上来就查"最重的接口"

这是很多推理服务最容易配错的地方。

第一层:进程存活

检查 /api/version 即可。它轻量、简单、返回快,适合高频探测。官方 API 提供该接口。(Ollama 文档)

第二层:模型是否已装载

检查 /api/ps。它能返回"当前已加载到内存的模型列表",适合用于预热完成后的巡检。官方 API 里就有这个接口。(Ollama 文档)

第三层:推理链路是否真的可用

这层不要用高频健康检查做,而应该用低频巡检或业务级探测,比如每隔一段时间打一条极短的 /api/generate 请求,验证模型能否在可接受时延内返回。因为 /api/generate 返回里自带 total_durationload_durationeval_duration 等指标,非常适合用于"慢病监控",但不适合每秒钟高频打。(Ollama 文档)

一句话总结就是:

  • 存活用 /api/version
  • 装载用 /api/ps
  • 性能用 /api/generate 指标

这样既不会把健康检查本身搞成负担,也能把实例状态看得比较完整。相关接口能力都来自官方 API 文档。(Ollama 文档)

九、如何判断"是不是已经把双卡真的吃起来了"

只看到两个服务 running 还不够。你要确认的是:

  1. 两个实例都在接流量
  2. 两个实例都装了模型
  3. 模型没有明显 offload 到 CPU
  4. 每个请求的负载分布基本均衡

先查各自的模型装载情况:

bash 复制代码
curl http://127.0.0.1:11434/api/ps
curl http://127.0.0.1:11435/api/ps

然后用 ollama ps 看本机当前模型状态。Ollama 的上下文长度文档明确建议:为了更好的性能,应避免把模型 offload 到 CPU,并通过 ollama ps 里的 PROCESSOR 字段确认是否为 100% GPU。(Ollama 文档)

再配合 nvidia-smi 观察两张卡的显存与利用率:

bash 复制代码
watch -n 1 nvidia-smi

如果轮询正常、预热正常、请求量足够,你会看到两张卡都在持续吃显存和算力,而不是只有一张卡承担绝大多数请求。

十、调用侧别写死单端口,做一个最朴素的客户端分流就够了

很多团队其实不一定非要上 Nginx 或 HAProxy。你完全可以在调用侧自己做一个非常朴素的分流器:比如轮询 1143411435,失败时自动切到另一边。这种方式的优点是轻量,缺点是健康检查和摘除逻辑要自己写。

最简单的 Python 伪代码大概是这样:

python 复制代码
import itertools
import requests

ENDPOINTS = itertools.cycle([
    "http://127.0.0.1:11434",
    "http://127.0.0.1:11435",
])

def generate(prompt, model="gemma3"):
    last_error = None
    for _ in range(2):
        base = next(ENDPOINTS)
        try:
            r = requests.post(
                f"{base}/api/generate",
                json={"model": model, "prompt": prompt, "stream": False},
                timeout=300,
            )
            r.raise_for_status()
            return r.json()
        except Exception as e:
            last_error = e
    raise last_error

这样做的底层依据是:Ollama 运行后 API 自动可用,而 /api/generate 是标准生成接口;如果你更偏向兼容现有 SDK,Ollama 还提供 OpenAI 兼容接口,base_url 指向 http://localhost:11434/v1 即可。(Ollama 文档)

如果你已经有一套 OpenAI SDK 代码,那么接入双实例时,可以把 "目标 base_url" 做成可切换配置;如果你前面挂了 HAProxy,那业务端甚至不用感知后端有两台 Ollama。Ollama 的 OpenAI 兼容能力来自官方文档。(Ollama 文档)

十一、别盲目把上下文拉大,吞吐优先和长上下文优先是两回事

很多人想"性能拉满",第一反应就是把 OLLAMA_CONTEXT_LENGTH 拉到很大。这个思路并不总对。Ollama 的上下文长度文档强调:为了获得更好性能,应尽量使用模型支持的合适上下文长度并避免 CPU offload;同时,也建议通过 ollama ps 检查实际分配的上下文和处理器分布。(Ollama 文档)

对双实例吞吐优先场景来说,8192 或 16384 这类更克制的上下文 往往更合理。因为你追求的是"单位时间处理更多请求",不是"单请求尽量塞进最长历史"。如果你的业务真的是 Agent、长文分析、超长代码理解,再单独给这类服务起长上下文实例会更科学。这个结论是结合官方对上下文与性能关系的建议做出的工程化取舍。(Ollama 文档)

十二、如何做性能观测,不要只盯着显卡利用率

显卡利用率只是结果,不是全貌。真正有用的观测应该至少包括三类:

1)API 返回指标

/api/generate 的响应里有 total_durationload_durationprompt_eval_countprompt_eval_durationeval_counteval_duration。这些字段能告诉你:到底慢在装载、慢在提示词处理,还是慢在生成本身。(Ollama 文档)

2)模型装载状态

/api/ps 能看到当前实例内有哪些模型在内存里。这个接口特别适合判断预热是不是掉了、实例是不是偷偷卸载了模型。(Ollama 文档)

3)实例可达性与版本

/api/version 是最轻量的可达性接口,很适合接到反向代理健康检查,也适合外部巡检脚本快速探测。(Ollama 文档)

所以,别再只看 nvidia-smi。真正能帮你定位瓶颈的,是"API 时延 + 模型装载 + GPU 状态"三件套。

十三、一个很实用的预热与巡检脚本

你可以在服务启动后跑一遍下面这种逻辑:

bash 复制代码
#!/usr/bin/env bash

MODEL="gemma3"

for port in 11434 11435; do
  echo "check version on ${port}"
  curl -sf "http://127.0.0.1:${port}/api/version" || exit 1

  echo "preload ${MODEL} on ${port}"
  curl -sf "http://127.0.0.1:${port}/api/generate" \
    -d "{\"model\":\"${MODEL}\"}" > /dev/null || exit 1

  echo "check running models on ${port}"
  curl -sf "http://127.0.0.1:${port}/api/ps"
done

这个脚本背后的逻辑完全来自官方接口能力:

  • /api/version 做轻探活
  • 空的 /api/generate 请求做预热
  • /api/ps 看是否已装载完成 (Ollama 文档)

如果你用 systemd 管理两个 Ollama 服务,还可以把这个脚本挂到服务启动后的初始化流程里,确保实例在被接流量前就已经热起来。

十四、最终建议:两种常见生产打法

打法一:简单稳定型

  • 双实例:1143411435
  • Nginx 做统一入口
  • 被动失败摘除
  • 启动后预热
  • 业务端只认一个入口

这种方案部署快,改造少,适合已经有 Nginx 的环境。Nginx 的 upstream 和失败摘除语义来自官方文档。(Nginx)

打法二:更像专业负载均衡型

  • 双实例:1143411435
  • HAProxy 做统一入口
  • httpchk GET /api/version
  • roundrobinleastconn
  • 独立预热脚本
  • 业务端只认 HAProxy 入口

这种方案更适合你明确在做 API 服务,且希望健康检查、摘除和分流行为更可控。HAProxy 的健康检查与后端算法能力来自官方文档。(HAProxy Technologies)

如果让我只给一个结论,我会说:

双卡 A100 上要把 Ollama 吞吐跑满,最关键的不是"把参数调多猛",而是"让两个实例持续稳定地接到差不多的流量"。

十五、结尾

到了这一步,双卡 A100 的部署才算真正从"会启动"进入"能打仗"。

前面的安装、权限、端口冲突,解决的是"服务起来";这一篇的轮询、健康检查、预热、性能观测,解决的是"服务跑稳"。只有这两部分合在一起,你的双卡机器才不是一个昂贵的摆设,而是一台真正可持续输出吞吐的推理节点。Ollama 的本地 API、预热方式、运行模型查询、性能指标、OpenAI 兼容接口,再加上 Nginx 或 HAProxy 的分发与健康检查能力,已经足够支撑一套很实用的本地生产方案。(Ollama 文档)

相关推荐
凤山老林15 小时前
Java 开发者零成本上手:用 Spring AI Alibaba + Ollama 本地跑通 DeepSeek 大模型
java·人工智能·ollama·deepseek·spring ai 阿里巴巴
诸神缄默不语2 天前
本地LLM部署工具(写给小白的LLM工具选型系列:第一篇)
llm·大规模预训练语言模型·vllm·ollama
福大大架构师每日一题3 天前
ollama v0.19.0 发布!Web 搜索插件上线、多模型兼容修复、MLX 与 KV 缓存全面优化,本地大模型体验再升级
缓存·ollama
AAA阿giao4 天前
打造你的 Git 提交 AI 神器:从零实现前后端分离的 Commit Message 生成器
react.js·express·ollama
村中少年5 天前
vscode如何添加ollama本地模型-实现token自由
vscode·llm·token·ollama·本地模型·qwen3
竹之却6 天前
【OpenClaw】云服务器端 openclaw 集成本地 Windows端 ollama 模型
windows·llama·ollama·openclaw·qwen3.5
加斯顿工程师6 天前
Windows系统使用Ollama本地化部署Qwen3.5-9B模型教程
windows·大模型·本地部署·ollama·qwen3.5
chenhua7 天前
openclaw基于飞书群聊中减少机器人大模型调用次数
飞书·ollama·群聊·本地小模型·多agent·openclaw
brucelee18610 天前
Debian 安装 Ollama 教程
debian·ollama·open claw