如果你现在还把“跑一下模型评测”当成普通 CI 任务,我建议立刻停下来重新画一遍威胁模型。

这不是危言耸听。Hacker News 上这两天讨论很热的一条帖子是 OpenAI and Hugging Face address security incident during model evaluation,真正值得看的不是“谁背锅”这种八卦,而是它把一个长期被低估的问题摊开了:模型评测、数据集处理、Leaderboard 跑分、Agent capability test,本质上都在执行来自外部的不可信输入。区别只是这段输入有时叫 Python loader,有时叫模型权重,有时叫 prompt,有时叫 eval harness。

Hugging Face 随后发布了更具体的 Security incident disclosure — July 2026。按披露内容,入侵入口出现在数据处理流水线:恶意数据集利用 dataset processing 里的代码执行路径,在处理 worker 上运行代码,随后进一步获取节点级访问、收集云和集群凭证,并横向移动到内部集群。Hugging Face 表示未发现公开模型、数据集、Spaces 或软件供应链被篡改,并验证了容器镜像和发布包是干净的。

我看到这里的第一反应不是“某个平台又出事了”,而是:这正是 AI 基础设施最容易自欺欺人的地方。大家嘴上说“模型是不可信的”,但工程上经常只把 API key 藏好、把网络出站关一半,然后就让评测任务在一个接近生产环境的集群里跑。

说白了,评测系统不是打分器,它是一个远程代码执行平台。

为什么模型评测比普通 CI 更危险

普通 CI 至少有一个相对清晰的信任边界:代码来自某个仓库,触发者是某个账号,依赖来源大概可追踪。模型评测环境就麻烦得多。它可能要下载第三方模型权重、解析数据集、执行自定义 loader、跑 benchmark 脚本、调用 GPU、读写缓存,还可能访问内部模型 API 或对象存储。

这些动作拆开看都合理,连起来就很危险。

比如 Hugging Face 的 Pickle Scanning 文档 明确提醒:pickle 是机器学习里常见的序列化格式,尤其曾经常用于 PyTorch 权重,但加载 pickle 文件可能触发任意代码执行。人话翻译就是:你以为自己在“加载模型”,实际可能是在运行别人塞进文件里的程序。

这也是 Safetensors 这类格式有工程价值的原因。Safetensors 的卖点不是“更潮”,而是它把张量存储做成更简单、更安全的格式,避免 pickle 这一类反序列化执行风险。它不能解决所有供应链问题,但至少把一个高频 RCE 面切掉了。

问题在于,模型评测很少只碰权重。数据集同样会带代码。很多数据加载逻辑为了灵活,会允许自定义脚本、模板、远程 loader。对于研究环境这很方便;对于生产评测平台,这就是一扇门。门本身不一定错,错的是你不能把它开在内网走廊尽头,还顺手把云凭证放在门边。

我之前写过 PyTorch Lightning 供应链攻击复盘,那篇讲的是依赖包层面的供应链风险;这次的教训更贴近 AI 平台自身:即使你的 pip 依赖干净,数据集、模型文件和评测脚本也可以成为供应链入口。

一个合格的评测沙箱,至少要先假设“样本会逃逸”

很多团队谈 sandbox,第一反应是 Docker。坦白说,只靠 Docker 不够。

Docker 是隔离工具,不是安全边界的全部。尤其在 GPU 场景里,容器经常需要挂载驱动、共享缓存、访问高速存储,权限一放宽,隔离质量就开始下降。再加上评测任务为了性能会复用 worker、复用镜像、复用本地模型缓存,攻击者只要找到一个持久化点,就可能从“单次评测”变成“污染后续任务”。

我更认可的设计思路是反过来:默认认为评测样本一定能执行代码,也默认认为它会尝试偷凭证、探测网络、写缓存、影响后续任务。然后再问:它最多能拿到什么?

第一层是一次性环境。评测 worker 应该尽量短生命周期,用完销毁,不要把“干净环境”建立在 rm -rf 某个目录上。GPU 资源贵,这点做起来确实痛,但安全和成本本来就是取舍。如果每个任务都复用同一个带缓存的节点,攻击面会被放大。

第二层是凭证最小化。评测任务通常只需要读某个输入、写某个输出,不应该拿到能枚举对象存储、访问内部服务、拉取生产镜像的长期凭证。临时凭证、短 TTL、按任务 scope 授权,这些听起来老生常谈,但在 AI 平台里经常被 GPU 调度和实验便利性挤掉。

第三层是网络默认拒绝。很多恶意行为不是在本地完成的,而是要出站拉 payload、回传凭证、探测元数据服务。评测环境如果必须访问外部模型仓库,最好走代理和 allowlist,而不是给一张通往互联网的全通票。尤其要拦住云 metadata endpoint,这个坑云原生安全讲了十年,AI 集群还是会踩。

第四层是缓存隔离。模型缓存、dataset cache、pip cache、容器层缓存都可能成为跨任务通道。最保守的做法是任务级隔离;折中做法是只缓存经过验证的只读 artifact,并把用户提交内容和平台缓存分开。不要让“不可信任务写入的东西”被后续高权限任务直接复用。

第五层是可观测性。Hugging Face 在披露里提到他们用 AI 辅助检测和分析入侵,这点很有意思,但我不想把它神化。AI 可以帮助总结日志、关联异常、生成调查假设,但底层仍然要有足够细的审计数据:进程、网络、文件写入、凭证使用、Kubernetes API 调用、对象存储访问。没有这些数据,再聪明的 Agent 也只能编故事。

这和我之前写 AI Agent 安全框架 时的判断一致:Agent 安全不是在 prompt 里写“不要越权”,而是把权限、环境、审计和回滚做成系统边界。

平台侧扫描有用,但不能替代运行时隔离

Hugging Face Hub 已经提供了不少平台侧安全能力,比如 Malware Scanning 会在每次 commit 后扫描仓库文件,Pickle Scanning 会针对 pickle 风险做提示,Signing commits with GPG 也能帮助确认提交来源。

这些能力都值得用,但不要误解它们的边界。

扫描是静态或准静态的,它能拦住已知恶意样本、危险格式、明显异常文件;运行时隔离解决的是“我没有提前识别出来,但它真的开始作恶了”的场景。两者不是替代关系。现实里你需要的是组合拳:上传前后扫描、格式白名单、签名校验、沙箱执行、出站控制、凭证隔离、行为审计。

特别是企业内部如果要做模型准入,别只问“这个模型在 benchmark 上多少分”。我会把准入检查拆成两类:

  • artifact 准入:权重格式、来源签名、license、模型卡、依赖清单、已知漏洞、是否需要 trust_remote_code;
  • runtime 准入:加载过程是否联网、是否写入非预期路径、是否访问敏感环境变量、是否产生异常子进程、是否触发 GPU/驱动异常。

前者决定“能不能进入仓库”,后者决定“能不能进入生产或半生产环境”。很多团队只做了前者,甚至前者也只是人工看 README。

我会怎么给企业落地排优先级

如果你是一个小团队,没必要一上来做一套昂贵的模型安全平台。先做四件事,收益最大。

第一,禁用默认的危险路径。能不用 pickle 就不用 pickle,优先 safetensors;能不用 trust_remote_code 就不用;必须用的时候,把它放进更严格的隔离池。这里没有银弹,但减少默认暴露面很实在。

第二,把评测环境从生产网络里切出去。它可以访问模型仓库代理、对象存储的临时输入输出桶、日志系统,但不应该能随便访问内部服务。评测不是内网应用,不要给它内网应用的信任。

第三,所有凭证都按任务下发,短期有效,用完作废。不要在节点上放长期云凭证,不要把 Hugging Face token、OpenAI key、私有 registry token 当环境变量长期挂在 worker 里。攻击者最喜欢的不是你的 GPU,而是这些凭证。

第四,保留足够的行为日志。最少要能回答:这个任务启动了哪些进程?连了哪些域名和 IP?读写了哪些路径?调用了哪些云 API?如果回答不了,出事后你连影响范围都界定不了。

反直觉的是,模型评测平台越自动化,越需要把它当成不可信代码执行平台来设计。人工评测慢,但人会本能地怀疑;自动化系统快,也更容易把恶意输入稳定、批量、带权限地跑起来。

最后:别把“模型安全”只理解成 jailbreak

过去一年,AI 安全讨论很容易被 prompt injection、jailbreak、Agent 越权占满。这些当然重要,但 Hugging Face 这次披露提醒我们:AI 安全还有一条更传统、也更容易造成实际损失的线——供应链和运行时隔离。

模型、数据集、评测脚本、依赖包、缓存、容器镜像、GPU worker,这些东西拼在一起,就是企业 AI 基础设施的真实攻击面。攻击者不需要和你的 chatbot 聊天,他只要让你的评测系统“帮他运行一下”。

我的判断很简单:未来企业做模型评测和 Agent benchmark,如果没有沙箱、临时凭证、网络隔离和 artifact 准入,分数越高,风险可能越大。因为你不仅在评估模型能力,也在给不可信代码提供一条进入内部基础设施的高速路。

这块我也不敢说有一个完美答案。GPU 隔离、缓存复用、安全扫描之间有很多现实妥协。但至少从今天开始,别再把 eval worker 当普通 CI runner 了。