You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解读从pickle文件读取的字节数据打印结果?

问题描述

我尝试从pickle格式的PyTorch模型文件(alexnet.pth)中读取数据,用二进制方式读取的代码如下:

f = open("alexnet.pth", "rb")
data = f.read()

读取后得到的字节流片段如下:

b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x12\x00archive/data.pklFB\x0e\x00ZZZZZZZZZZZZZZ\x80\x02ccollections\nOrderedDict\nq\x00)Rq\x01(X\x11\x00\x00\x00features.0.weightq\x02ctorch._utils\n_rebuild_tensor_v2\nq\x03((X\x07\x00\x00\x00storageq\x04ctorch\nFloatStorage\nq\x05X\r\x00\x00\x002472041505024q\x06X\x03\x00\x00\x00cpuq\x07M\xc0Ztq\x08QK\x00(K@K\x03K\x0bK\x0btq\t(Mk\x01KyK\x0bK\x01tq\n\x89h\x00)Rq\x0btq\x0cRq\rX\x0f\x00\x00\x00features.0.biasq\x0eh\x03((h\x04h\x05X\r\x00\x00\x002472041504928q\x0fh\x07K@tq\x10QK\x00K@\x85q\x11K\x01\x85q\x12\x89h\x00)Rq\x13tq\x14Rq\x15X\x11\x00\x00\x00features.3.weightq\x16h\x03((h\x04h\x05X\r\x00\x00\x002472041505120q\x17h\x07J\x00\xb0\x04\x00tq\x18QK\x00(K\xc0K@K\x05K\x05tq\x19(M@\x06K\x19K\x05K\x01tq\x1a\x89h\x00)Rq\x1btq\x1cRq\x1dX\x0f\x00\x00\x00features.3.biasq\x1eh\x03((h\x04h\x05X\r\x00\x00\x002472041507136q\x1fh\x07K\xc0tqQK\x00K\xc0\x85q!K\x01\x85q"\x89h\x00)Rq#tq$Rq%X\x11\x00\x00\x00features.6.weightq&h\x03((h\x04h\x05X\r\x00\x00\x002472041509056q'h\x07J\x00 \n\x00tq(QK\x00(M\x80\x01K\xc0K\x03K\x03tq)(M\xc0\x06K\tK\x03K\x01tq*\x89h\x00)Rq+tq,Rq-X\x0f\x00\x00\x00features.6.biasq.h\x03((h\x04h\x05X\r\x00\x00\x002472041505312q/h\x07M\x80\x01tq0QK\x00M\x80\x01\x85q1K\x01\x85q2\x89h\x00)Rq3tq4Rq5X\x11\x00\x00\x00features.8.weightq6h\x03((h\x04h\x05X\r\x00\x00\x002472041508192q7h\x07J\x00\x80\r\x00tq8QK\x00(M\x00\x01M\x80\x01K\x03K\x03tq9(M\x80\rK\tK\x03K\x01tq:\x89h\x00)Rq;tq<Rq=X\x0f\x00\x00\x00features.8.biasq>h\x03((h\x04h\x05X\r\n'

我的疑问:

  • 1字节是否对应1个十六进制字符(每个"\x"代表1字节)?
  • 该如何从字节角度解读这些内容?
  • 像\x02ctorch._utils和n_rebuild_tensor_v2这类十六进制加字符串的内容,它们是什么含义?
解答

1. 字节与十六进制的对应关系

每个\xXX表示一个字节,其中XX是两位十六进制字符(范围00-FF),所以1字节对应两位十六进制字符,不是一个。比如\x03是一个字节,十进制值为3;\xc0是一个字节,十进制值为192。Python打印字节流时,对于可打印的ASCII字符(比如P、K、c)会直接显示字符,而非打印字符则用\xXX的十六进制形式表示。

2. 字节流的整体解读

首先看开头的PK\x03\x04——这是ZIP压缩文件的文件头,因为PyTorch的.pth模型文件本质是一个ZIP包,里面包含了archive/data.pkl文件,这个文件才是真正的pickle序列化数据。

后续的字节流是pickle协议的序列化内容:

  • \x80\x02:表示使用pickle的协议版本2;
  • 各种\xXX是pickle的操作码,用来标记要执行的序列化/反序列化操作(比如创建字典、引用对象、导入模块等);
  • 穿插的字符串(比如collections\nOrderedDict)是要操作的模块、类或属性名;
  • 类似q\x00的标记是pickle的引用标识符,用来复用已经出现过的对象,减少序列化体积。

3. 十六进制加字符串片段的含义

以\x02ccollections\nOrderedDict和ctorch._utils\n_rebuild_tensor_v2为例:

  • \x02是pickle的操作码,代表“构建一个新对象”;
  • 开头的c是pickle的指令,意思是“导入指定模块并获取其中的类/函数”;
  • 后面的collections\nOrderedDict表示导入collections模块,获取OrderedDict类;torch._utils\n_rebuild_tensor_v2表示导入torch._utils模块,获取_rebuild_tensor_v2函数;
  • 末尾的q\x03是把这个函数存入pickle的引用表,后面需要重建张量时可以直接引用这个函数,不用重复序列化。

这些片段是pickle用来重建PyTorch张量的关键指令——因为张量包含底层存储等复杂结构,无法直接序列化,所以pickle会记录“调用哪个函数、传入哪些参数”来重新构造张量。

内容的提问来源于stack exchange,提问作者ryan chandra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:07:48