> 模型完整性验证的三种粒度——整文件哈希、内容定义分块、结构感知 Merkle

Security Engineering 中级 2026-09-06 07:21 2026-09-06
#model-integrity #merkle #supply-chain #safetensors #provenance

"验证模型没被篡改"是三个不同的问题,对应三种粒度,互相不能替代:

// TABLE_OF_CONTENTS

结论先行

"验证模型没被篡改"是三个不同的问题,对应三种粒度,互相不能替代

粒度 能回答 答不了 代表
整文件哈希 这个文件和我签名时是不是同一个 / 谁签的 差在哪 Sigstore、DVC、W&B、MLflow
内容定义分块(CDC) 两个版本共享多少字节,怎么增量同步 差在哪个张量/层 HF Xet
结构感知 Merkle 差在哪个张量、哪一层,能出证明 谁签的(无 provenance) 自建

选错粒度的典型症状:想回答"这次微调改了哪些层",却只有一个整文件 SHA-256—— 它只能告诉你"变了"。

另外记住一条:safetensors 本身没有任何内建的密码学完整性验证。 (Issue #220 在 2023-12 被 closed as "not planned"。) PyTorch 原生也没有(Issue #126952 仍开着)。 "用了 safetensors 所以安全"是个常见误解——safetensors 解决的是 反序列化任意代码执行,不是篡改检测

为什么

各家实际覆盖的能力(2026-03 时的调研):

能力 自建 Merkle HF Xet Sigstore/OMS DVC cuPQC IPFS lakeFS W&B
O(1) 根哈希比对
O(k log C) 差分比对 部分
张量/层级差分
Merkle 证明
来源/身份(谁签的) 部分
GPU 加速

三个值得单独记住的点:

  1. HF Xet 自 2025-05 起是新 HF repo 的默认后端(CDC + Blake3 + Merkle,Rust)。 它的 CDC 对字节位移鲁棒、能跨版本自动去重——但只在字节层面, 不知道模型结构,也不提供独立库。做这个方向必须先说清楚和它的差异。
  2. Sigstore Model Transparency 解决的是正交问题:provenance。 它回答"谁签的、签名何时进的透明日志",用的是整文件 SHA-256 → DSSE + in-toto → 签名。 它不做子文件粒度,也不做 diff。 NVIDIA NGC 的模型已全部签名,所以这是事实标准的一半。
  3. cuPQC 是加速层不是方案层:CUDA 加速的 SHA2/SHA3 + Merkle 构建/证明/验证, 70B+ 模型上 10–100× 吞吐,但没有 ML 语义的 API,且绑定 NVIDIA GPU。

学术侧的边界:ZKML(验证推理正确性)和这里(验证文件完整性)是互补的, 经常被混为一谈。链上存 Merkle 根是可行的组合点。

怎么用

选型时先问自己要回答哪个问题:

  • 「这个 checkpoint 是不是我发布的那个」→ 整文件哈希 + 签名(Sigstore 类)就够了。
  • 「怎么少传点字节」→ CDC(Xet 类)。
  • 「这次训练改动了哪些层,给我证明」→ 结构感知 Merkle。
  • 「谁签的」→ 只有 provenance 方案能回答,Merkle 树答不了。 需要就必须叠一层签名,别指望哈希树。

做自建方案时的定位纪律: 不要声称"比 Xet 好"——它在字节层面的去重和 HF 生态集成是你打不过的。 要声称的是它答不了的问题(张量/层级差分、同步节省估计)。 你设计的 workload 必须能让你的机制起作用——否则 ablation 一定是平的 的教训在这里同样适用: 如果你的评测里没有"只改了少数几层"的场景,结构感知的优势根本不会显现。

出处

  • ~/Engineering/merkle-weight-verify/COMPETITIVE_ANALYSIS.md(2026-03-26)
  • 关键外部引用:Xet Hashing Spec、sigstore/model-transparency v1.1.1(2025-10)、 safetensors Issue #220、PyTorch Issue #126952