gRPC 是一套远程过程调用(RPC,Remote Procedure Call)框架,Protobuf(Protocol Buffers)是它默认使用的接口描述语言与序列化格式。两者合起来做的事很简单:让一台机器上的程序调用另一台机器上的函数,并把数据压成紧凑的二进制传过去。
先说 Protobuf 怎么工作。开发者先写一个 .proto 文件,里面定义消息结构和方法签名,比如“一次请求包含若干 token 和采样参数,返回一段文本”。然后用工具生成各种语言的代码,客户端和服务端各自拿到一份强类型类。数据在网线上传输时,只带字段编号和值,不带字段名。
打个比方。JSON 像寄快递时在每个箱子上手写“收件人:张三,物品:苹果,数量:3”,字写得清清楚楚,谁看都懂。Protobuf 像双方事先约好一张表格,寄件人只填第 3 格、第 5 格,再贴上编号;收件人拿同一张表格对照着读。箱子变小了,填箱子的时间也短了。
这对推理服务为什么重要?因为推理请求里通常是大块数字:token 序列、embedding 向量、logits、batch 元数据。用 JSON 表示浮点数,每个数都要转成文本,还附带逗号、括号和重复出现的字段名。机器在序列化和反序列化上要花额外的 CPU,这部分开销挤占的是本来该给推理的时间;跨机器传输时还多占带宽。单个请求看不出来,成千上万个请求、每层服务之间都转一遍,就成了实实在在的成本。
| 维度 | JSON + REST | gRPC + Protobuf |
|---|---|---|
| 数据形态 | 文本 | 二进制 |
| 字段名 | 每次传输都带 | 只传编号,靠 .proto 约定 |
| 体积 | 较大 | 较小 |
| 解析开销 | 文本解析,较慢 | 按固定布局读取,较快 |
| 接口契约 | 文档、OpenAPI 等 | .proto 即契约,可生成代码 |
| 传输层 | 通常 HTTP/1.1 | HTTP/2,支持多路复用与双向流 |
| 可读性 | 肉眼可读 | 需工具解码 |
| 浏览器直连 | 天然支持 | 需要额外方案 |
三者的层次别搞混:REST 是接口风格,JSON 是数据格式,gRPC 是框架,Protobuf 是格式。Protobuf 可以脱离 gRPC 单独用,比如写文件、发消息队列;gRPC 也能换别的编码,只是默认搭配 Protobuf。
对从业者的实际意义:模型服务之间、推理网关到后端之间,常见做法就是 gRPC 加 Protobuf,契约明确、多语言客户端一致、流式输出适合逐 token 返回。代价是调试没那么直观,浏览器和前端不方便直连,命令行排查要借助专门的工具。所以常见的分工是对内高吞吐链路用二进制,对外给人调用、给前端调用的开放接口仍然用 JSON。具体工具和配置细节以官方页面为准。
