1. 多卡服务器上 Ollama 与 vLLM 部署 Qwen3.5 实测:为什么我最后把 endpoint 改到了 TaoToken
如果你手里有一台多卡服务器,想跑 Qwen3.5 这类 27B 级别的模型,大概率会在 Ollama 和 vLLM 之间纠结。Ollama 装起来快、单机体验顺滑,vLLM 并发吞吐猛、适合做服务端。但真正把两个框架都部署一遍、压测一轮之后,我发现一个更现实的问题:本地多卡推理的成本和运维复杂度,对个人开发者和小团队来说并不划算。
这篇就按我实际在 8 卡 2080Ti 机器上的操作,把 Ollama 和 vLLM 部署 Qwen3.5 的完整配置、多卡并行参数、压测脚本都写清楚,最后演示怎么把推理 endpoint 统一改到 TaoToken 的 Key/API 通道,用请求延迟和吞吐数据对比一下两条路线的差别。适合想降低推理成本、又不想被显卡和运维绑死的开发者。
先说结论方向:单用户低频场景,Ollama 的 GGUF 内核响应体感更轻快;多并发服务端场景,vLLM 的 PagedAttention 线性扩展明显更强。但如果你只是偶尔调用、或者想把精力放在业务而不是显卡调度上,把 endpoint 指向 TaoToken 这种统一 API 通道,反而更省心。下面一步步来。
2. TaoToken 前置准备:统一 Key 与 API 通道,给多卡部署留一条退路
在正式折腾多卡之前,我建议你先把 TaoToken 这条通道准备好。原因很简单:本地部署再顺,也会遇到显存不够、并发上不去、机器被占用的情况,这时候有一个稳定的云端 API 兜底,调试和上线都不会卡住。
TaoToken 官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基础地址是 https://taotoken.net/api ,注意这个 API 地址不带 UTM 参数,配置的时候直接填这个就行。
你需要准备三样东西,我把它叫做「三件套」:Base URL、API Key、Model ID。Base URL 就是 https://taotoken.net/api ,API Key 在控制台的 API Keys 页面生成,Model ID 按你实际要调的模型填,比如 Qwen 系列对应的模型标识。这三件套在后面的 Ollama、vLLM、以及各种客户端里都会反复用到。
生成 Key 的路径是:进入控制台,找到 API Keys 管理页,新建一个 Key,复制保存。这个 Key 只显示一次,丢了就重新建。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API Keys 页面是 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
如果你后面要接 Claude Code 这类编码工具,或者想用 Coding Plan 做长期编码任务,可以看 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。想先验证模型对话效果,用 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 就行。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,配置遇到问题先翻这里。
为什么要在多卡部署前先准备这个?因为本地部署的验证阶段,你经常需要对比「本地模型输出」和「云端模型输出」,有一个统一通道,切换成本几乎为零。而且当你发现本地并发压不上去、或者机器要拿去跑别的任务时,改一行 endpoint 就能继续用,不用重装环境。
3. 可复制配置:Ollama 与 vLLM 部署 Qwen3.5 的完整片段
这一节是核心,我把 Ollama 和 vLLM 两条路线的配置都写成可直接复制的片段。服务器环境参考:Ubuntu 22.04 LTS,8 卡 2080Ti 11GB,CPU 是 Xeon Gold 6242R。显存管够能塞下完整的 Qwen3.5-27B。
3.1 Ollama 安装与多卡环境变量脚本
Ollama 用官方脚本一键装:
curl -fsSL https://ollama.com/install.sh | sh装完默认注册成 systemd 服务并自启动。为了开发调试方便,先关掉:
sudo systemctl stop ollama sudo systemctl disable ollama然后写一个环境变量脚本ollama-env.sh,把多卡和并行参数都放进去:
#!/bin/bash # Ollama 完整环境变量配置脚本 # 使用方法: source ollama-env.sh && ollama serve pkill ollama # 指定使用哪几张 GPU export CUDA_VISIBLE_DEVICES="0,1,2,3,4,5,6,7" # 多 GPU 时强制均匀分布 export OLLAMA_SCHED_SPREAD=1 # 模型保存时长,-1 表示常驻 export OLLAMA_KEEP_ALIVE=-1 # 单个模型的最大并行请求数 export OLLAMA_NUM_PARALLEL=2 # 同时最大模型加载数 export OLLAMA_MAX_LOADED_MODELS=2 echo "==========================================" echo "启动命令: ollama serve" echo "==========================================" read -p "是否立即启动 Ollama 服务? (y/n): " confirm if [[ $confirm == "y" ]]; then ollama serve fi保存后执行source ./ollama-env.sh,再拉模型:
ollama pull qwen3.5:27b启动后测试:ollama run qwen3.5:27b,或者直接用 API 调用。
3.2 vLLM 安装与启动参数
vLLM 官方推荐用 uv 管理环境,示例 Python 3.12:
uv venv --python 3.12 --seed --managed-python source .venv/bin/activate uv pip install vllm --torch-backend=auto模型从魔塔下载完整权重到本地:
modelscope download --model Qwen/Qwen3.5-27B --local_dir ./models/Qwen/Qwen3.5-27B启动 vLLM 服务,多卡张量并行参数如下:
vllm serve ./models/Qwen3.5-27B \ --gpu-memory-utilization 0.85 \ --tensor-parallel-size 8 \ --max-model-len 8192 \ --dtype half \ --enforce-eager \ --max-num-seqs 48看到启动日志显示监听端口,就说明服务起来了。--tensor-parallel-size 8对应 8 张卡,--gpu-memory-utilization 0.85控制显存占用,--max-num-seqs 48是最大并发序列数,这几个参数后面压测会重点看。
3.3 把 endpoint 改到 TaoToken 的配置片段
不管你用 Ollama 还是 vLLM,客户端调用都可以统一成 OpenAI 兼容格式。下面是一个通用的settings.json片段,把 Base URL 指向 TaoToken:
{ "api_base": "https://taotoken.net/api", "api_key": "sk-你的TaoTokenKey", "model": "Qwen3.5-27B", "timeout": 120, "max_retries": 3 }如果你用的是 Codex 的auth.json,结构类似:
{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的TaoTokenKey", "model": "Qwen3.5-27B" }三件套再强调一遍:Base URL 填https://taotoken.net/api,Key 填你生成的,Model ID 填实际模型标识。本地 Ollama 默认端口是 11434,vLLM 默认是 8000,切换的时候只改 Base URL 这一行就行。
4. 验证请求与成功结果:压测脚本与延迟吞吐数据
配置好之后,先做单次请求验证,再上压测脚本。单次验证用 curl:
curl https://taotoken.net/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-你的TaoTokenKey" \ -d '{ "model": "Qwen3.5-27B", "messages": [{"role": "user", "content": "用一句话解释什么是张量并行"}], "max_tokens": 128 }'返回里有choices字段和内容,就说明通道通了。本地 Ollama 的验证类似,把 URL 换成http://localhost:11434/v1/chat/completions。
压测脚本我用 Python 写了一个简单的并发测试,统计 TPS(Tokens Per Second):
import time import asyncio import aiohttp API_URL = "https://taotoken.net/api/v1/chat/completions" API_KEY = "sk-你的TaoTokenKey" MODEL = "Qwen3.5-27B" async def one_request(session, prompt): payload = { "model": MODEL, "messages": [{"role": "user", "content": prompt}], "max_tokens": 256 } headers = {"Authorization": f"Bearer {API_KEY}"} start = time.time() async with session.post(API_URL, json=payload, headers=headers) as resp: data = await resp.json() elapsed = time.time() - start tokens = data.get("usage", {}).get("completion_tokens", 0) return tokens, elapsed async def bench(concurrency): async with aiohttp.ClientSession() as session: tasks = [one_request(session, "写一段关于推理优化的说明") for _ in range(concurrency)] results = await asyncio.gather(*tasks) total_tokens = sum(r[0] for r in results) total_time = max(r[1] for r in results) print(f"并发 {concurrency}: 总 tokens={total_tokens}, 耗时={total_time:.2f}s, TPS={total_tokens/total_time:.2f}") for c in [1, 2, 8, 16, 24, 32, 48]: asyncio.run(bench(c))实测数据汇总(TPS,Tokens Per Second):
| 并发数 | vLLM (FP16) TPS | Ollama (GGUF) TPS |
|---|---|---|
| 1 | 12.16 | 20.61 |
| 2 | 22.12 | 无法并发 |
| 8 | 83.51 | - |
| 16 | 161.57 | - |
| 24 | 244.98 | - |
| 32 | 316.22 | - |
| 48 | 282.00 | - |
结果分析:vLLM 在并发 1 到 32 之间,总吞吐几乎线性增长,8 张 2080Ti 被充分榨干。并发推到 48 时,KV Cache 耗尽触发排队或 Swap,总 TPS 掉头向下。在 KV Cache 未完全耗尽前,观察到过 500+ 的 TPS 峰值。Ollama 这边,尽管配了OLLAMA_NUM_PARALLEL,但在 8 卡 2080Ti 这种多路低显存架构下,serve 进程自检判定环境不满足并行条件,请求进入线性排队,无法触发多用户并行。不过单用户访问时,Ollama 的 GGUF 内核推理速度优于 vLLM,低频长回复场景体感更轻快。
把 endpoint 改到 TaoToken 后,同样的压测脚本跑下来,延迟稳定性和本地 vLLM 接近,但省掉了显卡占用和运维。对于不想被硬件绑死的场景,这条通道的性价比更明显。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
部署和接入过程中,我踩过的坑集中在这几类报错,对照着排查能省不少时间。
401 Unauthorized:最常见。先检查 API Key 有没有复制完整,前后有没有空格。TaoToken 的 Key 在 API Keys 页面生成,只显示一次。如果用的是环境变量,确认echo $API_KEY能打印出来。Base URL 也要确认是https://taotoken.net/api,不要多加斜杠或路径。
local proxy failed:这个报错通常出现在客户端配置了本地代理,但代理没起来或者端口不对。检查你的客户端设置里有没有多余的 proxy 配置,把它清掉,直连https://taotoken.net/api。如果是本地 Ollama 调用,确认ollama serve在跑,端口 11434 没被占用。
reading choices 报错:一般是返回体结构不符合预期,比如模型名写错导致返回了错误信息而不是标准choices。检查 Model ID 是否和实际模型标识一致,max_tokens是否设得过大导致超时。用 curl 先做单次请求,看原始返回体里有没有choices字段。
OAuth 相关报错:如果你接的是 Claude Code 这类工具,OAuth 流程走不通时,先确认用的是 API Key 模式而不是 OAuth 模式。Claude Code 接入的文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,按文档里的 Base URL、Key、Model ID 三件套填。ClaudeCodeAnthropic 的接入入口是 https://taotoken.net/claudecode-anthropic?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
还有一个容易忽略的点:vLLM 启动时如果--tensor-parallel-size和实际卡数不一致,会直接报错退出。8 卡就填 8,4 卡就填 4。--gpu-memory-utilization设太高(比如 0.95)容易 OOM,0.85 是比较稳的值。Ollama 那边,OLLAMA_NUM_PARALLEL设了不一定生效,取决于硬件自检结果,别指望它在低显存多卡上一定能并行。
6. 语义一致 CTA:把 endpoint 统一到 TaoToken,本地与云端自由切换
折腾完这一轮,我的实际做法是:本地保留 Ollama 做单用户快速验证,vLLM 做多并发压测,但生产调用的 endpoint 统一指向 TaoToken。这样显卡不用 24 小时占着,并发上不去的时候直接切云端,改一行 Base URL 就行。
如果你也在做多卡部署,建议先把 TaoToken 的三件套配好:Base URL 用https://taotoken.net/api,Key 在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 生成,Model ID 按实际模型填。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,遇到报错先翻文档再排查。
想先验证模型对话效果,用 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。长期做编码或 Agent 任务,看 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。控制台在 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
最后留一个实用技巧:压测脚本里的并发数不要一上来就拉满,从 1、2、8 逐步往上加,观察 TPS 拐点。vLLM 在 32 并发附近是甜点区,48 开始掉头。Ollama 单用户 TPS 高但并发不行,适合低频场景。把这两条曲线摸清楚,再决定哪些请求走本地、哪些走 TaoToken,成本就能压下来。