Skip to content
Bblog
返回博客列表
49 min readEnglish

Odin(正文系统名 THEMIS):Llama-3-8B 的开源 FHE 推理实现

arXiv 2609.12378 的笔记:CKKS packing 决定 LLM 同态推理的成本;论文第 4 章正文缺失,核心证据在作者开源仓库中,4.51× 不可复现。

0. 速览

一句话定位:THEMIS(工作区文件名与调查记录称 Odin,论文正文的系统名是 THEMIS,开源仓库的真名是 Homie/Holmes,见 §2.0)是一个用 GPU 加速 CKKS 把 Llama-3-8B 的 32 层前向整个跑在密文上的实现——但它只做 prefill:128 个 token、单卡 H100、366.4 秒,没有自回归解码。

维度数值条件出处
模型Meta-Llama-3-8B,32 层,d=4096,FFN=14336,GQA + SwiGLUQuaRot 旋转后的公开权重论文 §2.2 / §5.1
输入128 token,仅 prefill不解码、无 KV cache 增长论文 §6.1
端到端在线时间366.4 s单卡 H100 80 GB,32 层连续评估论文 §6.4
对比基线1651.9 s(作者自建 THOR-style Llama-3-8B)同模型、同 CKKS 参数、同硬件论文 §6.4
加速比4.51×分母不在发布范围内论文 §6.4 / docs/DESIGN.md
峰值显存58.9 GiBH100 80 GB论文 §6.4
单层(Layer 16)11.12 s(基线 60.87 s)稳态中间层论文 Table 9
状态规模每个残差边界 16 个 real 密文S=128、D=4096、32768 槽/密文docs/DESIGN.md

三个必须先记住的事实:(1) 论文的贡献章 §4 正文是空的,§5.3、§5.4.1、§5.4.2 同样只有标题,Table 10 里 FHE 实际执行的 PPL 是 XXX 占位符;(2) 4.51× 的分母是作者自己写的 THOR 适配版,其代码"remain outside this release tree",因此这个数只有作者自报这一个来源;(3) 系统的真实工程细节在仓库里比论文里多——本笔记凡是讲机制的地方都会标出证据来自「正文」还是「仓库文档」。

1. 问题与定位

1.1 为什么 CKKS 上做 LLM 时 packing 是第一位的问题

同态推理的成本由三样东西决定,而这三样都被 packing scheme(打包方案)牵着走:

  1. 密文数量:一个 4096 维 token 向量要装进多少个密文,决定乘法次数与旋转次数。
  2. 线性层的同态开销:矩阵乘在 CKKS 里必须展开成"明文对角 × 密文旋转"的 MAC(multiply-accumulate)序列,权重能不能复用编码,直接决定这一项的大小。
  3. 布局转换成本:线性层想要的布局、attention 想要的布局、非线性逐槽运算想要的布局互不相同;每换一次布局就是一次旋转/重排,模型越深、序列越长,这项越会累积。

论文对第二项给了一个非常具体的诊断(§3.4,这是全文最硬的一节):在 THOR 式的 page-diagonal 表示里,一个明文权重对象同时绑定 input page、output group、实/虚部、rotation copy 四个物理属性,只有四个属性全同才能复用同一份预编码;在 4096 隐维 + 14336 FFN 的 Llama-3 上,每层需要 425,984 个明文权重对象。于是要么预编码缓存(占存储与驻留),要么按需反复 pack/encode(占时间)。Table 2 给出后果:weight pack + encode 占线性层 44.10 s 中的 28.02 s(63.5%),其中 encoding 单项占线性时间 38.6%。

这不是"算力不够"的问题,而是"同一份逻辑权重无法把编码成本摊到多个兼容输入密文上"。THEMIS 的全部设计都从这个诊断出发。

1.2 已有系统站在哪里

论文 §1.1 把相关工作分成两条路线,这个分类值得直接搬进综述的坐标系:

  • MPC / 混合路线:Iron(HE packing 的安全矩阵乘 + Softmax/GELU/LayerNorm 协议)、PUMA(两方 LLaMA-7B)、BOLT(安全矩阵乘与非线性联合优化)、BumbleBee(低通信矩阵乘 + 激活协议)。共同代价是在线多轮通信,以及必须假设参与方不共谋。
  • 纯 HE 路线:NEXUS(研究了多种 packing 及其转换代价,但没有把转换成本放进端到端路径)、THOR(diagonal-major + compact packing,单 GPU 跑 BERT-base)、MOAI(跨模块协调 packing 以减少布局转换与旋转)、Park et al.(Llama-2-7B,区分 public 与 encrypted token 以支持更长输入)。

纯 HE 路线缺的是什么:缺一个把 packing 契约、布局转换、bootstrap 调度三者放进同一条端到端路径里的 LLM 规模实现。THOR 做到了单卡纯 HE,但只到 BERT-base、序列 128;MOAI 处理了布局转换但没到 LLM;NEXUS 分析了转换代价但没跑通端到端。THEMIS 的定位就是补这个缺口——代价是它只补了 prefill。

1.3 本文的三条主张(以及它们在正文里能落到哪)

摘要给出三条:(a) 用 feature-major 跨层布局统一残差与层间接口;(b) 用短命的算子内布局匹配线性层与 attention 的取数模式,从而减少宽投影里冗余的权重明文编码;(c) 非线性用区间上 minimax 多项式逼近 + 输入范围控制 + 由模型质量引导的联合误差分配。

问题在于 (a)(b) 的具体内容本该在 §4,而 §4 是空的。(c) 落在 §5.2,正文完整且写得相当好;性能证据落在 §6。所以本笔记的 §2 会明确区分:哪些句子是我从正文读到的,哪些是我从仓库文档读到的。

2. 方法解剖

2.0 先解决命名:四个名字一套系统

出现位置名字说明
论文正文(系统名)THEMIS全文不出现 "Odin" 这个词
工作区文件名、调查记录Odin论文化名,沿用
github.com/jizhuoran/homieHomieCUDA CKKS 张量运行时,C++/CUDA + Python API
github.com/jizhuoran/holmesHolmes多 GPU,prefill + 自回归 decode

论文里不给仓库链接,是因为双盲评审:holmes 的 README 原文写着 "This artifact has been anonymized for paper review... Upon paper acceptance, we will publish the original repository link to a verified release."(调查记录)。这也解释了名字的混乱:真实系统是 Homie 运行时 + Holmes 多 GPU(H 字头一家),Odin/THEMIS 是论文化名。

两条证据纪律,本笔记后续严格遵守:

  • 「正文」 = PDF 正文可引用的句子,标章节号。
  • 「仓库」 = 作者仓库 docs/DESIGN.md / docs/CODE_MAP.md / 代码注释,句末标来源。

2.1 canonical packing:feature-major 状态 — 仓库为主

正文能读到的只有功能性描述:§6.4 说 32 层串联时"每层收/发 FM 密文,层间无需额外布局转换",层输出仍是 16 个 real FM 密文;摘要说这个布局"统一了残差流与层间接口"。

精确契约在仓库(docs/DESIGN.md):

FM[c, slot = 8*d + u] = H[token = 8*c + u, feature = d]
 
    c = 0..15      密文下标(token shard)
    u = 0..7       shard 内的 token 偏移
    d = 0..4095    feature(channel)
 
128 token  = 16 shard * 8 token/shard
32768 slot = 8 token * 4096 feature
128 * 4096 = 524288 = 16 * 32768

每个残差边界是 16 个 real(非复数)FM 密文(docs/DESIGN.md)。相邻 token shard 在线性核内部临时配对成复数 z = x_even + i * x_odd,得到 8 个复数输入——这是算子内私有的,不改变跨层的公开状态(docs/DESIGN.md)。

这个设计有三个直接后果,值得记住:

  1. 密文数固定为 16,与层宽无关;与序列长度是线性关系(S=128 时正好铺满)。
  2. 一个明文权重的对角对齐的是"8 个 token 一起",所以同一个编码可以被 16 个 shard 中的多个复用——这正是 THOR 做不到、诊断里缺的那条复用链。
  3. 逐槽非线性(SiLU、exp、rsqrt)在 FM 上不需要重排;需要重排的只有 attention。

一个口径坑:论文 §6.1 写 "ring dimension is N = 2^16",docs/DESIGN.md 写 "N = 32768"。CKKS 里 ring dimension 为 2^16 时复数槽数为 32768,故两处可以对齐(128 * 4096 = 16 * 32768 也自洽),但两处用了同一个字母 N 表示不同的量。引用时要么写清 ring dimension,要么写清槽数,别混用。(口径对齐由本笔记核对,论文与仓库都未说明。)

2.2 线性层:BSGS MAC + 复数打包 — 正文有骨架,仓库有配置

正文先说清了一个常被混淆的点(§3.3.1):"BSGS is an evaluation strategy that reuses some rotations over a given layout rather than an independent packing scheme"。也就是说 BSGS 决定"用多少次旋转把一次矩阵乘展开",但能省多少权重编码是 packing 决定的。这个区分是读懂全文 Method 章(虽然它空着)的钥匙。

正文能给的性能证据(§6.2):Layer 0 的 PC 投影上,pack/enc 占比从 73% 降到 20%,同态评估本体从 10.03 s 降到 4.25 s(2.4×)——注意后者只有 2.4×,7.8× 的总加速主要来自"少打包"。静态操作数上,QKV 与 gate/up 的权重编码次数降到"无复用对角打包"的 1/16,W_O 与 down 降到 1/8(论文声明这是与公式的静态比较,不等于端到端实测比值)。

仓库给出了"一个 linear engine、四种调用配置"的骨架(docs/DESIGN.md):

调用输入密文形态权重明文形态carrier 语义出处
QKVreal FM,先做 token pairing复数复数明文权重编码 Q/Q、K/K、V/Vdocs/DESIGN.md
W_O已是复数 token-pair(来自 PairFM)实数模型权重复数密文 × 实数权重docs/DESIGN.md
gate/upreal FM一个复数明文投影同时搬运两个模型矩阵(multiplex)docs/DESIGN.md
down复数 token-pair实数模型权重与 W_O 同构docs/DESIGN.md

W_O / down 这一栏是可以自己算一遍的:若 z = x_e + i*x_o、权重 W 为实,则 z * W = (W x_e) + i*(W x_o)——实部与虚部恰好是两个 token 半批各自的真实结果,一次密文-明文乘拿到两份。QKV 一栏的权重本身也取复数,说明那里还有一次复数域内的重排(复数乘的实部/虚部会交叉混合 x_e 与 x_o),但 docs 没有展开符号与共轭约定,要确认必须读 operators/linear/qkv.py,本笔记不臆测。

策略归属(docs/DESIGN.md):baby step、anchor step、hoist strategy、plaintext chunk size、cache policy 全部属于 LinearOperatorConfig 与算子实例,权重不拥有 runtime policy;baby rotations 跨 plaintext chunk 复用。

2.3 attention:C–Δ 布局与"不 repack 分数" — 正文一句,仓库一张表

正文对这个机制的唯一直接证据是成本对比(§6.2):THOR 除了 CC 时间外还要 0.54 s 调整 attention 输入布局、0.85 s 把对角 Softmax 的输出 repack 成 PV 需要的 probability copies;THEMIS 的 S_Δ → P_Δ → PV 路径消掉了后者,保留了前者(QKV 输入适配)以及 attention 输出端的一次 PairFM 转换。摘要的原话是 attention 内 QK^T 直接产出 Softmax 可消费的 score、PV 直接消费概率。

布局契约在仓库(docs/DESIGN.md),注意 _C 是持久布局、_Δ 是以相对位移为索引的临时布局:

Q_C[d, q, lane]
K_Δ[d, q, lane] = K[(q + d) mod S, d, lane]
V_Δ[d, q, lane] = V[(q + d) mod S, d, lane]
S_Δ[delta, q, lane]
P_Δ[delta, q, lane]
O_C[d, q, lane]
PairFM[(2*d + lane), q]

K 与 V 沿 query 维被 shear 了 d 位之后,score 天然以 delta = q - k 为索引出现;Softmax 在那个 delta 轴上做行归约,PV 也在同一个轴上归约,所以中间那次"把分数数组转成 PV 要的概率副本"根本没有必要——docs 的原话是 "never repacks scores"——从 S_Δ 到 P_Δ 这一跳不需要重排分数。PairFM 输出转换器做一次 structured owner transpose,然后 W_O 回到持久 FM 状态(docs/DESIGN.md)。

每层内部的转换点(docs/CODE_MAP.md,按数据流顺序):

input RMSNorm(与 inter-layer bootstrap 融合)
  → complex-token QKV diagonal linear
  → 布局变换(lane/phase 重排、gathers、key shear)
  → Δ 形式 QK kernel
  → Δ-native Alg2 softmax
  → Δ PV kernel
  → PairFM 输出转换
  → feature-major W_O + 残差
  → post-attention bootstrap + RMSNorm(fused)
  → feature-major SwiGLU MLP + 残差

S_Δ/P_Δ 每个 delta 需要几次旋转、lane/phase 的具体排列,docs 只给了契约不给旋转数;静态代价模型在 operators/attention/audit.py(docs/CODE_MAP.md)。若要从论文里找这些数字,找不到——论文未报告。

2.4 非线性与归一化:本文最完整的一节(正文 §5.2)

这部分正文写得完整,可以直接引用。非线性算子层由 exp、reciprocal、rsqrt 三个构件拼出 Softmax 与 SiLU,SiLU 再与 RMSNorm 相邻使用(docs/DESIGN.md)。下面按正文顺序讲。

a) 软误差预算的起点:τ0 = 2⁻¹²(12-bit 起点,沿用 Park et al.)。§3.2.1 给出 minimax 误差随区间长度线性增长、随容差以 τ^(−1/s) 增长的界(充分非必要),§3.2.3 说明 12-bit 其实保守:即使把 δPPL 卡在 0.001,公共容差也能放宽到 2.258×10⁻³(9.25 倍)。

b) 输入范围控制(§3.2.2):先做了 WikiText-2 vs C4 的对照,算子位置 p99 幅度比中位数 = 1.0,说明两语料没有整体尺度漂移,但仍用 calibration 定区间。两类异常值分别处理:attention sink(token 维,prepend 固定 sink prefix,KV 可预算成公共静态 cache)与 QuaRot 的正交 Hadamard 旋转(feature 维,可离线折进公共权重,不增加在线同态操作)。作者强调两者不可互相替代。

c) Softmax 用 Alg1 做"倍增归约"(§5.2.1,宽/窄轨结构来自 Cho et al.):

k = ceil( log2(M_hat) - log2(ln n) )
z = x - U_hat
u(0) = p_exp(z / 2^k)
for j = 1..k:
    s(j)      = sum_i ( u_i(j-1) )^2        # 归约到 auxiliary track
    lambda(j) = p_rsqrt( s(j) )             # 窄轨,只在少量槽上算 rsqrt,然后 BS
    u(j)      = ( lambda(j) * u(j-1) )^2    # 宽轨,逐槽平方
Softmax(x) = u(k)

要点:U_hat 估小了会出区间、估大了会让指数区间变宽、k 变大;多数层共享 U_hat 与 k,Layer 31 用 head-wise U_hat 且 k = max_h k_h,目的是保持 SIMD batch 内迭代次数一致。各层实际 k:多数中间层 2,Layer 0–1 为 4,Layer 2 与 14 为 3,Layer 31 为 5(§6.4)。

d) 误差分配用 Alg2 的条件二分(§5.2.3):判据是注入扰动后的 PPL 变化 ΔPPL_inj(τ) ≤ δPPL(Eq 9);按优先级 π = [SiLU, RMSNorm2, RMSNorm1, Softmax] 逐个二分求条件上界(Eq 10)。为什么 SiLU 排第一:它在宽 14336 的 FFN 门控支路上,degree 一旦跨过乘深度边界,同时降低非线性与相邻宽线性层的成本;而 RMSNorm 的 degree 降下来不一定改变 bootstrap 位置。Table 4(δPPL = 0.001)的结果:

算子分配的容差 τ相对 2⁻¹²备注
RMSNorm19.881×10⁻³40.47×
RMSNorm29.881×10⁻³40.47×
Softmax-ex3.093×10⁻³12.67×
Softmax-rsqrt固定 2⁻¹²1×两轮 j1/j2 必经 bootstrap,不放松
SiLU1.993×10⁻²81.65×最高优先级

e) 多项式生成(§5.2.4):因为无法从 τ 反解 degree,做法是逐步加次数查端点最大误差(判据 max |f − p| ≤ τ_i),首次满足后再核相邻更低 degree 是否也满足。收益(同 12-bit 起点对比):32 层 SiLU 次数总和 2048 → 736,乘深度总和 199 → 155;全部非线性次数 24,448 → 22,694、深度 1,376 → 1,290(Table 7)。在线时间上,四段可调算子合计 0.49 → 0.23 s,完整 FFN 4.30 → 3.98 s(Table 8)。

f) 一个诚实的边界(§5.2.5):单次运算的绝对误差约 10⁻⁴(高精度配置 10⁻⁶),低于 10⁻³–2×10⁻² 的近似预算——但作者明确说这是单点结果,不能替代全模型累积误差评估,所以没把它放进搜索,只用 Poly-only vs FHE 的差分去衡量。这种"知道自己在哪儿没证据"的写法在本文里不多,值得记一笔。

g) 逐层不同次数(仓库补充,正文未说明):Layer 0 用 degree-16/32 的 RMSNorm 与 degree-48 的 SiLU,Layer 31 用 degree-128/128 与 degree-384(docs/DESIGN.md)。也就是说"每层用几个 degree"不是全局常数,而是逐层选的入口参数。

h) RMSNorm 与 bootstrap 的融合(仓库):post-attention refresh 与紧随其后的 RMSNorm 被合成一个显式 fused 算子,理由是让临时的复数配对 split scale 不要变成跨算子契约;Alg2 的 Softmax 自持 λ 的 bootstrap 算子(docs/DESIGN.md)。

2.5 bootstrap:被 §5.4 掩盖的那一层

论文对 bootstrap 只给了两句话(§6.4):MLP 残差完成后做一次 inter-layer bootstrap,把下一层 RMSNorm 及其后续计算需要的 limb 预算恢复回来;个别层 Softmax 的 k 较大时在层内额外加 bootstrap。§5.4.2 "Limb-Budget-Based Bootstrapping Schedule" 只有标题,正文没有。(正文)

仓库补上了机制(docs/DESIGN.md、docs/CODE_MAP.md):

  • 所有层共享一个 CKKS context、一份 rotation-key union、一个 bootstrap program;完整 Layer 0 创建其真实调度所需的模数容量(当前 validated 配置 depth-41,而论文正文写 modulus chain depth 37——两个口径可能分别是"容量"与"链深",本笔记不合并)。
  • drop_to_limbs / drop_levels 只降模数、不吃 depth,被用来在 bootstrap 前后对齐 level。
  • 两遍修正会静默退化(docs/CODE_MAP.md 的 Known rough edges 第 2 条):_bootstrap_with_optional_correction 把整个 iterations=2 的修正包在 except ValueError: return first 里,任一 align_to 拒绝目标状态就返回未修正的单遍密文,注释原话是 "That is a numerics change reported nowhere"。而两遍是 residual/softmax checkpoint 的生产默认(--softmax-bootstrap-iterations 2)。
  • Llama3Model.forward 里唯一一处 per-context 调整是把 qk_output_level 换成 None,原因是"绝对 Layer0 对齐目标活不过一次 bootstrap"。这句话本身说明 level 调度有多脆。

对复现的含义:只要动了 limb 预算(比如换 CKKS 参数、换多项式次数),必须先复验这条静默退化路径;作者的 smoke 套件看不见 limb 算术(docs/CODE_MAP.md)。

2.6 工程栈

层内容出处
密码学原语EasyFHE 提供 CKKS 原语与 GPU kernel论文 §6.1
张量运行时Homie:C++/CUDA,Python API,预编译 wheel homie-0.1.1+cu129-cp312调查记录
打包器Triton 写的专用对角线打包器(operators/linear/gpu_packer.py)docs/CODE_MAP.md
图与调度graph.py 的显式 level schedule + 单层计算图;LayerSchedule 只建一次并原样穿过所有签名docs/DESIGN.md
模型链model.py 的 32 层密文链;application 一次只让一层的 NumPy 权重驻留docs/DESIGN.md
server 边界止于第 32 层的输出;最终 RMSNorm、LM-head logits、token decoding 在解密后由 client 做docs/DESIGN.md
环境AMD Ryzen 9 9950X + 128 GB 主机内存,1× H100 80 GB,Python 3.12,CUDA 12.9论文 §6.1 / 调查记录
验证unit 约 30 s(含静态审计)、steady 约 3 min(单层加密,断言 L40 与墙钟带)、full 约 12 min(32 层 Paris fixture,断言 next token)docs/CODE_MAP.md

依赖归属有个小落差:论文 §6.1 只提 EasyFHE,全文不出现 Homie 这个名字(已 grep 确认);仓库里算子直接调 homie.fhe 的公共 API(docs/DESIGN.md)。引用工程栈时应写"EasyFHE 之上有 Homie 运行时",不要写成"只用 EasyFHE"。

3. 关键数字表

指标数值条件出处
参数规模8B,32 层,d=4096,FFN=14336Llama-3-8B论文 §2.2
序列长度128仅 prefill论文 §6.1
ring dimension2^16(32768 个复数槽)CKKS论文 §6.1(原文上标丢失,显示为 216)
modulus chain depth37首模 60 bit、其余 59 bit,dnum=5论文 §6.1
端到端在线时间366.4 s单卡 H100,32 层论文 §6.4
基线在线时间1651.9 s作者自建 THOR-style Llama-3-8B论文 §6.4
加速比4.51×分母不可复现论文 §6.4
峰值显存58.9 GiBH100 80 GB论文 §6.4
单层总时间(Layer 16)11.12 s(基线 60.87 s,5.5×)稳态论文 Table 9
单层线性段38.38 → 5.65 sLayer 16论文 §6.4
RMSNorm(单层)0.22 → 0.49 s(0.4×,更慢)Layer 16论文 Table 9
QKV(单层)5.71 → 1.09 s(5.2×)Layer 16论文 Table 9
QK–Softmax–PV(单层)11.70 → 1.40 s(8.4×)Layer 16论文 Table 9
W_O(单层)5.42 → 0.24 s(22.6×)Layer 16论文 Table 9
gate/up–SiLU–down(单层)27.24 → 4.32 s(6.3×)Layer 16论文 Table 9
layout conversion(单层)0.92 → 1.27 s(0.7×,更慢)Layer 16论文 Table 9
bootstrap(单层)5.10 → 2.30 s(2.2×)Layer 16论文 Table 9
Layer 0 线性(4 投影合计)41.37 → 5.32 s(7.8×)PC 投影论文 Table 5
pack/enc 占线性时间比73% → 20%Layer 0论文 §6.2
权重编码次数缩减1/16(QKV、gate/up)、1/8(W_O、down)静态计数,非实测论文 §6.2
QK^T(CC)9.88 → 0.34 s(29.1×)Layer 0论文 Table 6
THOR 额外 repack 开销0.54 s(输入布局)+ 0.85 s(Softmax 输出)Layer 0论文 §6.2
SiLU 次数总和(32 层)2048 → 73612-bit 对比 joint论文 Table 7
乘深度总和(32 层)199 → 155同上论文 Table 7
可调非线性在线时间0.49 → 0.23 s四段合计论文 Table 8
完整 FFN 在线时间4.30 → 3.98 sjoint allocation论文 Table 8
Exact PPL12.67(NLL 2.539)WikiText-2,8×128 token,1016 token论文 Table 10
Poly-only PPL12.79(ΔPPL 0.122 / 0.119)12-bit / joint allocation论文 Table 10
FHE 实测 PPLXXX(未填)—论文 Table 10
FHE 回归测试3 次重复都解出期望的 next token128-token prefill论文 §6.5
单次运算 CKKS 误差约 10⁻⁴(高精度 10⁻⁶)常规 bootstrap 位置,单点论文 §5.2.5
预编译 wheelhomie-0.1.1+cu129-cp312Python 3.12 + CUDA 12.9调查记录
硬件 profile32 GB 与 80 GB 两档具体配置未公开调查记录
仓库许可LICENSE.TBD发布时尚未确定调查记录

几个需要自己算一遍才发现的落差(本笔记核对,论文未解释):366.4 / 32 = 11.45 s/层,与 Table 9 的 11.12 s 吻合;但 1651.9 / 32 = 51.6 s/层,比 Table 9 基线的 60.87 s 低 15%,也比 Table 1 的 59.24 s 低。基线那侧的差额可能来自逐层 k 不同或计时口径(Table 1 是三次运行取值,端到端是单次),论文没给解释。

4. 证据分级与可复现性

这一节是本笔记的重点。读这篇论文时,先判断你读的是哪一层证据。

4.1 论文的空洞清单:不止第 4 章

位置论文中的状态仓库里的对应物
§4.1 Design Goals and Overview仅标题(p.7)docs/DESIGN.md
§4.2 Cross-Layer Feature-Major State and Intra-Operator Layouts仅标题(p.7)layouts/feature_major.py
§4.3 Packing-Aware Homomorphic Linear Computation仅标题(p.7)layouts/linear.py + operators/linear/
§4.4 C–Δ Attention Layout and Computation仅标题(p.7)layouts/attention.py + operators/attention/
§4.5 Layout Transitions in a Llama-3 Block仅标题(p.7)operators/attention/input.py → output.py
§4.6 Complexity and Overhead Analysis仅标题(p.7)operators/attention/audit.py
§5.3 Themis Packing Runtime仅标题(p.10)operators/linear/gpu_packer.py(Triton 打包器)
§5.4.1 / §5.4.2 调度两节仅标题(p.10)graph.py 的 level schedule + schedule.py
Table 10 的 FHE 行FHE XXX XXX XXX(未填)无替代
正文(p.12)"the final FHE PPL is XXX, a further change of XXX"无替代

也就是说:方法章(§4)整体 + 实现章的两个关键小节(§5.3、§5.4)+ 唯一的端到端质量数字(Table 10 的 FHE 行)都不存在。 这不是"某一节没写完",而是"论文的贡献空洞 + 实现空洞 + 质量空洞"三处同时出现。作者留下的 §5.2(误差分配)反而是最完整的——那一节能独立成文。

把它当"残缺说明书"读是唯一可行的方式:正文给结论与数字,仓库给机制。

4.2 4.51× 为什么不可复现

三层原因,一层比一层硬:

  1. 分母不是 THOR 的论文数字。THOR 原论文报的是 602.26 s,但那是 BERT-base、128 encrypted token、1× A100(见本文 Table 11)。THEMIS 的分母是 1651.9 s,作者自己实现的 THOR-style Llama-3-8B baseline。把这两个数混用会得到完全错误的比值。
  2. 那个基线不在发布范围。docs/DESIGN.md 末句原文:"The old THOR and LD implementations remain outside this release tree." 没有代码、没有配置、没有逐层日志,1651.9 s 无法被审计。
  3. 连基线的时间也不自洽。§3 末尾算过:51.6 s/层 vs Table 9 的 60.87 s/层,差 15%,论文没解释。

所以 4.51× 的准确表述是:"作者自报的、相对于其内部 THOR 适配基线的比值"。它不能被第三方复算,也不能被当作 THEMIS 与 THOR 系统之间的跨论文比较。论文自己在 §6.6 里也承认 Table 11 的跨系统比较不可用(硬件、模型、加密区间、计时边界全不同)——作者对这一点是诚实的,问题只出在 4.51× 这个数字太容易被单独摘出来引用。

4.3 三个复现门槛:权重、硬件、范围

  • 权重:必须用 QuaRot 转换后的 Meta-Llama-3-8B(§5.1 把 O 与 down 前的 Hadamard 折进相邻权重,calibration、多项式生成、FHE 执行用同一个转换后模型)。原始 Meta-Llama-3-8B 权重不能直接跑 32 层(调查记录)。"克隆即跑"不成立。
  • 硬件:论文报峰值 58.9 GiB → 需要 80 GB 档;但仓库 README 列了 32 GB 与 80 GB 两种 profile,CI 的 steady 门禁却断言跑在 L40(48 GB) 上(docs/CODE_MAP.md)。三档口径互不一致,而 32 GB 档如何在 58.9 GiB 峰值下工作,论文与仓库文档都未说明。
  • 范围:只有 prefill(128 token)。decode 在另一个仓库 holmes(多 GPU,2026-10-14),不在本文的测量范围;因此 366.4 s 不包含自回归解码、不包含 KV cache 增长后的开销、也不包含 client 侧的加密与解密时间(§3.1 明确 client 侧预处理与加密不计入 FHE 时间)。
  • 许可:仓库里是 LICENSE.TBD(调查记录)。

4.4 引用这篇论文时该怎么写

可以写的(有正文支撑,且限定条件):

  1. "THEMIS 报告了 Llama-3-8B 在单张 H100 上 128-token prefill 的端到端 CKKS 前向:366.4 s,峰值显存 58.9 GiB(作者自报)。"
  2. "该工作对其自建的 THOR 适配基线报出 4.51×,但该基线不在其发布范围内,比值无法独立复现。"
  3. "该工作把端到端 Llama-3 规模同态推理的瓶颈定位到权重明文编码(占其基线线性时间 63.5%),这一诊断基于可复算的逐算子分解(Table 1–2)。"
  4. 方法层面若要引 packing 契约,必须同时注明"方法章正文缺失,契约见作者仓库 docs/DESIGN.md"。

不要写的:

  • ✗ "Odin/THEMIS 比 THOR 快 4.51×"——THOR 论文的 602.26 s 是 BERT-base 且硬件不同,两个数不能连乘或相除。
  • ✗ "实现了 Llama-3-8B 的完整 FHE 推理"——只有 prefill,没有 decode。
  • ✗ "首个开源 Llama-3 FHE 实现"作为无条件事实断言——作者的原话限定了 "to the best of our knowledge",且 Holmes 的存在说明系统仍在演进。
  • ✗ 任何引用 FHE 端到端 PPL 的句子——那个格子是 XXX。

4.5 反向证据:为什么这不像伪造

给一条容易忽略的平衡:文档主动披露自己的数值缺陷。docs/CODE_MAP.md 有一节 "Known rough edges",第一条自曝 bootstrap 两遍修正的静默退化("That is a numerics change reported nowhere");Table 9 如实列出两项变慢(RMSNorm 0.4×、layout conversion 0.7×);参考文献里残留着 "Local reference PDF; final publication metadata to verify before submission"、"PDF: references/QuaRot.pdf" 这类本地便签。

这些特征共同指向一个判断:这是一份未清理的投稿稿,其工程比论文完整得多。§4 为空是真的缺陷(对可评审性、对引用都是硬伤),但它与"数据造假"是两类问题;本笔记的证据不足以支持后者,也不应该据此推定。

"论文是工程的残缺说明书"——这是我对这份材料最凝练的评价:想学方法,去读仓库;想快速了解定位与上限,读正文的 §3 和 §6。

4.6 存疑清单(逐条)

编号存疑项现状我的判断
S11651.9 s 的基线实现与逐层数据不在 release tree不可复现,只能自报引用
S251.6 vs 60.87 s/层 的 15% 缺口论文未解释存疑,可能是 k 或计时口径
S3Table 10 的 FHE PPLXXX 未填端到端质量无证据
S432 GB profile 与 58.9 GiB 峰值的关系文档未说明存疑,可能是不同 S 或不同层范围
S5论文 depth 37 vs 仓库 validated depth-41口径可能是链深 vs 容量存疑,引用时写清哪个
S6Table 1 Total 59.24 vs Table 9 Total 60.87同一 Layer 16 两个数存疑,取值/计时口径未说明
S7Softmax k 与 bootstrap 总次数论文只给分层 k,未给总 bootstrap 数论文未报告
S8Bootstrap 精度对 PPL 的影响未做系统消融;两遍修正可静默退化未解决,需读 OPTIMIZATIONS.md 复验
S9完整 32 层复现记录仓库有 full 门禁(约 12 min)但需 80 GB + QuaRot 权重未亲自复现(受硬件与权限限制)

5. 与同系列论文的关系

三篇同系列笔记构成一条从"分类"到"生成"的纵深,THEMIS 站在最深的位置:

  • 综述(./01-隐私保护Transformer推理综述.mdx)提供坐标系。它的两条主线分野是"MPC 交互式"与"HE 非交互式",并强调瓶颈会随 setup 迁移、不能用 FLOPs 衡量 PTI。THEMIS 属于 HE 非交互式一侧的末端:零在线交互、单服务器、无共谋假设——代价被换成了三个新的东西:布局契约的复杂度、bootstrap 的层级调度、以及"只做 prefill"。用综述的框架看,THEMIS 就是"瓶颈迁移"的又一个实例:它把瓶颈从 BERT 时代的线性层乘法,迁到了 packing 与 bootstrap 上。
  • BOLT(./02-BOLT-MPC与HE混合推理.mdx)是它的反面参照。BOLT 走 2PC 混合,共同优化安全矩阵乘与非线性协议,在线仍需双方持续通信。THEMIS 的路线则是"把所有交互换成服务器侧的旋转与 bootstrap"。两者在同一个算术问题上给出了两种成本结构:一边付网络往返,一边付 H100 的秒数。综述里"MPC 与 HE 的本质区别"那一节,正好可以用这一对做具体对照。
  • THOR(./03-THOR-纯CKKS推理.mdx)是它的直接前身。diagonal-major + compact packing、BSGS 重排延迟旋转、PC-MM/CC-MM 的分类,都是 THOR 的遗产。THEMIS 的贡献可以概括成一句:把 THOR 的方案推到 LLM 规模时,packing 的复用粒度不够(每层 425,984 个明文对象),于是换成 feature-major + 复数打包,把编码次数降到 1/16 或 1/8。反过来说,THEMIS 并没有推翻 THOR 的数学,它换的是"哪些物理属性必须一致才能复用编码"这个问题的答案。
  • 另一条纯 HE 岔路:Park et al. 的 Llama-2-7B 走 coefficient encoding(配合 slot encoding),代价是需要 SlotToCoeffs / CoeffsToSlots 这对同态 DFT,而它们要耗 level;§3.3.1 说 EasyFHE 里没有完整路径,所以 THEMIS 只在 slot domain 做比较。"coefficient encoding 的 Llama-2-7B" 与 "slot domain 的 THEMIS" 是纯 HE LLM 的两条技术路线,值得在综述里单列成一对,而不是当成同一路线的两个点。
  • MOAI 同样以降布局转换为目标,但停留在 BERT-base;THEMIS 的 Δ 布局与 MOAI 的保留策略是同一个问题的不同解,可并列。

6. 局限与可追问点

6.1 局限(按严重度)

  1. 方法章缺失,可评审性受损。§4 空、§5.3/§5.4 空,方法只能从仓库文档反推。任何审稿人都会因此要求重投。
  2. 端到端质量无数字。Table 10 的 FHE 行是 XXX。子系统有三条证据(3 次 next token 匹配、Poly-only PPL 12.79 对 Exact 12.67、单次运算误差 10⁻⁴),但这三条都不构成"端到端 FHE PPL 接近精确值"的证明。ΔPPL 0.119 是在多项式替换模型上算的,不是 FHE 执行的结果。
  3. 4.51× 不可审计(§4.2)。
  4. 只有 prefill。128 token 固定,无 decode,KV cache 的增长不在测量范围内。对一个"端到端"标题来说,这是范围上的实质缺口。
  5. 变慢的两项没有解释。RMSNorm 0.4×、layout conversion 0.7×,论文如实列出但未分析原因(可能是 FM 上 RMSNorm 需要跨 16 个密文归约,而 THOR 的布局在某些小算子上更省)。这正好说明"THEMIS 赢在线性层,不赢在转换与归一化"。
  6. 数值稳定性依赖一条会静默退化的路径(§2.5)。改 limb 预算就要重新验证。
  7. 安全边界窄:不保护服务器权重、不防恶意服务器/侧信道/DoS/访问模式;S 固定 128;client 必须做 embedding 与最终解码——这些是论文自己写明的(§3.1),但引用时常被忽略。
  8. 跨系统表不可比:作者已声明(§6.6),但 Table 11 仍容易被误读成排名。

6.2 可追问点

  • operators/attention/audit.py 里每个 delta 的旋转数与 gather 成本到底是多少?(论文未报告,仓库有静态模型)
  • operators/linear/qkv.py 里 QKV 复数 carrier 的共轭/符号约定是什么?为什么 QKV 用复权重而 W_O/down 用实权重?
  • 32 GB profile 的具体配置(S 更小?层数更少?只跑部分层?)与 58.9 GiB 峰值的关系。
  • bootstrap 每层几次、总次数多少?这个数字论文完全没给。
  • holmes 的 decode 性能与 KV cache 策略——如果 decode 也能跑,那"只 prefill"的局限就从"系统局限"降级为"本文测量范围的局限"。
  • 若把 δPPL 从 0.001 放宽到 0.010,端到端时间能省多少?Table 3 提示容差可到 9.84×,但论文没有做这个实验。
  • 端到端用户体验时间(含 client 侧加密与解密、网络)——论文明确排除,但这是实际部署里最关心的一个数。
  • 32 层 full 门禁的实测墙钟是否与 366.4 s 一致?仓库的 full 测试只断言 next token 和"墙钟带",不给数。

7. 自测题

Q1. 论文把端到端瓶颈定位到权重编码,依据是哪两个数字?

A:weight pack + encode 占线性层 44.10 s 中的 28.02 s(63.5%),其中 encoding 单项占线性时间 38.6%;根因是 page-diagonal 表示下每层需要 425,984 个明文权重对象,同一逻辑权重的编码成本无法摊到多个兼容输入密文上(§3.4、Table 2)。

Q2. 为什么"每层 16 个 real FM 密文"是个有意义的常数?它和 4096 维、128 token 怎么自洽?

A:FM[c, slot=8*d+u] 把 8 个 token 与 4096 个 feature 装进一个密文,8×4096 = 32768 = 槽数;128 token 需要 16 个 shard,故 16 个密文恰好铺满整条残差流(128×4096 = 16×32768)。它是常数而非随层宽变化的量,这让"层间无需额外布局转换"成为可能(docs/DESIGN.md,§6.4)。

Q3. attention 为什么能"不 repack 分数"?省掉的是哪一次重排?

A:K/V 沿 query 维被 shear 过(K_Δ[d,q,lane] = K[(q+d) mod S, d, lane]),score 天然以 delta = q−k 为索引,Softmax 的行归约与 PV 的归约共用同一根 delta 轴,所以 S_Δ → P_Δ 不需要重排;省掉的正是 THOR 那 0.85 s 的"对角 Softmax 输出 → PV 要的概率副本"。保留的是 QKV 输入适配(0.54 s)与输出端一次 PairFM 转换(§6.2、docs/DESIGN.md)。

Q4. 为什么 Softmax 的 rsqrt 不参与容差放宽?

A:Alg1 每一轮要用 p_rsqrt(s(j)) 把模长归一化,而这一步必经 bootstrap,所以它的深度不受"多项式次数"影响;既然放宽容差也省不掉这次 bootstrap,就没有放松它的收益。故 j1/j2 固定 2⁻¹²(§5.2.3、Table 4)。

Q5. 4.51× 为什么不可复现?把它写成一句可引用的话。

A:分母(1651.9 s)是作者自建的 THOR-style Llama-3-8B 基线,其实现"remain outside this release tree",因此无法审计;且它与 THOR 原论文 BERT-base 的 602.26 s 是两个不同对象。"THEMIS 报告其自建基线上 4.51×,该基线不在发布范围内。"

Q6. 这篇论文的"证据分级"该怎么记?给出三层。

A:第一层 正文可引(§3 诊断、§5.2 误差分配、§6 性能表、Table 3/4/7/8/9);第二层 仓库可考(FM 契约、attention 布局、carrier 语义、bootstrap 融合、两遍修正的静默退化);第三层 只有自报(4.51× 的分母、32 GB profile 的配置、端到端正确性的 next-token 测试)。Table 10 的 FHE 行不属于任何一层——它是空的。

8. 原文定位索引

主题论文位置仓库文档 / 代码位置
定位与三条贡献摘要、§1、§1.2(p.1–2)无
威胁模型与不保护的项§3.1(p.3)—
minimax 误差界、τ0=2⁻¹²§3.2.1(p.3–4)—
输入范围控制、sink prefix、QuaRot§3.2.2(p.4)§5.1(p.7)
公共容差搜索、Table 3§3.2.3(p.8–9)—
逐算子联合分配、Alg2、Table 4§5.2.3(p.9)—
BSGS 只是求值策略而非打包§3.3.1(p.5)—
THOR packing 与他山之石§3.3.2、Eq 6(p.5–6)—
权重编码瓶颈诊断、Table 1–2§3.4(p.6)—
方法章(正文全空)§4.1–4.6(p.7)docs/DESIGN.md 全篇
QuaRot 预处理、区间 1.2 倍扩张§5.1(p.7)—
Alg1 Softmax 倍增归约§5.2.1(p.7–8)operators/attention/softmax.py
ΔPPL 注入代理§5.2.2、Eq 9(p.8)—
多项式次数搜索、Eq 11§5.2.4(p.10)approx/
单次运算 CKKS 误差 10⁻⁴§5.2.5(p.10)—
打包运行时(正文全空)§5.3(p.10)operators/linear/gpu_packer.py(Triton)
图与 bootstrap 调度(正文全空)§5.4.1–5.4.2(p.10)graph.py、schedule.py
实验设置、硬件、CKKS 参数§6.1(p.10)application/settings.py
Layer 0 线性分解、Table 5§6.2(p.10–11)operators/linear/output.py、mlp.py
CC 分解与 repack 对比、Table 6§6.2(p.11)operators/attention/
非线性消融、Table 7–8§6.3(p.11)—
全模型与单层分解、Table 9§6.4(p.12)model.py、graph.py
模型质量、Table 10(FHE 行空)§6.5(p.12)—
跨系统比较、Table 11§6.6(p.12)—
FM 打包契约与 16 密文无docs/DESIGN.md、layouts/feature_major.py
attention C–Δ 布局与 PairFM无docs/DESIGN.md、layouts/attention.py
四个投影的 carrier 配置无docs/DESIGN.md、operators/linear/
stage 归属、调用链、验证分层无docs/CODE_MAP.md
bootstrap 两遍修正静默退化无docs/CODE_MAP.md、operators/nonlinear/bootstrap.py
"THOR/LD 不在发布树内"无docs/DESIGN.md 末句

相关阅读

评论

评论区尚未配置:部署 Twikoo 后端后,将 envId 填入 lib/site.ts。