ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

第 3 篇:权重文件的解剖(零门槛入门系列)

第 3 篇:权重文件的解剖(零门槛入门系列) 上一篇第 2 篇《数字在内存里怎么排队》 下一篇第 4 篇《并行4 个工人 ≠ 快 4 倍》一句话导读一个权重文件 一张目录 一堆数字加载只是把文件挂到手边不是把它读完背下来。关键词权重、张量、头、目录、偏移、加载上一篇把矩阵摊成了一条线。这一篇接着问这些线是怎么装进一个磁盘文件、又凭什么能做到打开就用而不是先整个读一遍答案全在文件的内部结构上。① 一句话概念权重文件 目录 数据加载只是把它挂上去。② 起点一本目录订在最前面的厚字典一本很厚的字典前面有十几页目录后面才是正文。目录里每一行写着某个词、它在第几页、占多少行。你想查琥珀不用从第一页翻起只要在目录里找到那一行按上面的页码直接翻过去。现在把这件事反过来想你要用一整本字典是不是必须把每个词的意思都抄到自己的笔记本上不必。你只要把字典摆在手边用到一个词的时候再翻那一页。字典本身没变笔记本上也没什么内容你得到的只是随手能翻到这件事。不过这里有个安静的危险如果目录里那一行页码写错了你翻过去看到的会是一个完全不同的词而且不会有人提醒你翻错了——你只会照着错的东西接着往下做。③ 伪代码一张目录 一段数据区文件 头(版本, 张量个数, 目录在哪) 数据区 目录项 { 名字, 形状, 类型, 在文件里的偏移, 长度 } 函数 加载(路径): 内存 把文件挂到手边 # 只挂不复制 → 内存 函数 取张量(名字): d 内存.目录[名字] → 内存[d.偏移 : d.偏移 d.长度]一个权重文件摊开来看就是如图 1 所示的三段。图 1权重文件 目录 数据区一条文件带从第 0 个字节开始一段接一段被切成三段从左到右依次是头版本 / 张量个数 / 目录偏移、目录每个张量一项、数据区真正的数字图上方是目录项的表头行名字 | 形状 | 类型 | 偏移 | 长度和两条示例目录项一条向上的虚线箭头从文件带的数据区一段指回上方的目录项表头行右侧旁注写着按偏移 长度到数据区取数底部一个红框提醒偏移写错一个字节取到的就是别人的数据而且不报错只会静默算错。逐行要点头(版本, 张量个数, 目录在哪)头header是全文件的封面固定长度、位置固定所以任何程序都能第一眼读懂它。它里面最重要的是目录在哪——没有这一项后面的目录就找不到了。目录项 { 名字, 形状, 类型, 偏移, 长度 }每个张量tensor就是一批数字比如一层权重在目录里占一项。名字用来点名形状告诉你它是几行几列类型告诉你每个数是怎么存的偏移offset是从文件开头数第几格长度是它占地多少格。把文件挂到手边这就是加载load的真实含义。文件不会被整个读进内存再抄一遍而是挂着真正用到哪一段才把哪一段拿过来。这是加载只要一眨眼的全部原因。内存[d.偏移 : d.偏移 d.长度]取一个张量只有这一种办法——按偏移和长度切一段。偏移写错不会报错程序会安静地取到别人的数据算出一堆看起来正常、其实全错的结果。这是这类文件最贵的一类坑。目录[名字]按名字查找所以这个文件是自己说清楚自己的——不需要额外再配一份说明文件这是它比裸数据强的地方。④ 纸笔实验必做设定你要为一个文件编一张目录文件里放 3 个张量每个数占 4 个字节B——这里先用不压缩的存法张量形状数据格数长度词嵌入(8 行, 4 列)8 × 4 32 个128 B注意力权重(4 行, 4 列)16 个64 B输出层(4 行, 8 列)32 个128 B再假设头固定 100 B目录紧跟在头后面每项固定 32 B共 3 项。请算出第二个张量的偏移并画出文件布局。手算过程目录起点 100 B头紧跟目录。目录占32 × 3 96 B所以数据区起点 100 96 196 B。第一个张量占 128 B所以第二个张量的偏移 196 128 324 B。第三个张量偏移 324 64 388 B文件总长 388 128 516 B。预期结果文件布局偏移 0 100 196 324 388 516 |------ 头 100 B ---------|-- 目录 96 B --| 词嵌入 | 注意力 | 输出层 | 128 B 64 B 128 B第二个张量注意力权重的偏移 324长度 64。请再验证一件事如果把头是 100 B错看成头是 96 B第二个张量的偏移会算成 320——只差 4 个字节取到的就是错位的一小段。可选 REPL 版任意语言直接跑头 100 目录项 [(词嵌入, (8, 4)), (注意力权重, (4, 4)), (输出层, (4, 8))] 每条 32 偏移 头 每条 * 目录项.个数() 对每个 名字, 形状 于 目录项: 长度 形状[0] * 形状[1] * 4 打印(名字, 形状, 偏移, 偏移, 长度, 长度) 偏移 偏移 长度 打印(文件总长, 偏移)预期输出末尾是文件总长 516且注意力权重那一行的偏移是 324。⑤ 进阶锚点进阶锚点本篇概念在《30 天手搓推理引擎》Day 3里被真正实现——3-1 mmap 直挂为什么权重加载可以只要一秒多/3-2 字节序与十六进制纪律一个字节序错误引擎当场翻脸/3-3 自研 util不引第三方也能活的边界感。入门版到这里就够了进阶版会多出真实的挂载式加载实现与它在设备上的加载耗时记录来自仓库 docs 报告口径、逐字节核对的读写纪律、改一个字段就拒绝加载的真实踩坑以及为什么这套小工具全部自己写。想动手 → 仓库https://gitee.com/pei-xiaoguang/kestrel-llm从 Day 1 开始。本篇的目录 偏移在进阶 Day 3 会变成可以直接读的字段表。下篇预告文件里那几百万个数字一个一个搬是搬不完的——得叫人来帮忙。第 4 篇讲为什么 4 个工人不等于快 4 倍。
返回列表