news 2026/10/8 11:11:22

【FHE 同态加密】我们如何实现同态加密推理(七):自举 Bootstrapping——一个不提高精度、只刷新模数链的“加油站“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【FHE 同态加密】我们如何实现同态加密推理(七):自举 Bootstrapping——一个不提高精度、只刷新模数链的“加油站“

【FHE 同态加密】我们如何实现同态加密推理(七):自举 Bootstrapping——一个不提高精度、只刷新模数链的"加油站"

关键词:同态加密 | FHE | 自举 | Bootstrapping | 模数链刷新 | coeff_to_slot | slot_to_coeff | EvalMod | 大模型密文推理

导读:自举(Bootstrapping)在同态加密里常被误解成"纠错"或"提精度"。本篇用实测数字说明它其实只是一个"加油站":把被乘法吃掉的模数链还给同态加密推理引擎,精度几乎不动。内容包含七段流水线、sin 折叠(EvalMod),以及 80% 时间花在哪两段域变换上。

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

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

0. 一句话结论

自举(bootstrapping)不提高精度,它只做一件事:把被乘法吃掉的模数链还给你。

实测证据很干净——同一层的结果,自举前后与明文参考的误差几乎不动:

| 对象 | 链长 |max|err||
|—|—|—|
|u0(lay0产出) |np=16|1.2712e-03|
|u0r112(boot0刷新后) |np=112|1.2706e-03|

链长从 16 回到 112,误差从1.2712e-03变成1.2706e-03。

如果你把自举理解成"纠错"或"提精度",那这个数字会让你困惑;把它理解成"加油"就通了——油加满了,车并没有变快。


1. 为什么必须自举

CKKS 的每一次乘法都要rescale,而rescale会切掉一个素数(本系列第 5 篇)。链长是单向消耗的。

一跳的实际数字:

阶段链长
输入112
lay消费后16
boot刷新后112

16 这个数字意味着"还能再算十几步乘法"——对于一个 28 层的模型,这远远不够。自举就是那个周期性的补给站。


2. 七段流水线(实测顺序)

驱动t23_chain.c的[boot profile]打印把整条自举摊开了,字段顺序就是执行顺序:

modraise → coeff_to_slot → rotate_k → conj_extract → sin_fold_re / sin_fold_im → restore_merge → slot_to_coeff
#段做什么对应函数
1modraise用 Garner 扩展把链抬回满链ckks_modraise()
2coeff_to_slot系数域 → 槽位域coeff_to_slot()
3rotate_kGalois 旋转ckks_rotate_k()
4conj_extract共轭提取:分出实部/虚部—
5sin_fold_re/_im对实部、虚部分别做sin折叠sin_fold()
6restore_merge还原并合并—
7slot_to_coeff槽位域 → 系数域slot_to_coeff()

图 7-1 怎么读:左列是域——modraise在系数域上做,coeff_to_slot与slot_to_coeff是两次跨域搬运,中间四段都在槽位域上逐点操作;右侧条形按实测耗时成比例,两根红框的条形(coeff_to_slot+slot_to_coeff)合起来就是那 80%。图中只画了正文 §4 给出的三个量,其余四段合计 ≈31 s,未逐段展开。

矢量版figs/fig07_bootstrap_pipeline.svg|Graphviz 源码figs/fig07_bootstrap_pipeline.dot

这个顺序本身就是答案:自举的本质是"把消息从槽位域搬到系数域,做一次取模(modular reduction),再搬回槽位域"。难点全在"搬"上。


3. 为什么要"搬":EvalMod 与 sin 折叠

在槽位域里,一个槽位装的是一个近似的实数(scale = 2^60定标)。你想对它做"取模q"这种操作,直接做不了——因为取模是在系数域上才有意义的整数操作。

于是标准做法是:

  1. modraise:把模数从当前的短链,用 Garner 扩展抬回满链。这一步把"模数空间"还给消息;
  2. coeff_to_slot:把消息从槽位域变回系数域,此时那个"需要取模的量"变成了系数的整数倍;
  3. sin_fold:用sin的周期性(sin(πx)型的倍角/折叠结构)来逼近那个取模函数。因为取模在数学上可以写成锯齿波,而锯齿波可以用sin的倍角多项式逼近;
  4. slot_to_coeff/restore_merge:搬回去。

rotate_k与conj_extract的存在,是因为"实部/虚部"要分开处理——复数的实虚部在系数域里纠缠在一起,需要用 Galois 自同构与共轭把它们分离出来,各自折叠,再合并回去。

3.1 为什么是把私钥稀疏度降到 8

一个不显然的取舍(头注释原文):

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

hw是私钥的非零系数个数,这代被设成8(CKKS_KEY_HW)。它不是随手取的:私钥越稀疏,sin折叠时产生的**混叠(aliasing)**越小(约hw/2 = 4),于是只需要9 次多项式就能逼近到位。

换句话说:为了自举的数值可行性,我们主动牺牲了密码学参数(hw越小越不安全)。作者在注释里明确标注了"原型无安全可接受"——这个取舍如果我们不写出来,读者会以为hw=8是某种安全选择。


4. 自举的代价:80% 的时间花在"搬"

boot0的实测分段(字段名与上文七段一一对应):

段耗时占比
coeff_to_slot1688 s~39%
slot_to_coeff1716 s~40%
sin_fold(实部+虚部)~850 s~20%
modraise/rotate_k/conj_extract/restore_merge其余余下
total4285.03 s100%

两个"域变换"加起来约 3400 s,占 80%。

这个结果直接否掉了我们的第一版优化直觉——“去优化多项式乘法”。乘法(NTT)确实是最热的内核,但在这条链上,时间不在卷积里,在域变换里:coeff_to_slot与slot_to_coeff每段都要做大量的 Galois 旋转和 key-switch(本系列第 6 篇那对3×2个密钥就是在这里被反复使用的)。

顺带对比:同一轮的lay0是1920 s,而boot0是4285 s。一层 1.8 小时里,有约 1.2 小时花在自举上。


5. 一个工程细节:懒初始化的并发陷阱

代码里留了一条修复记录(t23_chain.c附近):

tab_prepare(n); /* M1c 修复:coeff_to_slot/slot_to_coeff 的 omp 区并发首次触发 ... */

含义是:某些预计算表原来是在并行区里首次访问时懒初始化的。多线程同时"第一次"进入,就会并发触发初始化——这是经典的隐蔽竞态。修法是在进并行区之前显式tab_prepare。

这类 bug 的特点是:单线程永远不出现,多线程偶发。它跟本系列第 13 篇(位级可复现性)是同一类问题的两个面。


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

本文所述参数为机制验证级(n=2048、112/2100 素数链), 远低于 HE 参数标准的 128-bit 水平,不得用于保护真实数据。 本文主张的是:自举流水线的结构与实测账本。 本文不主张:安全强度、性能优越性。

特别提醒:§3.1 的hw=8是为数值可行性做的妥协,不是安全选择。请勿把本文任何参数当成可用的密码学配置。


7. 这一篇的未解问题

  1. coeff_to_slot/slot_to_coeff为什么这么贵,我们没有逐段归因。是旋转次数多?是 key-switch 的密钥太大导致缓存不友好?还是 NTT 调用次数过多?目前只有总量,没有分解。这是本项目最值得做的一块性能分析,也是收益最大的一块。
  2. hw=8与精度之间的关系没有量化。我们知道hw小→混叠小→多项式次数低,但"hw从 8 提到 16 会坏多少、慢多少"没有测。
  3. 自举的链长余量没有探边。t23boot编到 2100 素数;实际用到多少、还能压到多低,我们没有做"最小可用链长"的扫描。而链长直接决定内存与耗时。
  4. sin_fold的精度贡献与误差来源没有分离。我们只知道整链误差,不知道折叠这一步贡献了多少。

下一篇我们回到模型侧:SiLU 的密文化——两条拟合路径,以及那个只有 8 字节、却能让你算出错误答案的开关文件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 11:11:04

AI短剧制作:从剧本生成到视频合成的技术拆解与实操边界

1. 短剧行业现状与AI入局的真实图景1.1 短剧为什么成了内容行业最卷的赛道短剧这个品类,从2022年下半年开始爆发,到2024年已经成了一个年产值数百亿的庞然大物。它的核心逻辑其实特别朴素:用极低的制作成本,在极短的时间内&#x…

作者头像 李华
网站建设 2026/10/8 11:10:59

Python pygame打造植物大战僵尸识字版:中文渲染与判定全攻略

简介:一份基于Python的植物大战僵尸快乐识字版完整项目,面向Python学习者、游戏开发爱好者及需要完成课程设计的在校生。项目将经典塔防玩法与汉字学习巧妙结合,在打僵尸的趣味过程中帮助儿童认字,功能完善、界面美观、操作简单&a…

作者头像 李华
网站建设 2026/10/8 11:10:06

PDF体检与预处理:RAG知识库入库前的文档质量把控

做 RAG 的朋友应该都有过这种体验:花了大把时间调 embedding、调 prompt、调检索策略,最后回头一看,真正拖后腿的往往是那些看起来人畜无害的 PDF 文档。标题里提到的 pdf-inspector,严格来说它不是一个能装完就用的独立部署项目&…

作者头像 李华
网站建设 2026/10/8 11:09:09

从开源RAG逆向工程到自研蓝图:检索链路与数据治理实战

1. 先承认现实:RAG在真实场景里的瓶颈,比开源Demo里难看得多 我之所以决定把团队内部自研的RAG推倒重来,是因为生产环境连续三个月被同一个问题折磨:知识库检索命中率看着有80%,但用户真正满意的回答不到一半。这个数字…

作者头像 李华
网站建设 2026/10/8 11:08:59

Roo Code 本地模型卡顿优化:从模型到系统的全链路调优指南

1. 为什么本地模型在 Roo Code 里会卡成幻灯片 Roo Code 这个插件在 VSCode 生态里算是比较能打的一类 AI 编程助手,支持接入本地模型是它最吸引人的地方之一。但很多人第一次把 Ollama 或者 LM Studio 跑起来、在 Roo Code 里填好地址之后,得到的体验往…

作者头像 李华
网站建设 2026/10/8 11:08:08

25个AI Agent Skill实战:测试开发自动化体系搭建指南

1. 这套 Skill 体系到底解决了什么问题 我日常跟 AI Agent 打交道的时间,比跟真人同事说话的时间还长。从最早的 prompt 拼贴,到后来的 function calling,再到现在以 Claude Code、Codex 为代表的 Skill 机制,中间踩过的坑能写一本…

作者头像 李华