当前位置: 首页 > news >正文

从0到1搭一个云原生大模型推理平台:FastAPI + vLLM + Kubernetes + Prometheus

最近我做了一个小型的云原生大模型推理平台项目,主要目的是把大模型服务从“能调用”往“能部署、能治理、能观测”推进一步。

项目地址:https://github.com/ycx666994/llm-inference-platform

这个项目不是简单写一个接口去调用大模型 API,而是围绕大模型推理服务搭了一层网关,支持 OpenAI 兼容接口、API Key 鉴权、限流、Prometheus 指标、Grafana 监控、Kubernetes 部署和 k6 压测。

一:我为什么做这个项目

刚开始接触大模型应用时,很多 Demo 都是直接调用 API,比如写个聊天机器人、RAG 问答系统之类的。这些当然很有价值,但如果从AI Infra 或平台工程角度看,还缺少一个关键问题

模型服务真正上线以后,怎么部署?怎么限流?怎么鉴权?怎么监控?怎么压测?怎么迁移到 Kubernetes?

所以我想做一个更偏底层一点的项目,不重点展示“模型回答得多聪明”,而是展示一个大模型推理服务背后的工程化能力。

二:项目整体架构

项目的核心结构大概是这样:

Client / k6
|
v
FastAPI Gateway
|-- API Key Auth
|-- Rate Limit
|-- Prometheus Metrics
|
v
mock-vLLM / real vLLM
|
v
Prometheus + Grafana

三:项目里主要的部分

gateway/ FastAPI 推理网关
mock-vllm/ OpenAI 兼容的 mock 后端
k8s/ Kubernetes 部署文件
monitoring/ Prometheus 和 Grafana 配置
benchmark/ k6 压测脚本
scripts/ 本地和 K8s 部署脚本
docs/ 架构说明、运行手册、压测报告

四:Gateway 的设计

Gateway 是这个项目的核心。因为客户端不会直接请求 vLLM,而是先请求 Gateway。

这样做的好处是,很多和模型无关但上线必须要有的能力,都可以放在 Gateway 层做,比如说:

1.API Key 鉴权
2.请求限流
3.请求转发
4.默认模型补全
5.Prometheus 指标采集
6.上游错误处理

五:接口的设计

接口设计上,我做成了 OpenAI 兼容格式:POST /v1/chat/completions

这样客户端侧可以比较自然地迁移,不需要重新适配一套奇怪的协议。

六:健康检查和指标接口分别是

GET /healthz
GET /metrics

七:API Key 鉴权

鉴权逻辑比较简单,通过请求头里的 Bearer Token 判断是否合法:Authorization: Bearer sk-demo

如果没有带 token,返回 401;如果 token 不在允许列表里,返回 403。

这块虽然不复杂,但在推理服务里很重要。因为模型推理通常是高成本资源,不可能随便暴露一个无鉴权接口给外部访问。

八:限流设计

我的项目里实现了一个内存版的 per-key 限流器。每个API Key都有自己的请求窗口。

当前实现适合本地 Demo 和单实例场景。如果要上生产,可以继续改成 Redis 版本,这样多个 Gateway 副本之间也能共享限流状态。

这个地方我没有一开始就上复杂方案,因为项目目标是先把完整链路跑通。工程项目里我觉得很重要的一点是:先做出可验证的最小闭环,再逐步替换关键组件。

九:mock-vLLM 和 real vLLM

我的这个项目支持两种后端模式:

第一种是 mock 模式。这个模式不需要 GPU,适合本地开发、接口测试、Kubernetes 部署验证。

第二种是真实 vLLM 模式。我本地用的是 facebook/opt-125m 作为测试模型。由于本地 kind 集群没有暴露 nvidia.com/gpu,所以真实 vLLM 是跑在宿主机 Docker 里的,Kubernetes 里的 Gateway 再通过 host.docker.internal:8000去访问它。

然后这个方案不是最标准的生产架构,但很适合本地演示:Client -> K8s Gateway -> host Docker vLLM

当然,如果我后续有真正的 GPU Kubernetes 节点,应该可以直接使用项目里的 k8s/real-vllm 部署文件,再把 vLLM 放进集群里运行。

十:Prometheus 和 Grafana 监控

Gateway 暴露了 Prometheus 指标,包括请求数、请求延迟、上游请求状态等。

比如:

gateway_requests_total
gateway_request_latency_seconds
gateway_upstream_requests_total

Prometheus 负责采集指标,Grafana 用来展示 Dashboard。

这样做之后,我们就可以看到接口是否正常、请求延迟大概是多少、上游 vLLM 是否有错误。

我必须强调一句:对大模型推理服务来说,监控非常关键。因为一次推理请求可能耗时比较长, 也可能因为模型加载、显存、网络、并发等原因出现问题。但如果没有指标的话,就很难判断问题到底发生在哪里。

十一:k6 压测

项目里也加了 k6 压测脚本,然后我是想用它来测试 Gateway 到后端推理服务的整体表现。

然后目前 README 里已经记录了两组结果:

这里的数值不是为了追求多高的性能,而是为了证明整个链路可以被压测、可以被量化。

大家请注意:一个平台项目如果只有“能跑”,其实还不够。最好还能说明它在一定压力下表现怎么样。

十二:单元测试和 CI:

后面我又补了一些测试,主要覆盖:

1./healthz 健康检查
2.缺少 Bearer Token
3.API Key 非法
4.请求转发到上游
5.默认模型补全
6.per-key 限流
7./metrics 指标暴露

本地测试结果:6 passed

同时项目中也加了 GitHub Actions,这样,每次 push 或 pull request 都会自动安装依赖并运行测试。主要是我想方便展示给大家。别人打开仓库时,能看到项目不是只写了一堆代码,而是有基本的工程质量保障。

十三:本地快速验证

如果只想验证 Gateway 的基本行为,不需要 Docker、Kubernetes 或 GPU,可以直接跑测试:

cd C:\Users\HP\llm-inference-platform
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r gateway\requirements.txt -r requirements-dev.txt
$env:PYTHONPATH="gateway"
pytest -q

启动Gateway:

$env:PYTHONPATH="gateway"
uvicorn app.main:app --host 127.0.0.1 --port 8080

测试健康检查:

Invoke-RestMethod -Method Get -Uri "http://127.0.0.1:8080/healthz"

查看指标:

Invoke-WebRequest -Uri "http://127.0.0.1:8080/metrics" -UseBasicParsing

如果要测试完整的 chat completions 转发,就需要先启动 mock-vLLM 或真实 vLLM。

十四:收获

我说说我的收获。

其实,这个项目我最大的收获不是 FastAPI 怎么写,也不是 Kubernetes YAML 怎么写,而是我对“大模型推理服务工程化”有了更完整的理解。

以前看大模型项目,更多关注模型本身,比如参数量、推理效果、上下文长度。做完这个项目之后会发现,真正上线时还有很多模型外的问题:

1.请求入口怎么统一
2.用户怎么鉴权
3.不同用户怎么限流
4.服务挂了怎么发现
5.延迟变高怎么定位
6.本地怎么测试
7.Kubernetes 里怎么部署
8.GPU 不可用时怎么做 fallback 或 mock

这些问题单独看都不算特别难,但把它们串成一个完整系统,就很接近真实平台工程的工作方式。

十五:总结

这个项目可以理解为一个小型的大模型推理平台雏形。

它没有追求复杂的业务功能,而是把重点放在推理服务的工程化链路上:Gateway、鉴权、限流、监控、压测、Kubernetes 部署和CI。

如果只是做大模型应用,直接调用 API 就够了。但如果想往 AI Infra、云原生、平台工程方向深入,就必须理解模型服务背后的这些基础设施能力。

这个项目也算是我对这条技术路线的一次实践。后面我会继续完善它(因为还有很多的东西需要完善),然后我争取把它从 Demo 项目逐步打磨成一个更完整的 LLM Serving Platform。

欢迎大家留言以及欢迎大家来开源贡献。

http://www.jsqmd.com/news/1152210/

相关文章:

  • RPA 浏览器自动化:多账号防检测、网页批量数据采集、风控应对
  • 写了5年Python才发现,90%的人都用错了lambda表达式,难怪代码可读性差到被吐槽
  • 开发者必读:Claude Code和Cursor到底该用哪个?3类典型工作流(全栈/前端/数据工程)适配性分析,错过=多花47%调试时间
  • 174.1.智能消防喷淋监测-WiFi-基于STM32单片机物联网设计【硬件+APP+云平台】
  • AI文档时代已来,你还在手动改稿?Gemini for Docs高效工作流全解析,
  • CentOS7.5 编译 Python3.6.8+OpenStack 私有云 API 运维
  • Ubuntu 22.04下编译安装wave2Foam与OpenFOAM v2206完整指南
  • 阿里千问智能体下线:数据备份与迁移技术指南
  • 合肥TAVR手术安全性分析与临床实践——合肥高新心血管病医院经导管主动脉瓣置换术(TAVR)按国家标准及安徽省质控规范开展
  • 免费Mermaid实时编辑器:5分钟创建专业图表无需代码基础
  • WIZnet 开源方案分享:W55MH32 开发板 + 小智 AI实现以太网版本的小智机器人
  • 技术深度解析:Topit macOS窗口置顶技术的架构设计与性能优化
  • EasyConnect全平台部署与故障排查手册:Windows/macOS/Linux常见报错速查与解决
  • CPT Markets:从公开信息出发,观察移动端体验与平台稳定性
  • OceanBase 为什么要做 AI 数据库?
  • 2026 Web3 AI 融资地图:基础设施、应用层与中间件赛道的技术趋势分析
  • 2026年纯音乐素材下载网站清单:5个适合个人创作者与低成本项目的网站
  • 测试人必备的用例评审SKILL,采纳率提升至95%以上
  • DeepSeek与Claude的1000轮对抗测试(含越狱攻击、多跳推理、跨文档引用):结果颠覆认知,第876轮开始出现决定性分水岭
  • 为什么PCBA加工必须留工艺边?揭秘3大关键作用!
  • ROS2 Windows安装实战:从环境搭建到跨语言通信
  • Windsurf vs Cursor性能对决:本地代码索引耗时、AI补全准确率、多文件关联推理延迟——实验室级基准测试全公开
  • DM扩散模型_DDPM Denoising Diffusion Probabilistic Model去噪扩散概率模型_DALL模型_Clip模型---AI大模型系统从零开始0034
  • ClaudeAPI 旅游场景提示词模板:行程、攻略、报价和客服答疑
  • 大数据毕设项目:基于 Python 爬虫数据建模的智能书籍推荐系统的设计与实现 基于分布式爬虫的海量图书个性化推荐系统 (源码+文档,讲解、调试运行,定制等)
  • 如何用Photon光影包彻底改变你的Minecraft视觉体验?终极配置指南
  • CPT Markets:聚焦细节,看看风控思路的关键路径
  • 基于multisim的自动光控路灯控制电路设计
  • PHILIPS 4598-001-21121 接口模块
  • 机加工车间设备数据采不上来?SCADA系统选型先看这三点