资讯动态

【FHE 同态加密】我们如何实现同态加密推理(二):引擎全景——一次密态推理的完整数据流(明文 Python × 密文 C11)

发布时间:2026/10/5 2:37:22 来源:尧图企业网站定制
关键词同态加密推理 FHE 引擎全景 数据流 密文计算 明文预处理 CKKS 纯 C11 大模型推理导读这是一套同态加密推理引擎的完整数据流全景。整套系统被一条线劈成两个世界明文侧Python负责权重导出、非线性函数逼近与明文参考值密文侧纯 C11只读这些产物、在大模型的密文上把前向跑完。本篇讲清这条同态加密推理链路的分界线、各层职责以及哪一侧该信谁。项目仓库Gitee 主仓https://gitee.com/pei-xiaoguang/kestrel-llmGitHub 镜像https://github.com/m13253246268-ship-it/kestrel-llm相关文档术语与数据口径 性能与基准 构建与复现 快速上手 架构总览0. 一句话结论整套系统被一条线劈成两个世界明文侧Python把模型权重、非线性函数的逼近系数、以及正确答案明文参考算出来落成.bin密文侧纯 C只读这些.bin在密文上把前向跑完产出密文。分界线是两样东西拟合系数与明文参考。密文侧从不重新拟合任何东西明文侧从不碰密文——这个切法让两侧可以独立验证。1. 两个世界的产物对照明文侧tools/preproc/Python密文侧src/core/ 驱动C输入model.safetensors约 4.26 GB明文侧落下的.bin 密文产出权重、拟合系数、明文参考值、尺度表密文.ct 日志依赖numpy、safetensors仅libc libm是否可重跑可且产出逐字节可复现可且产出位级可复现需固定线程数怎么验与分发物比对哈希verify_layer独立解密复核2. 明文侧四个阶段24 个脚本tools/preproc/下是 24 个 Python 脚本按职责分四组完整执行顺序以tools/preproc/README.md的「执行顺序」一节为准① 导出_export_weights.py权重导出tail/w0..w27/每层 9 个文件_embed4.pylay0的明文输入——按 token id 从 embedding 表取 4 行l0/embed4.bin4×2048 float3232768 B② 定路径_silu_mode.py逐层写出 8 字节的tail/silu{L}.bin决定该层的 SiLU 走直接拟合还是÷21 折叠本系列第 8 篇专门讲这个开关它也是最危险的一个文件③ 生成参考值“正确答案”_full_layers.pyL0…L25 的明文因果前向参考_tail_ref.py链尾L26…L27参考以及_ln_fit*.py/_m2c*/_refit_lnq.py等LayerNorm 与倒数之类的分支参考④ 拟合与定标_sin_fit*.py/_cos_fit.py/_recip_fit.py/_attn_fit.py把非线性函数sin、cos、倒数、exp拟合成多项式直接生成 C 数组例如EXP_Q[7]、RECIP_Q[9]_fold_fit.py/_fold_sim.py/_cfold_plan.py折叠方案的设计与仿真_adap_scale.py逐层尺度自适应本系列第 9 篇_silu_err.py/_logits_tol.py误差与容差评估工具一个反直觉的事实这些脚本产出的数据包约 7 GB但它不随仓库分发。任何人都能用同一个模型把整包重新生成出来——我们核对过生成物与分发物逐字节相同。3. 密文侧四层职责┌──────────────────────────────────────────────┐ │ 驱动 t23_m3p.c (lay) / t23_chain.c (boot) │ ← 一个层的业务逻辑 ├──────────────────────────────────────────────┤ │ vllm_ckks.c RNS-CKKS编码/加密/加乘/ │ ← 密文语义 │ rescale/relin/rotate/modraise │ ├──────────────────────────────────────────────┤ │ vllm_ntt.c 负循环 NTT多项式乘法 │ ← 数学原语 │ vllm_tp.c 自研线程池替换 OpenMP │ ← 并行原语 └──────────────────────────────────────────────┘关键点下层不知道上层在算什么。NTT 不知道自己在做 attentionCKKS 不知道自己在算 Transformer。这条分层让位级可验证成为可能——你可以单独证明 NTT 是对的与教科书 O(n²) 位级对照而不用先信任整个模型。4. 一跳内部发生了什么4.1lay层内前向layL: u(L-1)r112 → uL一串同态算子的组合QKV 投影、attention、FFN、以及需要密文化的非线性SiLU、倒数、exp 等全部用预先拟合好的多项式代替。4.2boot自举刷新bootL: uL → u(L)r112。驱动 t23_chain.c 的[boot profile]打印把整条流水线摊开了实测的七段是modraise → coeff_to_slot → rotate_k → conj_extract → sin_fold_re / sin_fold_im → restore_merge → slot_to_coeff段作用modraise用 Garner 扩展把模数链抬回满链自举的起点coeff_to_slot系数域 → 槽位域Galois 旋转 key-switchrotate_k旋转conj_extract共轭提取分出实部/虚部sin_fold_re/im对实部、虚部分别做sin折叠EvalMod 核心restore_merge还原并合并slot_to_coeff槽位域 → 系数域这七段的时间分布极不均匀——coeff_to_slot与slot_to_coeff两段就占了约 80%。本系列第 15 篇给完整账本。5. 交接一跳的产物一跳结束落盘的东西很少产物数量 / 规格密文8 枚4 个 token 位置 × 2 个分量u{L}r112_*.ct单文件 ≈3.5 MB日志stage.out/stage.err元数据 哈希manifest.sha256逐文件 SHA256可自校验这个包就是接力棒。下一棒只需要三样这个包、sk.bin同一把私钥、以及编译好的驱动。6. 一张总图图 2-1 怎么读左边是明文侧Python只产出拟合系数与明文参考右边是密文侧纯 C只读这两样东西从不重新拟合任何函数。中间那条红色虚线就是分界线——它同时是两边的接口也是两边可以各自独立验证的原因。矢量版figs/fig02_dataflow.svgGraphviz 源码figs/fig02_dataflow.dot本机未装 Graphviz 时图片由figs/make_figs.py生成下面是同一张图的纯文本版便于在终端或纯文本环境里阅读model.safetensors ──┐ ├─[preproc]─→ .tmp_tok/tail/{w*,l*_ref,silu*.bin,scale*.bin} │ │ │ ▼ │ [t23lay (np112)] 明文输入 embed4 ──→ 密文 u0 ──────────┘ │ ▼ [t23boot (np2100)] → u0r112 │ ▼ 8 × u0r112_*.ct manifest.sha256 │ ├─→ 交给下一棒lay1 └─→ [verify_layer] 独立复核 max|err|7. 安全边界务请读完本文所述参数为机制验证级n2048、112 素数内层链、2100 素数自举链 远低于 HE 参数标准的 128-bit 水平不得用于保护真实数据。 本文主张的是系统结构与数据流的事实描述。 本文不主张安全强度、性能优越性。8. 这一篇的未解问题明文侧与密文侧的耦合点还是太多。拟合系数如EXP_Q是密文侧的常量但它的取值范围来自明文侧的统计——一旦换模型这些常量全部要重算。我们希望把这条依赖显式化成一份契约文件目前还散在脚本里。_silu_mode.py的逐层选择是固化调参结果不是从模型推导出来的规则。它目前是一个硬编码的层号集合这一点让换模型自动适配做不到。数据流图还缺一张真正的位级对照实验同一条链在 x86-64 与 aarch64 上逐系数一致我们已在层 0–4 验证但哪些步骤位级一致、哪些只是数值等价我们只做了整链对照没有分段归因。下一篇我们下到最底层手写 negacyclic NTT——为什么不用现成库以及怎么证明自己写对了在密文计算里意味着什么。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑