机器学习笔记(18.1): Swarm-LLM
可能更好的阅读体验 Jeefy's Blog: Swarm-LLM
H:论文称之为 "normalised sequence entropy":
\[H_i(t)=-\frac{1}{N}\sum_{j=1}^{N} P_i(t_j\mid t_{<j},Q)\log P_i(t_j\mid t_{<j},Q)
\]
注意它只对实际生成出来的 token 求和,每项是 \(p\cdot -\log p\)
当 \(p \to \frac 1 e\) 时最大。
V:top-k logits 方差,每个位置取 top-k logits 向量 \(z^{(k)}\) 算方差,再对位置平均。
\[V_i(Q) = \frac 1 N \sum_{i = 1}^N {\rm Var} (z_i^{(k)})
\]
U:难度分数:
\[U_i(Q)=\alpha H_i + (1-\alpha)\hat{V}_i,\quad \hat{V}\in[0,1]
\]
对于 H,在熵大的时候,说明生成 token 的归一化概率在 0.3 左右,就代表模型在该 token 的选择非常广,也就是说模型的确定性不高。
对于 V,方差越大,说明分布越不均匀,那么直觉上和确定性正相关。
为什么是 \(H + V\)
- 代码里的实际实现(
edge_node/slm_wrapper.py的_estimate_difficulty)
outputs = self.model(**inputs) # 只对 prompt 做一次前向,不生成
logits = outputs.logits[:, -1, :] # 取最后一个位置的下一个 token 分布
probs = F.softmax(logits, dim=-1)
entropy = -(probs * (probs + eps).log()).sum().item() # 全词表真实熵
h_norm = entropy / log(vocab_size) # 归一化到 [0,1]
len_term = min(len(prompt) / 200.0, 1.0) # prompt 字符长度项
difficulty = 0.6 * h_norm + 0.4 * len_term
代码里:
- H 是真正的全词表香农熵,但只是"给定 prompt 后第一个答案 token 的分布熵",不是论文写的"生成序列上 (p\log p) 的平均";
- V 根本不存在,代码用 prompt 长度启发式(200 字符封顶归一化)替代了 top-k logit 方差;
- U = 0.6·归一化熵 + 0.4·长度项,α 固定 0.6。
flowchart TD
A["收到查询 Q"] --> B["安全分类器 C_safety(Q)<br/>计算风险分 s 与风险标志 R(Q)"]
B --> C{"R(Q) = 1 ?<br/>高风险/敏感"}
C -- "是" --> D{"WAN 可用<br/>且云预算充足?"}
D -- "是" --> E["召唤云端 FM 回答"]
D -- "否" --> F["拒答 或 本地安全回复"]
C -- "否" --> G["探针 SLM 计算难度 U(Q)<br/>= α·H + (1-α)·V̂"]
G --> H{"U(Q) < τ_low ?"}
H -- "是" --> I["Level 0: 本地 SLM 直接回答"]
H -- "否" --> J{"U(Q) < τ_high ?"}
J -- "否" --> K{"WAN 可用<br/>且云预算充足?"}
K -- "是" --> E
K -- "否" --> L["尽力而为:<br/>本地/群体回答"]
J -- "是" --> M["Level 1: 选最多 k 个 peer<br/>收集答案 {y_j}"]
M --> N["答案规范化+聚簇<br/>加权共识 S(a), w_j = 1-U_j"]
N --> O{"max S(a) ≥ γ ?"}
O -- "是" --> P["返回 swarm 共识答案"]
O -- "否" --> Q{"WAN 可用<br/>且云预算充足?"}
Q -- "是" --> E
Q -- "否" --> R["返回得分最高的<br/>swarm 答案(尽力而为)"]
E --> S[("记录 (Q, FM答案)<br/>入蒸馏缓冲池<br/>用于后续 LoRA 微调边缘模型")]

浙公网安备 33010602011771号