
不用多说先讲故事。上个月我把一台退役下来的工作站翻出来装上双卡准备搭一套本地大模型部署环境。折腾到凌晨三点发现真正让我头疼的不是显卡驱动也不是vLLM启动失败而是整个流程里缺一个“顺手”的壳模型服务跑起来了我却得手动写一堆curl去调接口想测一下性能又得临时拼脚本统计首token延迟想换一个量化版本对比效果配置文件散落各处。那天夜里我忽然意识到我需要的东西其实就是一整套“开放的rig”——openrig。这个概念在国内讨论得不多但我个人理解它就是把本地模型部署、推理服务、性能评测、配置管理整合成一体的开源工作台。今天这篇文章我打算用做项目的方式把openrig这类方案从设计思路到实操落地完整拆一遍。代码会贴命令会写坑也会讲。适合谁看正在做私有化部署的工程师、想本地跑模型做产品原型的开发者以及被一堆推理框架折腾得想摔键盘的同学这篇应该都对你有用。2. 先聊聊openrig到底解决什么问题2.1 我把“rig”理解成一套完整的部署栈先解释一下这个词。Rig在英文里有“设备架”“试验台”的意思摄影圈说camera rig是相机套件矿圈说mining rig是矿机架子。到了模型部署领域openrig的核心含义就是把你跑模型需要的所有零部件——推理引擎、API网关、模型权重、评测脚本、监控面板——像搭积木一样装进同一个框架里对外暴露一套统一的操作方式。我见过的绝大多数本地部署场景其实都长这样先装Ollama或者llama.cpp启动一个模型服务然后为了暴露给上层应用再套一层FastAPI或者Flask接着要做性能验证又去翻vLLM文档写压测脚本最后想记录历史表现只能靠Excel。这套流程不是不能跑但它属于“手工作坊”每个环节都靠人肉衔接换个模型就要重新填一遍参数换台机器就全部重来。openrig这类项目的目标就是把这条链路“流水线化”。再往深了说我认为openrig解决的痛点有三个。第一个是可复现性模型版本、推理参数、评测数据集、环境依赖如果能全部固化成一个可分享的配置那你做过的实验就不会丢失第二个是可观测性不只是看日志里的报错而是能拿到每轮请求的耗时、吞吐、显存占用这些量化指标第三个是多模型管理同时跑多个模型、多套量化版本随时切换对比。2.2 什么人最适合用openrig我按用户画像分三类说。第一类是私有化部署工程师。你给企业客户搭内部知识库问答客户要求所有数据不出内网那你必须把模型跑在自己的服务器上。openrig的价值是帮你把部署过程标准化拿到新机器的第一件事不再是翻博客找教程而是直接加载一份rig配置一键拉起整套服务。第二类是做 RAG 或 Agent 的应用开发者。这类人最烦的不是推理引擎本身而是“怎么稳定地调接口”。openrig把模型服务封装成统一API你只需要关心业务逻辑不用关心背后是vLLM、TensorRT-LLM还是llama.cpp。第三类是算法工程师和评测同学。你们的目标不是上线而是对比不同模型、不同量化方案的差异。openrig这类平台可以把评测任务批量编排最后输出结构化报告。如果你完全没接触过命令行、没装过Docker那说实话openrig类项目现在还不适合你。但如果“docker run”对你来说不陌生那这个工具我建议你花一个周末试试。2.3 不吹不黑openrig和“自己写脚本”的差别有朋友可能会问我自己用Python写个调度脚本再挂个Grafana看监控不也是一个rig吗没错能但代价不同。我自己也走过这条路。第一版脚本大概分了几个模块启动模型服务的Shell脚本、转发请求的FastAPI代码、采集指标的子进程、一个简单的SQLite存结果。听起来没多复杂但实际用起来问题很多换一台新机器CUDA版本、驱动版本、Python依赖全部要重新排雷想并行跑两个模型端口配置简直是灾难评测的prompt稍有改动之前的结果全作废。这就是“自研平台”的通病——写脚本花一天维护脚本花一周最后发现问题全在脚本本身。相比之下openrig这类项目强调整体性和组合性。你可以把整个rig当作一套可移植装配配置一次到处运行。这里我也不是说一定要用某个具体产品而是提倡“rig思维”把模型部署环境视作一个可复现、可评测、可分享的独立单元。3. 核心设计思路一个开放的rig应该怎么拆3.1 控制平面和数据平面分离我见过很多失败的部署项目崩就崩在“整成了一坨”。模型服务、评测任务、监控采集全在一个进程里。一个评测任务把显存打满了API也跟着挂掉或者模型服务重启一下整个管理端都连不上。这属于典型的控制平面和数据平面没有分离。在openrig的架构里我的理解是两层结构。数据平面负责“真正干活”推理引擎就是被拉起的模型服务、存储、监控采集器。控制平面负责“安排干活”启停服务、下发评测任务、收集结果。两层之间通过API通信。这么设计的好处非常直观模型服务可以独立横向扩展评测任务压死一个实例并不影响其他服务管理端被重启时正在跑的推理任务不会中断。打个比方这就像餐厅后厨和前台的关系。后厨只管炒菜前台只管接单。顾客再多前台可以加人排队后厨压力太大也是加灶台解决而不是让前台跑到厨房里帮忙炒菜。模型部署也是这样推理负载高就扩展推理节点评测任务重就单独起评测执行器互不干扰。如果你自己写代码请务必把调度逻辑和推理进程拆开否则后面维护成本会高到让你怀疑人生。3.2 用插件协议统一模型接入openrig这类平台的第二个设计要点是模型接入方式的协议化。什么叫协议化就是说我不针对Ollama写一套代码再针对vLLM写一套代码而是定一个抽象的“模型服务协议”然后给每个推理引擎写一个适配器把各自的差异挡在适配器内部。上层只看到一个统一的标准接口。具体到实操层面标准接口大概长这样几个维度加载模型指定模型名、量化方式、上下文长度、GPU编号推理请求输入prompt、温度、max tokens输出回复文本健康检查模型是否就绪、当前排队长度、是否在加载中指标上报显存占用、平均延迟、吞吐量我自己在配置openrig时比较喜欢把模型注册表写成YAML。每一份模型配置就是一个固定结构的描述文件包括模型来源、精度、所需显存、引擎类型。下面是当时写的示例配置你们可以直接参考models: - name: qwen2.5-7b-instruct engine: vllm path: /models/Qwen2.5-7B-Instruct precision: bf16 max_model_len: 8192 gpu_memory_utilization: 0.45 serving_port: 8101 health_path: /health - name: qwen2.5-7b-instruct-gptq engine: vllm path: /models/Qwen2.5-7B-Instruct-GPTQ-Int4 precision: int4 max_model_len: 8192 gpu_memory_utilization: 0.30 serving_port: 8102 health_path: /health这两份配置放在一起体现出rig思维的核心同一个基座模型一个bf16原版、一个int4量化版并排注册。我想做对比评测时只需要一次切换剩下的推理、评测逻辑完全复用。没有这层注册抽象你就得手动记端口、手动改地址、手动维护两套评测脚本。3.3 评测与指标定义让结果可对比一个真正的openrig不能只负责跑模型还得管“跑得好不好”。评测模块是我认为整个项目里含金量最高的部分因为它直接关系到模型选型决策。我在实践中把评测任务设计成三种基本类型。第一种是单轮问答评测给定一组问题和标准答案调用模型接口比对生成内容与标准答案的相关性。适合快速验证模型的基本能力。第二种是性能压测模拟指定并发数持续发送请求统计吞吐量和延迟分布。适合判断当前硬件能支撑多少并发。第三种是长稳回归用固定的prompt集每隔一段时间跑一遍看生成结果是否稳定、显存是否泄漏。适合上线前的最终检查。评测任务本身也应该是配置化的。我在openrig里会为每个任务定义一个“评测场景”里面包含模型名、数据集路径、超时时间、并发数、采样温度、最大生成长度。比如这样evaluation: name: qwen7b-bf16-vs-int4 dataset: ./datasets/rag_qa_200.jsonl concurrency: 8 max_retries: 3 timeout_per_request: 120 sampling_params: temperature: 0.2 top_p: 0.8 max_tokens: 512 metrics: - tps - first_token_latency - avg_latency - gpu_memory_peak这里有一个我踩了很多次才明白的细节评测时温度参数一定要固定而且最好设得很低比如0.1或0.2。不然你每次跑同一道题模型回答都不同你很难判断是模型能力问题还是随机性问题。后面问题排查部分我会再展开讲。4. 从零搭建openrig的实操记录4.1 硬件准备和环境初始化先说硬件。我推荐的最低门槛是“能跑得动你目标模型的机器”。以7B量级模型为例bf16精度下模型权重本身约14GB加上KV Cache、CUDA上下文、推理引擎的额外开销单卡建议至少24GB显存。如果你想跑13B到14B模型那32GB甚至双卡48GB会更舒服。如果你的目标模型是3B或者以下一张12GB的卡也能玩但别指望并行跑多个实例。我实际用的环境是双RTX 309024GB*2CPU是AMD 5900X内存64GB系统Ubuntu 22.04。第一步是把基础环境准备好这里直接给你命令序列# 更新系统基础组件 sudo apt update sudo apt upgrade -y # 安装NVIDIA驱动以550系列为例 ubuntu-drivers devices sudo apt install -y nvidia-driver-550 # 安装完务必重启然后检查驱动和CUDA可用性 nvidia-smi # 安装Docker Engine和Compose插件 curl -fsSL https://get.docker.com | sh sudo systemctl enable --now docker docker compose version # 给当前用户添加Docker权限避免每次sudo sudo usermod -aG docker $USER newgrp docker这些操作我建议一步一步执行不要一口气全跑完。尤其是NVIDIA驱动装完重启这一步很多人跳过后面跑容器时才发现英伟达容器工具包检测不到GPU又回来返工。接着安装NVIDIA Container Toolkit这是让Docker容器内能够访问GPU的关键组件curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed s#deb https://#deb [signed-by/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt update sudo apt install -y nvidia-container-toolkit安装完过后记得重启Docker守护进程sudo systemctl restart docker docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi最后一条命令如果能正常输出显卡信息就说明环境跑通了。4.2 部署第一个推理服务并注册到rig环境准备好之后我开始部署推理服务。在openrig这个框架里推理服务不是“零零散散手动敲命令启动”而是统一由rig的管理端拉起并注册。但为了让你理解底层发生了什么我先把最核心的容器启动命令拆开看。我推荐直接用vLLM作为第一个推理引擎因为它的性能、生态成熟度都比较好。以Qwen2.5-7B-Instruct为例启动命令大概是这样的docker run -d --name qwen7b-bf16 \ --gpus device0 \ --shm-size 16g \ -p 8101:8000 \ -v /models:/models \ -e HF_TOKEN你的huggingface_token \ vllm/vllm-openai:latest \ --model /models/Qwen2.5-7B-Instruct \ --served-model-name qwen2.5-7b-instruct \ --tensor-parallel-size 1 \ --max-model-len 8192 \ --gpu-memory-utilization 0.45 \ --port 8000解释几个关键参数。--shm-size 16g是很多人忽略的vLLM在并行处理时会用共享内存做数据交换默认的64MB根本不够模型一加载就报shared memory related错误。--tensor-parallel-size 1表示只用单卡如果要把模型切到双卡就设成2并且--gpus要指定两张卡。--gpu-memory-utilization 0.45是我根据双卡环境设置的让第一张卡只使用45%显存给这个大模型留出另外的空间跑其他模型或评测任务。服务起来之后你可以先手动验证一下连通性curl http://127.0.0.1:8101/v1/models curl http://127.0.0.1:8101/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5-7b-instruct, messages: [{role: user, content: 你好用一句话介绍你自己}], max_tokens: 100, temperature: 0.2 }通了之后再把它登记进rig的模型注册表也就是前面第3节写的YAML。管理端会自动检测这个端口的健康状态后续的评测任务就能直接引用qwen2.5-7b-instruct这个名字而不是记一长串IP加端口。为什么一定要先手动调通再注册因为排查容器问题比排查rig问题容易得多。你直接把问题隔离在“模型服务层”等它稳定了再交给rig管理。这是我干活一直奉行的原则先让零件转起来再装配整机。4.3 创建第一个评测任务并分析报告第一个服务注册好之后接下来干一件最能体现openrig价值的事建评测任务。我准备了一个200条问答的测试集内容来自我积累的内部RAG场景问题单条格式是JSON Lines{id: 1, question: 公司今年第一季度的营收目标是多少, reference: 根据内部规划第一季度营收目标为4800万元。}评测任务配置文件之前也给了这里再说一下跑评测时的实际输出。评测跑起来之后管理端会定时轮询推理服务的指标比如每个请求的首token延迟、平均生成速度、排队时间。一轮跑完后我拿到的报告长这样指标值总请求数200并发数8平均首token延迟约420ms平均单轮总延迟约3.8s吞吐量约42 tokens/s回答包含参考要点的比例76.5%显存峰值约11.2GB这个报告本身就能说明很多问题。比如平均首token延迟四百多毫秒对于内部知识库问答来说体感上会有一点点“迟钝”如果是客户对面客系统最好控制在200ms以内。于是我下一步就会压一下max_model_len或者换一个量化版本去优化这个指标。没有评测报告这些决策全靠拍脑袋有了报告每一步都有数据支撑。这里补充一句我在双卡环境下又注册了GPTQ int4量化版的服务。对比之后发现bf16版在RAG问答上的准确率确实更高约76.5% vs 71.2%但int4版在显存占用上省了近40%。如果你们公司只有单张24GB卡又想跑一个大模型又跑一个向量库那量化版大概是更稳的选择。这类结论都是openrig搭好之后跑出来的而不是靠纸面推算。5. 常见问题与排查技巧实录5.1 服务起来了但评测一直超时这个是我用openrig初期遇到频率最高的问题。具体症状是模型服务手动curl能通但一跑评测任务大量请求都报超时。排查思路十分关键不是一上来就改配置。我当时的排查顺序是看最后一次评测的时间点模型日志有没有异常看并发数是不是突然打满了排队队列看单次生成长度是不是远远超过预期。最后定位到问题是两个因素叠加一是评测并发设了16而单张卡跑7B模型时实际吞吐并不足以支撑16个并发请求快速结束二是测试集里有几道题触发了模型生成非常长的回答最多的生成了上千tokens直接把请求卡到了超时阈值之外。解决方案很简单并发降到8超时时间从60秒调到120秒同时把每个请求的max_tokens上限设成512。调完之后评测稳定跑完耗时还缩短了因为排队不再互相阻塞。这个问题的深层教训是评测任务的参数设置不是越大越好。并发高不代表效率高反而可能因为推理引擎的排队机制导致大量请求一起变慢。建议先小并发验证一轮再逐步加压不要一步到位。5.2 显存OOM和显存碎片化OOM这个问题我在切换多个模型评测的时候踩得最深。第一个模型跑完第二个模型启动时直接报CUDA out of memory。正常情况下模型服务进程停掉后显存应该被释放。但在vLLM这种高性能推理引擎里显存的释放并不总是立即归还给系统存在一定程度上的缓存和碎片化。我当时用了最直接的办法来清理显存占用# 查看GPU上还有哪些进程占用内存 nvidia-smi --query-compute-appspid,used_memory,name --formatcsv # 清理残留进程谨慎操作确认是已停止服务的残留 pkill -9 -f vllm # 或者从Docker层面强制清理所有已退出的容器 docker container prune -f但更根本的解法还是在rig里做显存配额。就是我配置里gpu_memory_utilization字段。不要把每张卡的利用率都设成0.9留一点余量给调度和碎片化开销。我自己跑双卡时两个模型的利用率分别设0.45和0.4这样能保证同时跑的稳定性。另外一个很实用的技巧在NVIDIA卡上可以开显存复用特性不过不同卡支持程度不同建议实测确认这里不展开细说。5.3 评测结果不稳定同一道题答案总变这个问题前面埋了伏笔就是温度参数导致的随机性。很多评测平台没有把采样参数固化到任务配置里导致不同时间跑出来的结果天差地别。你会以为是模型变笨了其实是采样随机性在捣乱。我的建议是评测场景一律设temperature: 0.1甚至0如果引擎支持固定随机种子seed: 42使用相同的prompt模板不要混用“你是助手”和“你是一个AI助手”这类措辞。别小看prompt模板的作用。我做过一次对比同一个7B模型只是把系统提示词从“请用中文回答问题”改成“你是企业内部助手请用简洁中文回答”准确率直接涨了4到5个百分点。评测不是只测模型权重而是测“模型提示词参数”这个整体。所以评测配置里这些必须是固化项。5.4 日志太多看不到重点openrig跑起来之后日志是海量的。模型服务打印的每轮请求信息、管理端的调度日志、监控采集器的数据上报全部混在一起。我前几次排查问题全靠CtrlF搜关键词效率极低。后来我养成了几个好习惯分享给大家跑评测前先清空所有容器的日志文件评测结束后优先看管理端的任务汇总而不是逐行翻日志遇到报错先确认是“推理引擎报错”还是“调度流程报错”——前者去模型服务日志找后者去控制平面日志找不要混在一起看。如果要量化我大概用了三成精力做推理服务的调优剩下七成全是做可靠性和可观测性的活。如果你打算自己从零搭rig请务必把日志规范当作一等公民来设计不要到最后才想起来。6. 后续可以怎么扩展以及我的几点体会openrig这套东西用顺手之后我目前正在做三件事。第一件是把固定的评测数据集接入CI/CD每次更新模型权重之后自动跑一轮回归这样模型有没有“变笨”数据说话。第二件是把多机部署纳入进来一台机器专心跑推理另一台机器跑评测和调度控制平面和数据平面在物理上也拆开。第三件是尝试接入TensorRT-LLM这套引擎看看在同样显存下能把吞吐再往上推多少。这里再分享一个小技巧算是我目前最想告诉你的经验。评测模型服务时不要只盯着首token延迟和吞吐量记得把端到端成功率也算进去。我第一轮跑评测时发现虽然平均延迟看起来正常但有一批请求因为排队时间过长被重试最终成功率只有97.2%。对于内部工具来说97%可能够用但如果是面向外部客户的服务这3%的失败率就可能是投诉来源。把成功率纳入评测指标之后你会发现很多之前被“平均性能”掩盖的问题。我在实际接触openrig这类项目之后最大的体会是模型本身只是方案的一半另一半是把它“接好”——接上数据、接上评测、接上监控。很多团队买了好卡、跑起了大模型最后却输在“没有一套稳定可复现的部署评测体系”。openrig这类思路正是补上这一环。我自己也是踩了无数坑才总结出上面这些套路这篇分享里的配置基本都是可直接落地的你可以拿去按自己的硬件情况改一改。如果跑通了欢迎回来聊你的指标数字。