夜雨聆风学习资料网

ARTICLE · 1294793

一台电脑同时服务多人:Ollama 并发推理实战

一台电脑同时服务多人:Ollama 并发推理实战

前几期,我们已经完成了 Ollama 的安装、局域网共享,以及大模型的 CPU/RAM 运行和性能优化。

现在,一台配置不错的电脑,已经可以作为本地 AI 服务器,供家里或办公室里的其他设备使用。

但这里还有一个问题:

如果两台电脑同时向同一个模型提问,Ollama 会怎么处理?

比如:

  • 台式机正在让模型分析一段代码。
  • 笔记本同时请求模型总结一篇文章。
  • 另一台电脑也在使用同一个模型进行问答。

它们会一起生成回答,还是必须等前一个请求结束?

如果三个人同时使用,会不会让每个人的回答速度都变慢?

实际上,Ollama 提供了专门的并发处理和模型调度机制。

这一期,我们就通过几个环境变量和一组简单实验,看看怎样让一台电脑更合理地处理多个 AI 请求。

1. 先理解:并发和并行有什么区别?

这两个概念经常被放在一起讨论,但含义并不完全相同。

并发(Concurrency),指系统能够在一段时间内处理多个任务。

这些任务不一定在同一时刻真正执行,也可能轮流获得计算资源。

并行(Parallelism),则强调多个任务在同一时间实际执行。

举个简单的例子。

假设有两个人同时向 Ollama 发送请求。

第一种情况:

时间 ──────────────────────────────→请求 A:██████████请求 B:          ██████████

请求 B 必须等待请求 A 完成。

这属于排队处理。

第二种情况:

时间 ──────────────────────────────→请求 A:██████████请求 B:████████████

两个请求的执行时间发生了重叠。

这才是我们希望测试的并行推理能力。

不过,并行不意味着两个请求都能保持原来单独运行时的速度。

因为 CPU、GPU、显存和内存带宽仍然是有限的。

并行处理的核心价值,是提高系统同时服务多个请求的能力,而不是保证每个请求都变得更快。

2. Ollama 是怎样处理多个请求的?

Ollama 的并发处理可以分为两个层面。

第一层:同一个模型处理多个请求。

例如,两台电脑都调用 qwen2.5:7b。

这时可以通过 OLLAMA_NUM_PARALLEL 调整同一个模型能够同时处理的请求数量。

第二层:多个不同模型同时加载。

例如:

qwen2.5:7bllama3.1:8bdeepseek-r1:7b

这些模型都可能被不同客户端调用。

此时,Ollama 需要决定能否让多个模型同时驻留在内存或显存中。

对应的配置是 OLLAMA_MAX_LOADED_MODELS。

如果请求过多,还涉及第三个问题:

暂时处理不了的请求应该排队多久?队列最多能容纳多少请求?

这由 OLLAMA_MAX_QUEUE 控制。

所以,今天最重要的三个参数就是:

参数
主要作用
OLLAMA_NUM_PARALLEL
控制单个模型最多同时处理多少个请求
OLLAMA_MAX_LOADED_MODELS
控制最多同时加载多少个模型
OLLAMA_MAX_QUEUE
控制等待队列最多容纳多少个请求

这三个参数解决的是不同问题,不能相互代替。

3. 第一招:让同一个模型同时处理两个请求

先来看最直接的场景。

假设我们已经下载了:

ollama run qwen2.5:7b

现在希望它能够同时处理两个聊天请求。

在 Windows PowerShell 中执行:

[Environment]::SetEnvironmentVariable(    ”OLLAMA_NUM_PARALLEL”,    ”2”,    ”User”)

这段代码的含义如下。

OLLAMA_NUM_PARALLEL:

控制同一个模型允许的最大并行请求数量。

2:

将最大并行请求数设置为两个。

User:

将环境变量永久保存到当前 Windows 用户的环境配置中。

设置完成后,需要彻底退出 Ollama,再重新启动。

注意:Windows 版 Ollama 可能在系统托盘中后台运行。仅关闭 PowerShell 窗口,并不能确保服务已经重新加载环境变量。

设置为 1、2、4 有什么区别?

设置值
含义
适用情况
1
同一模型最多同时处理一个请求
个人使用、资源有限
2
同一模型最多同时处理两个请求
两台设备共享、小规模并发
4
同一模型最多同时处理四个请求
多用户使用、内存较充足

这里有个重要问题:

为什么不直接设置为 8,甚至 16?

因为并行请求需要额外的运行内存。

每个请求都有各自需要处理的上下文,Ollama 必须为这些请求分配足够的缓存资源。

因此,并行数量越高,通常意味着更高的内存或显存需求。

不能简单认为设置得越大,模型就越快。

4. 并发为什么会增加显存占用?

这就涉及我们第五期介绍过的 KV Cache。

模型处理上下文时,需要保留一部分注意力计算结果,以减少重复计算。

如果只有一个请求,就只需要为当前请求分配相应的上下文缓存。

如果两个请求同时运行,就需要为两个请求准备运行所需的缓存资源。

假设单个请求使用:

num_ctx = 8192

当并行请求数设置为:

OLLAMA_NUM_PARALLEL = 4

那么系统就需要考虑多个并行上下文带来的内存需求。

可以用下面的关系进行初步理解:

并行上下文总容量≈ 单请求上下文容量 × 并行请求数

例如:

8192 × 4 = 32768

这不代表四个请求可以共享同一个 32768 Token 的对话,也不代表 KV Cache 的实际显存占用一定严格增加四倍。

它只是说明:

当单请求上下文长度不变时,提高并行数量,通常需要更多上下文缓存资源。

所以,如果你的显存只有 8GB 或 12GB,直接设置较大的并发数,可能并不合适。

对于显存比较充足的电脑,可以从 2 开始测试,再决定是否提高。

5. 第二招:控制同时加载的模型数量

前面的参数解决的是:

一个模型同时服务多少个请求?

现在再看另一个问题:

一台电脑同时运行多少个模型?

例如,电脑中已经安装:

qwen2.5:7bllama3.1:8bdeepseek-r1:7b

这三个模型的权重可以分别存放在硬盘上,但如果希望它们同时保持加载状态,就需要有足够的内存或显存。

Ollama 提供了:

OLLAMA_MAX_LOADED_MODELS

例如:

[Environment]::SetEnvironmentVariable(    ”OLLAMA_MAX_LOADED_MODELS”,    ”2”,    ”User”)

这里的 2 表示最多允许同时加载两个模型。

不过,它只是数量上限。

并不是设置为 2,Ollama 就一定能够把两个模型同时装入显存。

如果模型过大、显存不足,系统仍然需要根据实际资源情况进行调度。

什么时候适合设置为 1?

如果电脑显存不多,而且主要使用一个大型模型,可以考虑:

[Environment]::SetEnvironmentVariable(    ”OLLAMA_MAX_LOADED_MODELS”,    ”1”,    ”User”)

这样可以限制同时加载的模型数量,避免多个模型竞争有限资源。

但缺点也很明显:

如果两个客户端分别请求不同模型,可能需要等待模型切换。

因此,这个参数的选择取决于使用习惯。

如果经常在多个小模型之间切换,且显存足够,可以尝试更高的值。

如果主要运行一个显存占用很大的模型,则不必追求同时加载多个模型。

6. 第三招:控制请求排队数量

当多个请求同时到达,而服务器暂时没有足够资源处理时,Ollama 可以把部分请求放入等待队列。

例如:

请求 A ──┐         ├── 正在处理请求 B ──┘请求 C ───── 等待请求 D ───── 等待

这时就涉及:

OLLAMA_MAX_QUEUE

例如,可以设置:

[Environment]::SetEnvironmentVariable(    ”OLLAMA_MAX_QUEUE”,    ”16”,    ”User”)

这里的 16 表示最多允许 16 个请求处于等待队列中。

它并不意味着 Ollama 可以同时处理 16 个请求。

两者一定要区分:

  • OLLAMA_NUM_PARALLEL
    :控制同时执行多少个请求。
  • OLLAMA_MAX_QUEUE
    :控制最多允许多少个请求等待。

如果等待队列已满,Ollama 会拒绝额外请求,并可能返回:

HTTP 503Service Unavailable

这通常表示服务端当前过于繁忙。

排队数量是不是越大越好?

不是。

如果模型生成一条回答需要很长时间,那么排在后面的请求即使没有被拒绝,也可能需要等待很久。

因此,对于个人电脑或小规模局域网使用,不一定需要很大的队列。

适当限制等待数量,反而有助于避免大量请求长期积压。

这里的 16 只是用于演示的小规模配置,并不是所有电脑都适用的最佳值。

7. 实战:同时发送两个请求,测试真正的并发能力

原理讲完,接下来直接测试。

这里我们不需要两台电脑,也不需要安装额外软件。

只使用一台 Windows 电脑,通过 PowerShell 同时发送两个请求,就能够观察 Ollama 的处理情况。

第一步:准备测试环境

首先确认模型存在:

ollama list

本次示例使用:

qwen2.5:7b

如果你电脑里没有这个模型,可以将后续代码中的模型名称替换为已经安装的其他模型。

为了方便普通读者照着操作,本文继续使用 Ollama 默认端口:

http://127.0.0.1:11434

第二步:先设置单请求运行

在 PowerShell 中执行:

[Environment]::SetEnvironmentVariable(    ”OLLAMA_NUM_PARALLEL”,    ”1”,    ”User”)

彻底退出并重新启动 Ollama。

接着预加载模型:

ollama run qwen2.5:7b ””

这样可以尽量减少首次加载带来的干扰。

第三步:通过 PowerShell 同时发送两个请求

打开 PowerShell,执行以下代码:

# 基础设置$base = ”http://127.0.0.1:11434”$model = ”qwen2.5:7b”# 定义每个请求要执行的任务$task = {    param($base, $model, $prompt)    $json = @{        model = $model        prompt = $prompt        stream = $false        keep_alive = ”30m”        options = @{            num_ctx = 4096            num_predict = 256        }    } | ConvertTo-Json -Depth 5    $body = [System.Text.Encoding]::UTF8.GetBytes($json)    $sw = [Diagnostics.Stopwatch]::StartNew()    $r = Invoke-RestMethod `        -Uri ”$base/api/generate” `        -Method Post `        -ContentType ”application/json; charset=utf-8” `        -Body $body `        -TimeoutSec 600    $sw.Stop()    [PSCustomObject]@{        Seconds = [math]::Round($sw.Elapsed.TotalSeconds, 2)        Tokens = $r.eval_count        TokensPerSecond = if ($r.eval_duration -gt 0) {            [math]::Round(                $r.eval_count * 1e9 / $r.eval_duration, 2            )        } else { 0 }    }}# 准备两个不同的问题$prompt1 = ”请列举五种提高学习效率的方法,并逐条解释。”$prompt2 = ”请列举五种降低电脑能耗的方法,并逐条解释。”# 开始计时$clock = [Diagnostics.Stopwatch]::StartNew()# 同时启动两个后台请求$job1 = Start-Job -ScriptBlock $task `    -ArgumentList $base, $model, $prompt1$job2 = Start-Job -ScriptBlock $task `    -ArgumentList $base, $model, $prompt2# 等待请求完成$jobs = @($job1, $job2)$jobs | Wait-Job | Out-Null$clock.Stop()# 查看两个请求的结果$jobs | Receive-Job# 查看全部完成时间Write-Host ”两个请求总耗时:” `    $clock.Elapsed.TotalSeconds ”秒”# 清理后台任务$jobs | Remove-Job

代码看起来比较长,但实际上只做了三件事:

① 构造两个聊天请求。

两个请求使用同一个模型,但问题不同。

② 使用Start-Job同时发送。

PowerShell 会创建两个后台任务,让两个 HTTP 请求的执行时间尽可能重叠。

③ 等待全部完成并统计时间。

通过 Wait-Job 等待两个任务结束,然后查看各自耗时和整体完成时间。

这里需要特别解释几个参数。

参数
作用
Start-Job
启动 PowerShell 后台任务
Wait-Job
等待后台任务完成
Receive-Job
获取后台任务的执行结果
Remove-Job
清理已经完成的后台任务
Stopwatch
测量实际经过的时间
stream = $false
等待模型生成完成后一次性返回
num_predict = 256
限制单次生成的最大 Token 数量

这段代码并不会创建两个 Ollama 服务器。

两个 PowerShell 任务最终仍然访问同一个 Ollama 服务。

因此,我们测试的是同一个模型服务对并发请求的处理能力。

第四步:修改为两个并行请求

第一次实验完成后,修改环境变量:

[Environment]::SetEnvironmentVariable(    ”OLLAMA_NUM_PARALLEL”,    ”2”,    ”User”)

然后彻底退出 Ollama,重新启动,再次预加载模型。

接着重复运行刚才的测试代码。

两次实验唯一需要重点改变的配置,就是:

第一次:OLLAMA_NUM_PARALLEL = 1第二次:OLLAMA_NUM_PARALLEL = 2

这样就能够观察并行数量变化对实际请求处理的影响。

8. 怎样判断并发有没有效果?

建议把两次实验的结果整理成表格。

测试项目
并行数 = 1
并行数 = 2
两个请求的整体完成时间
实测填写
实测填写
请求 A 耗时
实测填写
实测填写
请求 B 耗时
实测填写
实测填写
请求 A 的 Token/s
实测填写
实测填写
请求 B 的 Token/s
实测填写
实测填写
GPU 显存占用
实测填写
实测填写

这里不预先填写结果,因为不同显卡、模型和上下文配置的测试表现可能相差很大。

我们需要关注两个问题。

问题一:两个请求的整体完成时间有没有缩短?

如果在 OLLAMA_NUM_PARALLEL=2 时,两个请求能够更充分地重叠执行,那么整体完成时间可能缩短。

但具体收益取决于计算资源是否充足。

问题二:单个请求的生成速度有没有下降?

这同样很重要。

假设一个模型单独运行时,GPU 资源已经基本被充分利用。

此时让两个请求同时运行,不一定能够让每个请求维持原来的 Token/s。

甚至可能出现:

整体处理能力有所改善,但单个请求的生成速度下降。

因此,评价并发能力时不能只看某一个请求的速度。

更合理的指标是:

整体吞吐量= 测试期间完成的总输出 Token 数量÷ 整体经过时间

另外,PowerShell 后台任务的启动也会产生少量额外开销。

如果希望实验更加可靠,建议多运行几次,交换两组测试的先后顺序,并保持模型、输入内容、上下文和其他运行设置一致。

需要注意,PowerShell 测得的请求总耗时包含客户端等待时间,而 Ollama 返回的 eval_duration 主要用于统计生成阶段。两者不应直接混为一谈。

9. 实际使用时,应该怎么设置?

对于普通个人电脑,我不建议一开始就把所有并发参数调得很高。

可以根据使用场景选择。

使用场景
并行请求数
同时加载模型数
建议
一个人使用一个模型
1
1
以稳定和单请求体验为主
两台设备共用一个模型
2
1
优先测试两个请求能否并行
多人使用同一个小模型
2~4
1
观察显存和整体吞吐量
经常切换多个小模型
1~2
2
重点测试模型加载与切换
大模型占满显存
1
1
不宜盲目提高并发

这些只是适合入门测试的起点,并不是通用的最优配置。

例如,某些拥有大内存的电脑,即使显卡显存不足,也可能利用 CPU/RAM 运行多个模型。

但此时瓶颈可能转移到 CPU 性能和内存带宽上。

因此,硬件资源丰富,并不代表并发数量可以无限提高。

一组适合小规模共享的起步配置

假设你的电脑主要运行一个模型,同时服务两台设备,可以先尝试:

# 单个模型最多处理两个并行请求[Environment]::SetEnvironmentVariable(    ”OLLAMA_NUM_PARALLEL”,    ”2”,    ”User”)# 最多同时加载一个模型[Environment]::SetEnvironmentVariable(    ”OLLAMA_MAX_LOADED_MODELS”,    ”1”,    ”User”)# 最多允许16个请求等待[Environment]::SetEnvironmentVariable(    ”OLLAMA_MAX_QUEUE”,    ”16”,    ”User”)

设置完成后,重新启动 Ollama。

这套配置的思路是:

保留一个主要模型,让它尽量同时服务两个请求,并限制过多请求积压。

如果后续需要同时使用多个不同模型,再根据显存容量调整 OLLAMA_MAX_LOADED_MODELS。

10. 常见问题

为什么设置了 OLLAMA_NUM_PARALLEL=2,两个请求还是很慢?

并发数量只是服务端允许的最大并行请求数,并不意味着硬件有足够资源让两个请求都快速运行。

如果模型本身已经占用了大量显存,增加并发可能进一步提高缓存占用和计算压力。

可以先通过:

ollama ps

检查模型当前的运行位置和上下文配置。

两台电脑同时使用,需要启动两个 Ollama 吗?

不需要。

第二期已经介绍过 Ollama 的局域网共享。

只要服务器允许局域网访问,两台设备就可以连接同一个 Ollama 服务。

并行处理能力由运行模型的服务器负责。

不过,局域网访问与并发调度是两个不同概念:网络能够连接,并不保证请求一定会并行执行。

OLLAMA_NUM_PARALLEL=4,是不是最多只能有四个人使用?

不是。

这个参数控制的是单个模型同时处理请求的数量。

如果更多请求到达,其他请求可以进入等待队列,直到有处理能力可用。

是否允许继续排队,还取决于 OLLAMA_MAX_QUEUE 等设置。

为什么切换到另一个模型后,需要等待很久?

因为新模型可能尚未加载。

如果内存或显存不足以同时容纳多个模型,Ollama 可能需要等待已有模型空闲并卸载,然后再加载新模型。

所以,频繁切换多个大型模型,可能产生明显的等待时间。

11. 小结

这一期,我们主要理解了 Ollama 的三个并发调度参数。

OLLAMA_NUM_PARALLEL

控制同一模型能够同时处理多少个请求。

OLLAMA_MAX_LOADED_MODELS

控制最多允许同时加载多少个模型。

OLLAMA_MAX_QUEUE

控制最多允许多少个请求等待处理。

它们分别对应:

并行处理、模型加载和请求排队。

实际使用时,应该根据电脑硬件和使用人数选择合适的配置,而不是简单地将每个参数调到最大。

尤其要记住:

并发能力提高,不等于单个请求一定更快。

对于只有一个用户的电脑,优先保证单请求性能通常更加重要。

而对于需要服务两三台电脑的本地 AI 服务器,适当提高并发能力,可能改善多人同时使用时的整体体验。

这一期,我们已经让 Ollama 从“一个人使用的聊天工具”,进一步走向了“能够同时处理多个请求的本地 AI 服务”。

不过,到目前为止,模型主要还是在回答问题。

如果希望它不仅能够聊天,还能够调用外部功能、处理实际任务,就需要用到另一个重要能力:

Tool Calling(工具调用)。

下一期,我们就来看看,如何让 Ollama 不只会回答问题,还能真正使用工具。

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料