enhanced-replica-model-pack / docs /final_ensemble.md
LUCIFerace's picture
Add files using upload-large-folder tool
7186231 verified
# Final Ensemble
## 正式最终系统
本仓库的正式最终系统是一个 **7-voter Logistic Regression Stacking** 方案。它不是规则硬投票,也不是探索阶段的静态加权投票,而是基于连续分数学习出来的 stacking 模型。
正式结果入口:
- `results/final-system/ds13/ensemble_meta.json`
- `configs/ensemble_config.json`
- `results/final-system/upstream-voters/ds13/`
## 7 个 voter 包含什么
| Voter | 类型 | 仓库里保留的资产 | 在最终系统中的角色 |
|---|---|---|---|
| `qwen7b_general` | LoRA adapter | `models/qwen-adapters/general/` | 通用主力分支 |
| `qwen7b_short` | LoRA adapter | `models/qwen-adapters/short/` | 补强 76-180 字短文本 |
| `qwen7b_extreme_short` | LoRA adapter | `models/qwen-adapters/ultra-short/` | 补强 0-75 字极短文本 |
| `bert` | 微调分类模型 | `models/bert-final/` | 最终 LR 权重最高 |
| `roberta` | 微调分类模型 | `models/roberta-final/` | 与 BERT 和 Qwen 分支形成互补 |
| `FastDetectGPT` | 零样本 detector | 算法脚本 + 结果文件 | 提供生成痕迹分数 |
| `Binoculars` | 零样本 detector | 算法脚本 + 结果文件 | 提供另一类生成痕迹分数 |
这里最容易被误解的是最后两个 detector。`FastDetectGPT``Binoculars` 不是单独训练出来的新分类模型,它们是零样本检测算法分支:
- `FastDetectGPT` 使用 `Qwen2.5-3B-Instruct``Qwen2.5-3B` 的对比分数。
- `Binoculars` 也基于同一对 3B 模型,只是打分公式不同。
- 对应实现位于 `scripts/inference/run_zero_shot_detectors.py`
因此仓库不会给这两个 detector 单独保存“分类器权重目录”。它们的可交付形式是:算法说明、推理脚本、实验留档和最终分数文件。
## 最终权重如何确定
正式 DS13 系统的权重学习流程如下:
1. 收集 7 个 voter 在 dev 上的连续输出分数。
2. 构造特征矩阵,并额外加入长度特征 `len_norm = length / 1000.0`
3. 通过 `StandardScaler` 标准化特征。
4.`sklearn.linear_model.LogisticRegression(solver="lbfgs", C=1.0)` 拟合二分类 stacking 模型。
5. 在 dev 上按 F1 搜索最优阈值,得到最终推理阈值。
对应实现可从 `scripts/inference/run_logistic_regression_ensemble.py` 看出,正式参数以结果文件为准,而不是以脚本默认参数猜测。
## DS13 正式 LR 系数与阈值
以下数字直接来自 `results/final-system/ds13/ensemble_meta.json``configs/ensemble_config.json`
| Feature | Coefficient |
|---|---:|
| `bert` | 2.0188854029 |
| `qwen7b_general` | 1.8788706258 |
| `roberta` | 1.8788624937 |
| `qwen7b_short` | 1.2970493780 |
| `qwen7b_extreme_short` | 0.8596312618 |
| `FastDetectGPT` | 0.2563906985 |
| `Binoculars` | 0.2295749248 |
| `len_norm` | 0.0062348417 |
补充参数:
- `intercept = 1.6861943699`
- `threshold = 0.1307`
可以直接把这些系数理解成“正式最终系统的权重”。如果有人去看 `src/enhanced_replica/voter_registry.py`,会看到 `default_weight_champion``bucket_weights`。这些值属于 E04 / E06 探索阶段的硬投票默认值,只服务于探索期脚本,不代表正式最终 DS13 ensemble 权重。
## 分桶方式与 DS13 的 fallback
本仓库保留的 bucket 定义为:
- `extreme_short = 0-75`
- `short = 76-180`
- `general = 181+`
DS13 正式 bundle 虽然同时保存了 `lr_global``lr_bucket` 两套结果,但 `lr_bucket` 在 DS13 上没有学出单独桶模型,而是全部回退到 global:
| Bucket | `n_dev` | 是否回退到 global |
|---|---:|---|
| `extreme_short` | 1 | 是 |
| `short` | 0 | 是 |
| `general` | 9 | 是 |
这意味着:
- DS13 的 bucket 流程被保留了。
- 但因为 dev 样本极少,正式结果实际上等价于 global LR。
- 所以 DS13 上讨论“bucket 权重”没有意义,真正需要看的就是全局 LR 系数。
## 为什么会回退到 DS01 dev
DS13 dev 过小,不足以稳定拟合 7-voter LR stacking。因此最终配置明确采用了 fallback 思路:用更稳定的 dev 参考来拟合 LR,再迁移到 DS13 test 评估。仓库里保留 `results/final-system/ds01-reference/`,是为了让这条 fallback 逻辑有一个可追溯的参考 bundle。
需要注意的是,`ds01-reference` 是参考证据区,不是第二个正式最终系统入口。对于 DS13 的正式最终权重,始终以:
- `results/final-system/ds13/ensemble_meta.json`
- `configs/ensemble_config.json`
为准。
## DS13 正式最终结果
### 总体结果
- `F1 = 0.986091`
- `Accuracy = 0.986182`
- `Precision = 0.992448`
- `Recall = 0.979815`
### 子集结果
| Subset | N | F1 | Precision | Recall | Accuracy |
|---|---:|---:|---:|---:|---:|
| `normal` | 4000 | 0.997505 | 0.995518 | 0.999500 | 0.997500 |
| `mixed_attack` | 1000 | 0.962810 | 0.993603 | 0.933868 | 0.964000 |
| `paraphrase_attack` | 1000 | 0.979675 | 0.995868 | 0.964000 | 0.980000 |
| `perturbation_attack` | 1000 | 0.996000 | 0.996000 | 0.996000 | 0.996000 |
| `len_64` | 1000 | 0.940452 | 0.966245 | 0.916000 | 0.942000 |
| `len_128` | 1000 | 0.982880 | 0.989858 | 0.976000 | 0.983000 |
| `len_256` | 1000 | 0.994995 | 0.995992 | 0.994000 | 0.995000 |
| `len_512` | 1000 | 0.998004 | 0.996016 | 1.000000 | 0.998000 |
这里最值得保留的结论是:短文本仍然最难,`len_64` 明显低于长文本段。这也解释了为什么最终系统没有只保留一个通用 Qwen 分支,而是把 `short``extreme_short` 两个长度专门化 adapter 一起保留下来。
## 上游 voter 结果为什么也要保留
`results/final-system/upstream-voters/ds13/` 保存了 7 个 voter 的 dev / test 输出。保留它们不是为了让人手动拼装提交,而是为了做到两件事:
1. 让最终 DS13 ensemble 可追溯。
2. 让后续研究者能直接看到每个 voter 的分数文件,从而复算 stacking、阈值与误差来源。
## 一句话区分两类“权重”
- 正式最终系统权重:看 `results/final-system/ds13/ensemble_meta.json``configs/ensemble_config.json`
- 探索期硬投票默认值:看 `src/enhanced_replica/voter_registry.py`,只属于 E04 / E06 研究路线。