资讯动态

实战自用模型API平台:Ollama+vLLM+Nginx统一服务配TaoToken

发布时间:2026/9/30 21:21:45 来源:尧图企业网站定制
1. 本地多模型服务为什么需要一个统一入口如果你手上有一台带 GPU 的机器大概率经历过这样的场景Ollama 跑着几个轻量模型vLLM 又单独起了一个高吞吐服务每个服务监听不同端口调用方要记住11434是 Ollama、8000是 vLLM换模型就得改代码里的base_url。模型一多端口一乱团队里谁也不知道现在到底有几个模型在跑、该用哪个地址。这就是本地多模型服务统一接入要解决的问题把 Ollama 的轻量灵活、vLLM 的高吞吐推理通过 Nginx 反向代理收口到一个域名下再用 TaoToken 统一 Key 和 API 通道让调用方只认一套 OpenAI 格式接口。适合有一定本地部署基础、想把零散模型服务整合成体系的小团队或个人开发者。我试过把三个模型分别暴露三个端口结果光是维护调用方的配置就够头疼。后来改成 Nginx 统一路由 TaoToken 收口调用方只需要一个 Base URL 和一个 Key模型切换在服务端完成业务代码零改动。这篇文章按真实搭建顺序走先讲 Ollama 和 vLLM 各自怎么起、参数怎么配再给可复制的 Nginx 路由配置然后接 TaoToken 的 settings.json / config.toml 骨架最后用 curl 验证多模型切换并给出常见报错的排查动作。跟着做完你会得到一个对外只有一个入口、对内多引擎并行的本地模型 API 平台。核心检索词先明确Ollama 是轻量本地模型运行工具vLLM 是高吞吐推理引擎Nginx 做反向代理与路由分发TaoToken 提供统一 Key/API 通道。四者组合就是一套可自用的模型 API 平台。2. Ollama 与 vLLM 双引擎启动参数配置这一节把两个引擎分别拉起来参数直接可复制。先明确分工vLLM 跑主模型扛并发Ollama 跑备用模型应付低频需求。显存分配的原则是主模型吃饱、备用吃余量。2.1 vLLM 启动高吞吐主模型假设主模型选 Qwen2.5-14B 的 AWQ 量化版本单卡 24GB 显存。启动命令如下vllm serve Qwen/Qwen2.5-14B-Instruct-AWQ \ --quantization awq \ --gpu-memory-utilization 0.65 \ --max-model-len 8192 \ --port 8000 \ --served-model-name qwen-main几个参数的含义要讲清楚。--quantization awq指定 4bit 量化权重从约 28GB 压到约 8GB。--gpu-memory-utilization 0.65表示 vLLM 最多用 65% 显存24GB 卡上约 15.6GB其中权重 8GB剩下约 7GB 留给 KV Cache能支撑 20 路以上 4K 上下文并发。--max-model-len 8192限制单请求最大长度防止超长请求把 KV Cache 吃光。--served-model-name qwen-main是给调用方看的模型名后面 Nginx 和 TaoToken 都用这个名字路由。启动后看到Uvicorn running on http://0.0.0.0:8000就说明服务起来了。第一次加载模型会花几十秒到几分钟取决于磁盘速度。2.2 Ollama 启动轻量备用模型Ollama 的启动更简单先拉模型再起服务ollama pull llama3.1:8b OLLAMA_HOST0.0.0.0:11434 ollama serveOLLAMA_HOST0.0.0.0:11434是关键默认 Ollama 只监听127.0.0.1Nginx 容器或外部调用方访问不到。设成0.0.0.0才能被反向代理转发。Llama3.1-8B 的 Q4 量化权重约 4.7GB低频调用时按需加载不占常驻显存。如果你想让 Ollama 也常驻可以在启动后先发一个请求把它加载进显存curl http://localhost:11434/api/generate -d { model: llama3.1:8b, prompt: hello, stream: false }这样备用模型就绪主模型和备用模型合计占用约 20.3GB24GB 卡留足安全余量。2.3 用 docker-compose 一键拉起双引擎手动起两个服务容易漏参数用 compose 编排更稳services: vllm-main: image: vllm/vllm-openai:latest command: vllm serve Qwen/Qwen2.5-14B-Instruct-AWQ --quantization awq --gpu-memory-utilization 0.65 --max-model-len 8192 --served-model-name qwen-main ports: - 8000:8000 deploy: resources: reservations: devices: [{driver: nvidia, capabilities: [gpu]}] ollama-backup: image: ollama/ollama:latest environment: - OLLAMA_HOST0.0.0.0:11434 ports: - 11434:11434 volumes: - ollama_models:/root/.ollama deploy: resources: reservations: devices: [{driver: nvidia, capabilities: [gpu]}] volumes: ollama_models:注意两个服务都声明了 GPU 资源但显存分配靠 vLLM 的--gpu-memory-utilization控制Ollama 按需加载不会抢主模型的额度。启动顺序上 vLLM 先起等它加载完再起 Ollama避免显存争抢。3. Nginx 反向代理路由配置与 TaoToken 接入骨架两个引擎起来后对外还是两个端口。这一节用 Nginx 把它们收口到一个入口再通过 TaoToken 统一 Key 和 API 通道。3.1 Nginx 路由分发配置核心思路Nginx 监听 443按路径或模型名把请求转发到不同后端。下面是一份可复制的配置worker_processes auto; events { worker_connections 1024; } http { limit_req_zone $binary_remote_addr zoneapi_limit:10m rate20r/s; upstream vllm_backend { server vllm-main:8000; } upstream ollama_backend { server ollama-backup:11434; } server { listen 443 ssl; server_name llm.internal.com; ssl_certificate /etc/nginx/certs/fullchain.pem; ssl_certificate_key /etc/nginx/certs/privkey.pem; location /v1/ { limit_req zoneapi_limit burst40 nodelay; proxy_pass http://vllm_backend; proxy_read_timeout 300s; proxy_buffering off; proxy_cache off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /ollama/ { limit_req zoneapi_limit burst40 nodelay; proxy_pass http://ollama_backend/; proxy_read_timeout 300s; proxy_buffering off; proxy_cache off; } } }三个容易翻车的点必须强调。第一proxy_read_timeout默认 60 秒长推理请求会被 Nginx 掐断必须调到 300 秒。第二proxy_buffering默认开启Nginx 会攒齐响应再转发流式输出直接报废必须关掉。第三证书用 Lets Encrypt 免费签发certbot certonly --nginx -d llm.internal.com配个 cron 每月自动续期。limit_req_zone做连接级限流单 IP 每秒 20 请求、突发 40防止某个调用方猛刷拖垮后端。3.2 TaoToken 统一 Key 与 API 通道Nginx 解决了路由但调用方还是要分别管 vLLM 和 Ollama 的地址。TaoToken 的作用是把这些后端统一到一个 Key 和一套 API 通道下调用方只认一个 Base URL。TaoToken 的 API 入口是https://taotoken.net/api官网是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。你可以在控制台创建 Key然后在配置里把本地 Nginx 入口注册为上游。先看 Claude Code 的 settings.json 骨架{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-your-taotoken-key, ANTHROPIC_MODEL: qwen-main } }再看 Codex 的 config.toml 骨架model qwen-main model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY如果你用 Cline 或 CC Switch 这类工具配置三件套是固定的Base URL 填https://taotoken.net/apiKey 填控制台生成的sk-开头字符串Model ID 填你在 Nginx 里定义的qwen-main或llama-backup。三者缺一不可Model ID 必须和 vLLM 的--served-model-name或 Ollama 的模型名一致否则会报模型不存在。TaoToken 在这里的角色是统一收口调用方拿一个 Key通过 TaoToken 的通道访问TaoToken 再转发到你本地 Nginx 入口。这样本地模型和云端模型可以共用一套鉴权和计费逻辑模型上下架在服务端完成业务方无感。4. curl 验证多模型切换与成功结果配置写完必须验证否则上线就是盲盒。这一节用 curl 逐个打通。4.1 验证 vLLM 主模型先直连 vLLM 确认服务本身正常curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen-main, messages: [{role: user, content: 用一句话介绍你自己}], stream: false }正常返回是一个 JSONchoices[0].message.content里有模型回复。如果返回model not found检查--served-model-name是否和请求里的model一致。4.2 验证 Ollama 备用模型Ollama 的 OpenAI 兼容接口在/v1路径下curl http://localhost:11434/v1/chat/completions \ -H Content-Type: application/json \ -d { model: llama3.1:8b, messages: [{role: user, content: hello}], stream: false }能返回内容说明 Ollama 的 OpenAI 兼容层正常。注意模型名要带:8b标签和ollama list里显示的一致。4.3 验证 Nginx 统一入口通过 Nginx 入口访问确认路由生效curl https://llm.internal.com/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen-main, messages: [{role: user, content: 测试统一入口}], stream: true }stream: true时应该看到逐字返回的流式输出。如果卡住不动最后一次性返回说明proxy_buffering没关。如果 60 秒后断开说明proxy_read_timeout没调。4.4 验证 TaoToken 通道与模型切换最后通过 TaoToken 通道访问并测试模型切换curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-your-taotoken-key \ -H Content-Type: application/json \ -d { model: llama-backup, messages: [{role: user, content: 切换到备用模型}], stream: false }把model从qwen-main换成llama-backup请求应该路由到 Ollama 后端。两个模型都能通说明统一入口和模型切换都成功了。实测下来从 vLLM 切到 Ollama 的延迟差异明显主模型首字快、备用模型稍慢符合预期。5. 常见报错排查401、local proxy failed、reading choices、OAuth配置过程中最容易撞上四类报错逐个拆解。5.1 401 Unauthorized报错长这样{error: {message: Invalid API key, type: authentication_error}}原因通常是 Key 没传、传错或者 TaoToken 控制台里 Key 被禁用。排查动作先确认请求头是Authorization: Bearer sk-xxx注意Bearer后面有空格。再登录 TaoToken 控制台检查 Key 状态和额度。如果用的是 Claude Code检查 settings.json 里ANTHROPIC_API_KEY是否被环境变量覆盖。5.2 local proxy failed这个报错一般出现在 Cline、CC Switch 这类工具里提示本地代理连接失败。原因是工具配置的 Base URL 指向了本地某个端口但那个端口没有服务在监听。排查动作确认 Nginx 是否在跑docker ps看容器状态。如果 Base URL 填的是http://localhost:8000确认 vLLM 容器端口映射正确。用 TaoToken 通道时Base URL 应该是https://taotoken.net/api不要填本地地址。5.3 reading choices 相关报错报错类似Cannot read properties of undefined (reading choices)这是调用方解析响应时拿不到choices字段。根因通常是后端返回了错误 JSON但调用方按成功格式解析。排查动作先用 curl 直连后端看原始返回确认是不是{error: ...}。常见触发是模型名不匹配vLLM 返回model not found调用方却去读choices。检查--served-model-name和请求里的model是否一致。5.4 OAuth 相关报错Claude Code 或 Codex 在首次配置时可能提示 OAuth 失败或 token 过期。原因是工具默认走官方 OAuth 流程但你用的是自定义 Base URL。排查动作在 settings.json 或 config.toml 里显式指定 API Key 方式不要走 OAuth。Claude Code 里设置ANTHROPIC_API_KEYCodex 里设置env_key TAOTOKEN_API_KEY并导出对应环境变量。确认环境变量在当前 shell 里生效echo $TAOTOKEN_API_KEY能看到值。5.5 排查通用动作遇到任何报错按这个顺序走第一步直连后端 curl确认引擎本身正常。第二步通过 Nginx curl确认路由和超时配置。第三步通过 TaoToken curl确认 Key 和通道。三步定位到具体哪一层出问题比盲目改配置快得多。日志方面Nginx 的access.log和error.log能看到请求是否到达、转发到哪个 upstreamvLLM 和 Ollama 的容器日志能看到模型加载和推理报错。6. 把统一入口用起来从验证到日常调用走到这里你已经有了一个对外单入口、对内双引擎的本地模型 API 平台。日常调用时业务方只需要记住一个 Base URL 和一个 Key模型切换在请求的model字段里完成。如果你主要做模型对话验证可以直接用 TaoToken 的模型对话页面测试不同模型的效果地址是https://taotoken.net/api对应的控制台入口。如果长期做编码或 Agent 任务建议走 Coding Plan把本地模型和云端模型统一编排避免每次手动切配置。接入文档在https://taotoken.net/api的文档区API Keys 在控制台生成。几个实用技巧收尾。第一模型上下架是配置操作改 Nginx 的 upstream 或 TaoToken 的模型注册表重启对应服务即可业务方零感知。第二显存分配先喂饱 vLLMOllama 吃余量主模型并发是命根子。第三流式输出的命门是proxy_buffering off这个坑不踩一次记不住。第四费用和用量在 TaoToken 控制台能看到哪个模型被重度使用一目了然比事后拍脑袋强。平台搭完不是终点日常维护才是。建议把 Nginx 配置、compose 文件、TaoToken 的 settings.json 骨架都放进版本管理下次换模型或加引擎改配置重启就行不用从头再来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑