踩到 Protobuf 解析坑了,如何才能严格解析 Protobuf?

2023-09-21 18:03:17 +08:00
 tool2d
解析是指 protobuf 二进制文件。这协议和 json 不一样,数据类型并不是 1 对 1 的。

比如一个 Length-delimited 类型,int 是 2 ,同时对应多个子类型。可以是嵌入式 messages ,可以是 utf8 文本字符串,也可以是纯 bytes 数组。

现在写了一个解析器,是什么类型,要纯粹靠猜。先尝试 utf8 ,不行再退回到嵌入式 messages ,解析一次。如果还是不行,就默认为 bytes 数组。

总觉得很不靠谱的样子,在没有 proto 辅助的前提下,如何才能优雅的转为 json?
2450 次点击
所在节点    程序员
22 条回复
AoEiuV020JP
2023-09-21 18:10:42 +08:00
在用 protobuf ,这玩意儿难道不是自动生成序列化和反序列化代码然后再也不改的?
还是你解析的是别人的 protobuf 消息不知道真实格式?这当然只能猜了,多整点数据排除所有错误答案才能得出结果,
tool2d
2023-09-21 18:19:06 +08:00
@AoEiuV020JP 我在用微软 ai 推理模型,用的是 protobuf 格式。

pb 本身是序列化格式没错,但是大部分模型推导的结构都比较松散,而且 onnx 里面的 layers 复杂度比较高。会夹杂各种没遇到过的 operators 。用库不太方便,一些 OP 会变。

复杂度一高,代码就会变复杂。就希望能写一个稍微通用一点的转换工具了,化简 AI 推导流程。
stamhe
2023-09-21 18:19:23 +08:00
proto 本身就会定义数据类型啊。。。还有不知道的?
tool2d
2023-09-21 18:22:15 +08:00
@stamhe AI 模型和通讯协议不一样,并没有 proto 文本数据。

就只给一个模型 pb 二进制文件,我要反推内部的输入参数,把 input/output 对接上才行。

每个模型权重输入,每个版本都不太一样。
pkoukk
2023-09-21 18:22:19 +08:00
我以为你在吐槽隔壁那个帖子,没想到你是认真的
thinkershare
2023-09-21 18:28:45 +08:00
@tool2d proto 不是自包含和自解释协议,因此你的想法不对。
tool2d
2023-09-21 18:33:21 +08:00
@thinkershare 这个开源工具可以解析任意 proto 生成的二进制文件,不需要原始格式

https://protobuf-decoder.netlify.app/

这工具用起来没问题,但是我去看源代码实现方式,核心功能是依靠 try catch 实现的,说白了就是靠猜,这就很尴尬了。
sujin190
2023-09-21 18:36:46 +08:00
预定义格式不是自解析的不靠猜靠啥,不知道你在无厘头吐槽啥
thinkershare
2023-09-21 18:38:28 +08:00
@tool2d protobuf 的官网已经明确说明,没有 proto 的原始定义下,如果要实现子描述,你需要自己实现。
tool2d
2023-09-21 18:40:10 +08:00
@sujin190 当年 google 发明 protobuf 的时候,如果想弄成 json 这种自解析,就是举手之劳。但就是偏不,我想吐槽这一点。

把文本和 messages 分开有那么难嘛,不就是一个 byte 类型,就能解决的事情。
billlee
2023-09-21 19:06:09 +08:00
@tool2d 发明 protobuf 就是为了不自解析,已经有 json 和 xml 了,为什么要重新造轮子呢
lasuar
2023-09-21 19:07:45 +08:00
lightweight, compact
seakingii
2023-09-21 19:11:03 +08:00
还自解析....你太自以为是了吧
PB 尽量的压缩数据,做自解析不是和目标相勃了
changnet
2023-09-21 19:19:22 +08:00
@tool2d 你这说法就怪了
当初之所以弄一个 protobuf 出来,就是因数 json 是自解析的,包含了太多数据,导致编码后的数据太大,效率也不高,才做出来的。

假如做成和 json 一样,那为什么不直接用 json 。或者,你想找的是 bson ,而不是 protobuf 。

为什么非要按 json 的方式去使用 protobuf ,他们本来就不是一样的东西。想吃青菜就买青菜,而不是买了个萝卜,再想这萝卜的味道为什么和青菜不一样。
duke807
2023-09-21 19:27:45 +08:00
@tool2d

你需要的是用 msgpack 代替 json
exch4nge
2023-09-21 19:49:09 +08:00
可以用 protoc --decode_raw 解析任意二进制到 protobuf 的 text format ,没 proto ,最多只能到这个程度。
lsry
2023-09-21 20:00:22 +08:00
/t/975214
模仿是吧
bianhui
2023-09-22 08:39:15 +08:00
没理解,为啥要自己写?现成的不能用吗?第二,为啥要自解析,你想转 json ,那你就先转为程序的对象,在序列化为 json 呗。为啥不要 proto ,你是爬取别的数据吗?获取不到别人的 proto 吗?
sujin190
2023-09-22 08:51:57 +08:00
@tool2d 发明 protobuf 本来就是为了解决现有压缩率和性能不足的问题,否则文本型有 json ,二进制型有 msgpack ,为啥要再造一个,再说选 protobuf 的场景本来就是看重其编码效率、压缩率和兼容性方案,你居然偏偏吐槽 protobuf 之所以被选择有优势的地方设计的不行
sujin190
2023-09-22 09:09:27 +08:00
@tool2d 而且顺便说,protobuf 之所以能在数据库,分布式系统和 AI 学习场景中得到广泛应用。很大程度就是因为你吐槽设计不行的预定义格式不自解析,可靠而稳定的数据结构才能保证这些系统的可靠性与准确性,不自解析预定义格式又有良好兼容性才是 protobuf 设计的好的地方

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/975959

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX