
很多人第一次听到 openrig 这个名字都以为是个新出的开源框架或者某个大厂的内部项目。其实它就是我给自己那套自托管推理环境起的代号——把开源模型、推理引擎、API 网关这三样东西像搭乐高一样攒起来最终变成一套能稳定对外提供服务的 AI 后端。整个成本可能比你想象的低踩坑过程却一定比你想象的多。这篇就把我从零开始搭 openrig 的完整思路、配置过程和排障记录全部摊开想在自己机器上跑开源模型、又不想被各种碎片化教程绕晕的人可以直接照着抄。1. openrig 的定位为什么我要自己攒一套推理环境1.1 开源模型到底解决了什么问题先聊一个最基础的问题现在各家大模型的 API 已经够便宜、够快了为什么还要折腾一套本地推理环境我的答案很简单——你手里有敏感数据、有高频调用、有定制化需求的时候公有 API 并不总是最优解。举个例子我之前接过一个内部知识库问答需求文档内容属于业务机密不能出内网同时问答场景是白天 8 小时高频并发晚上几乎没人用。如果按公有 API 的按量计费来跑白天高峰期费用高晚上闲置又白花钱而且数据出网这一关就过不了。这种场景下openrig 这套自托管方案就是刚需模型权重放在自己的服务器上推理引擎自己控请求量自己管数据完全在内网流转。很多人觉得开源模型能力不如闭源这个判断放到 2025 年其实已经不太准确了。现在 7B 到 14B 级别的开源模型在代码生成、结构化输出、意图识别这些任务上已经能打到接近商用模型的水准70B 级别以上的模型配合好的推理框架综合能力更是拉近了差距。对大多数业务场景来说模型能力不是瓶颈部署方式和成本结构才是。1.2 自组装的边界与取舍openrig 不是什么大工程它追求的恰恰是“够用就好”。我在设计这套环境时给自己定了三条边界。第一只用开源推理引擎不碰闭源重框架。原因很简单可审计、可改、社区活跃。出了问题能看源码性能瓶颈能自己调换模型不用迁就厂商。第二只做 OpenAI 兼容的 API 层。现在几乎所有开源推理框架都支持 OpenAI 格式的接口这意味着我给 openrig 配好之后既有业务代码几乎不用改把 base_url 指过去就行。这是降低接入成本最关键的一步。第三组件尽可能少能用一个进程解决的就不要拆成微服务。很多人一上来就上个 Kubernetes配个 Ray搞一堆监控面板结果模型还没跑起来先把基础设施折腾坏了。openrig 初期就是一台 GPU 服务器 一个推理引擎进程 一个反向代理 一套存储结构清晰出了问题也好排查。这个取舍思路说到底就是先跑起来再谈优化。2. 组件选型openrig 由哪几块拼成2.1 模型选型先定能力基线openrig 的“芯”是模型权重。选模型我一般按照任务类型和显存预算两条线来。如果是通用对话、代码生成、复杂推理我优先看 14B 到 32B 这个档位的开源模型。这个区间是目前性价比最舒服的位置推理能力足够量化之后显存压力可控单卡 24G 或双卡 24G 就能跑起来。比如 Qwen2.5-14B-Instruct、DeepSeek-R1-Distill-Qwen-14B 这类都是社区验证过、资料很多的模型遇到问题能搜到大量解决方案。如果是纯文本分类、意图识别、信息抽取这类轻任务7B 甚至 1.5B 都够。模型小了部署成本低推理延迟低单位成本极低。我甚至会把小模型用于大模型的前置路由——先让小模型判断请求该走哪条处理链路再决定要不要调大模型。这个组合套路在实际业务里非常省资源。如果对能力要求极高又不想碰闭源就要考虑 70B 级别的模型加多卡并行。但这里我建议谨慎70B 模型的显存、内存、带宽要求都是指数级上涨单机 4 卡起步而且推理引擎的并行配置、量化选择都会直接影响稳定性。openrig 更适合从中小模型起步跑顺之后再评估要不要升级。2.2 推理引擎vLLM 之外的几种选择模型权重只是“食材”推理引擎才是“锅”。openrig 里我首选的引擎是 vLLM这是目前生态最成熟、性能最强的开源推理框架之一。它基于 PagedAttention 技术把 KV Cache 按页管理显存利用率比传统方案高不少而且自带 OpenAI 兼容的 API server装上就能用。vLLM 的优势在大并发、长上下文的场景下特别明显。你可以把它理解成一个专门为 LLM 推理优化的数据库——查询优化、缓存管理、批处理安排都做得很细不需要你自己再去处理连续性问题的细节。除了 vLLM还有几个备选方案按场景选择SGLang同样高性能前几年我在跑复杂采样逻辑时用过它的一些特性和 vLLM 的性能差距在伯仲之间但是资料相对少一些。llama.cpp纯 CPU 起家支持各种量化格式适合没有 N 卡、或者只有 Apple Silicon 的开发机。性能不如 GPU 版本但是兼容性和轻量化无可替代。Transformers FastAPI 自建这是最不推荐的方案因为你要自己处理并发、缓存、连续批处理等一堆工程问题。除非是纯学术验证否则别在生产环境这么干。选 vLLM 还有一层原因它接模型最简单。拉起服务之后自带 /v1/models 和 /v1/chat/completions 接口一个 pip install 加一行启动命令模型服务就起来了。2.3 API 网关与业务接入层模型服务起来之后下一步是让业务方用得舒服。openrig 的接入层我仍然走 OpenAI 兼容协议但会在模型服务前面加一层 Nginx 或者 API 网关。为什么加这一层因为 vLLM 的 API server 本身是直连的直接暴露给内部服务时你没法统一做鉴权、限流、日志审计。加一层网关之后业务方只需要知道一个统一入口实际指向哪台 GPU 服务器、哪个模型版本对业务方完全透明。后续要切换模型、灰度发布也只需要在网关层改配置不需要业务方改一行代码。这一层实际做的事情是鉴权统一校验 API Key防止内部接口裸奔。限流按客户端维度限制 QPS防止一个业务方突然发疯把 GPU 打满。日志记录每个请求的模型名、输入 token 数、输出 token 数、耗时——这是后面做成本核算和性能优化的基础数据。错误码统一把上游的超时、过载、模型不存在等错误转换成业务方熟悉的 HTTP 状态码。接入层我用 Nginx Lua 脚本实现过一次也用过 Apache APISIX 这些现成网关跑过。如果你的团队运维能力有限直接用 APISIX 更快开源方案Dashboard 里有现成的 route、限流、日志插件。3. 从零搭起 openrig完整实操流程3.1 环境准备我默认读者手里有一台 Linux 服务器至少一张 24G 显存的 NVIDIA 显卡系统盘 100G 以上数据盘越大越好。没有 GPU 的可以先在云服务器上租一台按小时计费的把流程跑通后再决定要不要长期持有。基础环境三步走安装 NVIDIA 驱动和 CUDA 工具链。如果机器上没有装过可以直接通过 apt 装驱动再装 CUDA。检查驱动是否正常最直接的命令是nvidia-smi能看到 GPU 型号和显存就说明驱动没问题。# 查看 GPU 状态 nvidia-smi安装 Python 3.10 以上版本建议用 conda 或 pyenv 管理避免系统 Python 被污染。这里我踩过一个坑直接用系统 Python 装 vLLM因为系统里已经有了别的包依赖冲突把 glibc 干坏了最后整个环境重装。用虚拟环境是一切干净环境的第一步。# 创建虚拟环境 python3 -m venv openrig-env source openrig-env/bin/activate安装 PyTorch。vLLM 对 PyTorch 版本有严格要求建议先根据 CUDA 版本从 PyTorch 官网安装对应的稳定版。pip install torch --index-url https://download.pytorch.org/whl/cu1243.2 装引擎与拉起模型服务环境准备好之后装上 vLLMpip install vllm然后从模型库下载权重。国内环境我一般用 ModelScope海外用 Hugging Face比较稳的方式如下# 使用 modelscope 下载模型权重 from modelscope import snapshot_download model_dir snapshot_download(Qwen/Qwen2.5-7B-Instruct, cache_dir/data/models) print(model_dir)模型下来之后启动服务。这里有几个参数需要重点解释。vllm serve /data/models/Qwen/Qwen2.5-7B-Instruct \ --served-model-name openrig-qwen7b \ --gpu-memory-utilization 0.9 \ --max-model-len 8192 \ --enforce-eagerserved-model-name对外暴露的模型名业务方请求时要用这个名字。gpu-memory-utilization允许 vLLM 使用的显存比例我习惯设为 0.9留出 10% 给驱动和其他进程防止 OOM。max-model-len上下文窗口长度。这个值直接影响 KV Cache 显存占用。设太大并发能力会断崖式下降。enforce-eager关闭图编译模式。首次启动会快很多缺点是推理性能略降。正式部署时我一般不加这个让 vLLM 自己决定是否走 graph mode。启动过程如果看到类似 “Starting vLLM server” 的日志说明服务已经在跑。此时再开一个终端用 curl 测一下接口是否通curl http://127.0.0.1:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: openrig-qwen7b, messages: [{role: user, content: 你好介绍一下你自己}], max_tokens: 256 }如果返回一个带choices字段的 JSONopenrig 的最小可用版就搭好了。3.3 用 OpenAI 协议接入业务vLLM 内置的 API server 已经兼容 OpenAI 格式业务侧几乎不用改代码。假设你之前是用 OpenAI Python SDK 调的闭源模型现在只需要改两行from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:8000/v1, api_keysk-openrig-local, # 本地服务不验证 key但占位不能少 ) response client.chat.completions.create( modelopenrig-qwen7b, messages[ {role: system, content: 你是一个严谨的运维助手。}, {role: user, content: 帮我写一个清理临时文件的脚本}, ], temperature0.3, ) print(response.choices[0].message.content)这里要注意api_key随便填一个字符串都能过因为 vLLM 本地服务器默认不做鉴权。这只有一个问题——如果你把服务暴露到了非本机端口别人只要知道地址和端口就能直接刷你的 GPU。所以 openrig 上线之前务必在网关层把鉴权补上。如果你用的是 LangChain、LlamaIndex 这类框架接入方式同样简单把框架里的 OpenAI 实例的 base_url 指到 openrig 的地址即可。我之前用 LangChain 接 openrig改动的地方只有环境变量。export OPENAI_API_BASEhttp://127.0.0.1:8000/v1 export OPENAI_API_KEYsk-openrig-local这样一来你的团队里不管用什么框架统一一套环境变量就能切到私有模型迁移成本几乎为零。4. 性能与资源openrig 的显存、并发和延迟怎么算4.1 显存预算的实测口径搭 openrig 之前第一件事是算清楚手里的卡到底能跑多大的模型、多少个并发。很多人一上来就把 7B 模型塞进 24G 显卡然后用 gpu-memory-utilization 设为 0.95结果呼叫量稍微上来直接 OOM。问题在于显存预算没算明白。一个模型推理时的显存占用分为三块模型权重、KV Cache、运行时激活值。模型权重一个 BF16 精度模型每 10 亿参数大约占 2G 显存。7B 模型就是大约 14G14B 就是大约 28G看得见的账。KV Cache这是一个动态变化的部分。它的占用可以用下面的公式粗略估算KV Cache 内存 ≈ 2K 和 V × 层数 × 头数 * 头维度 * 序列长度 * 并发数 * 精度字节数这个公式太抽象我直接给你一个经验数据7B 模型、4096 上下文、BF16 精度、并发 10 的情况下KV Cache 大约会吃掉 3G 到 5G 显存。如果你把上下文干到 32K并发放到 100KV Cache 会飙到几十 G直接把显存吃穿。运行时激活值不同模型差别大一般是 1G 到 2G 的余量。所以我给 openrig 做容量规划时有一个口诀权重二倍、缓存留量、余量一成。比如 7B 模型权重 14GKV Cache 按最大并发算好之后再加 10% 的冗余这样才是一个健康的显存预算。如果你的显卡只有 24G那 7B 模型开 8192 上下文、并发 50 以内的方案是可接受的14B 模型就得考虑量化或者缩并发了。4.2 并发上不去时先查这几个地方很多人在实际运行 openrig 时会遇到一个诡异现象单请求延迟挺快并发一上来每个请求都变慢甚至直接超时。这时候先别急着怪引擎按顺序查四个地方。第一查KV Cache 是否被超额释放。vLLM 默认会在显存不足时拒绝新的请求而非排队如果你看到返回 429 之类的错误码说明显存里 KV Cache 的池子不够了。解决方法是调低--max-num-seqs限制最大并发数让单请求延迟保持稳定。第二查模型是否在跑 CPU offload。如果你用了--cpu-offload-gb参数显存和 CPU 内存之间的搬运开销会非常吓人并发一上来就会变成硬盘级延迟。非必要不用 CPU offload。第三查输入输出的 token 长度。上下文越长KV Cache 越高prefill 阶段越耗时。很多业务系统默认拼大段 system prompt把几万字符塞进去结果每个请求都在 prefill 上花掉三秒。排查方法是在接入层记录 prefill 和 decode 分别的耗时vLLM 日志里能看到这两个数。第四查网关层是否成了瓶颈。Nginx 默认配置下并发能力很强但如果你开了太多插件或者日志落盘太频繁可能会把 CPU 打满。我遇到过的问题是 access log 每条都写 JSON高并发时磁盘 IO 直接飙到 100%处理器全耗在日志上了。后来改成采样日志或者用异步写入日志问题立刻缓解。4.3 量化方案怎么选显存不够的时候第一个想到的肯定是量化。openrig 里我常用三种量化精度AWQ、GPTQ、FP8。AWQ 是 Activation-aware Weight Quantization基于激活值分布做权重量化4bit 精度下质量损失很小而且 vLLM 支持度极好。我的 14B 模型在 24G 显卡上就是用 AWQ 4bit 跑起来的。GPTQ 是经典的后训练量化方案社区模型多老牌稳定。缺点是量化过程慢对激活值的处理不如 AWQ 精细。FP8 是 Hopper 架构及之后显卡的原生支持能力8bit 精度保留更多信息质量损失极小但目前对显卡代次有要求老卡跑不了。选择建议很简单先试试原始精度能不能跑能跑就别量化跑不了优先上 AWQ 4bit质量下降通常可以接受还不行再降模型尺寸。量化不是银弹强行压缩模型可能会让输出质量崩坏尤其是推理任务一步错步步错。5. 常见问题速查与避坑实录5.1 高频问题排查清单我把自己在 openrig 日常运维中遇到过的典型问题整理成了一张表按“现象-原因-解法”列出来方便你快速定位。现象常见原因处理方法启动时报 CUDA out of memory显卡驱动占用显存多或 gpu-memory-utilization 设太高降到 0.85先关掉桌面进程占用的显存首次请求非常慢图编译 / 权重加载导致冷启动预热服务启动后先发 1-2 个请求再接入流量并发时大量请求 429显存中 KV Cache 池见底调低 max-num-seqs或减少 max-model-len生成的内容突然变短max_tokens 设置过小或模型在采样阶段被截断检查 max_tokens确认≥输出长度响应有重复乱码温度设置过高 / 模型量化过激降低 temperature换更高精度权重网关返回 502后端推理进程卡死或重启中检查 vLLM 日志监控显存和磁盘这张表是我踩坑的真实汇总不是理论推演。比如 502 那个问题我遇到过 vLLM 在高并发下进程直接崩溃的情况后来定位是显存不足触发 OOM Killer不仅服务挂了连带着网关日志都堆满了。解决方案还是上面说的容量规划留足冗余不要榨干每一兆显存。5.2 几个值得单独强调的坑第一个坑权重下载来源要选稳定的源。如果你在大陆网络环境里直接从 HuggingFace 默认源拉大文件速度奇慢不说中途断流也是家常便饭。改用 ModelScope 之后7B 模型几 GB 的权重几分钟就能拉完。这个细节不涉及任何技术难度就是经验。第二个坑模型精度保持一个方案。同一套服务里不要一部分请求走原始 BF16 权重、另一部分走 AWQ 量化权重。不同权重文件的输出行为会有细微差异除非你专门做模型对比测试否则业务方会反馈“同一个问题这次答对了下次答错了”。openrig 的原则是环境统一。第三个坑监控从第一天就要有。不要等出了线上事故才去配监控。最基本的三个指标GPU 显存使用率、GPU 利用率、请求平均延迟和 token 吞吐。这几个数据有了你才能提前判断容量天花板在哪、什么时候该加卡、什么时候该缩权重。我用 Grafana Prometheus nvidia-dcgm-exporter 搭了一套最简监控整个配置过程不超过半小时但后面省的事远远不止半小时。第四个坑模型更新不要直接覆盖。openrig 支持同时挂多个模型新模型上线时先并列跑用网关层灰度切流量观察一天再切全量。我见过有人直接把老模型路径覆盖了结果新模型有兼容性问题线上服务全线不可用回滚又找不到老权重整场事故非常被动。5.3 补充体验openrig 还能往哪里扩展最后一个让我意外的收获是 openrig 的复用性。原本它是为内部知识库问答搭的后来发现同一套服务直接可以作为多个业务方向的公共底座。比如我在接入层做了个小模型路由1.5B 模型先判断请求类型分类问题走小模型推理问题走 14B 模型。这个改造上线后整体 GPU 成本下降了四成左右因为大量简单请求根本不需要大模型出手。再比如 RAG挂一个向量库把检索流程串进去openrig 就从单纯的模型服务变成了完整的知识应用底座。我个人现在的习惯是新项目先用 openrig 跑通核心逻辑模型方案验证无误后再决定要不要升级更大参数或者加更多并发能力。这套环境已经稳定跑了好几个月中间虽然踩了不少坑但每次故障都是清晰可查的问题定位基本都在半小时以内。所有技能和工具的打磨都是从这样一套可复制的环境开始的建议你也从一个小模型、一次 curl 调通开始慢慢感受自己掌控模型服务的踏实感。