【FHE】我们如何实现同态加密推理(四):为什么我们最终放弃了 BFV——明文模上的除法如何逼死 GELU(纯 C11 · 零依赖)

项目仓库
Gitee 主仓:https://gitee.com/pei-xiaoguang/kestrel-llm
GitHub 镜像:https://github.com/m13253246268-ship-it/kestrel-llm

相关文档
术语与数据口径
性能与基准
构建与复现
快速上手
架构总览

0. 一句话结论

我们引擎里同时留着两代同态加密实现vllm_fhe.c(BFV 风格)和 vllm_ckks.c(CKKS 风格)。

换代不是因为 BFV "不好",而是因为一个非常具体的语义问题:在 BFV 的明文模环上做除法,得到的是"模数意义下的解",不是实数除法。而 Transformer 里那些非线性函数(GELU、SiLU)的逼近多项式天然带非整数系数——它们塞不进整数模环。

CKKS 用 scale 管理近似误差,才让这条路走得通。


1. BFV 那一代的真实设计

先把话说明白:第一代实现不是玩具,它有一份完整、自洽的设计。以下摘自 include/core/vllm_fhe.h 的头注释(原文):

出处
方案 Ring-LWE / BGV 风格 leveled HE(Fan-Vercauteren BFV) vllm_fhe.h
R_q = Z_q[x]/(x^n+1)n = 1024 VFHE_N_DEFAULT
密文模 q = 2^64 - 2^32 + 1Goldilocks prime,64-bit 域) VFHE_Q_BITS 64
明文模 t = 12289 VFHE_T_DEFAULT
缩放 Delta = floor(q/t),明文编码为 Delta * m(BFV scaling) 头注释
乘法语义 3 分量 tensor + (t/q) rescale;解密用 (1, s, s^2) 头注释
为什么选 t=12289 t-1 = 12288 = 6 × 2048支持 n=1024 的 SIMD 槽位打包 头注释
噪声 均匀小范围 [-B, B)B=8 VFHE_B_NOISE
私钥 稀疏三元 {-1,0,1},非零个数 hw = 64 VFHE_KEY_HW

1.1 一个刻意的取舍:不做重线性化

头注释里写得很直接(原文):

不做 relinearization:一次乘法分量数 = deg(a)+deg(b),解密使用 1, s, s^2, ... 最高 5 分量(深度 2)。

代码里的体现是:

/* 密文分量数:2 (level1) / 3 (level2) / 5 (level3) ... */
#define VFHE_CT_MAX_COMP 5

这是个典型的原型期取舍:跳过 key-switch(重线性化)能少掉一整套密钥生成与数字分解逻辑,代价是密文尺寸随深度按分量数增长,而且深度被硬顶在 2。

1.2 它已经跑通了什么

同一份头文件里列出的自测项,说明这一代确实端到端验证过:

T1 定点编码往返精度
T2 对称/公钥 加密-解密往返
T3 同态加法(含负数中心化)
T4 同态乘法(深度 1)
T5 混合表达式 ((a*b)+c) 深度 2
T6 定点数同态加/乘

注意 T4 标注"深度 1"——这不是谦虚,是硬限制。


2. 出问题的地方:非整数系数无处安放

Transformer 的非线性激活不是多项式。工程上的做法是用多项式逼近它,例如 SiLU / GELU 的逼近式、LayerNorm 里的倒数、以及自举里的 sin 折叠。

这些逼近式的系数是实数,比如 0.5x + 0.7978...x³ - ...

在 BFV 里,明文住在 Z_t(模 t 的环)里。你想表示 0.7978,只能把它"放进"模环——比如取 round(0.7978 × Delta)问题在于:接下来所有的运算都在模 t 的意义下进行,除法给出的不是实数除法,而是模逆。

于是会出现两种后果:

  1. 精度语义错位t 上的模运算结果,在解密后需要除以 Delta 才回到实数。当中间结果经过多次乘法与"除法",噪声不再只是"加性小扰动",而是与模数结构耦合——你很难再给出干净的误差界。

  2. 动态范围被 t 卡死t=12289 只有约 13.6 bit。头注释里已经标注了这条硬限制(原文):

    深 2 需 t < ~5150,仅深 1

    也就是说,为了保住深度 2 的正确性,t 要压到 5150 以下;而我们默认的 12289 只够深度 1。这与 T4 标注的"深度 1"完全对应。

这就是死结:一个 28 层的模型,加上自举内部几十层深的折叠逼近,需要的乘法深度是几十,而 BFV 原型被卡在 1~2

这里要特别说明:BFV 本身不是错的,也不是弱于 CKKS。BFV 适合精确整数运算的场景(例如需要精确的整数聚合、计票、集合运算)。我们的场景是"近似实数神经网络的推理",与 BFV 的精确整数语义天然不匹配。 头部注释里把这条判断写得很清楚,原文:

非整数系数多项式(GELU 等)在 BFV 明文模下不可行(模环除法给出模数解),CKKS 的 scale 管理 + 模数切换(rescale)天然支持——本模块解决该缺口。


3. CKKS 补上了什么

第二代 vllm_ckks.c 换了两件事:用 RNS 多素数链代替单一模数scale 代替"精确整数除法"

BFV 那代 CKKS 这代 出处
密文模 单个 64-bit Goldilocks q RNS 链CKKS_NPRIMES 个 60-bit 素数,每个 q_i ≡ 1 mod 2n vllm_ckks.h
实数编码 定点 round(x · 2^K) mod t scale = 2^60X = round(x · S) CKKS_SCALE_BITS 60
乘法后处理 (t/q) rescale(BFV scaling) rescale = 模数切换切掉一个素数,把 scale2^120 拉回 2^60 ckks_rescale()
深度瓶颈 t 的大小(t<~5150 才够深 2) 链长NPRIMES),32 个素数 ≈ 常规深 10 CKKS_NPRIMES 注释
乘法分量 不做 relin,comps = 深度+2,上限 5 relin3 → 2 分量 ckks_relin()
槽位旋转 Galois 自动态 + key-switch ckks_rotate_k()

关键的一句话:CKKS 把"精确"换成了"可控的近似"。 乘法后 scale 从 2^60 翻到 2^120rescale 切掉一个素数把它拉回来——误差不再被模数结构耦合,而是变成可以被 scale 追踪的近似误差。这才是能量化误差、逐层定标(本系列第 9 篇)的前提。

还有一个副作用值得单说:CKKS 这代的私钥非零个数从 hw=64 降到了 hw=8。原因写在头注释里(原文):

降 hw 控制 bootstrapping 折叠混叠:混叠 I ~ hw/2 = 4,sin 逼近多项式 9 次;原型无安全可接受。

也就是说,为了自举的折叠逼近能收敛,我们主动把私钥稀疏度降下来——代价是安全性进一步退化(本项目本身就不主张安全强度,见 §5)。这类"为了数值可行性牺牲密码学参数"的取舍,在原型阶段是常态,但必须写清楚。


4. 两代并存:为什么不删掉旧的那代

vllm_fhe.c 至今留在源码树里。原因有三:

  1. 它是槽位打包与定点编码的参考实现vllm_ckks.c 的头注释明确写着它复用了 vllm_fhe 的评估同态(R_t ≅ ∏ F_t)与槽位打包思想。
  2. 它是自测链条的基础vfhe_self_test() 的 T1–T6 是"最简单的正确性验证",改动底层的 NTT 或模乘时,它是最快的一道防线。
  3. 它是一份"反面教材的正本"。把"为什么这条路走不通"的原样设计留在树里,比写一篇总结文档更有说服力——注释里的那条限制(t<~5150,仅深 1)就是证据本身。

代价也很实在:两套密钥/密文结构、两套自测、两份维护成本,而且新人容易走错门。这个取舍我们目前是选择保留。


5. 安全边界(务请读完)

本文所述参数为机制验证级,远低于 HE 参数标准的 128-bit 水平,
不得用于保护真实数据。
本文主张的是:设计取舍的工程记录。
本文不主张:安全强度、性能优越性、与 BFV/CKKS 任一方案本身的优劣评判。

特别提醒:本文 §3 提到的 hw=8、非密码学 RNG、以及 n=2048,共同意味着这套实现不具备密码学安全强度。它验证的是"近似实数神经网络能不能在密文下算得动、算得对"。


6. 这一篇的未解问题

  1. t 的上界推导我们只做了实测:头注释里"深 2 需 t < ~5150"是一个经验界,我们没有把它整理成一条可复用的噪声增长公式。如果谁有干净的推导,欢迎指教。
  2. 换到 CKKS 之后的误差传播仍是逐层实测scale 让误差"可追踪",但"可追踪"不等于"有闭式界"。链尾出现的超阈项(u27t1h1=3.82e-2t3h1=7.97e-2,超出 verify_layer 默认容差 3e-2)就是这个问题的一次现形。
  3. 是否该给 BFV 那代一个明确的退役条件:目前是"保留但不用"。什么情况下可以删、什么时候必须修它,还没有判据。

下一篇我们回到密码学内核的最低层:手写 negacyclic NTT——为什么不用现成库,以及"怎么证明自己写对了"这件事在密文计算里意味着什么。

posted @ 2026-09-19 23:36  haliu  阅读(0)  评论(0)    收藏  举报