Hollow-LLM攻击:幽灵权重如何绕过零知识验证

📅 发布时间:2026/8/27 2:38:54
Hollow-LLM攻击:幽灵权重如何绕过零知识验证 这次我们来看一个 LLM 安全验证方向的攻击研究Hollow-LLM Attack中文可以理解为“中空大模型攻击”。它利用一组“幽灵权重”Ghost Weights让零知识验证Zero-Knowledge Verification在验证大模型时“检查通过”但实际拿到手、跑起来的模型却是一个空壳或已经被替换过的模型。这个攻击的核心矛盾在于验证者以为自己在验证“模型本身”但攻击者构造的验证证据只覆盖了模型的局部或表象真正参与推理的权重早就被换掉了。换句话说验证者验证的是一个精心布置的“影子”生产环境里跑的则是另一个模型。对于依赖第三方模型托管、模型网关、合规审计、模型供应链校验的团队来说这个方向值得认真关注。本文会从攻击原理、攻击场景、模拟验证思路、防御方案四个角度拆解 Hollow-LLM Attack。如果你是做 LLM 应用开发、模型部署、安全测试、或者正在建设模型合规验证体系的工程师这篇文章可以收藏备用。1. Hollow-LLM Attack 核心能力速览能力项说明攻击类型模型验证绕过 / 供应链投毒 / 推理服务降级目标对象使用 Zero-Knowledge Proof 验证 LLM 权重的系统以及第三方模型托管、模型网关、合规审计链路核心手段构造 Ghost Weights让验证者在抽检层、哈希校验层或 ZK 证明层看到“正确”的证据前置条件攻击者能接触待验证模型权重或在模型托管、分发链路中有写入权限影响范围模型完整性验证失效、后门模型上线、合规审计被欺骗、推理结果不可信检测难度较高传统哈希校验和基准测试采样不一定能发现问题防御方向全量权重指纹、非参数化行为验证、ZK 证明范围扩展、运行时行为监控从材料看目前关于 Hollow-LLM Attack 的公开实验数据还不完整很多攻击效果数字需要按实际模型、验证策略和硬件环境测试确认不能直接套用。下面我会尽量用原理拆解和通用实验流程来说明避免写死不存在的参数。2. 攻击背景为什么 LLM 验证会成为攻击面先明确一个问题在大模型落地过程中验证环节的必要性来自哪里。第一类是模型来源验证。企业采购或下载开源模型后需要确认这个模型没有被中间人替换没有被植入后门。最常见的做法是比较模型文件的 SHA256 哈希或者对比发布方的数字签名。这类验证生效的前提是发布方提供可信的哈希值并且从发布方到使用方的整个下载链路是可信的。第二类是推理过程验证。当模型托管在第三方平台、或者通过 API 对外提供服务时用户希望确认服务端确实运行了“声称的那个模型”而不是一个故意降级的小模型。这里就涉及零知识证明、可信执行环境TEE、远程证明等技术验证重点是“模型推理这个计算过程有没有被执行”而不仅仅是“模型文件对不对”。第三类是合规审计验证。在金融、医疗、政务等场景监管要求审计模型版本、推理日志和权重变更记录。审计方需要快速判断当前部署的模型是否和备案信息一致。问题在于目前的验证手段都有盲区。哈希校验只能验证文件层面的完整性但如果攻击者同时控制了“发布方哈希”和“模型文件”哈希校验就变成摆设。基准测试采样只能证明模型在少数样本上的表现如果攻击者在验证样本上“诚实”在真实业务请求上“降级”采样结果就失去了代表性。ZK 证明可以证明“某个权重文件被加载并完成了一次前向计算”但证明者完全可以加载一个被替换过的权重文件只要证明电路允许这个权重数据进入计算过程。从最近热词里也能看出这个方向的讨论热度LLM 框架、LLM API、远端验证失败、fp16/fp32 精度问题。精度问题尤其关键因为量化、精度截断、张量并行切分都会让同一个模型的权重在文件层面发生变化严格哈希校验反而会误报这让很多团队在实际操作中不得不放宽校验规则而放宽规则本身就是攻击面。Hollow-LLM Attack 瞄准的正是这些盲区文件表面合法、验证证据合法、真实推理不合法的中间地带。3. Ghost Weights 攻击原理拆解3.1 什么是 Ghost WeightsGhost Weights 指的是攻击者构造的一组“视觉上合法、验证逻辑上无法发现异常、但真实推理时会导致模型行为完全失控或定向偏移”的权重。可以把一个正常的 LLM 权重矩阵理解为一张完整的参数地图。攻击者要做两件事让权重文件在“验证者关注的位置”看起来正常。让权重文件在“推理引擎实际读取的位置”变成攻击者想要的内容。如果验证者只做全权重哈希攻击者要绕过比较困难因为任何一位的改动都会改变哈希值。但如果验证者为了性能只做局部抽检或者验证依赖 ZK 证明但证明电路没有覆盖全部权重约束Ghost Weights 就有了生存空间。3.2 攻击构造逻辑从攻击实现的一般逻辑来看Hollow-LLM Attack 的构造可以分成几个阶段。假设攻击者拿到了一个合法模型 W目标是构造一个伪装模型 W让验证者 V 验证 W 时认为它等价于 W但推理引擎实际加载 W 后输出的结果不等于 W 的输出。第一确定验证者 V 的验证范围。如果 V 只抽查前几层、只检查某些命名参数、或者只计算局部权重的统计信息攻击者就可以只保留这些被检查区域的权重“正常”其余区域替换为噪声权重、随机权重或攻击者自己的后门权重。第二构造伪装权重。攻击者保留原模型的 Embedding 层和输出层让模型在 Token 维度的输入输出映射看上去仍然正常中间层全部替换为随机矩阵或者精心构造的低质量权重。这样模型实际上已经“中空”只有外壳完整。第三处理验证者可能发起的推理采样。如果验证者会随机挑选几条 prompt 让模型推理并检查输出攻击者可以在验证请求进入时临时切换到完整权重验证结束后再切回中空权重。这种动态切换可以依靠推理服务层的前缀检测或请求特征实现验证请求带特定 header就加载完整权重普通用户请求就加载中空权重。第四处理 ZK 证明。如果验证者要求生成一段证明攻击者只需要在自己的推理服务中运行“中空权重”的计算过程并把该计算过程生成证明。ZK 证明保证的是计算完整性也就是“你确实运行了你声明的计算”并不保证计算权重本身的语义正确性。证明者还可以在证明电路中固定一份“合法权重快照”在证明生成时用真实权重计算但对外声称权重是另一个值。这本质上是在滥用证明系统的“证明内容”和“被证明对象”之间的脱节。3.3 为什么 Zero-Knowledge 验证也会被绕过这是 Hollow-LLM Attack 最容易让人困惑的地方既然用了零知识证明为什么还会被骗原因在于零知识证明验证的属性是什么。ZK 证明通常验证的是给定输入 x、电路 C、输出 y证明者知道一组 witness w使得 C(x, w) y。在 LLM 验证场景里x 是 prompty 是模型输出w 是模型权重C 是 Transformer 的计算电路。证明者需要证明的是“我用 w 运行了计算 C得到了 y”。这里有两个漏洞。第一个漏洞验证者通常不检查 w 的语义。w 可以是一堆随机权重只要证明电路允许计算照样能成立。输出 y 可能是一堆乱码但证明在密码学上是有效的因为计算过程确实被执行了。第二个漏洞w 本身没有被“绑定”到某个公开可信的模型。如果攻击者可以在部署时把 w 替换成自己的权重那么证明者证明的就是“替换后的权重执行了一次前向计算”而不是“某个受信任的模型执行了一次前向计算”。很多验证方案会把权重哈希写进证明的公共输入里但如果这个哈希本身来自攻击者控制的部署环境哈希就没有公信力。更隐蔽的情况是借助 fp16/fp32/bf16 精度问题绕过高精度校验。模型权重在加载阶段会被反量化或类型转换如果验证者用原始 fp32 权重计算哈希而推理引擎实际加载的是 fp16 版本攻击者可以在 fp16 转换过程中做微小的、不影响单个数值检查的扰动跑出来的模型行为却可以出现明显差异。这一点在做模型校验时必须特别注意。4. 攻击场景与攻击链4.1 场景一模型供应链替换这是最直接的场景。一个企业从第三方模型市场下载了 Llama 或 Qwen 的开源权重市场平台校验过文件哈希企业自己也做了一次哈希比对。如果攻击者已经攻破了平台分发链路在下载连接里替换成“中空权重”同时把平台展示的哈希值也替换成中空权重的哈希那么企业和平台都会认为文件是完整的。这时候模型能加载、能推理、能返回结果但回答质量会断崖式下跌或者会在特定语义触发下输出攻击者预设的内容。由于企业在后续基准测试中可能只跑几个常规数据集中空模型在常规样本上的表现可能看起来只是“有点差”但不至于明显异常问题会被掩盖。4.2 场景二第三方验证服务绕过假设一个第三方服务专门提供“模型验证证明”客户上传模型文件服务端计算哈希、运行若干 benchmark、输出一份验证报告。攻击者可以先用合法权重拿到报告然后在客户实际部署时替换成中空权重并声称报告适用于当前权重。如果验证服务没有绑定“报告编号、模型权重哈希、部署环境标识”这三者这份报告就会被复用。Hollow-LLM Attack 中 Ghost Weights 的价值在于攻击者可以在原始验证阶段就构造一个“合法权重和恶意权重混合体”让验证服务抽检的层和 benchmark 样本都通过但真实行为已经带毒。4.3 场景三推理服务商恶意降级推理服务商如果运营成本压力大有可能在用户无感知的情况下把大型模型降级成小型模型或稀疏化模型但仍然按大模型价格收费。Hollow-LLM Attack 提供了一个更隐蔽的实现方式权重文件里大量参数是噪声推理引擎按同样结构加载计算量无法按模型大小直接判断。用户侧很难通过推理时延、返回格式、API 结构来判断模型是否被降级只能通过输出质量对比。但中空模型在常见问题上可能表现尚可只在复杂推理、长上下文、代码生成等高质量任务上崩盘用户往往把它归因于 prompt 问题而不是模型被替换。4.4 通用攻击链用文字描述完整攻击链大概是这样的顺序攻击者获取一个目标合法模型的权重。构造 Ghost Weights保留 Embedding、部分 LayerNorm、输出层替换中间 Attention 和 FFN 的权重矩阵。在推理服务中实现“验证请求走完整权重、普通请求走中空权重”的流量分流逻辑。对验证者提交一份“包含合法权重哈希”的证明或者让验证者对模型做一次局部抽检。验证通过后普通用户开始使用中空模型输出结果受攻击者控制或明显劣化。审计阶段若只检查哈希、日志和 benchmark 报告很难发现异常。攻击是否成立取决于验证者是否对完整权重做强制约束而不只是对计算过程做证明。5. 模拟实验在授权环境中验证攻击思路这里我给出一套在本地授权测试环境中模拟 Hollow-LLM Attack 思路的实验流程。注意该流程仅用于安全研究和防御验证必须在你自己拥有或获得明确授权的模型、环境和代码上进行任何未经授权的替换、投毒和欺骗行为都是违法的。5.1 实验目标验证两个问题如果验证者只对模型权重做局部抽检中空权重能否通过抽检。中空权重加载后模型输出是否和原始权重出现可观察的差异。5.2 环境准备建议准备一台有 NVIDIA GPU 的 Linux 机器也可以先用 CPU 跑一个小模型做原理验证。需要安装的组件包括Python 3.10 以上环境PyTorch 2.xTransformers 库一个小型语言模型比如Qwen2.5-0.5B或TinyLlama以 Transformers 加载模型为例from transformers import AutoModelForCausalLM, AutoTokenizer model_name Qwen/Qwen2.5-0.5B-Instruct tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name, torch_dtypeauto)5.3 构造 Ghost Weights 模拟这里模拟“部分层被替换”的效果。假设我们把模型中间层的某些权重矩阵替换为随机噪声然后观察模型输出变化。import torch def hollow_out_model(model, num_layers_to_hollow4): 将模型中间的若干层替换为带噪声的权重仅用于授权安全实验。 真实攻击的构造会更精细这里只演示验证机制的缺口。 for layer_idx in range(num_layers_to_hollow): layer model.model.layers[layer_idx] with torch.no_grad(): # 替换 self_attn 的 q_proj 权重 original_shape layer.self_attn.q_proj.weight.shape layer.self_attn.q_proj.weight.copy_( torch.randn(original_shape, dtypelayer.self_attn.q_proj.weight.dtype) * 0.02 ) return model跑一个生成对比def generate_text(model, tokenizer, prompt, max_new_tokens50): inputs tokenizer(prompt, return_tensorspt) outputs model.generate( inputs.input_ids, max_new_tokensmax_new_tokens, do_sampleFalse ) return tokenizer.decode(outputs[0], skip_special_tokensTrue) prompt 请用一句话解释什么是零知识证明。 # 原始模型 original_model AutoModelForCausalLM.from_pretrained(model_name, torch_dtypeauto) print(原始输出:, generate_text(original_model, tokenizer, prompt)) # 中空模型 hollow_model AutoModelForCausalLM.from_pretrained(model_name, torch_dtypeauto) hollow_model hollow_out_model(hollow_model, num_layers_to_hollow4) print(中空输出:, generate_text(hollow_model, tokenizer, prompt))从实验效果上看原始模型输出是通顺的中空模型大概率会输出乱码、重复片段或完全偏离主题。这证明了一点模型权重中只有一部分参数真正对输出质量负责当验证者只抽检这部分之外的参数时中空模型完全可能通过抽检但输出质量崩溃。5.4 模拟局部抽检验证假设验证者并不检查全部权重而是随机抽检若干层的权重矩阵统计值比如均值、方差、L2 范数。def verify_by_layer_sampling(model, sampled_layers, original_model): results [] for layer_idx in sampled_layers: for proj_name in [q_proj, k_proj, v_proj, o_proj]: original_weight getattr(original_model.model.layers[layer_idx].self_attn, proj_name).weight current_weight getattr(model.model.layers[layer_idx].self_attn, proj_name).weight diff (original_weight - current_weight).abs().max().item() results.append((layer_idx, proj_name, diff)) return results # 只抽检最后两层很多中间层的中空修改不会被发现 sampled_layers [20, 21] print(verify_by_layer_sampling(hollow_model, sampled_layers, original_model))如果抽检只覆盖最后两层攻击者把中间层全部替换抽检结果会显示“权重一致”但模型其实已经中空。这个实验完整演示了 Ghost Weights 的验证绕过逻辑攻击者只需要知道验证者抽检哪些位置并把正常权重保留在那些位置即可。5.5 ZK 证明场景的模拟在完整 ZK 证明场景里攻击者未必需要直接修改权重文件而是可以通过证明电路本身只覆盖“计算过程”来绕过语义验证。简单说证明者可以构造一个电路输入是权重文件路径输出是前向计算结果。验证者只验证证明的正确性但不会去检查权重文件路径对应的参数值是否符合预期。因此即使权重已经中空证明依然可以生成并通过验证。如果验证方案把权重参数作为公共输入参与约束攻击者则可以通过“用合法权重生成证明、部署中空权重”的方式分离证明和实际执行。这需要验证者绑定部署环境、证明生成过程和实际推理过程否则证明可以复用。6. 防御与检测方案6.1 全量权重指纹校验最直接的防御是尽量做全量校验而不是局部抽检。对于本地部署的模型可以在下载完成后对模型目录内所有.safetensors文件计算哈希与官方或内部可信发布的哈希进行比对。# 计算 safetensors 文件的 SHA256 哈希 find ./models/ -name *.safetensors -type f -exec sha256sum {} \; /tmp/model_hashes.txt注意如果采用 fp16/bf16 精度加载可以先统一转换成同一精度后再计算哈希否则会因为精度表示差异产生不必要的误报。更稳妥的做法是保存一份“规范精度权重”的哈希白名单部署前做强制比对。6.2 非参数化行为验证仅靠权重校验还不够因为攻击者可能会在模型加载时动态篡改权重。这时候需要做行为验证。非参数化验证思路是不直接等于“权重是否正确”而是看“模型在大量内外分布样本上的输出是否和基准版本一致”。可以准备一组覆盖知识问答、推理、代码生成、指令遵循的测试集用原始模型和中空模型分别跑比较输出分布、困惑度、token 熵。import torch def compute_perplexity(model, tokenizer, text): inputs tokenizer(text, return_tensorspt) with torch.no_grad(): outputs model(**inputs, labelsinputs.input_ids) loss outputs.loss return torch.exp(loss).item() sample_text 量子计算和经典计算的主要区别是什么 print(原始困惑度:, compute_perplexity(original_model, tokenizer, sample_text)) print(中空困惑度:, compute_perplexity(hollow_model, tokenizer, sample_text))中空模型的困惑度通常会显著高于原始模型。如果部署后的模型在一个固定测试集上的困惑度、输出长度、回答重复率等指标出现明显漂移就应该触发告警。6.3 将权重约束纳入 ZK 证明如果必须依赖 ZK 证明不应该只证明前向计算过程还要把权重参数本身的约束纳入证明电路。一个更严苛的约束是证明者在证明中必须公开中间层权重的全局统计指纹而验证者把该指纹和链上/可信数据库中登记的原始指纹做比对。这样即使攻击者替换权重指纹比对也会失败。这个方案的成本较高因为 LLM 参数量动辄数十亿把全量权重纳入 ZK 电路会导致证明生成时间暴涨。折中方案是采用“分层指纹提交”每层单独计算精简哈希或多项式承诺验证者随机抽查若干层并要求被抽查层的承诺值匹配。6.4 运行时模型行为监控在生产环境里可以加一层运行时行为监控重点观察模型输出的平均 token 熵是否异常升高。相同 prompt 在多次调用中的输出一致性是否下降。特定前缀或特定 prompt 是否触发了异常的模型行为。推理服务进程是否有动态加载额外权重文件的网络行为或文件读取行为。这些信号可以接入现有的日志告警体系。不要在发现指标异常后才人工排查建议设置自动化阈值比如困惑度超过基准模型 1.5 倍时自动熔断该推理服务。6.5 硬件信任根与 TEE如果攻击者控制了整个软件栈任何在软件层面的校验都可以被绕过。更稳妥的边界是引入可信执行环境TEE比如 Intel TDX、AMD SEV-SNP 或 NVIDIA 的可信计算方案。模型权重在 TEE 内部解密后加载推理过程对外部不可见外部审计可以远程证明 TEE 的度量值从而确保推理确实发生在受信任的执行环境中。TEE 方案能解决一部分模型替换问题但部署复杂度和硬件要求较高适合对安全性要求极高的场景。7. 常见误判与排查清单问题现象可能原因排查方式解决方案模型哈希一致但输出质量明显下降权重加载时被动态替换或精度转换被利用输出层困惑度对比、中间激活分布对比增加运行时行为监控禁止动态加载外部权重哈希校验通过但推理行为异常验证者对哈希的输入和推理引擎实际加载的权重不是同一份文件检查推理服务的权重加载路径、缓存策略固定权重文件路径加载前后再次计算哈希ZK 证明生成成功但模型输出不可信证明只覆盖计算过程未覆盖权重语义检查证明公共输入是否包含权重指纹扩展证明电路提交权重分层指纹fp16 量化后模型表现和 fp32 差异大精度转换过程中的微小扰动被攻击者利用对比 fp32/fp16 在固定测试集上的输出差异统一精度基准使用 bf16 考虑降低敏感度验证请求通过、普通请求异常推理服务按请求特征分流权重检查访问日志中验证请求和普通请求的模型版本标记确保所有请求共用同一权重禁止动态切换基准测试通过但线上实际表现差基准测试集和业务场景分布差异过大增加业务真实样本的离线回放测试构建贴近业务分布的验证集定期回归8. 最佳实践与安全边界第一所有安全攻击分析都必须在授权环境中进行。Hollow-LLM Attack 的验证实验只应该用于防御测试、红队演练和学术研究不能用于实际生产环境的模型替换、欺骗审计或商业欺诈。把攻击思路转化为防御力而不是攻击力。第二模型供应链建立“双重签名”机制。发布方对模型权重文件做数字签名使用方在部署前验证签名同时把权重哈希、签名、部署环境标识绑定写入部署清单。这样即使攻击者替换了模型文件也无法伪造发布方的签名。第三验证策略避免“固定抽检”。如果使用抽检方案抽检层、抽检参数、抽检时间必须随机化并且每次验证至少包含一次全量权重统计指纹比对。不要每次抽检同一个层否则攻击者可以把正常权重固定放在那一层。第四推理服务禁止动态加载“额外权重”。部署流程中模型权重目录应该是只读的加载逻辑只允许读取预置目录不允许从外部 url、临时目录或客户请求参数中动态加载权重。这是阻断动态切换型 Hollow-LLM Attack 的关键工程手段。第五建立模型行为基准线。模型上线前记录一组“标准输出基准”包括指定 prompt 的回答、困惑度、平均输出 token 数、重复率。每次发布或例行巡检时对比这些指标。指标漂移超过阈值就告警并暂停服务。第六零知识验证方案必须明确“证明了什么”。在采购或选型 LLM 验证服务时要仔细检查证明覆盖的范围确认权重指纹、模型版本、推理环境标识是否被绑定。如果协议只证明“一次前向计算发生了”那它几乎没有抵御 Hollow-LLM Attack 的能力。9. 总结与后续关注Hollow-LLM Attack 的核心价值不是提供一个可以直接搬走的攻击代码而是揭示了一个容易被忽略的事实大模型验证体系如果只验证“文件存在”或“计算发生”就没有真正验证“模型可信”。Ghost Weights 让攻击者可以在验证和推理之间制造一道信息差而零知识证明在标准用法下很难发现这道信息差。最值得验证的点是你自己的模型验证流程到底覆盖了哪些内容。如果只是算一个哈希、跑一个 benchmark、或者采几个随机 prompt建议先用本文第 5 节的模拟思路做一次缺口测试看看模型在替换部分层之后会不会仍然通过现有验证。最容易踩的坑集中在三点一是抽检固定层二是不绑定权重指纹三是允许推理服务动态加载权重。把这三点堵住大部分 Hollow-LLM Attack 的简易变体都会被拦截。后续可以继续关注的方向包括更强的 ZK 权重约束协议、TEE 与远程证明的组合方案、面向 LLM 供应链的完整性审计标准以及 fp8/bf16 量化环境下权重校验的稳定性问题。如果你正在建设和维护大模型推理平台建议把“验证链路本身被攻击”纳入安全评估范围。